audioflinger: fix crash when starting offload thread

Passing a sp to parent thread to AsyncCallbackThread() constructor
causes a strong reference to be acquired on the OffloadThread inside
its constructor which causes an early launch of the thread loop
with unpredictable consequences.

Pass a wp to parent thread instead.

Also move the creation of the AsyncCallbackThread to
readOutputParameters() where mUseAsyncWrite is initialized which
makes more sense.

Also change the type of AsyncCallbackThread parent thread to PlaybackThread
instead of OffloadThread to allow a broder use of non blocking write which
in theory is not limited to audio offload use case.

Bug: 8174034.
Change-Id: I4b093b022030cd4f5eb8b8e477333e91098a6549
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b771e3b..2d9d485 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1594,6 +1594,7 @@
         if (mOutput->stream->set_callback(mOutput->stream,
                                       AudioFlinger::PlaybackThread::asyncCallback, this) == 0) {
             mUseAsyncWrite = true;
+            mCallbackThread = new AudioFlinger::AsyncCallbackThread(this);
         }
     }
 
@@ -3746,9 +3747,9 @@
 // ----------------------------------------------------------------------------
 
 AudioFlinger::AsyncCallbackThread::AsyncCallbackThread(
-        const sp<AudioFlinger::OffloadThread>& offloadThread)
+        const wp<AudioFlinger::PlaybackThread>& playbackThread)
     :   Thread(false /*canCallJava*/),
-        mOffloadThread(offloadThread),
+        mPlaybackThread(playbackThread),
         mWriteAckSequence(0),
         mDrainSequence(0)
 {
@@ -3783,13 +3784,13 @@
             mDrainSequence &= ~1;
         }
         {
-            sp<AudioFlinger::OffloadThread> offloadThread = mOffloadThread.promote();
-            if (offloadThread != 0) {
+            sp<AudioFlinger::PlaybackThread> playbackThread = mPlaybackThread.promote();
+            if (playbackThread != 0) {
                 if (writeAckSequence & 1) {
-                    offloadThread->resetWriteBlocked(writeAckSequence >> 1);
+                    playbackThread->resetWriteBlocked(writeAckSequence >> 1);
                 }
                 if (drainSequence & 1) {
-                    offloadThread->resetDraining(drainSequence >> 1);
+                    playbackThread->resetDraining(drainSequence >> 1);
                 }
             }
         }
@@ -3847,7 +3848,6 @@
         mHwPaused(false),
         mPausedBytesRemaining(0)
 {
-    mCallbackThread = new AudioFlinger::AsyncCallbackThread(this);
 }
 
 AudioFlinger::OffloadThread::~OffloadThread()
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 443b8d7..241424f 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -759,7 +759,7 @@
 class AsyncCallbackThread : public Thread {
 public:
 
-    AsyncCallbackThread(const sp<OffloadThread>& offloadThread);
+    AsyncCallbackThread(const wp<PlaybackThread>& playbackThread);
 
     virtual             ~AsyncCallbackThread();
 
@@ -776,17 +776,17 @@
             void        resetDraining();
 
 private:
-    wp<OffloadThread>   mOffloadThread;
+    const wp<PlaybackThread>   mPlaybackThread;
     // mWriteAckSequence corresponds to the last write sequence passed by the offload thread via
     // setWriteBlocked(). The sequence is shifted one bit to the left and the lsb is used
     // to indicate that the callback has been received via resetWriteBlocked()
-    uint32_t            mWriteAckSequence;
+    uint32_t                   mWriteAckSequence;
     // mDrainSequence corresponds to the last drain sequence passed by the offload thread via
     // setDraining(). The sequence is shifted one bit to the left and the lsb is used
     // to indicate that the callback has been received via resetDraining()
-    uint32_t            mDrainSequence;
-    Condition           mWaitWorkCV;
-    Mutex               mLock;
+    uint32_t                   mDrainSequence;
+    Condition                  mWaitWorkCV;
+    Mutex                      mLock;
 };
 
 class DuplicatingThread : public MixerThread {