Code drop from //branches/cupcake/...@124589
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 89ab2be..0dee1f6 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -88,57 +88,35 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 ToneGenerator::ToneGenerator(int streamType, float volume) {
-    const sp<IAudioFlinger>& lpAudioFlinger = AudioSystem::get_audio_flinger();
 
     LOGV("ToneGenerator constructor: streamType=%d, volume=%f\n", streamType, volume);
 
     mState = TONE_IDLE;
+
+    if (AudioSystem::getOutputSamplingRate(&mSamplingRate) != NO_ERROR) {
+        LOGE("Unable to marshal AudioFlinger");
+        return;
+    }
+    if (AudioSystem::getOutputFrameCount(&mBufferSize) != NO_ERROR) {
+        LOGE("Unable to marshal AudioFlinger");
+        return;
+    }
+    mStreamType = streamType;
+    mVolume = volume;
     mpAudioTrack = 0;
     mpToneDesc = 0;
     mpNewToneDesc = 0;
 
-    if (lpAudioFlinger == 0) {
-        LOGE("Unable to marshal AudioFlinger");
-        goto ToneGenerator_exit;
+    if (initAudioTrack()) {
+        LOGV("ToneGenerator INIT OK, time: %d\n", (unsigned int)(systemTime()/1000000));
+    } else {
+        LOGV("!!!ToneGenerator INIT FAILED!!!\n");
     }
-
-    mSamplingRate = lpAudioFlinger->sampleRate();
-
-    mVolume = volume;
-    // Open audio track in mono, PCM 16bit, default sampling rate, 2 buffers
-    mpAudioTrack
-            = new AudioTrack(streamType, 0, AudioSystem::PCM_16_BIT, 1, NUM_PCM_BUFFERS, 0, audioCallback, this);
-
-    if (mpAudioTrack == 0) {
-        LOGE("AudioTrack allocation failed");
-        goto ToneGenerator_exit;
-    }
-    LOGV("Create Track: %p\n", mpAudioTrack);
-
-    if (mpAudioTrack->initCheck() != NO_ERROR) {
-        LOGE("AudioTrack->initCheck failed");
-        goto ToneGenerator_exit;
-    }
-
-    mpAudioTrack->setVolume(volume, volume);
-
-    LOGV("ToneGenerator INIT OK, time: %d\n", (unsigned int)(systemTime()/1000000));
-
-    mState = TONE_INIT;
-
-    return;
-
-ToneGenerator_exit:
-
-    // Cleanup
-    if (mpAudioTrack) {
-        LOGV("Delete Track I: %p\n", mpAudioTrack);
-        delete mpAudioTrack;
-    }
-
-    LOGV("!!!ToneGenerator INIT FAILED!!!\n");
 }
 
+
+
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 //    Method:        ToneGenerator::~ToneGenerator()
@@ -179,9 +157,16 @@
 bool ToneGenerator::startTone(int toneType) {
     bool lResult = false;
 
-    if (mState == TONE_IDLE || toneType >= NUM_TONES)
+    if (toneType >= NUM_TONES)
         return lResult;
 
+    if (mState == TONE_IDLE) {
+        LOGV("startTone: try to re-init AudioTrack");
+        if (!initAudioTrack()) {
+            return lResult;
+        }
+    }
+
     LOGV("startTone\n");
 
     mLock.lock();
@@ -198,8 +183,10 @@
             mpAudioTrack->start();
             mLock.lock();
             if (mState == TONE_STARTING) {
-                if (mWaitCbkCond.waitRelative(mLock, seconds(1)) != NO_ERROR)
+                if (mWaitCbkCond.waitRelative(mLock, seconds(1)) != NO_ERROR) {
                     LOGE("--- timed out");
+                    mState = TONE_IDLE;
+                }
             }
 
             if (mState == TONE_PLAYING)
@@ -216,6 +203,7 @@
             LOGV("cond received");
         } else {
             LOGE("--- timed out");
+            mState = TONE_IDLE;
         }
     }
     mLock.unlock();
@@ -250,7 +238,8 @@
             LOGV("track stop complete, time %d", (unsigned int)(systemTime()/1000000));
         } else {
             LOGE("--- timed out");
-            mState = TONE_INIT;
+            mState = TONE_IDLE;
+            mpAudioTrack->stop();
         }
     }
 
@@ -262,6 +251,62 @@
 //---------------------------------- private methods ---------------------------
 
 
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Method:        ToneGenerator::initAudioTrack()
+//
+//    Description:    Allocates and configures AudioTrack used for PCM output.
+//
+//    Input:
+//        none
+//
+//    Output:
+//        none
+//
+////////////////////////////////////////////////////////////////////////////////
+bool ToneGenerator::initAudioTrack() {
+
+    if (mpAudioTrack) {
+        delete mpAudioTrack;
+        mpAudioTrack = 0;
+    }
+
+   // Open audio track in mono, PCM 16bit, default sampling rate, 2 buffers of
+    mpAudioTrack
+            = new AudioTrack(mStreamType, 0, AudioSystem::PCM_16_BIT, 1, NUM_PCM_BUFFERS*mBufferSize, 0, audioCallback, this, mBufferSize);
+
+    if (mpAudioTrack == 0) {
+        LOGE("AudioTrack allocation failed");
+        goto initAudioTrack_exit;
+    }
+    LOGV("Create Track: %p\n", mpAudioTrack);
+
+    if (mpAudioTrack->initCheck() != NO_ERROR) {
+        LOGE("AudioTrack->initCheck failed");
+        goto initAudioTrack_exit;
+    }
+
+    mpAudioTrack->setVolume(mVolume, mVolume);
+
+    mState = TONE_INIT;
+
+    return true;
+
+initAudioTrack_exit:
+
+    // Cleanup
+    if (mpAudioTrack) {
+        LOGV("Delete Track I: %p\n", mpAudioTrack);
+        delete mpAudioTrack;
+        mpAudioTrack = 0;
+    }
+
+    return false;
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 //    Method:        ToneGenerator::audioCallback()
@@ -278,19 +323,24 @@
 //        returned value: always true.
 //
 ////////////////////////////////////////////////////////////////////////////////
-void ToneGenerator::audioCallback(void* user, const AudioTrack::Buffer& info) {
+void ToneGenerator::audioCallback(int event, void* user, void *info) {
+    
+    if (event != AudioTrack::EVENT_MORE_DATA) return;
+    
+    const AudioTrack::Buffer *buffer = static_cast<const AudioTrack::Buffer *>(info);
     ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user);
-    short *lpOut = info.i16;
-    unsigned int lReqSmp = info.size/sizeof(short);
+    short *lpOut = buffer->i16;
+    unsigned int lReqSmp = buffer->size/sizeof(short);
     unsigned int lGenSmp;
     unsigned int lWaveCmd = WaveGenerator::WAVEGEN_CONT;
     bool lSignal = false;
 
+    if (buffer->size == 0) return;
 
     lpToneGen->mLock.lock();
 
     // Clear output buffer: WaveGenerator accumulates into lpOut buffer
-    memset(lpOut, 0, info.size);
+    memset(lpOut, 0, buffer->size);
 
     // Update pcm frame count and end time (current time at the end of this process)
     lpToneGen->mTotalSmp += lReqSmp;
@@ -317,8 +367,11 @@
         goto audioCallback_Exit;
     }
 
-    // Exit if to sequence is over
+    // Exit if tone sequence is over
     if (lpToneGen->mpToneDesc->segments[lpToneGen->mCurSegment] == 0) {
+        if (lpToneGen->mState == TONE_PLAYING) {
+            lpToneGen->mState = TONE_STOPPING;            
+        }
         goto audioCallback_Exit;
     }
 
@@ -327,7 +380,7 @@
 
         LOGV("End Segment, time: %d\n", (unsigned int)(systemTime()/1000000));
 
-        lGenSmp = lReqSmp; 
+        lGenSmp = lReqSmp;
 
         if (lpToneGen->mCurSegment & 0x0001) {
             // If odd segment,  OFF -> ON transition : reset wave generator