From 08f6e5054416273cfa19ab12b8b17c9207eb55b3 Mon Sep 17 00:00:00 2001 From: Hsin-Yu Chao Date: Fri, 7 Oct 2016 15:43:47 +0800 Subject: CRAS: iodev - Fix no stream playback state transition When the last output stream is removed, iodev transits to the NO_STREAM_RUN state if it was in NORMAL_RUN state. However this iodev may not started yet if the output stream was added and then removed right away. This bug causes failure for test audio_CrasOutputStress on Samus because its internal speaker open could take 150 ms long so that the 1st short life stream has destroyed already. And the incorrect state change causes the iodev never started, hence its buffer level accumulates to 65535. BUG=chromium:623868 TEST=test_that -b samus audio_CrasOutputStress should pass Change-Id: Iba282e1f09a3b611cd1d4c4021667fd91d8a2781 Reviewed-on: https://chromium-review.googlesource.com/394457 Commit-Ready: Cheng-Yi Chiang Tested-by: Hsinyu Chao Reviewed-by: Hsinyu Chao Reviewed-by: Dylan Reid --- cras/src/server/cras_iodev.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'cras') diff --git a/cras/src/server/cras_iodev.c b/cras/src/server/cras_iodev.c index 3490ac53..5dc6405f 100644 --- a/cras/src/server/cras_iodev.c +++ b/cras/src/server/cras_iodev.c @@ -127,6 +127,13 @@ static int cras_iodev_no_stream_playback_transition(struct cras_iodev *odev, if (odev->direction != CRAS_STREAM_OUTPUT) return -EINVAL; + /* This function is for transition between normal run and + * no stream run state. + */ + if ((odev->state != CRAS_IODEV_STATE_NORMAL_RUN) && + (odev->state != CRAS_IODEV_STATE_NO_STREAM_RUN)) + return -EINVAL; + if (enable) { ATLOG(atlog, AUDIO_THREAD_ODEV_NO_STREAMS, odev->info.idx, 0, 0); @@ -712,11 +719,12 @@ struct dev_stream *cras_iodev_rm_stream(struct cras_iodev *iodev, buffer_share_destroy(iodev->buf_state); iodev->buf_state = NULL; iodev->min_cb_level = old_min_cb_level; - /* Let output device transit into no stream state. - * Leave input device in normal run state. */ - if (iodev->direction == CRAS_STREAM_OUTPUT) { + /* Let output device transit into no stream state if it's + * in normal run state now. Leave input device in normal + * run state. */ + if ((iodev->direction == CRAS_STREAM_OUTPUT) && + (iodev->state == CRAS_IODEV_STATE_NORMAL_RUN)) cras_iodev_no_stream_playback_transition(iodev, 1); - } } return ret; } -- cgit v1.2.3