am b8341cf7: am 6d42d806: Merge change I9cc489a2 into eclair

Merge commit 'b8341cf7c8b0b4af14ea87a4c2335e28865adff1' into eclair-mr2-plus-aosp

* commit 'b8341cf7c8b0b4af14ea87a4c2335e28865adff1':
  Fix issue 2304669: VoiceIME: starting and canceling voice IME yields persistent "error 8" state on future attempts and breaks voice search.
This commit is contained in:
Eric Laurent
2009-12-07 11:06:15 -08:00
committed by Android Git Automerger
5 changed files with 48 additions and 26 deletions

View File

@@ -224,17 +224,17 @@ native_track_failure:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static void static int
android_media_AudioRecord_start(JNIEnv *env, jobject thiz) android_media_AudioRecord_start(JNIEnv *env, jobject thiz)
{ {
AudioRecord *lpRecorder = AudioRecord *lpRecorder =
(AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj); (AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
if (lpRecorder == NULL ) { if (lpRecorder == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL); jniThrowException(env, "java/lang/IllegalStateException", NULL);
return; return AUDIORECORD_ERROR;
} }
lpRecorder->start(); return android_media_translateRecorderErrorCode(lpRecorder->start());
} }
@@ -482,7 +482,7 @@ static jint android_media_AudioRecord_get_min_buff_size(JNIEnv *env, jobject th
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = { static JNINativeMethod gMethods[] = {
// name, signature, funcPtr // 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_stop", "()V", (void *)android_media_AudioRecord_stop},
{"native_setup", "(Ljava/lang/Object;IIIII)I", {"native_setup", "(Ljava/lang/Object;IIIII)I",
(void *)android_media_AudioRecord_setup}, (void *)android_media_AudioRecord_setup},

View File

@@ -3086,23 +3086,34 @@ bool AudioFlinger::RecordThread::threadLoop()
} }
if (mActiveTrack != 0) { if (mActiveTrack != 0) {
if (mActiveTrack->mState == TrackBase::PAUSING) { if (mActiveTrack->mState == TrackBase::PAUSING) {
if (!mStandby) {
mInput->standby();
mStandby = true;
}
mActiveTrack.clear(); mActiveTrack.clear();
mStartStopCond.broadcast(); mStartStopCond.broadcast();
} else if (mActiveTrack->mState == TrackBase::RESUMING) { } else if (mActiveTrack->mState == TrackBase::RESUMING) {
mRsmpInIndex = mFrameCount;
if (mReqChannelCount != mActiveTrack->channelCount()) { if (mReqChannelCount != mActiveTrack->channelCount()) {
mActiveTrack.clear(); mActiveTrack.clear();
} else { mStartStopCond.broadcast();
mActiveTrack->mState = TrackBase::ACTIVE; } 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 != 0) {
if (mActiveTrack->mState != TrackBase::ACTIVE) { if (mActiveTrack->mState != TrackBase::ACTIVE &&
mActiveTrack->mState != TrackBase::RESUMING) {
usleep(5000); usleep(5000);
continue; continue;
} }
@@ -3140,18 +3151,19 @@ bool AudioFlinger::RecordThread::threadLoop()
} }
} }
if (framesOut && mFrameCount == mRsmpInIndex) { if (framesOut && mFrameCount == mRsmpInIndex) {
ssize_t bytesRead;
if (framesOut == mFrameCount && if (framesOut == mFrameCount &&
(mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) { (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
bytesRead = mInput->read(buffer.raw, mInputBytes); mBytesRead = mInput->read(buffer.raw, mInputBytes);
framesOut = 0; framesOut = 0;
} else { } else {
bytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
mRsmpInIndex = 0; mRsmpInIndex = 0;
} }
if (bytesRead < 0) { if (mBytesRead < 0) {
LOGE("Error reading audio input"); LOGE("Error reading audio input");
sleep(1); if (mActiveTrack->mState == TrackBase::ACTIVE) {
sleep(1);
}
mRsmpInIndex = mFrameCount; mRsmpInIndex = mFrameCount;
framesOut = 0; framesOut = 0;
buffer.frameCount = 0; buffer.frameCount = 0;
@@ -3220,7 +3232,7 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac
if (recordTrack != mActiveTrack.get()) { if (recordTrack != mActiveTrack.get()) {
status = -EBUSY; status = -EBUSY;
} else if (mActiveTrack->mState == TrackBase::PAUSING) { } else if (mActiveTrack->mState == TrackBase::PAUSING) {
mActiveTrack->mState = TrackBase::RESUMING; mActiveTrack->mState = TrackBase::ACTIVE;
} }
return status; return status;
} }
@@ -3235,6 +3247,8 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac
return status; return status;
} }
mActiveTrack->mState = TrackBase::RESUMING; mActiveTrack->mState = TrackBase::RESUMING;
mRsmpInIndex = mFrameCount;
mBytesRead = 0;
// signal thread to start // signal thread to start
LOGV("Signal record thread"); LOGV("Signal record thread");
mWaitWorkCV.signal(); mWaitWorkCV.signal();
@@ -3275,6 +3289,7 @@ void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
mLock.unlock(); mLock.unlock();
AudioSystem::stopInput(mId); AudioSystem::stopInput(mId);
mLock.lock(); mLock.lock();
LOGV("Record stopped OK");
} }
} }
} }
@@ -3325,10 +3340,12 @@ status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer*
int channelCount; int channelCount;
if (framesReady == 0) { if (framesReady == 0) {
ssize_t bytesRead = mInput->read(mRsmpInBuffer, mInputBytes); mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
if (bytesRead < 0) { if (mBytesRead < 0) {
LOGE("RecordThread::getNextBuffer() Error reading audio input"); LOGE("RecordThread::getNextBuffer() Error reading audio input");
sleep(1); if (mActiveTrack->mState == TrackBase::ACTIVE) {
sleep(1);
}
buffer->raw = 0; buffer->raw = 0;
buffer->frameCount = 0; buffer->frameCount = 0;
return NOT_ENOUGH_DATA; return NOT_ENOUGH_DATA;
@@ -3546,9 +3563,11 @@ int AudioFlinger::openOutput(uint32_t *pDevices,
if (pFormat) *pFormat = format; if (pFormat) *pFormat = format;
if (pChannels) *pChannels = channels; if (pChannels) *pChannels = channels;
if (pLatencyMs) *pLatencyMs = thread->latency(); if (pLatencyMs) *pLatencyMs = thread->latency();
return mNextThreadId;
} }
return mNextThreadId; return 0;
} }
int AudioFlinger::openDuplicateOutput(int output1, int output2) int AudioFlinger::openDuplicateOutput(int output1, int output2)
@@ -3694,9 +3713,11 @@ int AudioFlinger::openInput(uint32_t *pDevices,
if (pChannels) *pChannels = reqChannels; if (pChannels) *pChannels = reqChannels;
input->standby(); input->standby();
return mNextThreadId;
} }
return mNextThreadId; return 0;
} }
status_t AudioFlinger::closeInput(int input) status_t AudioFlinger::closeInput(int input)

View File

@@ -744,6 +744,7 @@ private:
size_t mInputBytes; size_t mInputBytes;
int mReqChannelCount; int mReqChannelCount;
uint32_t mReqSampleRate; uint32_t mReqSampleRate;
ssize_t mBytesRead;
}; };
class RecordHandle : public android::BnAudioRecord { class RecordHandle : public android::BnAudioRecord {

View File

@@ -498,8 +498,9 @@ public class AudioRecord
// start recording // start recording
synchronized(mRecordingStateLock) { synchronized(mRecordingStateLock) {
native_start(); if (native_start() == SUCCESS) {
mRecordingState = RECORDSTATE_RECORDING; mRecordingState = RECORDSTATE_RECORDING;
}
} }
} }
@@ -764,7 +765,7 @@ public class AudioRecord
private native final void native_release(); private native final void native_release();
private native final void native_start(); private native final int native_start();
private native final void native_stop(); private native final void native_stop();

View File

@@ -125,7 +125,7 @@ status_t AudioRecord::set(
audio_io_handle_t input = AudioSystem::getInput(inputSource, audio_io_handle_t input = AudioSystem::getInput(inputSource,
sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
if (input == 0) { 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; return BAD_VALUE;
} }
@@ -539,7 +539,6 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize)
return BAD_VALUE; return BAD_VALUE;
} }
LOGV("read size: %d", userSize);
do { do {