audioflinger: offload: fix pause/flush/resume

If a pause/flush/resume sequence is fast enough, resume is received while
we are still in PAUSING state in which case it is a NOP. If this happens,
flush is still forwarded to the audio HAL but is not preceeded by a pause
which can cause problems to the audio DSP.
It is necessary to preserve the flush as this sequence is typical to a seek.

The fix consists in forcing a pause/resume when a flush request must be
executed and the audio HAL has not been paused previously.

Bug: 11081559.
Change-Id: Ib84ed26d503a61c05933b923ec556b10cedfe140
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 943a70e..b618eff 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3864,6 +3864,7 @@
         AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
     :   DirectOutputThread(audioFlinger, output, id, device, OFFLOAD),
         mHwPaused(false),
+        mFlushPending(false),
         mPausedBytesRemaining(0)
 {
 }
@@ -4029,9 +4030,15 @@
         processVolume_l(track, last);
     }
 
-    // make sure the pause/flush/resume sequence is executed in the right order
-    if (doHwPause) {
+    // make sure the pause/flush/resume sequence is executed in the right order.
+    // If a flush is pending and a track is active but the HW is not paused, force a HW pause
+    // before flush and then resume HW. This can happen in case of pause/flush/resume
+    // if resume is received before pause is executed.
+    if (doHwPause || (mFlushPending && !mHwPaused && (count != 0))) {
         mOutput->stream->pause(mOutput->stream);
+        if (!doHwPause) {
+            doHwResume = true;
+        }
     }
     if (mFlushPending) {
         flushHw_l();