am 6d42d806: Merge change I9cc489a2 into eclair

Merge commit '6d42d80653f2c41f3e72a878a1d9a6f9693b89f7' into eclair-mr2

* commit '6d42d80653f2c41f3e72a878a1d9a6f9693b89f7':
  Fix issue 2304669: VoiceIME: starting and canceling voice IME yields persistent "error 8" state on future attempts and breaks voice search.
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 0be996d..d7485ae 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -224,17 +224,17 @@
 
 
 // ----------------------------------------------------------------------------
-static void
+static int
 android_media_AudioRecord_start(JNIEnv *env, jobject thiz)
 {
     AudioRecord *lpRecorder = 
             (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
     if (lpRecorder == NULL ) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
+        return AUDIORECORD_ERROR;
     }
     
-    lpRecorder->start();
+    return android_media_translateRecorderErrorCode(lpRecorder->start());
 }
 
 
@@ -482,7 +482,7 @@
 // ----------------------------------------------------------------------------
 static JNINativeMethod gMethods[] = {
     // name,               signature,  funcPtr
-    {"native_start",         "()V",    (void *)android_media_AudioRecord_start},
+    {"native_start",         "()I",    (void *)android_media_AudioRecord_start},
     {"native_stop",          "()V",    (void *)android_media_AudioRecord_stop},
     {"native_setup",         "(Ljava/lang/Object;IIIII)I",
                                        (void *)android_media_AudioRecord_setup},
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 9ec8de5..f3f6e4f 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -3086,23 +3086,34 @@
             }
             if (mActiveTrack != 0) {
                 if (mActiveTrack->mState == TrackBase::PAUSING) {
+                    if (!mStandby) {
+                        mInput->standby();
+                        mStandby = true;
+                    }
                     mActiveTrack.clear();
                     mStartStopCond.broadcast();
                 } else if (mActiveTrack->mState == TrackBase::RESUMING) {
-                    mRsmpInIndex = mFrameCount;
                     if (mReqChannelCount != mActiveTrack->channelCount()) {
                         mActiveTrack.clear();
-                    } else {
-                        mActiveTrack->mState = TrackBase::ACTIVE;
+                        mStartStopCond.broadcast();
+                    } else if (mBytesRead != 0) {
+                        // record start succeeds only if first read from audio input
+                        // succeeds
+                        if (mBytesRead > 0) {
+                            mActiveTrack->mState = TrackBase::ACTIVE;
+                        } else {
+                            mActiveTrack.clear();
+                        }
+                        mStartStopCond.broadcast();
                     }
-                    mStartStopCond.broadcast();
+                    mStandby = false;
                 }
-                mStandby = false;
             }
         }
 
         if (mActiveTrack != 0) {
-            if (mActiveTrack->mState != TrackBase::ACTIVE) {
+            if (mActiveTrack->mState != TrackBase::ACTIVE &&
+                mActiveTrack->mState != TrackBase::RESUMING) {
                 usleep(5000);
                 continue;
             }
@@ -3140,18 +3151,19 @@
                             }
                         }
                         if (framesOut && mFrameCount == mRsmpInIndex) {
-                            ssize_t bytesRead;
                             if (framesOut == mFrameCount &&
                                 (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
-                                bytesRead = mInput->read(buffer.raw, mInputBytes);
+                                mBytesRead = mInput->read(buffer.raw, mInputBytes);
                                 framesOut = 0;
                             } else {
-                                bytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+                                mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
                                 mRsmpInIndex = 0;
                             }
-                            if (bytesRead < 0) {
+                            if (mBytesRead < 0) {
                                 LOGE("Error reading audio input");
-                                sleep(1);
+                                if (mActiveTrack->mState == TrackBase::ACTIVE) {
+                                    sleep(1);
+                                }
                                 mRsmpInIndex = mFrameCount;
                                 framesOut = 0;
                                 buffer.frameCount = 0;
@@ -3220,7 +3232,7 @@
             if (recordTrack != mActiveTrack.get()) {
                 status = -EBUSY;
             } else if (mActiveTrack->mState == TrackBase::PAUSING) {
-                mActiveTrack->mState = TrackBase::RESUMING;
+                mActiveTrack->mState = TrackBase::ACTIVE;
             }
             return status;
         }
@@ -3235,6 +3247,8 @@
             return status;
         }
         mActiveTrack->mState = TrackBase::RESUMING;
+        mRsmpInIndex = mFrameCount;
+        mBytesRead = 0;
         // signal thread to start
         LOGV("Signal record thread");
         mWaitWorkCV.signal();
@@ -3275,6 +3289,7 @@
                 mLock.unlock();
                 AudioSystem::stopInput(mId);
                 mLock.lock();
+                LOGV("Record stopped OK");
             }
         }
     }
@@ -3325,10 +3340,12 @@
     int channelCount;
 
     if (framesReady == 0) {
-        ssize_t bytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
-        if (bytesRead < 0) {
+        mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+        if (mBytesRead < 0) {
             LOGE("RecordThread::getNextBuffer() Error reading audio input");
-            sleep(1);
+            if (mActiveTrack->mState == TrackBase::ACTIVE) {
+                sleep(1);
+            }
             buffer->raw = 0;
             buffer->frameCount = 0;
             return NOT_ENOUGH_DATA;
@@ -3546,9 +3563,11 @@
         if (pFormat) *pFormat = format;
         if (pChannels) *pChannels = channels;
         if (pLatencyMs) *pLatencyMs = thread->latency();
+
+        return mNextThreadId;
     }
 
-    return mNextThreadId;
+    return 0;
 }
 
 int AudioFlinger::openDuplicateOutput(int output1, int output2)
@@ -3694,9 +3713,11 @@
         if (pChannels) *pChannels = reqChannels;
 
         input->standby();
+
+        return mNextThreadId;
     }
 
-    return mNextThreadId;
+    return 0;
 }
 
 status_t AudioFlinger::closeInput(int input)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 5a17294..8c29da85 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -744,6 +744,7 @@
                 size_t                              mInputBytes;
                 int                                 mReqChannelCount;
                 uint32_t                            mReqSampleRate;
+                ssize_t                             mBytesRead;
     };
 
     class RecordHandle : public android::BnAudioRecord {
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 7a47157..c48eaad 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -498,8 +498,9 @@
 
         // start recording
         synchronized(mRecordingStateLock) {
-            native_start();
-            mRecordingState = RECORDSTATE_RECORDING;
+            if (native_start() == SUCCESS) {
+                mRecordingState = RECORDSTATE_RECORDING;
+            }
         }
     }
 
@@ -764,7 +765,7 @@
     
     private native final void native_release();
 
-    private native final void native_start();  
+    private native final int native_start();
 
     private native final void native_stop();
 
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index c3828f0..f4165ff 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -125,7 +125,7 @@
     audio_io_handle_t input = AudioSystem::getInput(inputSource,
                                     sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
     if (input == 0) {
-        LOGE("Could not get audio output for stream type %d", inputSource);
+        LOGE("Could not get audio input for record source %d", inputSource);
         return BAD_VALUE;
     }
 
@@ -539,7 +539,6 @@
         return BAD_VALUE;
     }
 
-    LOGV("read size: %d", userSize);
 
     do {