Improve underrun handling for fast tracks

Maintain more accurate accounting of type of underrun.
Automatically remove track from active list after a series of "empty" underruns.

Change-Id: If042bf80e1790dcaaf195c99dc9c0ed9b55382c1
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 04d0f65..cd55396 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -360,20 +360,25 @@
                 // in the overall fast mix cycle being delayed.  Should use a non-blocking FIFO.
                 size_t framesReady = fastTrack->mBufferProvider->framesReady();
                 FastTrackDump *ftDump = &dumpState->mTracks[i];
-                uint32_t underruns = ftDump->mUnderruns;
+                FastTrackUnderruns underruns = ftDump->mUnderruns;
                 if (framesReady < frameCount) {
                     ATRACE_INT("underrun", i);
-                    ftDump->mUnderruns = (underruns + 2) | 1;
                     if (framesReady == 0) {
+                        underruns.mBitFields.mEmpty++;
+                        underruns.mBitFields.mMostRecent = UNDERRUN_EMPTY;
                         mixer->disable(name);
                     } else {
                         // allow mixing partial buffer
+                        underruns.mBitFields.mPartial++;
+                        underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
                         mixer->enable(name);
                     }
-                } else if (underruns & 1) {
-                    ftDump->mUnderruns = underruns & ~1;
+                } else {
+                    underruns.mBitFields.mFull++;
+                    underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
                     mixer->enable(name);
                 }
+                ftDump->mUnderruns = underruns;
             }
             // process() is CPU-bound
             mixer->process(AudioBufferProvider::kInvalidPTS);