summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlper Nebi Yasak <alpernebiyasak@gmail.com>2021-06-24 09:11:59 +0300
committerAlper Nebi Yasak <alpernebiyasak@gmail.com>2022-06-28 15:08:45 +0300
commitc83b34516929214876bd2c46b5f346e53a3adcf7 (patch)
tree07f4f7013500a71749db68b78536c7aaff3520d8
parent9b06e8fef43b161b85bf860e39a73492cd02bfb5 (diff)
downloadpulseaudio-c83b34516929214876bd2c46b5f346e53a3adcf7.tar.gz
alsa-ucm: Add enable, disable, status helpers for devices
Right now manipulating device status is done inline once while setting a port. However, we will need to reuse this code to disable conflicting devices of a device we want to enable. Split it into enable and disable helper functions. There is another issue with the device enable logic, where trying to disabling an already disabled device sometimes fails. To avoid that, implement a status helper and check if the device we want to enable is already enabled/disabled before trying to do so. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
-rw-r--r--src/modules/alsa/alsa-ucm.c81
1 files changed, 63 insertions, 18 deletions
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index 858aa011a..7b857785d 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -631,6 +631,59 @@ static int ucm_get_devices(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr) {
return 0;
};
+static long ucm_device_status(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev) {
+ const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+ char *devstatus;
+ long status = 0;
+
+ devstatus = pa_sprintf_malloc("_devstatus/%s", dev_name);
+ if (snd_use_case_geti(ucm->ucm_mgr, devstatus, &status) < 0) {
+ pa_log_debug("Failed to get status for UCM device %s", dev_name);
+ status = -1;
+ }
+ pa_xfree(devstatus);
+
+ return status;
+}
+
+static int ucm_device_disable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev) {
+ const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+ /* If any of dev's conflicting devices is enabled, trying to disable
+ * dev gives an error despite the fact that it's already disabled.
+ * Check that dev is enabled to avoid this error. */
+ if (ucm_device_status(ucm, dev) == 0) {
+ pa_log_debug("UCM device %s is already disabled", dev_name);
+ return 0;
+ }
+
+ pa_log_debug("Disabling UCM device %s", dev_name);
+ if (snd_use_case_set(ucm->ucm_mgr, "_disdev", dev_name) < 0) {
+ pa_log("Failed to disable UCM device %s", dev_name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ucm_device_enable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev) {
+ const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+ /* We don't need to enable devices that are already enabled */
+ if (ucm_device_status(ucm, dev) > 0) {
+ pa_log_debug("UCM device %s is already enabled", dev_name);
+ return 0;
+ }
+
+ pa_log_debug("Enabling UCM device %s", dev_name);
+ if (snd_use_case_set(ucm->ucm_mgr, "_enadev", dev_name) < 0) {
+ pa_log("Failed to enable UCM device %s", dev_name);
+ return -1;
+ }
+
+ return 0;
+}
+
static int ucm_get_modifiers(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr) {
const char **mod_list;
int num_mod, i;
@@ -1417,7 +1470,7 @@ int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *p
int i;
int ret = 0;
pa_alsa_ucm_config *ucm;
- const char **enable_devs;
+ pa_alsa_ucm_device **enable_devs;
int enable_num = 0;
uint32_t idx;
pa_alsa_ucm_device *dev;
@@ -1427,31 +1480,23 @@ int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *p
ucm = context->ucm;
pa_assert(ucm->ucm_mgr);
- enable_devs = pa_xnew(const char *, pa_idxset_size(context->ucm_devices));
+ enable_devs = pa_xnew(pa_alsa_ucm_device *, pa_idxset_size(context->ucm_devices));
/* first disable then enable */
PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
if (ucm_port_contains(port->name, dev_name, is_sink))
- enable_devs[enable_num++] = dev_name;
- else {
- pa_log_debug("Disable ucm device %s", dev_name);
- if (snd_use_case_set(ucm->ucm_mgr, "_disdev", dev_name) > 0) {
- pa_log("Failed to disable ucm device %s", dev_name);
- ret = -1;
- break;
- }
- }
- }
+ enable_devs[enable_num++] = dev;
+ else
+ ret = ucm_device_disable(ucm, dev);
- for (i = 0; i < enable_num; i++) {
- pa_log_debug("Enable ucm device %s", enable_devs[i]);
- if (snd_use_case_set(ucm->ucm_mgr, "_enadev", enable_devs[i]) < 0) {
- pa_log("Failed to enable ucm device %s", enable_devs[i]);
- ret = -1;
+ if (ret < 0)
break;
- }
+ }
+
+ for (i = 0; i < enable_num && ret == 0; i++) {
+ ret = ucm_device_enable(ucm, enable_devs[i]);
}
pa_xfree(enable_devs);