Merge "Put usb stream into standby on disconnection if offloading" into oc-dr1-dev
am: 8f3ad15ee5
Change-Id: I26555e7f56fb5ea719a732da2e848211328a6c67
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 32f2def..7f91a24 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2067,16 +2067,13 @@
return -ENOSYS;
}
-static int out_standby(struct audio_stream *stream)
+/* must be called with out->lock locked */
+static int out_standby_l(struct audio_stream *stream)
{
struct stream_out *out = (struct stream_out *)stream;
struct audio_device *adev = out->dev;
bool do_stop = true;
- ALOGV("%s: enter: usecase(%d: %s)", __func__,
- out->usecase, use_case_table[out->usecase]);
-
- lock_output_stream(out);
if (!out->standby) {
if (adev->adm_deregister_stream)
adev->adm_deregister_stream(adev->adm_data, out->handle);
@@ -2105,6 +2102,18 @@
}
pthread_mutex_unlock(&adev->lock);
}
+ return 0;
+}
+
+static int out_standby(struct audio_stream *stream)
+{
+ struct stream_out *out = (struct stream_out *)stream;
+
+ ALOGV("%s: enter: usecase(%d: %s)", __func__,
+ out->usecase, use_case_table[out->usecase]);
+
+ lock_output_stream(out);
+ out_standby_l(stream);
pthread_mutex_unlock(&out->lock);
ALOGV("%s: exit", __func__);
return 0;
@@ -2220,7 +2229,19 @@
ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
if (ret >= 0) {
val = atoi(value);
+
lock_output_stream(out);
+
+ // The usb driver needs to be closed after usb device disconnection
+ // otherwise audio is no longer played on the new usb devices.
+ // By forcing the stream in standby, the usb stack refcount drops to 0
+ // and the driver is closed.
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD && val == AUDIO_DEVICE_NONE &&
+ audio_is_usb_out_device(out->devices)) {
+ ALOGD("%s() putting the usb device in standby after disconnection", __func__);
+ out_standby_l(&out->stream.common);
+ }
+
pthread_mutex_lock(&adev->lock);
/*