fix volume and effect enable delay on offloaded tracks

Volume: add a method to wake up the mediaserver playback
thread when a volume command is received on an offloaded track.

Effects: call effect chain process on offloaded playback threads
asynchronously from writes to allow effect state updates while
waiting for async write callback.

Bug: 10796540.

Change-Id: Id2747ae88783575d1d7ffd6fc86fbd054ab2c739
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 6e0354d..a8a5169 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -972,13 +972,20 @@
         }
         mEnabled = false;
     } else {
-        if (thread != 0 && !mEffect->isOffloadable()) {
-            if ((thread->type() == ThreadBase::OFFLOAD)) {
+        if (thread != 0) {
+            if (thread->type() == ThreadBase::OFFLOAD) {
                 PlaybackThread *t = (PlaybackThread *)thread.get();
-                t->invalidateTracks(AUDIO_STREAM_MUSIC);
+                Mutex::Autolock _l(t->mLock);
+                t->broadcast_l();
             }
-            if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
-                thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable();
+            if (!mEffect->isOffloadable()) {
+                if (thread->type() == ThreadBase::OFFLOAD) {
+                    PlaybackThread *t = (PlaybackThread *)thread.get();
+                    t->invalidateTracks(AUDIO_STREAM_MUSIC);
+                }
+                if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
+                    thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable();
+                }
             }
         }
     }
@@ -1009,6 +1016,11 @@
     sp<ThreadBase> thread = mEffect->thread().promote();
     if (thread != 0) {
         thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+        if (thread->type() == ThreadBase::OFFLOAD) {
+            PlaybackThread *t = (PlaybackThread *)thread.get();
+            Mutex::Autolock _l(t->mLock);
+            t->broadcast_l();
+        }
     }
 
     return status;