hal: Fix combo device issue with routing change
- If one of the split backends match with derived sound
device, we are disabling only the backends that do not
match with derived sound device. This was introduced
with Change-Id: I171fbead85746a2a34632f7580f56ef40505665c
- However, the change does not clean up the combo device
which is being disabled.
- We need to decrement reference count of combo device and
send some updates for combo device along with the change
mentioned above. Not doing this can lead to combo device
not getting enabled on subsequent tries.
This change fixes the above issue.
- Also, if one of the split backends matches with derived
sound device, do not re-enable the device.
Change-Id: Id1bd00bfa5f0236400529e5771851749421ac84c
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index d3e7a5f..a3b374c 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -681,6 +681,7 @@
int audio_extn_utils_get_bit_width_from_string(const char *);
int audio_extn_utils_get_sample_rate_from_string(const char *);
int audio_extn_utils_get_channels_from_string(const char *);
+void audio_extn_utils_release_snd_device(snd_device_t snd_device);
#ifdef DS2_DOLBY_DAP_ENABLED
#define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so"
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 0a48953..433743e 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -2518,3 +2518,12 @@
return -EINVAL;
}
+
+void audio_extn_utils_release_snd_device(snd_device_t snd_device)
+{
+ audio_extn_dev_arbi_release(snd_device);
+ audio_extn_sound_trigger_update_device_status(snd_device,
+ ST_EVENT_SND_DEVICE_FREE);
+ audio_extn_listen_update_device_status(snd_device,
+ LISTEN_EVENT_SND_DEVICE_FREE);
+}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 3e3f72f..34f27e4 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1183,11 +1183,7 @@
ALOGD("%s: deinit ec ref loopback", __func__);
audio_extn_ffv_deinit_ec_ref_loopback(adev, snd_device);
}
- audio_extn_dev_arbi_release(snd_device);
- audio_extn_sound_trigger_update_device_status(snd_device,
- ST_EVENT_SND_DEVICE_FREE);
- audio_extn_listen_update_device_status(snd_device,
- LISTEN_EVENT_SND_DEVICE_FREE);
+ audio_extn_utils_release_snd_device(snd_device);
}
return 0;
@@ -1413,16 +1409,19 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (switch_device[usecase->id]) {
- /* Check if sound device to be switched can be split and if any
+ /* Check if output sound device to be switched can be split and if any
of the split devices match with derived sound device */
- platform_split_snd_device(adev->platform, usecase->out_snd_device,
- &num_devices, split_snd_devices);
- if (num_devices > 1) {
- for (i = 0; i < num_devices; i++) {
- /* Disable devices that do not match with derived sound device */
- if (split_snd_devices[i] != derive_snd_device[usecase->id]) {
- disable_snd_device(adev, split_snd_devices[i]);
+ if (platform_split_snd_device(adev->platform, usecase->out_snd_device,
+ &num_devices, split_snd_devices) == 0) {
+ adev->snd_dev_ref_cnt[usecase->out_snd_device]--;
+ if (adev->snd_dev_ref_cnt[usecase->out_snd_device] == 0) {
+ ALOGD("%s: disabling snd_device(%d)", __func__, usecase->out_snd_device);
+ for (i = 0; i < num_devices; i++) {
+ /* Disable devices that do not match with derived sound device */
+ if (split_snd_devices[i] != derive_snd_device[usecase->id])
+ disable_snd_device(adev, split_snd_devices[i]);
}
+ audio_extn_utils_release_snd_device(usecase->out_snd_device);
}
} else {
disable_snd_device(adev, usecase->out_snd_device);
@@ -1433,7 +1432,23 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (switch_device[usecase->id]) {
- enable_snd_device(adev, derive_snd_device[usecase->id]);
+ if (platform_split_snd_device(adev->platform, usecase->out_snd_device,
+ &num_devices, split_snd_devices) == 0) {
+ /* Enable derived sound device only if it does not match with
+ one of the split sound devices. This is because the matching
+ sound device was not disabled */
+ bool should_enable = true;
+ for (i = 0; i < num_devices; i++) {
+ if (derive_snd_device[usecase->id] == split_snd_devices[i]) {
+ should_enable = false;
+ break;
+ }
+ }
+ if (should_enable)
+ enable_snd_device(adev, derive_snd_device[usecase->id]);
+ } else {
+ enable_snd_device(adev, derive_snd_device[usecase->id]);
+ }
}
}