Workaround slow AudioTrack destruction

Bug: 10809586
Change-Id: I5f30d4deb1233e8ade8967568e40684ef680c395
diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp
index 5239b2f..37b400c 100644
--- a/media/libmedia/SoundPool.cpp
+++ b/media/libmedia/SoundPool.cpp
@@ -537,6 +537,18 @@
     mSoundPool = soundPool;
 }
 
+// This class is used to destroy a RefBase asynchronously
+class AsyncDestructThread : public Thread
+{
+public:
+    AsyncDestructThread(sp<RefBase> refBase) : mRefBase(refBase) { }
+protected:
+    virtual ~AsyncDestructThread() { }
+private:
+    virtual bool        threadLoop()    { return false; }
+    const   sp<RefBase> mRefBase;
+};
+
 // call with sound pool lock held
 void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume,
         float rightVolume, int priority, int loop, float rate)
@@ -641,6 +653,17 @@
     if (status != NO_ERROR) {
         mAudioTrack.clear();
     }
+    // FIXME AudioTrack destruction should not be slow
+    if (oldTrack != 0) {
+        // must be a raw reference to avoid a race after run()
+        AsyncDestructThread *adt = new AsyncDestructThread(oldTrack);
+        // guaranteed to not run destructor
+        oldTrack.clear();
+        // after the run(), adt thread will hold a strong reference to oldTrack,
+        // and the only strong reference to itself
+        adt->run("AsyncDestruct");
+        // do not delete adt here: adt thread destroys itself, and oldTrack if needed
+    }
 }
 
 void SoundChannel::nextEvent()