AudioTrack: Add getUnderrunCount()

This allows an app to detect application-level output glitches.
Underrun counts survive track recreation.

Change-Id: I8eb14e92f6fc1007718a29b0666ab51ace30cdb8
Bug: 25641253
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index e458f3c..fd6a160 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -59,7 +59,8 @@
     volatile int32_t mRear;     // written by producer (output: client, input: server)
     volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
                                 // server notices and discards all data between mFront and mRear
-    volatile uint32_t mUnderrunFrames;  // server increments for each unavailable but desired frame
+    volatile uint32_t mUnderrunFrames; // server increments for each unavailable but desired frame
+    volatile uint32_t mUnderrunCount;  // server increments for each underrun occurrence
 };
 
 // Represents a single state of an AudioTrack that was created in static mode (shared memory buffer
@@ -174,8 +175,6 @@
 
     volatile    int32_t     mFlags;         // combinations of CBLK_*
 
-                // Cache line boundary (32 bytes)
-
 public:
                 union {
                     AudioTrackSharedStreaming   mStreaming;
@@ -347,6 +346,9 @@
     virtual uint32_t    getUnderrunFrames() const {
         return mCblk->u.mStreaming.mUnderrunFrames;
     }
+    virtual uint32_t    getUnderrunCount() const {
+        return mCblk->u.mStreaming.mUnderrunCount;
+    }
 
     bool        clearStreamEndDone();   // and return previous value
 
@@ -471,7 +473,8 @@
     AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
             size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
         : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
-          mPlaybackRateObserver(&cblk->mPlaybackRateQueue) {
+          mPlaybackRateObserver(&cblk->mPlaybackRateQueue),
+          mUnderrunCount(0), mUnderrunning(false) {
         mCblk->mSampleRate = sampleRate;
         mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
     }
@@ -514,6 +517,10 @@
 private:
     AudioPlaybackRate             mPlaybackRate;  // last observed playback rate
     PlaybackRateQueue::Observer   mPlaybackRateObserver;
+
+    // The server keeps a copy here where it is safe from the client.
+    uint32_t                      mUnderrunCount; // echoed to mCblk
+    bool                          mUnderrunning;  // used to detect edge of underrun
 };
 
 class StaticAudioTrackServerProxy : public AudioTrackServerProxy {