audio flinger: fix standby on output with HW A/V sync

Fix a bug in audio HAL pause logic on output threads with
HW A/V sync preventing the HAL to enter standby when
the audio track is stopped and detroyed.

Bug: 19980184.

Change-Id: Ia497dad23159038b447fcbc18a67bb61b70b79cc
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 5988d2c..4efb3d7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4316,6 +4316,10 @@
             }
             if (track->isStopping_1()) {
                 track->mState = TrackBase::STOPPING_2;
+                if (last && mHwPaused) {
+                     doHwResume = true;
+                     mHwPaused = false;
+                 }
             }
             if ((track->sharedBuffer() != 0) || track->isStopped() ||
                     track->isStopping_2() || track->isPaused()) {
@@ -4455,14 +4459,17 @@
 bool AudioFlinger::DirectOutputThread::shouldStandby_l()
 {
     bool trackPaused = false;
+    bool trackStopped = false;
 
     // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack
     // after a timeout and we will enter standby then.
     if (mTracks.size() > 0) {
         trackPaused = mTracks[mTracks.size() - 1]->isPaused();
+        trackStopped = mTracks[mTracks.size() - 1]->isStopped() ||
+                           mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE;
     }
 
-    return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused));
+    return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused && !trackStopped));
 }
 
 // getTrackName_l() must be called with ThreadBase::mLock held
@@ -4565,7 +4572,10 @@
 
     // use shorter standby delay as on normal output to release
     // hardware resources as soon as possible
-    if (audio_is_linear_pcm(mFormat)) {
+    // no delay on outputs with HW A/V sync
+    if (usesHwAvSync()) {
+        standbyDelay = 0;
+    } else if (audio_is_linear_pcm(mFormat)) {
         standbyDelay = microseconds(activeSleepTime*2);
     } else {
         standbyDelay = kOffloadStandbyDelayNs;