Merge "Workaround: Do not send command to a disconnected usb subsystem" into oc-dr1-dev
am: 2cfb8392cb
Change-Id: Icdf69b557873f8983b2671e76e076f0370f83791
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 36a8ba5..c7d6768 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -82,6 +82,7 @@
#define audio_extn_usb_get_max_channels(dir) (0)
#define audio_extn_usb_get_max_bit_width(dir) (0)
#define audio_extn_usb_sup_sample_rates(t, s, l) (0)
+#define audio_extn_usb_alive(adev) (false)
#else
void audio_extn_usb_init(void *adev);
void audio_extn_usb_deinit();
@@ -98,6 +99,7 @@
int audio_extn_usb_get_max_channels(bool is_playback);
int audio_extn_usb_get_max_bit_width(bool is_playback);
int audio_extn_usb_sup_sample_rates(bool is_playback, uint32_t *sr, uint32_t l);
+bool audio_extn_usb_alive(int card);
#endif
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 4b81ae2..743ba58 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -305,6 +305,7 @@
goto done;
}
+ // TODO: figure up if this wait is needed any more
while (tries--) {
if (access(path, F_OK) < 0) {
ALOGW("stream %s doesn't exist retrying\n", path);
@@ -1101,6 +1102,13 @@
return;
}
+bool audio_extn_usb_alive(int card) {
+ char path[PATH_MAX] = {0};
+ // snprintf should never fail
+ (void) snprintf(path, sizeof(path), "/proc/asound/card%u/stream0", card);
+ return access(path, F_OK) == 0;
+}
+
void audio_extn_usb_init(void *adev)
{
if (usbmod == NULL) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index fd32e77..5b5a434 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2217,6 +2217,19 @@
val = AUDIO_DEVICE_OUT_SPEAKER;
}
+ audio_devices_t new_dev = val;
+
+ // Workaround: If routing to an non existing usb device, fail gracefully
+ // The routing request will otherwise block during 10 second
+ if (audio_is_usb_out_device(new_dev) && !audio_extn_usb_alive(adev->snd_card)) {
+ ALOGW("out_set_parameters() ignoring rerouting to non existing USB card %d",
+ adev->snd_card);
+ pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
+ status = -ENOSYS;
+ goto routing_fail;
+ }
+
/*
* select_devices() call below switches all the usecases on the same
* backend to the new device. Refer to check_and_route_playback_usecases() in
@@ -2235,7 +2248,6 @@
* Because select_devices() must be called to switch back the music
* playback to headset.
*/
- audio_devices_t new_dev = val;
if (new_dev != AUDIO_DEVICE_NONE) {
bool same_dev = out->devices == new_dev;
out->devices = new_dev;
@@ -2279,6 +2291,7 @@
/*handles device and call state changes*/
audio_extn_extspk_update(adev->extspk);
}
+ routing_fail:
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
parse_compress_metadata(out, parms);
@@ -3125,16 +3138,26 @@
if (ret >= 0) {
val = atoi(value);
if (((int)in->device != val) && (val != 0) && audio_is_input_device(val) ) {
- in->device = val;
- /* If recording is in progress, change the tx device to new device */
- if (!in->standby) {
- ALOGV("update input routing change");
- // inform adm before actual routing to prevent glitches.
- if (adev->adm_on_routing_change) {
- adev->adm_on_routing_change(adev->adm_data,
- in->capture_handle);
+
+ // Workaround: If routing to an non existing usb device, fail gracefully
+ // The routing request will otherwise block during 10 second
+ if (audio_is_usb_in_device(val) && !audio_extn_usb_alive(adev->snd_card)) {
+ ALOGW("in_set_parameters() ignoring rerouting to non existing USB card %d",
+ adev->snd_card);
+ status = -ENOSYS;
+ } else {
+
+ in->device = val;
+ /* If recording is in progress, change the tx device to new device */
+ if (!in->standby) {
+ ALOGV("update input routing change");
+ // inform adm before actual routing to prevent glitches.
+ if (adev->adm_on_routing_change) {
+ adev->adm_on_routing_change(adev->adm_data,
+ in->capture_handle);
+ }
+ select_devices(adev, in->usecase);
}
- select_devices(adev, in->usecase);
}
}
}