Allow releaseBuffer after flush

After AudioTrack start checks for pending flush,
allow releaseBuffer on any previously obtained buffer.
For example, this can happen if the resampler has obtained
a buffer but not released the whole buffer yet.
Note that the resampler will be reading obsolete data.

Bug: 11285590
Change-Id: I0614fbb62e43604aac3089cce4b7797c87a306b5
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 395f164..7fd9379 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -360,6 +360,7 @@
     //      which must be > 0.
     //  buffer->mNonContig is unused.
     //  buffer->mRaw is unused.
+    //  ackFlush is true iff being called from Track::start to acknowledge a pending flush.
     // On exit:
     //  buffer->mFrameCount has the actual number of contiguous available frames,
     //      which is always 0 when the return status != NO_ERROR.
@@ -370,7 +371,7 @@
     //  NO_ERROR    Success, buffer->mFrameCount > 0.
     //  WOULD_BLOCK No frames are available.
     //  NO_INIT     Shared memory is corrupt.
-    virtual status_t    obtainBuffer(Buffer* buffer);
+    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush = false);
 
     // Release (some of) the frames last obtained.
     // On entry, buffer->mFrameCount should have the number of frames to release,
@@ -437,7 +438,7 @@
 public:
     virtual size_t      framesReady();
     virtual void        framesReadyIsCalledByMultipleThreads();
-    virtual status_t    obtainBuffer(Buffer* buffer);
+    virtual status_t    obtainBuffer(Buffer* buffer, bool ackFlush);
     virtual void        releaseBuffer(Buffer* buffer);
     virtual void        tallyUnderrunFrames(uint32_t frameCount);
     virtual uint32_t    getUnderrunFrames() const { return 0; }
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index da73d65..caa7900 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -506,7 +506,7 @@
 {
 }
 
-status_t ServerProxy::obtainBuffer(Buffer* buffer)
+status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
 {
     LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0);
     if (mIsShutdown) {
@@ -579,7 +579,11 @@
     buffer->mRaw = part1 > 0 ?
             &((char *) mBuffers)[(mIsOut ? front : rear) * mFrameSize] : NULL;
     buffer->mNonContig = availToServer - part1;
-    mUnreleased = part1;
+    // After flush(), allow releaseBuffer() on a previously obtained buffer;
+    // see "Acknowledge any pending flush()" in audioflinger/Tracks.cpp.
+    if (!ackFlush) {
+        mUnreleased = part1;
+    }
     return part1 > 0 ? NO_ERROR : WOULD_BLOCK;
     }
 no_init:
@@ -761,7 +765,7 @@
     return (ssize_t) position;
 }
 
-status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer)
+status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
 {
     if (mIsShutdown) {
         buffer->mFrameCount = 0;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e93833f..363bc9d 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -608,7 +608,7 @@
             // and for fast tracks the track is not yet in the fast mixer thread's active set.
             ServerProxy::Buffer buffer;
             buffer.mFrameCount = 1;
-            (void) mAudioTrackServerProxy->obtainBuffer(&buffer);
+            (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
         }
     } else {
         status = BAD_VALUE;