Report underruns for fast tracks also

This fixes a regression that was introduced earlier
by commit 9f80dd223d83d9bb9077fb6baee056cee4eaf7e5
called "New control block for AudioTrack and AudioRecord".
That commit broke underrun reporting for fast tracks.

Also remove Track::mUnderrunCount, which counted the number of underrun
events, and was only used by dumpsys media.audio_flinger.

Now dumpsys media.audio_flinger reports the number of underrun frames,

Isolated underrun-related control block accesses via the proxy, so that
the server is not directly poking around in the control block.

The new proxy APIs are AudioTrackServerProxy::getUnderrunFrames() and
AudioTrackServerProxy::tallyUnderrunFrames().  getUnderrunFrames() returns
a rolling counter for streaming tracks, or zero for static buffer tracks
which never underrun, but do a kind of 'pause' at end of buffer.
tallyUnderrunFrames() increments the counter by a specified number of frames.

Change-Id: Ib31fd73eb17cbb23888ce3af8ff29f471f5bd5a2
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d9c312e..0c1cc35 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2739,8 +2739,10 @@
             track->mObservedUnderruns = underruns;
             // don't count underruns that occur while stopping or pausing
             // or stopped which can occur when flush() is called while active
-            if (!(track->isStopping() || track->isPausing() || track->isStopped())) {
-                track->mUnderrunCount += recentUnderruns;
+            if (!(track->isStopping() || track->isPausing() || track->isStopped()) &&
+                    recentUnderruns > 0) {
+                // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun
+                track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount);
             }
 
             // This is similar to the state machine for normal tracks,
@@ -3056,12 +3058,8 @@
                 mixerStatus = MIXER_TRACKS_READY;
             }
         } else {
-            // only implemented for normal tracks, not fast tracks
             if (framesReady < desiredFrames && !track->isStopped() && !track->isPaused()) {
-                // we missed desiredFrames whatever the actual number of frames missing was
-                cblk->u.mStreaming.mUnderrunFrames += desiredFrames;
-                // FIXME also wake futex so that underrun is noticed more quickly
-                (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags);
+                track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
             }
             // clear effect chain input buffer if an active track underruns to avoid sending
             // previous audio buffer again to effects
@@ -3086,7 +3084,6 @@
                     tracksToRemove->add(track);
                 }
             } else {
-                track->mUnderrunCount++;
                 // No buffers for this track. Give it a few chances to
                 // fill a buffer, then remove it from active list.
                 if (--(track->mRetryCount) <= 0) {