mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
card: Add messages to enable/disable jack detection
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.
This commit is contained in:
parent
58521c05e8
commit
f178a5b12e
7 changed files with 95 additions and 21 deletions
|
|
@ -47,3 +47,28 @@ Object path: /card/<card_name>
|
|||
Message: get-profile-sticky
|
||||
Parameters: None
|
||||
Return value: JSON "true" or "false"
|
||||
|
||||
Object path: /cards/<card_name>
|
||||
Message: set-jack-detection
|
||||
Parameters: {"port_name|all":true|false}
|
||||
Return value: None
|
||||
|
||||
Object path: /cards/<card_name>
|
||||
Message: get-jack-detection
|
||||
Parameters: "port_name|all"
|
||||
Return value: {"port_name":true|false}
|
||||
If "all" is specified, the returned object looks different:
|
||||
{"Card name":"card_name", "Detection states":{"port_name":true|false, ...}}
|
||||
|
||||
Object path: /cards/<card_name>
|
||||
Message: set-port-state
|
||||
Parameters: {"port_name|all":0|1|2}
|
||||
Return value: None
|
||||
0=unknown, 1=no, 2=yes
|
||||
|
||||
Object path: /cards/<card_name>
|
||||
Message: get-port-state
|
||||
Parameters: "port_name|all"
|
||||
Return value: {"port_name":0|1|2}
|
||||
If "all" is specified, the returned object looks different:
|
||||
{"Card name":"card_name", "Port states":{"port_name":0|1|2, ...}}
|
||||
|
|
|
|||
|
|
@ -2480,7 +2480,7 @@ static void device_set_available(pa_alsa_ucm_device *device, pa_available_t avai
|
|||
device->available = available;
|
||||
|
||||
PA_DYNARRAY_FOREACH(port, device->ucm_ports, idx)
|
||||
pa_device_port_set_available(port->core_port, port->device->available);
|
||||
pa_device_port_set_available(port->core_port, port->device->available, false);
|
||||
}
|
||||
|
||||
void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device) {
|
||||
|
|
@ -2519,7 +2519,7 @@ static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *
|
|||
port->paths = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
|
||||
(pa_free_cb_t) pa_alsa_path_free);
|
||||
|
||||
pa_device_port_set_available(port->core_port, port->device->available);
|
||||
pa_device_port_set_available(port->core_port, port->device->available, false);
|
||||
}
|
||||
|
||||
static void ucm_port_data_free(pa_device_port *port) {
|
||||
|
|
|
|||
|
|
@ -435,10 +435,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;
|
||||
|
|
|
|||
|
|
@ -2340,9 +2340,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);
|
||||
|
|
|
|||
|
|
@ -163,10 +163,10 @@ static int card_message_handler(const char *object_path, const char *message, co
|
|||
pa_card *c = userdata;
|
||||
const char *port_name;
|
||||
bool jack_detection;
|
||||
int64_t port_state;
|
||||
void *state = NULL;
|
||||
pa_device_port *port = NULL;
|
||||
const pa_json_object *o;
|
||||
int64_t current_state;
|
||||
char *message_handler_path;
|
||||
|
||||
pa_assert(c);
|
||||
|
|
@ -240,7 +240,7 @@ static int card_message_handler(const char *object_path, const char *message, co
|
|||
pa_log_info("Parameters type does not match message command");
|
||||
return -PA_ERR_INVALID;
|
||||
}
|
||||
current_state = pa_json_object_get_int(o);
|
||||
port_state = pa_json_object_get_int(o);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -256,15 +256,35 @@ static int card_message_handler(const char *object_path, const char *message, co
|
|||
}
|
||||
}
|
||||
|
||||
state = NULL;
|
||||
|
||||
if (pa_streq(message, "set-jack-detection")) {
|
||||
|
||||
if (!port) {
|
||||
|
||||
PA_HASHMAP_FOREACH(port, c->ports, state)
|
||||
port->jack_detection = jack_detection;
|
||||
PA_HASHMAP_FOREACH(port, c->ports, state) {
|
||||
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;
|
||||
|
||||
port->jack_detection = 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;
|
||||
|
||||
|
|
@ -291,10 +311,25 @@ static int card_message_handler(const char *object_path, const char *message, co
|
|||
|
||||
} 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;
|
||||
/* 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, state) {
|
||||
|
||||
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_json_encoder *encoder;
|
||||
|
|
@ -306,14 +341,14 @@ static int card_message_handler(const char *object_path, const char *message, co
|
|||
|
||||
pa_json_encoder_begin_member_object(encoder, "Port states");
|
||||
PA_HASHMAP_FOREACH(port, c->ports, state) {
|
||||
current_state = port->available;
|
||||
pa_json_encoder_add_member_int(encoder, port->name, current_state);
|
||||
port_state = port->available;
|
||||
pa_json_encoder_add_member_int(encoder, port->name, port_state);
|
||||
}
|
||||
pa_json_encoder_end_object(encoder);
|
||||
|
||||
} else {
|
||||
current_state = port->available;
|
||||
pa_json_encoder_add_member_int(encoder, port->name, current_state);
|
||||
port_state = port->available;
|
||||
pa_json_encoder_add_member_int(encoder, port->name, port_state);
|
||||
}
|
||||
pa_json_encoder_end_object(encoder);
|
||||
|
||||
|
|
|
|||
|
|
@ -90,12 +90,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;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ struct pa_device_port {
|
|||
unsigned priority;
|
||||
pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
|
||||
char *availability_group; /* a string indentifier which determine the group of devices handling the available state simulteneously */
|
||||
pa_available_t hw_available;
|
||||
|
||||
pa_proplist *proplist;
|
||||
pa_hashmap *profiles; /* Does not own the profiles */
|
||||
|
|
@ -88,7 +89,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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue