AudioTrack: fix head position after restore

The head position transfered to the new track
by restoreTrack_l() must take into account the frames that
are dropped from the old track to avoid a non recoverable
offset in the playback head position returned to applications.

Bug: 11230062.
Change-Id: I51143a08b95e8f264ed709ae2054360315f2b8b1
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index fe258ad..395f164 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -256,6 +256,8 @@
         return mEpoch;
     }
 
+    size_t      getFramesFilled();
+
 private:
     size_t      mEpoch;
 };
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 37d50cf..507f9bc 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1662,7 +1662,9 @@
     // if the new IAudioTrack is created, createTrack_l() will modify the
     // following member variables: mAudioTrack, mCblkMemory and mCblk.
     // It will also delete the strong references on previous IAudioTrack and IMemory
-    size_t position = mProxy->getPosition();
+
+    // take the frames that will be lost by track recreation into account in saved position
+    size_t position = mProxy->getPosition() + mProxy->getFramesFilled();
     mNewPosition = position + mUpdatePeriod;
     size_t bufferPosition = mStaticProxy != NULL ? mStaticProxy->getBufferPosition() : 0;
     result = createTrack_l(mStreamType,
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 4fd92b2..da73d65 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -316,6 +316,27 @@
             (mFrameCountP2 - 1);
 }
 
+size_t ClientProxy::getFramesFilled() {
+    audio_track_cblk_t* cblk = mCblk;
+    int32_t front;
+    int32_t rear;
+
+    if (mIsOut) {
+        front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
+        rear = cblk->u.mStreaming.mRear;
+    } else {
+        rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
+        front = cblk->u.mStreaming.mFront;
+    }
+    ssize_t filled = rear - front;
+    // pipe should not be overfull
+    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
+        ALOGE("Shared memory control block is corrupt (filled=%d); shutting down", filled);
+        return 0;
+    }
+    return (size_t)filled;
+}
+
 // ---------------------------------------------------------------------------
 
 void AudioTrackClientProxy::flush()