auto import from //branches/cupcake/...@132276
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index 3c18036..d1b7af3 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -72,7 +72,8 @@
 }
 
 AudioStreamIn* A2dpAudioInterface::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status)
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
 {
     if (status)
         *status = -1;
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 38ba684..5bef5da 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -58,7 +58,8 @@
                                 int format,
                                 int channelCount,
                                 uint32_t sampleRate,
-                                status_t *status);
+                                status_t *status,
+                                AudioSystem::audio_in_acoustics acoustics);
 
 protected:
     virtual status_t    doRouting();
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index 42204d6..9a94102 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -78,8 +78,9 @@
     virtual status_t    setParameter(const char* key, const char* value)
                             {return mFinalInterface->setParameter(key, value);}
 
-    virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status)
-                            {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status);}
+    virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status,
+                                            AudioSystem::audio_in_acoustics acoustics)
+                            {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status, acoustics);}
 
     virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
 
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index d347f14..557d93b 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -278,6 +278,9 @@
         mA2dpMixerThread->dump(fd, args);
 #endif
 
+        // dump record client
+        if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
+
         if (mAudioHardware) {
             mAudioHardware->dumpState(fd, args);
         }
@@ -1155,7 +1158,7 @@
             // active tracks were late. Sleep a little bit to give
             // them another chance. If we're too late, the audio
             // hardware will zero-fill for us.
-//            LOGV("no buffers - usleep(%lu)", sleepTime);
+            //LOGV("no buffers - usleep(%lu)", sleepTime);
             usleep(sleepTime);
             if (sleepTime < kMaxBufferRecoveryInUsecs) {
                 sleepTime += kBufferRecoveryInUsecs;
@@ -1223,6 +1226,11 @@
 
         track = new Track(this, client, streamType, sampleRate, format,
                 channelCount, frameCount, sharedBuffer);
+        if (track->getCblk() == NULL) {
+            track.clear();
+            lStatus = NO_MEMORY;
+            goto Exit;
+        }
         mTracks.add(track);
         lStatus = NO_ERROR;
     }
@@ -1506,6 +1514,7 @@
             int format,
             int channelCount,
             int frameCount,
+            uint32_t flags,
             const sp<IMemory>& sharedBuffer)
     :   RefBase(),
         mMixerThread(mixerThread),
@@ -1515,7 +1524,7 @@
         mState(IDLE),
         mClientTid(-1),
         mFormat(format),
-        mFlags(0)
+        mFlags(flags & ~SYSTEM_FLAGS_MASK)
 {
     mName = mixerThread->getTrackName();
     LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
@@ -1526,7 +1535,6 @@
 
     LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
 
-
     // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
    size_t size = sizeof(audio_track_cblk_t);
    size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
@@ -1614,7 +1622,7 @@
     cblk->server = 0;
     cblk->userBase = 0;
     cblk->serverBase = 0;
-    mFlags = 0;
+    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
     LOGV("TrackBase::reset");
 }
 
@@ -1659,7 +1667,7 @@
             int channelCount,
             int frameCount,
             const sp<IMemory>& sharedBuffer)
-    :   TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer)
+    :   TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
 {
     mVolume[0] = 1.0f;
     mVolume[1] = 1.0f;
@@ -1836,10 +1844,11 @@
             uint32_t sampleRate,
             int format,
             int channelCount,
-            int frameCount)
+            int frameCount,
+            uint32_t flags)
     :   TrackBase(mixerThread, client, streamType, sampleRate, format,
-            channelCount, frameCount, 0),
-            mOverflow(false)
+                  channelCount, frameCount, flags, 0),
+        mOverflow(false)
 {
 }
 
@@ -2232,7 +2241,12 @@
 
     // create new record track and pass to record thread
     recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
-            format, channelCount, frameCount);
+                                               format, channelCount, frameCount, flags);
+    if (recordTrack->getCblk() == NULL) {
+        recordTrack.clear();
+        lStatus = NO_MEMORY;
+        goto Exit;
+    }
 
     // return to handle to client
     recordHandle = new RecordHandle(recordTrack);
@@ -2323,15 +2337,17 @@
                     input = 0;
                 }
                 mRecordTrack.clear();
+                mStopped.signal();
 
                 mWaitWorkCV.wait(mLock);
                
                 LOGV("AudioRecordThread: loop starting");
                 if (mRecordTrack != 0) {
                     input = mAudioHardware->openInputStream(mRecordTrack->format(), 
-                                            mRecordTrack->channelCount(), 
-                                            mRecordTrack->sampleRate(), 
-                                            &mStartStatus);
+                                    mRecordTrack->channelCount(), 
+                                    mRecordTrack->sampleRate(), 
+                                    &mStartStatus,
+                                    (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
                     if (input != 0) {
                         inBufferSize = input->bufferSize();
                         inFrameCount = inBufferSize/input->frameSize();                        
@@ -2347,12 +2363,13 @@
                 mWaitWorkCV.signal();
             }
             mLock.unlock();
-        } else if (mRecordTrack != 0){
+        } else if (mRecordTrack != 0) {
 
             buffer.frameCount = inFrameCount;
             if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR)) {
                 LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
-                if (input->read(buffer.raw, inBufferSize) < 0) {
+                ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
+                if (bytesRead < 0) {
                     LOGE("Error reading audio input");
                     sleep(1);
                 }
@@ -2407,6 +2424,7 @@
     AutoMutex lock(&mLock);
     if (mActive && (recordTrack == mRecordTrack.get())) {
         mActive = false;
+        mStopped.wait(mLock);
     }
 }
 
@@ -2421,6 +2439,22 @@
     requestExitAndWait();
 }
 
+status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    pid_t pid = 0;
+
+    if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
+        snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
+        result.append(buffer);
+    } else {
+        result.append("No record client\n");
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
 
 status_t AudioFlinger::onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 3b5932d..dfbb1e9 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -221,16 +221,22 @@
             };
 
             enum track_flags {
-                STEPSERVER_FAILED = 0x01   //  StepServer could not acquire cblk->lock mutex
+                STEPSERVER_FAILED = 0x01, //  StepServer could not acquire cblk->lock mutex
+                SYSTEM_FLAGS_MASK = 0x0000ffffUL,
+
+                AUDIO_IN_AGC_ENABLE = AudioSystem::AGC_ENABLE << 16,
+                AUDIO_IN_NS_ENABLE  = AudioSystem::NS_ENABLE << 16,
+                AUDIO_IN_IIR_ENABLE = AudioSystem::TX_IIR_ENABLE << 16
             };
 
-                                TrackBase(  const sp<MixerThread>& mixerThread,
+                                TrackBase(const sp<MixerThread>& mixerThread,
                                         const sp<Client>& client,
                                         int streamType,
                                         uint32_t sampleRate,
                                         int format,
                                         int channelCount,
                                         int frameCount,
+                                        uint32_t flags,
                                         const sp<IMemory>& sharedBuffer);
                                 ~TrackBase();
 
@@ -295,7 +301,7 @@
             int                 mState;
             int                 mClientTid;
             uint8_t             mFormat;
-            uint8_t             mFlags;
+            uint32_t            mFlags;
         };
 
         // playback track
@@ -362,13 +368,14 @@
         // record track
         class RecordTrack : public TrackBase {
         public:
-                                RecordTrack(  const sp<MixerThread>& mixerThread,
+                                RecordTrack(const sp<MixerThread>& mixerThread,
                                         const sp<Client>& client,
                                         int streamType,
                                         uint32_t sampleRate,
                                         int format,
                                         int channelCount,
-                                        int frameCount);
+                                        int frameCount,
+                                        uint32_t flags);
                                 ~RecordTrack();
 
             virtual status_t    start();
@@ -585,6 +592,7 @@
                 status_t    start(MixerThread::RecordTrack* recordTrack);
                 void        stop(MixerThread::RecordTrack* recordTrack);
                 void        exit();
+                status_t    dump(int fd, const Vector<String16>& args);
 
     private:
                 AudioRecordThread();
@@ -592,6 +600,7 @@
                 sp<MixerThread::RecordTrack>        mRecordTrack;
                 Mutex                               mLock;
                 Condition                           mWaitWorkCV;
+                Condition                           mStopped;
                 volatile bool                       mActive;
                 status_t                            mStartStatus;
     };
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
index e455186..62beada 100644
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -93,7 +93,8 @@
 }
 
 AudioStreamIn* AudioHardwareGeneric::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status)
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
 {
     AutoMutex lock(mLock);
 
@@ -107,7 +108,7 @@
 
     // create new output stream
     AudioStreamInGeneric* in = new AudioStreamInGeneric();
-    status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate);
+    status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
     if (status) {
         *status = lStatus;
     }
@@ -246,7 +247,8 @@
         int fd,
         int format,
         int channels,
-        uint32_t rate)
+        uint32_t rate,
+        AudioSystem::audio_in_acoustics acoustics)
 {
     // FIXME: remove logging
     LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
index a7822e1..1d58389 100644
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -69,7 +69,8 @@
             int mFd,
             int format,
             int channelCount,
-            uint32_t sampleRate);
+            uint32_t sampleRate,
+            AudioSystem::audio_in_acoustics acoustics);
 
     uint32_t    sampleRate() const { return 8000; }
     virtual size_t      bufferSize() const { return 320; }
@@ -114,7 +115,8 @@
             int format,
             int channelCount,
             uint32_t sampleRate,
-            status_t *status);
+            status_t *status,
+            AudioSystem::audio_in_acoustics acoustics);
 
             void            closeOutputStream(AudioStreamOutGeneric* out);
             void            closeInputStream(AudioStreamInGeneric* in);
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index e9f3d69..b13cb1c 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -56,10 +56,11 @@
 }
 
 AudioStreamIn* AudioHardwareStub::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status)
+        int format, int channelCount, uint32_t sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
 {
     AudioStreamInStub* in = new AudioStreamInStub();
-    status_t lStatus = in->set(format, channelCount, sampleRate);
+    status_t lStatus = in->set(format, channelCount, sampleRate, acoustics);
     if (status) {
         *status = lStatus;
     }
@@ -142,7 +143,8 @@
 
 // ----------------------------------------------------------------------------
 
-status_t AudioStreamInStub::set(int format, int channels, uint32_t rate)
+status_t AudioStreamInStub::set(int format, int channels, uint32_t rate,
+				AudioSystem::audio_in_acoustics acoustics)
 {
     if ((format == AudioSystem::PCM_16_BIT) &&
             (channels == channelCount()) &&
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
index 24736ed..d406424 100644
--- a/libs/audioflinger/AudioHardwareStub.h
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -43,7 +43,7 @@
 
 class AudioStreamInStub : public AudioStreamIn {
 public:
-    virtual status_t    set(int format, int channelCount, uint32_t sampleRate);
+    virtual status_t    set(int format, int channelCount, uint32_t sampleRate, AudioSystem::audio_in_acoustics acoustics);
     virtual uint32_t    sampleRate() const { return 8000; }
     virtual size_t      bufferSize() const { return 320; }
     virtual int         channelCount() const { return 1; }
@@ -81,7 +81,8 @@
                                 int format,
                                 int channelCount,
                                 uint32_t sampleRate,
-                                status_t *status);
+                                status_t *status,
+				AudioSystem::audio_in_acoustics acoustics);
 
 protected:
     virtual status_t    doRouting() { return NO_ERROR; }