Fix issue 2046140: master: media_server crash when powering down A2DP headset while a ringtone is playing.

This is because the AudioFlinger duplicating thread is closed while the output tracks are still active. This cause the output tracks objects to be destroyed at a time where they can be in use by the destination output mixer.

The fix consists in adding the OutputTrack to the track list (mTracks) of its destination thread so that a strong reference is help during the mixer processed and the track is detroyed only when safe by destination thread.

Also added detection of problems when creating the output track (e.g. no more tracks in mixer). In this case the output track is not added to output track list of duplicating thread.
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index fab75ef..77a126c 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1860,9 +1860,7 @@
                          mSuspended) {
                 if (!mStandby) {
                     for (size_t i = 0; i < outputTracks.size(); i++) {
-                        mLock.unlock();
                         outputTracks[i]->stop();
-                        mLock.lock();
                     }
                     mStandby = true;
                     mBytesWritten = 0;
@@ -1903,9 +1901,9 @@
             if (!mSuspended) {
                 for (size_t i = 0; i < outputTracks.size(); i++) {
                     outputTracks[i]->write(curBuf, mFrameCount);
+                    mustSleep = false;
                 }
                 mStandby = false;
-                mustSleep = false;
                 mBytesWritten += mixBufferSize;
             }
         } else {
@@ -1935,11 +1933,14 @@
         outputTracks.clear();
     }
 
-    if (!mStandby) {
-        for (size_t i = 0; i < outputTracks.size(); i++) {
-            mLock.unlock();
-            outputTracks[i]->stop();
-            mLock.lock();
+    { // scope for the mLock
+
+        Mutex::Autolock _l(mLock);
+        if (!mStandby) {
+            LOGV("DuplicatingThread() exiting out of standby");
+            for (size_t i = 0; i < mOutputTracks.size(); i++) {
+                mOutputTracks[i]->destroy();
+            }
         }
     }
 
@@ -1957,9 +1958,11 @@
                                             mFormat,
                                             mChannelCount,
                                             frameCount);
-    thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
-    mOutputTracks.add(outputTrack);
-    LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
+    if (outputTrack->cblk() != NULL) {
+        thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
+        mOutputTracks.add(outputTrack);
+        LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
+    }
 }
 
 void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
@@ -1967,6 +1970,7 @@
     Mutex::Autolock _l(mLock);
     for (size_t i = 0; i < mOutputTracks.size(); i++) {
         if (mOutputTracks[i]->thread() == (ThreadBase *)thread) {
+            mOutputTracks[i]->destroy();
             mOutputTracks.removeAt(i);
             return;
         }
@@ -2456,20 +2460,23 @@
 {
 
     PlaybackThread *playbackThread = (PlaybackThread *)thread.unsafe_get();
-    mCblk->out = 1;
-    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
-    mCblk->volume[0] = mCblk->volume[1] = 0x1000;
-    mOutBuffer.frameCount = 0;
-    mWaitTimeMs = (playbackThread->frameCount() * 2 * 1000) / playbackThread->sampleRate();
-
-    LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p mWaitTimeMs %d",
-            mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd, mWaitTimeMs);
-
+    if (mCblk != NULL) {
+        mCblk->out = 1;
+        mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+        mCblk->volume[0] = mCblk->volume[1] = 0x1000;
+        mOutBuffer.frameCount = 0;
+        mWaitTimeMs = (playbackThread->frameCount() * 2 * 1000) / playbackThread->sampleRate();
+        playbackThread->mTracks.add(this);
+        LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p mWaitTimeMs %d",
+                mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd, mWaitTimeMs);
+    } else {
+        LOGW("Error creating output track on thread %p", playbackThread);
+    }
 }
 
 AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
 {
-    stop();
+    clearBufferQueue();
 }
 
 status_t AudioFlinger::PlaybackThread::OutputTrack::start()
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 4ba5977..65c148e 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -245,6 +245,7 @@
             virtual status_t    start() = 0;
             virtual void        stop() = 0;
                     sp<IMemory> getCblk() const;
+                    audio_track_cblk_t* cblk() const { return mCblk; }
 
         protected:
             friend class ThreadBase;
@@ -260,10 +261,6 @@
             virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
             virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
 
-            audio_track_cblk_t* cblk() const {
-                return mCblk;
-            }
-
             int format() const {
                 return mFormat;
             }
@@ -528,6 +525,7 @@
     private:
 
         friend class AudioFlinger;
+        friend class OutputTrack;
         friend class Track;
         friend class TrackBase;
         friend class MixerThread;