hal: Handle compress drain event interruption
- A spurious drain ready callback is being sent when drain
is interrupted.
- Drain buffer is an interruptible event in driver and offload
thread can expect to receive an interrupt (EINTR) while drain
is processing.
- Currently, offload thread checks only for reset (ENETRESET)
event during compress_drain before sending drain ready CB.
- Sending drain ready event CB when drain is not complete results
in EOS being triggered early.
- Fix this by checking for compress drain interruption within
offload thread loop.
CRs-Fixed: 2135703
Change-Id: Iefb1be5eee4d85b897d5d4b028a5a5788b5dcf1e
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index bbd05ee..f16326e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2734,10 +2734,11 @@
ret = -errno;
}
else if (ret == -ETIMEDOUT)
- compress_drain(out->compr);
+ ret = compress_drain(out->compr);
else
ALOGE("%s: Next track returned error %d",__func__, ret);
- if (ret != -ENETRESET) {
+ if (-ENETRESET != ret && !(-EINTR == ret &&
+ CARD_STATUS_OFFLINE == out->card_status)) {
send_callback = true;
pthread_mutex_lock(&out->lock);
out->send_new_metadata = 1;
@@ -2750,10 +2751,15 @@
break;
case OFFLOAD_CMD_DRAIN:
ALOGD("copl(%p):calling compress_drain", out);
- compress_drain(out->compr);
- ALOGD("copl(%p):calling compress_drain", out);
- send_callback = true;
- event = STREAM_CBK_EVENT_DRAIN_READY;
+ ret = compress_drain(out->compr);
+ ALOGD("copl(%p):out of compress_drain", out);
+ // EINTR check avoids drain interruption due to SSR
+ if (-ENETRESET != ret && !(-EINTR == ret &&
+ CARD_STATUS_OFFLINE == out->card_status)) {
+ send_callback = true;
+ event = STREAM_CBK_EVENT_DRAIN_READY;
+ } else
+ ALOGI("%s: Block drain ready event during SSR", __func__);
break;
case OFFLOAD_CMD_ERROR:
ALOGD("copl(%p): sending error callback to AF", out);