Merge "Move declarations of local variables to first use"
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index ef77692..813ea85 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -17,21 +17,14 @@
 #ifndef AUDIORECORD_H_
 #define AUDIORECORD_H_
 
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <media/IAudioFlinger.h>
-#include <media/IAudioRecord.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
 #include <binder/IMemory.h>
 #include <cutils/sched_policy.h>
-#include <utils/threads.h>
-
-#include <system/audio.h>
 #include <media/AudioSystem.h>
+#include <media/IAudioRecord.h>
+#include <system/audio.h>
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
 
 namespace android {
 
@@ -46,11 +39,10 @@
     static const int DEFAULT_SAMPLE_RATE = 8000;
 
     /* Events used by AudioRecord callback function (callback_t).
-     *
-     * to keep in sync with frameworks/base/media/java/android/media/AudioRecord.java
+     * Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*.
      */
     enum event_type {
-        EVENT_MORE_DATA = 0,        // Request to reqd more data from PCM buffer.
+        EVENT_MORE_DATA = 0,        // Request to read more data from PCM buffer.
         EVENT_OVERRUN = 1,          // PCM buffer overrun occured.
         EVENT_MARKER = 2,           // Record head is at the specified marker position
                                     // (See setMarkerPosition()).
@@ -72,7 +64,7 @@
         int         channelCount;
         audio_format_t format;
         size_t      frameCount;
-        size_t      size;
+        size_t      size;           // total size in bytes == frameCount * frameSize
         union {
             void*       raw;
             short*      i16;
@@ -115,7 +107,7 @@
      static status_t getMinFrameCount(int* frameCount,
                                       uint32_t sampleRate,
                                       audio_format_t format,
-                                      int channelCount);
+                                      audio_channel_mask_t channelMask);
 
     /* Constructs an uninitialized AudioRecord. No connection with
      * AudioFlinger takes place.
@@ -133,32 +125,22 @@
      * sampleRate:         Track sampling rate in Hz.
      * format:             Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
      *                     16 bits per sample).
-     * channelMask:        Channel mask: see audio_channels_t.
+     * channelMask:        Channel mask.
      * frameCount:         Total size of track PCM buffer in frames. This defines the
      *                     latency of the track.
-     * flags:              A bitmask of acoustic values from enum record_flags.  It enables
-     *                     AGC, NS, and IIR.
      * cbf:                Callback function. If not null, this function is called periodically
      *                     to provide new PCM data.
+     * user:               Context for use by the callback receiver.
      * notificationFrames: The callback function is called each time notificationFrames PCM
      *                     frames are ready in record track output buffer.
-     * user                Context for use by the callback receiver.
+     * sessionId:          Not yet supported.
      */
 
-     // FIXME consider removing this alias and replacing it by audio_in_acoustics_t
-     //       or removing the parameter entirely if it is unused
-     enum record_flags {
-         RECORD_AGC_ENABLE = AUDIO_IN_ACOUSTICS_AGC_ENABLE,
-         RECORD_NS_ENABLE  = AUDIO_IN_ACOUSTICS_NS_ENABLE,
-         RECORD_IIR_ENABLE = AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE,
-     };
-
                         AudioRecord(audio_source_t inputSource,
                                     uint32_t sampleRate = 0,
                                     audio_format_t format = AUDIO_FORMAT_DEFAULT,
-                                    uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
+                                    audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO,
                                     int frameCount      = 0,
-                                    record_flags flags  = (record_flags) 0,
                                     callback_t cbf = NULL,
                                     void* user = NULL,
                                     int notificationFrames = 0,
@@ -166,7 +148,7 @@
 
 
     /* Terminates the AudioRecord and unregisters it from AudioFlinger.
-     * Also destroys all resources assotiated with the AudioRecord.
+     * Also destroys all resources associated with the AudioRecord.
      */
                         ~AudioRecord();
 
@@ -182,9 +164,8 @@
             status_t    set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
                             uint32_t sampleRate = 0,
                             audio_format_t format = AUDIO_FORMAT_DEFAULT,
-                            uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
+                            audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO,
                             int frameCount      = 0,
-                            record_flags flags  = (record_flags) 0,
                             callback_t cbf = NULL,
                             void* user = NULL,
                             int notificationFrames = 0,
@@ -205,11 +186,10 @@
      */
             uint32_t     latency() const;
 
-   /* getters, see constructor */
+   /* getters, see constructor and set() */
 
             audio_format_t format() const;
             int         channelCount() const;
-            int         channels() const;
             uint32_t    frameCount() const;
             size_t      frameSize() const;
             audio_source_t inputSource() const;
@@ -271,7 +251,7 @@
             status_t    getPositionUpdatePeriod(uint32_t *updatePeriod) const;
 
 
-    /* Gets record head position. The position is the  total number of frames
+    /* Gets record head position. The position is the total number of frames
      * recorded since record start.
      *
      * Parameters:
@@ -294,7 +274,7 @@
      */
             audio_io_handle_t    getInput() const;
 
-    /* returns the audio session ID associated to this AudioRecord.
+    /* returns the audio session ID associated with this AudioRecord.
      *
      * Parameters:
      *  none.
@@ -357,42 +337,47 @@
             bool processAudioBuffer(const sp<ClientRecordThread>& thread);
             status_t openRecord_l(uint32_t sampleRate,
                                 audio_format_t format,
-                                uint32_t channelMask,
+                                audio_channel_mask_t channelMask,
                                 int frameCount,
                                 audio_io_handle_t input);
             audio_io_handle_t getInput_l();
             status_t restoreRecord_l(audio_track_cblk_t*& cblk);
 
-    sp<IAudioRecord>        mAudioRecord;
-    sp<IMemory>             mCblkMemory;
     sp<ClientRecordThread>  mClientRecordThread;
     status_t                mReadyToRun;
     mutable Mutex           mLock;
     Condition               mCondition;
 
-    uint32_t                mFrameCount;
+    volatile int32_t        mActive;
 
-    audio_track_cblk_t*     mCblk;
+    // for client callback handler
+    callback_t              mCbf;
+    void*                   mUserData;
+
+    // for notification APIs
+    uint32_t                mNotificationFrames;
+    uint32_t                mRemainingFrames;
+    uint32_t                mMarkerPosition;    // in frames
+    bool                    mMarkerReached;
+    uint32_t                mNewPosition;       // in frames
+    uint32_t                mUpdatePeriod;      // in ms
+
+    // constant after constructor or set()
+    uint32_t                mFrameCount;
     audio_format_t          mFormat;
     uint8_t                 mChannelCount;
     audio_source_t          mInputSource;
     status_t                mStatus;
     uint32_t                mLatency;
-
-    volatile int32_t        mActive;
-
-    callback_t              mCbf;
-    void*                   mUserData;
-    uint32_t                mNotificationFrames;
-    uint32_t                mRemainingFrames;
-    uint32_t                mMarkerPosition;
-    bool                    mMarkerReached;
-    uint32_t                mNewPosition;
-    uint32_t                mUpdatePeriod;
-    record_flags            mFlags;
-    uint32_t                mChannelMask;
-    audio_io_handle_t       mInput;
+    audio_channel_mask_t    mChannelMask;
+    audio_io_handle_t       mInput;                     // returned by AudioSystem::getInput()
     int                     mSessionId;
+
+    // may be changed if IAudioRecord object is re-created
+    sp<IAudioRecord>        mAudioRecord;
+    sp<IMemory>             mCblkMemory;
+    audio_track_cblk_t*     mCblk;
+
     int                     mPreviousPriority;          // before start()
     SchedPolicy             mPreviousSchedulingGroup;
 };
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index e2662f2..18c9c92 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -110,8 +110,8 @@
 
     static bool routedToA2dpOutput(audio_stream_type_t streamType);
 
-    static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount,
-        size_t* buffSize);
+    static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+        audio_channel_mask_t channelMask, size_t* buffSize);
 
     static status_t setVoiceVolume(float volume);
 
@@ -201,7 +201,6 @@
                                     uint32_t samplingRate = 0,
                                     audio_format_t format = AUDIO_FORMAT_DEFAULT,
                                     uint32_t channels = AUDIO_CHANNEL_IN_MONO,
-                                    audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
                                     int sessionId = 0);
     static status_t startInput(audio_io_handle_t input);
     static status_t stopInput(audio_io_handle_t input);
@@ -277,7 +276,7 @@
     // previous parameters for recording buffer size queries
     static uint32_t gPrevInSamplingRate;
     static audio_format_t gPrevInFormat;
-    static int gPrevInChannelCount;
+    static audio_channel_mask_t gPrevInChannelMask;
 
     static sp<IAudioPolicyService> gAudioPolicyService;
 
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 86e228b..5d95b3b 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -60,7 +60,7 @@
                                 audio_stream_type_t streamType,
                                 uint32_t sampleRate,
                                 audio_format_t format,
-                                uint32_t channelMask,
+                                audio_channel_mask_t channelMask,
                                 int frameCount,
                                 track_flags_t flags,
                                 const sp<IMemory>& sharedBuffer,
@@ -74,7 +74,7 @@
                                 audio_io_handle_t input,
                                 uint32_t sampleRate,
                                 audio_format_t format,
-                                uint32_t channelMask,
+                                audio_channel_mask_t channelMask,
                                 int frameCount,
                                 track_flags_t flags,
                                 int *sessionId,
@@ -84,7 +84,9 @@
      * and therefore can be cached.
      */
     virtual     uint32_t    sampleRate(audio_io_handle_t output) const = 0;
+#if 0
     virtual     int         channelCount(audio_io_handle_t output) const = 0;
+#endif
     virtual     audio_format_t format(audio_io_handle_t output) const = 0;
     virtual     size_t      frameCount(audio_io_handle_t output) const = 0;
 
@@ -126,7 +128,8 @@
     virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
 
     // retrieve the audio recording buffer size
-    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const = 0;
+    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+            audio_channel_mask_t channelMask) const = 0;
 
     virtual audio_io_handle_t openOutput(audio_module_handle_t module,
                                          audio_devices_t *pDevices,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index e160d70..23fa964 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -64,7 +64,6 @@
                                     uint32_t samplingRate = 0,
                                     audio_format_t format = AUDIO_FORMAT_DEFAULT,
                                     uint32_t channels = 0,
-                                    audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
                                     int audioSession = 0) = 0;
     virtual status_t startInput(audio_io_handle_t input) = 0;
     virtual status_t stopInput(audio_io_handle_t input) = 0;
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index e25d444..4a8e221 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -79,10 +79,6 @@
             MediaBuffer **buffer, const ReadOptions *options = NULL);
     virtual sp<MetaData> getFormat();
 
-    // Pass the metadata over to the buffer, call when you have the lock
-    void passMetadataBufferLocked(MediaBuffer **buffer);
-    bool checkBufferMatchesSlot(int slot, MediaBuffer *buffer);
-
     // Get / Set the frame rate used for encoding. Default fps = 30
     status_t setFrameRate(int32_t fps) ;
     int32_t getFrameRate( ) const;
@@ -105,9 +101,6 @@
     // when a new frame becomes available.
     void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
 
-    // getCurrentBuffer returns the buffer associated with the current image.
-    sp<GraphicBuffer> getCurrentBuffer() const;
-
     // dump our state in a String
     void dump(String8& result) const;
     void dump(String8& result, const char* prefix, char* buffer,
@@ -165,11 +158,12 @@
     // reset mCurrentTexture to INVALID_BUFFER_SLOT.
     int mCurrentSlot;
 
-    // mCurrentBuf is the graphic buffer of the current slot to be used by
-    // buffer consumer. It's possible that this buffer is not associated
-    // with any buffer slot, so we must track it separately in order to
-    // properly use IGraphicBufferAlloc::freeAllGraphicBuffersExcept.
-    sp<GraphicBuffer> mCurrentBuf;
+    // mCurrentBuffers is a list of the graphic buffers that are being used by
+    // buffer consumer (i.e. the video encoder). It's possible that these
+    // buffers are not associated with any buffer slots, so we must track them
+    // separately.  Buffers are added to this list in read, and removed from
+    // this list in signalBufferReturned
+    Vector<sp<GraphicBuffer> > mCurrentBuffers;
 
     // mCurrentTimestamp is the timestamp for the current texture. It
     // gets set to mLastQueuedTimestamp each time updateTexImage is called.
diff --git a/libvideoeditor/lvpp/Android.mk b/libvideoeditor/lvpp/Android.mk
index c018d74..0ed7e6c 100755
--- a/libvideoeditor/lvpp/Android.mk
+++ b/libvideoeditor/lvpp/Android.mk
@@ -59,6 +59,7 @@
     libstagefright            \
     libstagefright_foundation \
     libstagefright_omx        \
+    libsync                   \
     libui                     \
     libutils                  \
     libvideoeditor_osal       \
diff --git a/libvideoeditor/lvpp/NativeWindowRenderer.cpp b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
index b2c2675..2e15ff9 100755
--- a/libvideoeditor/lvpp/NativeWindowRenderer.cpp
+++ b/libvideoeditor/lvpp/NativeWindowRenderer.cpp
@@ -22,9 +22,9 @@
 #include <cutils/log.h>
 #include <gui/SurfaceTexture.h>
 #include <gui/SurfaceTextureClient.h>
-#include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/ADebug.h>
 #include "VideoEditorTools.h"
 
 #define CHECK_EGL_ERROR CHECK(EGL_SUCCESS == eglGetError())
@@ -382,7 +382,7 @@
     int64_t timeUs;
     CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
     native_window_set_buffers_timestamp(anw, timeUs * 1000);
-    status_t err = anw->queueBuffer(anw, buffer->graphicBuffer().get());
+    status_t err = anw->queueBuffer(anw, buffer->graphicBuffer().get(), -1);
     if (err != 0) {
         ALOGE("queueBuffer failed with error %s (%d)", strerror(-err), -err);
         return;
@@ -399,18 +399,16 @@
     native_window_set_usage(anw, GRALLOC_USAGE_SW_WRITE_OFTEN);
 
     ANativeWindowBuffer* anb;
-    anw->dequeueBuffer(anw, &anb);
+    CHECK(NO_ERROR == native_window_dequeue_buffer_and_wait(anw, &anb));
     CHECK(anb != NULL);
 
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-    CHECK(NO_ERROR == anw->lockBuffer(anw, buf->getNativeBuffer()));
-
     // Copy the buffer
     uint8_t* img = NULL;
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
     copyI420Buffer(buffer, img, width, height, buf->getStride());
     buf->unlock();
-    CHECK(NO_ERROR == anw->queueBuffer(anw, buf->getNativeBuffer()));
+    CHECK(NO_ERROR == anw->queueBuffer(anw, buf->getNativeBuffer(), -1));
 }
 
 void NativeWindowRenderer::copyI420Buffer(MediaBuffer* src, uint8_t* dst,
diff --git a/libvideoeditor/lvpp/PreviewRenderer.cpp b/libvideoeditor/lvpp/PreviewRenderer.cpp
index 4aa4eb3..b1cfc8e 100755
--- a/libvideoeditor/lvpp/PreviewRenderer.cpp
+++ b/libvideoeditor/lvpp/PreviewRenderer.cpp
@@ -97,13 +97,12 @@
 void PreviewRenderer::getBufferYV12(uint8_t **data, size_t *stride) {
     int err = OK;
 
-    if ((err = mSurface->ANativeWindow::dequeueBuffer(mSurface.get(), &mBuf)) != 0) {
-        ALOGW("Surface::dequeueBuffer returned error %d", err);
+    if ((err = native_window_dequeue_buffer_and_wait(mSurface.get(),
+            &mBuf)) != 0) {
+        ALOGW("native_window_dequeue_buffer_and_wait returned error %d", err);
         return;
     }
 
-    CHECK_EQ(0, mSurface->ANativeWindow::lockBuffer(mSurface.get(), mBuf));
-
     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
 
     Rect bounds(mWidth, mHeight);
@@ -131,7 +130,7 @@
     if (mBuf!= NULL) {
         CHECK_EQ(0, mapper.unlock(mBuf->handle));
 
-        if ((err = mSurface->ANativeWindow::queueBuffer(mSurface.get(), mBuf)) != 0) {
+        if ((err = mSurface->ANativeWindow::queueBuffer(mSurface.get(), mBuf, -1)) != 0) {
             ALOGW("Surface::queueBuffer returned error %d", err);
         }
     }
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
index 5026073..f735c0b 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
@@ -1483,11 +1483,15 @@
                     (int32_t*)&(pVideoStreamHandler->m_videoHeight));
 
                 (*pStreamHandler)  = (M4_StreamHandler*)(pVideoStreamHandler);
-                meta->findInt64(kKeyDuration,
-                    (int64_t*)&(Duration));
-                ((*pStreamHandler)->m_duration) =
-                    (int32_t)((Duration)/1000); // conversion to mS
+                meta->findInt64(kKeyDuration, (int64_t*)&(Duration));
+                ((*pStreamHandler)->m_duration) = (int32_t)((Duration)/1000); // conversion to mS
                 pC->mMaxDuration = ((*pStreamHandler)->m_duration);
+                if (pC->mMaxDuration == 0) {
+                    ALOGE("Video is too short: %lld Us", Duration);
+                    delete pVideoStreamHandler;
+                    pVideoStreamHandler = NULL;
+                    return M4ERR_PARAMETER;
+                }
                 ALOGV("VideoEditor3gpReader_getNextStreamHandler m_duration %d",
                     (*pStreamHandler)->m_duration);
 
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 0562f8e..f8813c9 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -18,29 +18,19 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "AudioRecord"
 
-#include <stdint.h>
+#include <sys/resource.h>
 #include <sys/types.h>
 
-#include <sched.h>
-#include <sys/resource.h>
+#include <binder/IPCThreadState.h>
+#include <cutils/atomic.h>
+#include <cutils/compiler.h>
+#include <media/AudioRecord.h>
+#include <media/AudioSystem.h>
+#include <system/audio.h>
+#include <utils/Log.h>
 
 #include <private/media/AudioTrackShared.h>
 
-#include <media/AudioSystem.h>
-#include <media/AudioRecord.h>
-#include <media/mediarecorder.h>
-
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <utils/Timers.h>
-#include <utils/Atomic.h>
-
-#include <system/audio.h>
-#include <cutils/bitops.h>
-#include <cutils/compiler.h>
-
 namespace android {
 // ---------------------------------------------------------------------------
 
@@ -49,18 +39,18 @@
         int* frameCount,
         uint32_t sampleRate,
         audio_format_t format,
-        int channelCount)
+        audio_channel_mask_t channelMask)
 {
     size_t size = 0;
-    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
+    if (AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size)
             != NO_ERROR) {
         ALOGE("AudioSystem could not query the input buffer size.");
         return NO_INIT;
     }
 
     if (size == 0) {
-        ALOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
-            sampleRate, format, channelCount);
+        ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x",
+            sampleRate, format, channelMask);
         return BAD_VALUE;
     }
 
@@ -68,6 +58,7 @@
     size <<= 1;
 
     if (audio_is_linear_pcm(format)) {
+        int channelCount = popcount(channelMask);
         size /= channelCount * audio_bytes_per_sample(format);
     }
 
@@ -87,9 +78,8 @@
         audio_source_t inputSource,
         uint32_t sampleRate,
         audio_format_t format,
-        uint32_t channelMask,
+        audio_channel_mask_t channelMask,
         int frameCount,
-        record_flags flags,
         callback_t cbf,
         void* user,
         int notificationFrames,
@@ -98,7 +88,7 @@
       mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
 {
     mStatus = set(inputSource, sampleRate, format, channelMask,
-            frameCount, flags, cbf, user, notificationFrames, sessionId);
+            frameCount, cbf, user, notificationFrames, sessionId);
 }
 
 AudioRecord::~AudioRecord()
@@ -122,9 +112,8 @@
         audio_source_t inputSource,
         uint32_t sampleRate,
         audio_format_t format,
-        uint32_t channelMask,
+        audio_channel_mask_t channelMask,
         int frameCount,
-        record_flags flags,
         callback_t cbf,
         void* user,
         int notificationFrames,
@@ -132,7 +121,7 @@
         int sessionId)
 {
 
-    ALOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount);
+    ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, frameCount);
 
     AutoMutex lock(mLock);
 
@@ -174,7 +163,6 @@
                                                     sampleRate,
                                                     format,
                                                     channelMask,
-                                                    (audio_in_acoustics_t)flags,
                                                     mSessionId);
     if (input == 0) {
         ALOGE("Could not get audio input for record source %d", inputSource);
@@ -229,7 +217,6 @@
     mNewPosition = 0;
     mUpdatePeriod = 0;
     mInputSource = inputSource;
-    mFlags = flags;
     mInput = input;
     AudioSystem::acquireAudioSessionId(mSessionId);
 
@@ -457,7 +444,7 @@
 status_t AudioRecord::openRecord_l(
         uint32_t sampleRate,
         audio_format_t format,
-        uint32_t channelMask,
+        audio_channel_mask_t channelMask,
         int frameCount,
         audio_io_handle_t input)
 {
@@ -613,7 +600,6 @@
                                 mCblk->sampleRate,
                                 mFormat,
                                 mChannelMask,
-                                (audio_in_acoustics_t)mFlags,
                                 mSessionId);
     return mInput;
 }
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 4c41ba5..9c270c8 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -41,7 +41,7 @@
 // Cached values for recording queries, all protected by gLock
 uint32_t AudioSystem::gPrevInSamplingRate = 16000;
 audio_format_t AudioSystem::gPrevInFormat = AUDIO_FORMAT_PCM_16_BIT;
-int AudioSystem::gPrevInChannelCount = 1;
+audio_channel_mask_t AudioSystem::gPrevInChannelMask = AUDIO_CHANNEL_IN_MONO;
 size_t AudioSystem::gInBuffSize = 0;
 
 
@@ -334,25 +334,25 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount,
-    size_t* buffSize)
+status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+        audio_channel_mask_t channelMask, size_t* buffSize)
 {
     gLock.lock();
     // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values
     size_t inBuffSize = gInBuffSize;
     if ((inBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat)
-        || (channelCount != gPrevInChannelCount)) {
+        || (channelMask != gPrevInChannelMask)) {
         gLock.unlock();
         const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
         if (af == 0) {
             return PERMISSION_DENIED;
         }
-        inBuffSize = af->getInputBufferSize(sampleRate, format, channelCount);
+        inBuffSize = af->getInputBufferSize(sampleRate, format, channelMask);
         gLock.lock();
         // save the request params
         gPrevInSamplingRate = sampleRate;
         gPrevInFormat = format;
-        gPrevInChannelCount = channelCount;
+        gPrevInChannelMask = channelMask;
 
         gInBuffSize = inBuffSize;
     }
@@ -625,12 +625,11 @@
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     uint32_t channels,
-                                    audio_in_acoustics_t acoustics,
                                     int sessionId)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return 0;
-    return aps->getInput(inputSource, samplingRate, format, channels, acoustics, sessionId);
+    return aps->getInput(inputSource, samplingRate, format, channels, sessionId);
 }
 
 status_t AudioSystem::startInput(audio_io_handle_t input)
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index e8dd438..27f6b45 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -32,7 +32,7 @@
     CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
     OPEN_RECORD,
     SAMPLE_RATE,
-    CHANNEL_COUNT,
+    CHANNEL_COUNT,  // obsolete
     FORMAT,
     FRAME_COUNT,
     LATENCY,
@@ -86,7 +86,7 @@
                                 audio_stream_type_t streamType,
                                 uint32_t sampleRate,
                                 audio_format_t format,
-                                uint32_t channelMask,
+                                audio_channel_mask_t channelMask,
                                 int frameCount,
                                 track_flags_t flags,
                                 const sp<IMemory>& sharedBuffer,
@@ -182,6 +182,7 @@
         return reply.readInt32();
     }
 
+#if 0
     virtual int channelCount(audio_io_handle_t output) const
     {
         Parcel data, reply;
@@ -190,6 +191,7 @@
         remote()->transact(CHANNEL_COUNT, data, &reply);
         return reply.readInt32();
     }
+#endif
 
     virtual audio_format_t format(audio_io_handle_t output) const
     {
@@ -347,13 +349,14 @@
         remote()->transact(REGISTER_CLIENT, data, &reply);
     }
 
-    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const
+    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+            audio_channel_mask_t channelMask) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(sampleRate);
         data.writeInt32(format);
-        data.writeInt32(channelCount);
+        data.writeInt32(channelMask);
         remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
         return reply.readInt32();
     }
@@ -698,7 +701,7 @@
             int streamType = data.readInt32();
             uint32_t sampleRate = data.readInt32();
             audio_format_t format = (audio_format_t) data.readInt32();
-            int channelCount = data.readInt32();
+            audio_channel_mask_t channelMask = data.readInt32();
             size_t bufferCount = data.readInt32();
             track_flags_t flags = (track_flags_t) data.readInt32();
             sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
@@ -708,7 +711,7 @@
             status_t status;
             sp<IAudioTrack> track = createTrack(pid,
                     (audio_stream_type_t) streamType, sampleRate, format,
-                    channelCount, bufferCount, flags, buffer, output, tid, &sessionId, &status);
+                    channelMask, bufferCount, flags, buffer, output, tid, &sessionId, &status);
             reply->writeInt32(sessionId);
             reply->writeInt32(status);
             reply->writeStrongBinder(track->asBinder());
@@ -720,13 +723,13 @@
             audio_io_handle_t input = (audio_io_handle_t) data.readInt32();
             uint32_t sampleRate = data.readInt32();
             audio_format_t format = (audio_format_t) data.readInt32();
-            int channelCount = data.readInt32();
+            audio_channel_mask_t channelMask = data.readInt32();
             size_t bufferCount = data.readInt32();
             track_flags_t flags = (track_flags_t) data.readInt32();
             int sessionId = data.readInt32();
             status_t status;
             sp<IAudioRecord> record = openRecord(pid, input,
-                    sampleRate, format, channelCount, bufferCount, flags, &sessionId, &status);
+                    sampleRate, format, channelMask, bufferCount, flags, &sessionId, &status);
             reply->writeInt32(sessionId);
             reply->writeInt32(status);
             reply->writeStrongBinder(record->asBinder());
@@ -737,11 +740,13 @@
             reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
+#if 0
         case CHANNEL_COUNT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             reply->writeInt32( channelCount((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
+#endif
         case FORMAT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
@@ -846,8 +851,8 @@
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             uint32_t sampleRate = data.readInt32();
             audio_format_t format = (audio_format_t) data.readInt32();
-            int channelCount = data.readInt32();
-            reply->writeInt32( getInputBufferSize(sampleRate, format, channelCount) );
+            audio_channel_mask_t channelMask = data.readInt32();
+            reply->writeInt32( getInputBufferSize(sampleRate, format, channelMask) );
             return NO_ERROR;
         } break;
         case OPEN_OUTPUT: {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 7aab8d6..5a4512e 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -176,7 +176,6 @@
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     uint32_t channels,
-                                    audio_in_acoustics_t acoustics,
                                     int audioSession)
     {
         Parcel data, reply;
@@ -185,7 +184,6 @@
         data.writeInt32(samplingRate);
         data.writeInt32(static_cast <uint32_t>(format));
         data.writeInt32(channels);
-        data.writeInt32(static_cast <uint32_t>(acoustics));
         data.writeInt32(audioSession);
         remote()->transact(GET_INPUT, data, &reply);
         return static_cast <audio_io_handle_t> (reply.readInt32());
@@ -465,14 +463,11 @@
             uint32_t samplingRate = data.readInt32();
             audio_format_t format = (audio_format_t) data.readInt32();
             uint32_t channels = data.readInt32();
-            audio_in_acoustics_t acoustics =
-                    static_cast <audio_in_acoustics_t>(data.readInt32());
             int audioSession = data.readInt32();
             audio_io_handle_t input = getInput(inputSource,
                                                samplingRate,
                                                format,
                                                channels,
-                                               acoustics,
                                                audioSession);
             reply->writeInt32(static_cast <int>(input));
             return NO_ERROR;
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index 284ba01..33b7bd5 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -28,6 +28,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/mediarecorder.h>
 #include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 
 namespace android {
@@ -44,7 +46,7 @@
 
     ALOGV("AACWriter Constructor");
 
-    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
+    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
     if (mFd >= 0) {
         mInitCheck = OK;
     }
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c4743a1..b4894e9 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -595,7 +595,7 @@
     // Dequeue buffers and send them to OMX
     for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
         ANativeWindowBuffer *buf;
-        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
         if (err != 0) {
             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
             break;
@@ -653,7 +653,7 @@
          mComponentName.c_str(), info->mBufferID);
 
     int err = mNativeWindow->cancelBuffer(
-        mNativeWindow.get(), info->mGraphicBuffer.get());
+        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
 
     CHECK_EQ(err, 0);
 
@@ -664,7 +664,8 @@
 
 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
     ANativeWindowBuffer *buf;
-    if (mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf) != 0) {
+    int fenceFd = -1;
+    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
         ALOGE("dequeueBuffer failed.");
         return NULL;
     }
@@ -2188,7 +2189,8 @@
     // on the screen and then been replaced, so an previous video frames are
     // guaranteed NOT to be currently displayed.
     for (int i = 0; i < numBufs + 1; i++) {
-        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
+        int fenceFd = -1;
+        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
         if (err != NO_ERROR) {
             ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
                     strerror(-err), -err);
@@ -2196,13 +2198,6 @@
         }
 
         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-        err = mNativeWindow->lockBuffer(mNativeWindow.get(),
-                buf->getNativeBuffer());
-        if (err != NO_ERROR) {
-            ALOGE("error pushing blank frames: lockBuffer failed: %s (%d)",
-                    strerror(-err), -err);
-            goto error;
-        }
 
         // Fill the buffer with the a 1x1 checkerboard pattern ;)
         uint32_t* img = NULL;
@@ -2223,7 +2218,7 @@
         }
 
         err = mNativeWindow->queueBuffer(mNativeWindow.get(),
-                buf->getNativeBuffer());
+                buf->getNativeBuffer(), -1);
         if (err != NO_ERROR) {
             ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
                     strerror(-err), -err);
@@ -2238,7 +2233,7 @@
     if (err != NO_ERROR) {
         // Clean up after an error.
         if (anb != NULL) {
-            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb);
+            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
         }
 
         native_window_api_disconnect(mNativeWindow.get(),
@@ -2751,7 +2746,7 @@
         status_t err;
         if ((err = mCodec->mNativeWindow->queueBuffer(
                     mCodec->mNativeWindow.get(),
-                    info->mGraphicBuffer.get())) == OK) {
+                    info->mGraphicBuffer.get(), -1)) == OK) {
             info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
         } else {
             mCodec->signalError(OMX_ErrorUndefined, err);
@@ -3253,11 +3248,6 @@
             if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
                 continue;
             }
-
-            status_t err = mCodec->mNativeWindow->lockBuffer(
-                    mCodec->mNativeWindow.get(),
-                    info->mGraphicBuffer.get());
-            CHECK_EQ(err, (status_t)OK);
         } else {
             CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
         }
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index ca85640..15a7143 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -36,7 +36,7 @@
       mPaused(false),
       mResumed(false) {
 
-    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
+    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
     if (mFd >= 0) {
         mInitCheck = OK;
     }
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 8a68036..e5b4d75 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -81,6 +81,7 @@
         libssl \
         libstagefright_omx \
         libstagefright_yuv \
+        libsync \
         libui \
         libutils \
         libvorbisidec \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 72d797e..ed142a4 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -48,7 +48,8 @@
 
 AudioSource::AudioSource(
         audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
-    : mStarted(false),
+    : mRecord(NULL),
+      mStarted(false),
       mSampleRate(sampleRate),
       mPrevSampleTimeUs(0),
       mNumFramesReceived(0),
@@ -61,7 +62,7 @@
     status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
                                            sampleRate,
                                            AUDIO_FORMAT_PCM_16_BIT,
-                                           channelCount);
+                                           audio_channel_in_mask_from_count(channelCount));
     if (status == OK) {
         // make sure that the AudioRecord callback never returns more than the maximum
         // buffer size
@@ -73,15 +74,10 @@
             bufCount++;
         }
 
-        AudioRecord::record_flags flags = (AudioRecord::record_flags)
-                        (AudioRecord::RECORD_AGC_ENABLE |
-                         AudioRecord::RECORD_NS_ENABLE  |
-                         AudioRecord::RECORD_IIR_ENABLE);
         mRecord = new AudioRecord(
                     inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
                     audio_channel_in_mask_from_count(channelCount),
                     bufCount * frameCount,
-                    flags,
                     AudioRecordCallbackFunction,
                     this,
                     frameCount);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 0f346d8..2c68075 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -130,7 +130,7 @@
         CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
         native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);
         status_t err = mNativeWindow->queueBuffer(
-                mNativeWindow.get(), buffer->graphicBuffer().get());
+                mNativeWindow.get(), buffer->graphicBuffer().get(), -1);
         if (err != 0) {
             ALOGE("queueBuffer failed with error %s (%d)", strerror(-err),
                     -err);
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index 668d7f7..29bb056 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -350,7 +350,7 @@
         for (FLAC__uint32 i = 0; i < vc->num_comments; ++i) {
             FLAC__StreamMetadata_VorbisComment_Entry *vce;
             vce = &vc->comments[i];
-            if (mFileMetadata != 0) {
+            if (mFileMetadata != 0 && vce->entry != NULL) {
                 parseVorbisComment(mFileMetadata, (const char *) vce->entry,
                         vce->length);
             }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 755b502..cc18a1d 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -269,7 +269,7 @@
       mAreGeoTagsAvailable(false),
       mStartTimeOffsetMs(-1) {
 
-    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
+    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
     if (mFd >= 0) {
         mInitCheck = OK;
     }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index fde7ebf..1d4ab32 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1776,7 +1776,7 @@
     // Dequeue buffers and send them to OMX
     for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
         ANativeWindowBuffer* buf;
-        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
         if (err != 0) {
             ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
             break;
@@ -1832,7 +1832,7 @@
     CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
     CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer);
     int err = mNativeWindow->cancelBuffer(
-        mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get());
+        mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1);
     if (err != 0) {
       CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
 
@@ -1846,7 +1846,8 @@
 OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
     // Dequeue the next buffer from the native window.
     ANativeWindowBuffer* buf;
-    int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+    int fenceFd = -1;
+    int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
     if (err != 0) {
       CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
 
@@ -1950,7 +1951,8 @@
     // on the screen and then been replaced, so an previous video frames are
     // guaranteed NOT to be currently displayed.
     for (int i = 0; i < numBufs + 1; i++) {
-        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
+        int fenceFd = -1;
+        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
         if (err != NO_ERROR) {
             ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
                     strerror(-err), -err);
@@ -1958,13 +1960,6 @@
         }
 
         sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-        err = mNativeWindow->lockBuffer(mNativeWindow.get(),
-                buf->getNativeBuffer());
-        if (err != NO_ERROR) {
-            ALOGE("error pushing blank frames: lockBuffer failed: %s (%d)",
-                    strerror(-err), -err);
-            goto error;
-        }
 
         // Fill the buffer with the a 1x1 checkerboard pattern ;)
         uint32_t* img = NULL;
@@ -1985,7 +1980,7 @@
         }
 
         err = mNativeWindow->queueBuffer(mNativeWindow.get(),
-                buf->getNativeBuffer());
+                buf->getNativeBuffer(), -1);
         if (err != NO_ERROR) {
             ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
                     strerror(-err), -err);
@@ -2000,7 +1995,7 @@
     if (err != NO_ERROR) {
         // Clean up after an error.
         if (anb != NULL) {
-            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb);
+            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
         }
 
         native_window_api_disconnect(mNativeWindow.get(),
@@ -3199,23 +3194,6 @@
         return;
     }
 
-    if (info->mMediaBuffer != NULL) {
-        sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
-        if (graphicBuffer != 0) {
-            // When using a native buffer we need to lock the buffer before
-            // giving it to OMX.
-            CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer);
-            int err = mNativeWindow->lockBuffer(mNativeWindow.get(),
-                    graphicBuffer.get());
-            if (err != 0) {
-                CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err);
-
-                setState(ERROR);
-                return;
-            }
-        }
-    }
-
     CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
     status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
 
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 5d72a05..f1f444e 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -96,11 +96,6 @@
     mFrameAvailableListener = listener;
 }
 
-sp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
-    Mutex::Autolock lock(mMutex);
-    return mCurrentBuf;
-}
-
 void SurfaceMediaSource::dump(String8& result) const
 {
     char buffer[1024];
@@ -185,6 +180,35 @@
     return meta;
 }
 
+// Pass the data to the MediaBuffer. Pass in only the metadata
+// The metadata passed consists of two parts:
+// 1. First, there is an integer indicating that it is a GRAlloc
+// source (kMetadataBufferTypeGrallocSource)
+// 2. This is followed by the buffer_handle_t that is a handle to the
+// GRalloc buffer. The encoder needs to interpret this GRalloc handle
+// and encode the frames.
+// --------------------------------------------------------------
+// |  kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
+// --------------------------------------------------------------
+// Note: Call only when you have the lock
+static void passMetadataBuffer(MediaBuffer **buffer,
+        buffer_handle_t bufferHandle) {
+    // MediaBuffer allocates and owns this data
+    MediaBuffer *tempBuffer = new MediaBuffer(4 + sizeof(buffer_handle_t));
+    char *data = (char *)tempBuffer->data();
+    if (data == NULL) {
+        ALOGE("Cannot allocate memory for metadata buffer!");
+        return;
+    }
+    OMX_U32 type = kMetadataBufferTypeGrallocSource;
+    memcpy(data, &type, 4);
+    memcpy(data + 4, &bufferHandle, sizeof(buffer_handle_t));
+    *buffer = tempBuffer;
+
+    ALOGV("handle = %p, , offset = %d, length = %d",
+            bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
+}
+
 status_t SurfaceMediaSource::read( MediaBuffer **buffer,
                                     const ReadOptions *options)
 {
@@ -220,7 +244,8 @@
                 if (mStartTimeNs > 0) {
                     if (item.mTimestamp < mStartTimeNs) {
                         // This frame predates start of record, discard
-                        mBufferQueue->releaseBuffer(item.mBuf, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+                        mBufferQueue->releaseBuffer(item.mBuf, EGL_NO_DISPLAY,
+                                EGL_NO_SYNC_KHR, Fence::NO_FENCE);
                         continue;
                     }
                     mStartTimeNs = item.mTimestamp - mStartTimeNs;
@@ -251,13 +276,14 @@
     if (item.mGraphicBuffer != NULL) {
         mBufferSlot[mCurrentSlot] = item.mGraphicBuffer;
     }
-    mCurrentBuf = mBufferSlot[mCurrentSlot];
+
+    mCurrentBuffers.push_back(mBufferSlot[mCurrentSlot]);
     int64_t prevTimeStamp = mCurrentTimestamp;
     mCurrentTimestamp = item.mTimestamp;
 
     mNumFramesEncoded++;
     // Pass the data to the MediaBuffer. Pass in only the metadata
-    passMetadataBufferLocked(buffer);
+    passMetadataBuffer(buffer, mBufferSlot[mCurrentSlot]->handle);
 
     (*buffer)->setObserver(this);
     (*buffer)->add_ref();
@@ -270,34 +296,12 @@
     return OK;
 }
 
-// Pass the data to the MediaBuffer. Pass in only the metadata
-// The metadata passed consists of two parts:
-// 1. First, there is an integer indicating that it is a GRAlloc
-// source (kMetadataBufferTypeGrallocSource)
-// 2. This is followed by the buffer_handle_t that is a handle to the
-// GRalloc buffer. The encoder needs to interpret this GRalloc handle
-// and encode the frames.
-// --------------------------------------------------------------
-// |  kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
-// --------------------------------------------------------------
-// Note: Call only when you have the lock
-void SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) {
-    ALOGV("passMetadataBuffer");
-    // MediaBuffer allocates and owns this data
-    MediaBuffer *tempBuffer =
-        new MediaBuffer(4 + sizeof(buffer_handle_t));
-    char *data = (char *)tempBuffer->data();
-    if (data == NULL) {
-        ALOGE("Cannot allocate memory for metadata buffer!");
-        return;
-    }
-    OMX_U32 type = kMetadataBufferTypeGrallocSource;
-    memcpy(data, &type, 4);
-    memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t));
-    *buffer = tempBuffer;
-
-    ALOGV("handle = %p, , offset = %d, length = %d",
-            mCurrentBuf->handle, (*buffer)->range_length(), (*buffer)->range_offset());
+static buffer_handle_t getMediaBufferHandle(MediaBuffer *buffer) {
+    // need to convert to char* for pointer arithmetic and then
+    // copy the byte stream into our handle
+    buffer_handle_t bufferHandle;
+    memcpy(&bufferHandle, (char*)(buffer->data()) + 4, sizeof(buffer_handle_t));
+    return bufferHandle;
 }
 
 void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
@@ -307,20 +311,31 @@
 
     Mutex::Autolock lock(mMutex);
 
-    if (mStopped) {
-        ALOGV("signalBufferReturned: mStopped = true! Nothing to do!");
-        return;
+    buffer_handle_t bufferHandle = getMediaBufferHandle(buffer);
+
+    for (size_t i = 0; i < mCurrentBuffers.size(); i++) {
+        if (mCurrentBuffers[i]->handle == bufferHandle) {
+            mCurrentBuffers.removeAt(i);
+            foundBuffer = true;
+            break;
+        }
+    }
+
+    if (!foundBuffer) {
+        ALOGW("returned buffer was not found in the current buffer list");
     }
 
     for (int id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) {
         if (mBufferSlot[id] == NULL) {
             continue;
         }
-        if (checkBufferMatchesSlot(id, buffer)) {
+
+        if (bufferHandle == mBufferSlot[id]->handle) {
             ALOGV("Slot %d returned, matches handle = %p", id,
                     mBufferSlot[id]->handle);
 
-            mBufferQueue->releaseBuffer(id, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+            mBufferQueue->releaseBuffer(id, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
+                    Fence::NO_FENCE);
 
             buffer->setObserver(0);
             buffer->release();
@@ -335,15 +350,6 @@
     }
 }
 
-bool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) {
-    ALOGV("Check if Buffer matches slot");
-    // need to convert to char* for pointer arithmetic and then
-    // copy the byte stream into our handle
-    buffer_handle_t bufferHandle ;
-    memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t));
-    return mBufferSlot[slot]->handle  ==  bufferHandle;
-}
-
 // Part of the BufferQueue::ConsumerListener
 void SurfaceMediaSource::onFrameAvailable() {
     ALOGV("onFrameAvailable");
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 8673bad..2704a37 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -141,13 +141,12 @@
         const void *data, size_t size, void *platformPrivate) {
     ANativeWindowBuffer *buf;
     int err;
-    if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) {
+    if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),
+            &buf)) != 0) {
         ALOGW("Surface::dequeueBuffer returned error %d", err);
         return;
     }
 
-    CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf));
-
     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
 
     Rect bounds(mCropWidth, mCropHeight);
@@ -231,7 +230,8 @@
 
     CHECK_EQ(0, mapper.unlock(buf->handle));
 
-    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) {
+    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf,
+            -1)) != 0) {
         ALOGW("Surface::queueBuffer returned error %d", err);
     }
     buf = NULL;
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
index a1e6be7..57fff0b 100644
--- a/media/libstagefright/tests/Android.mk
+++ b/media/libstagefright/tests/Android.mk
@@ -20,9 +20,10 @@
 	libgui \
 	libmedia \
 	libstagefright \
-	libstagefright_omx \
 	libstagefright_foundation \
+	libstagefright_omx \
 	libstlport \
+	libsync \
 	libui \
 	libutils \
 
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index 466f521..cc2aca7 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -509,31 +509,31 @@
 // cpu YV12 buffer
 void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
     ANativeWindowBuffer* anb;
-    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
     ASSERT_TRUE(anb != NULL);
 
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
 
     // Fill the buffer with the a checkerboard pattern
     uint8_t* img = NULL;
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
     buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
     SurfaceMediaSourceTest::fillYV12Buffer(img, width, height, buf->getStride());
     buf->unlock();
 
-    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
+            -1));
 }
 
 // Dequeuing and queuing the buffer without really filling it in.
 void SurfaceMediaSourceTest::oneBufferPassNoFill(int width, int height ) {
     ANativeWindowBuffer* anb;
-    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
     ASSERT_TRUE(anb != NULL);
 
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-    // ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
     // We do not fill the buffer in. Just queue it back.
-    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
+            -1));
 }
 
 // Fill a YV12 buffer with a multi-colored checkerboard pattern
@@ -652,7 +652,7 @@
     ANativeWindowBuffer* anb;
 
     // Note: make sure we get an ERROR back when dequeuing!
-    ASSERT_NE(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_NE(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
 }
 
 // pass multiple buffers from the native_window the SurfaceMediaSource
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index bf7795c..d672dff 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -667,7 +667,7 @@
 // reads the object's data and writes it to the specified file path
 bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) {
     ALOGD("readObject: %s", destPath);
-    int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC);
+    int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
     if (fd < 0) {
         ALOGE("open failed for %s", destPath);
         return false;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 5606187..662a93d 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -931,7 +931,7 @@
     initialData = ret - MTP_CONTAINER_HEADER_SIZE;
 
     mtp_file_range  mfr;
-    mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC);
+    mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
     if (mfr.fd < 0) {
         result = MTP_RESPONSE_GENERAL_ERROR;
         goto done;
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 8473fab..c2d2790 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -89,7 +89,7 @@
 
 LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"'
 
-LOCAL_CFLAGS += -DHAVE_REQUEST_PRIORITY -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE -USOAKER
+LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
 
 # uncomment for systrace
 # LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_AUDIO
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b78c6d1..ceaf27d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -83,13 +83,7 @@
 #include "PipeReader.h"
 #include "SourceAudioBufferProvider.h"
 
-#ifdef HAVE_REQUEST_PRIORITY
 #include "SchedulingPolicyService.h"
-#endif
-
-#ifdef SOAKER
-#include "Soaker.h"
-#endif
 
 // ----------------------------------------------------------------------------
 
@@ -908,7 +902,7 @@
     {
         Mutex::Autolock _l(mLock);
         thread = checkPlaybackThread_l(ioHandle);
-        if (thread == NULL) {
+        if (thread == 0) {
             thread = checkRecordThread_l(ioHandle);
         } else if (thread == primaryPlaybackThread_l()) {
             // indicate output device change to all input threads for pre processing
@@ -964,7 +958,8 @@
     return String8("");
 }
 
-size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const
+size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+        audio_channel_mask_t channelMask) const
 {
     status_t ret = initCheck();
     if (ret != NO_ERROR) {
@@ -975,7 +970,7 @@
     mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
     struct audio_config config = {
         sample_rate: sampleRate,
-        channel_mask: audio_channel_in_mask_from_count(channelCount),
+        channel_mask: channelMask,
         format: format,
     };
     size_t size = mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, &config);
@@ -1106,6 +1101,20 @@
     mClients.removeItem(pid);
 }
 
+// getEffectThread_l() must be called with AudioFlinger::mLock held
+sp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId)
+{
+    sp<PlaybackThread> thread;
+
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
+            ALOG_ASSERT(thread == 0);
+            thread = mPlaybackThreads.valueAt(i);
+        }
+    }
+
+    return thread;
+}
 
 // ----------------------------------------------------------------------------
 
@@ -1118,8 +1127,7 @@
         mChannelCount(0),
         mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
         mParamStatus(NO_ERROR),
-        mStandby(false), mId(id),
-        mDevice(device),
+        mStandby(false), mDevice((audio_devices_t) device), mId(id),
         mDeathRecipient(new PMDeathRecipient(this))
 {
 }
@@ -1775,7 +1783,7 @@
             track = TimedTrack::create(this, client, streamType, sampleRate, format,
                     channelMask, frameCount, sharedBuffer, sessionId);
         }
-        if (track == NULL || track->getCblk() == NULL || track->name() < 0) {
+        if (track == 0 || track->getCblk() == NULL || track->name() < 0) {
             lStatus = NO_MEMORY;
             goto Exit;
         }
@@ -1790,7 +1798,6 @@
         }
     }
 
-#ifdef HAVE_REQUEST_PRIORITY
     if ((flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
         pid_t callingPid = IPCThreadState::self()->getCallingPid();
         // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
@@ -1801,7 +1808,6 @@
                     1, callingPid, tid, err);
         }
     }
-#endif
 
     lStatus = NO_ERROR;
 
@@ -2181,9 +2187,6 @@
         audio_io_handle_t id, uint32_t device, type_t type)
     :   PlaybackThread(audioFlinger, output, id, device, type),
         // mAudioMixer below
-#ifdef SOAKER
-        mSoaker(NULL),
-#endif
         // mFastMixer below
         mFastMixerFutex(0)
         // mOutputSink below
@@ -2253,13 +2256,6 @@
         mTeeSource = teeSource;
 #endif
 
-#ifdef SOAKER
-        // create a soaker as workaround for governor issues
-        mSoaker = new Soaker();
-        // FIXME Soaker should only run when needed, i.e. when FastMixer is not in COLD_IDLE
-        mSoaker->run("Soaker", PRIORITY_LOWEST);
-#endif
-
         // create fast mixer and configure it initially with just one fast track for our submix
         mFastMixer = new FastMixer();
         FastMixerStateQueue *sq = mFastMixer->sq();
@@ -2291,14 +2287,12 @@
 
         // start the fast mixer
         mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
-#ifdef HAVE_REQUEST_PRIORITY
         pid_t tid = mFastMixer->getTid();
         int err = requestPriority(getpid_cached, tid, 2);
         if (err != 0) {
             ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
                     2, getpid_cached, tid, err);
         }
-#endif
 
 #ifdef AUDIO_WATCHDOG
         // create and start the watchdog
@@ -2356,12 +2350,6 @@
         delete fastTrack->mBufferProvider;
         sq->end(false /*didModify*/);
         delete mFastMixer;
-#ifdef SOAKER
-        if (mSoaker != NULL) {
-            mSoaker->requestExitAndWait();
-        }
-        delete mSoaker;
-#endif
         if (mAudioWatchdog != 0) {
             mAudioWatchdog->requestExit();
             mAudioWatchdog->requestExitAndWait();
@@ -2494,9 +2482,6 @@
 
     // MIXER
     nsecs_t lastWarning = 0;
-if (mType == MIXER) {
-    longStandbyExit = false;
-}
 
     // DUPLICATING
     // FIXME could this be made local to while loop?
@@ -2621,11 +2606,6 @@
                             ns2ms(delta), mNumDelayedWrites, this);
                     lastWarning = now;
                 }
-                // FIXME this is broken: longStandbyExit should be handled out of the if() and with
-                // a different threshold. Or completely removed for what it is worth anyway...
-                if (mStandby) {
-                    longStandbyExit = true;
-                }
             }
 }
 
@@ -2833,11 +2813,10 @@
         } else {
             sleepTime = idleSleepTime;
         }
-    } else if (mBytesWritten != 0 ||
-               (mMixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
+    } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) {
         memset (mMixBuffer, 0, mixBufferSize);
         sleepTime = 0;
-        ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
+        ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED)), "anticipated start");
     }
     // TODO add standby time extension fct of effect tail
 }
@@ -3359,7 +3338,7 @@
     idleSleepTime = idleSleepTimeUs();
 }
 
-void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
+void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
 {
     ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
             this,  streamType, mTracks.size());
@@ -3468,7 +3447,7 @@
 
             // forward device change to effects that have requested to be
             // aware of attached audio device.
-            mDevice = (uint32_t)value;
+            mDevice = (audio_devices_t) value;
             for (size_t i = 0; i < mEffectChains.size(); i++) {
                 mEffectChains[i]->setDevice_l(mDevice);
             }
@@ -3588,7 +3567,7 @@
                     }
                     break;
                 }
-                ALOG_ASSERT(actual <= count);
+                ALOG_ASSERT(actual <= (ssize_t)count);
                 write(teeFd, buffer, actual * channelCount * sizeof(short));
                 total += actual;
             }
@@ -4056,6 +4035,7 @@
             return false;
         }
         PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+        // see note at standby() declaration
         if (playbackThread->standby() && !playbackThread->isSuspended()) {
             ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), thread.get());
             return false;
@@ -4677,6 +4657,44 @@
     sp<ThreadBase> thread = mThread.promote();
     if (thread != 0) {
         PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+        sp<AudioFlinger> af = mClient->audioFlinger();
+
+        Mutex::Autolock _l(af->mLock);
+
+        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
+
+        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
+            Mutex::Autolock _dl(playbackThread->mLock);
+            Mutex::Autolock _sl(srcThread->mLock);
+            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
+            if (chain == 0) {
+                return INVALID_OPERATION;
+            }
+
+            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
+            if (effect == 0) {
+                return INVALID_OPERATION;
+            }
+            srcThread->removeEffect_l(effect);
+            playbackThread->addEffect_l(effect);
+            // removeEffect_l() has stopped the effect if it was active so it must be restarted
+            if (effect->state() == EffectModule::ACTIVE ||
+                    effect->state() == EffectModule::STOPPING) {
+                effect->start();
+            }
+
+            sp<EffectChain> dstChain = effect->chain().promote();
+            if (dstChain == 0) {
+                srcThread->addEffect_l(effect);
+                return INVALID_OPERATION;
+            }
+            AudioSystem::unregisterEffect(effect->id());
+            AudioSystem::registerEffect(&effect->desc(),
+                                        srcThread->id(),
+                                        dstChain->strategy(),
+                                        AUDIO_SESSION_OUTPUT_MIX,
+                                        effect->id());
+        }
         status = playbackThread->attachAuxEffect(this, EffectId);
     }
     return status;
@@ -4774,7 +4792,7 @@
             const sp<IMemory>& sharedBuffer,
             int sessionId) {
     if (!client->reserveTimedTrack())
-        return NULL;
+        return 0;
 
     return new TimedTrack(
         thread, client, streamType, sampleRate, format, channelMask, frameCount,
@@ -5009,7 +5027,7 @@
     AudioBufferProvider::Buffer* buffer, int64_t pts)
 {
     if (pts == AudioBufferProvider::kInvalidPTS) {
-        buffer->raw = 0;
+        buffer->raw = NULL;
         buffer->frameCount = 0;
         mTimedAudioOutputOnTime = false;
         return INVALID_OPERATION;
@@ -5024,7 +5042,7 @@
 
         // if we have no timed buffers, then fail
         if (mTimedBufferQueue.isEmpty()) {
-            buffer->raw = 0;
+            buffer->raw = NULL;
             buffer->frameCount = 0;
             return NOT_ENOUGH_DATA;
         }
@@ -5051,7 +5069,7 @@
                 // the transform failed.  this shouldn't happen, but if it does
                 // then just drop this buffer
                 ALOGW("timedGetNextBuffer transform failed");
-                buffer->raw = 0;
+                buffer->raw = NULL;
                 buffer->frameCount = 0;
                 trimTimedBufferQueueHead_l("getNextBuffer; no transform");
                 return NO_ERROR;
@@ -5060,7 +5078,7 @@
             if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) {
                 if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS,
                                                           &headLocalPTS)) {
-                    buffer->raw = 0;
+                    buffer->raw = NULL;
                     buffer->frameCount = 0;
                     return INVALID_OPERATION;
                 }
@@ -6456,11 +6474,12 @@
             // store input device and output device but do not forward output device to audio HAL.
             // Note that status is ignored by the caller for output device
             // (see AudioFlinger::setParameters()
+            uint32_t /*audio_devices_t*/ newDevice = mDevice;
             if (value & AUDIO_DEVICE_OUT_ALL) {
-                mDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
+                newDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
                 status = BAD_VALUE;
             } else {
-                mDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+                newDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
                 // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
                 if (mTrack != NULL) {
                     bool suspend = audio_is_bluetooth_sco_device(
@@ -6469,7 +6488,8 @@
                     setEffectSuspended_l(FX_IID_NS, suspend, mTrack->sessionId());
                 }
             }
-            mDevice |= (uint32_t)value;
+            newDevice |= value;
+            mDevice = (audio_devices_t) newDevice;    // since mDevice is read by other threads, only write to it once
         }
         if (status == NO_ERROR) {
             status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
@@ -7002,7 +7022,7 @@
     {
         Mutex::Autolock _l(mLock);
         thread = checkRecordThread_l(input);
-        if (thread == NULL) {
+        if (thread == 0) {
             return BAD_VALUE;
         }
 
@@ -7026,21 +7046,11 @@
 status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
 {
     Mutex::Autolock _l(mLock);
-    MixerThread *dstThread = checkMixerThread_l(output);
-    if (dstThread == NULL) {
-        ALOGW("setStreamOutput() bad output id %d", output);
-        return BAD_VALUE;
-    }
-
     ALOGV("setStreamOutput() stream %d to output %d", stream, output);
-    audioConfigChanged_l(AudioSystem::STREAM_CONFIG_CHANGED, output, &stream);
 
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
         PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
-        if (thread != dstThread && thread->type() != ThreadBase::DIRECT) {
-            MixerThread *srcThread = (MixerThread *)thread;
-            srcThread->invalidateTracks(stream);
-        }
+        thread->invalidateTracks(stream);
     }
 
     return NO_ERROR;
@@ -7134,20 +7144,14 @@
             }
         }
         if (!found) {
+            Mutex::Autolock _l (t->mLock);
             // remove all effects from the chain
             while (ec->mEffects.size()) {
                 sp<EffectModule> effect = ec->mEffects[0];
                 effect->unPin();
-                Mutex::Autolock _l (t->mLock);
                 t->removeEffect_l(effect);
-                for (size_t j = 0; j < effect->mHandles.size(); j++) {
-                    sp<EffectHandle> handle = effect->mHandles[j].promote();
-                    if (handle != 0) {
-                        handle->mEffect.clear();
-                        if (handle->mHasControl && handle->mEnabled) {
-                            t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
-                        }
-                    }
+                if (effect->purgeHandles()) {
+                    t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
                 }
                 AudioSystem::unregisterEffect(effect->id());
             }
@@ -7618,7 +7622,7 @@
         }
         // create effect handle and connect it to effect module
         handle = new EffectHandle(effect, client, effectClient, priority);
-        lStatus = effect->addHandle(handle);
+        lStatus = effect->addHandle(handle.get());
         if (enabled != NULL) {
             *enabled = (int)effect->isEnabled();
         }
@@ -7645,6 +7649,12 @@
     return handle;
 }
 
+sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId)
+{
+    Mutex::Autolock _l(mLock);
+    return getEffect_l(sessionId, effectId);
+}
+
 sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
 {
     sp<EffectChain> chain = getEffectChain_l(sessionId);
@@ -7752,7 +7762,7 @@
 }
 
 void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
-                                                    const wp<EffectHandle>& handle,
+                                                    EffectHandle *handle,
                                                     bool unpinIfLast) {
 
     Mutex::Autolock _l(mLock);
@@ -7944,8 +7954,15 @@
                                         effect_descriptor_t *desc,
                                         int id,
                                         int sessionId)
-    : mThread(thread), mChain(chain), mId(id), mSessionId(sessionId), mEffectInterface(NULL),
-      mStatus(NO_INIT), mState(IDLE), mSuspended(false)
+    : mPinned(sessionId > AUDIO_SESSION_OUTPUT_MIX),
+      mThread(thread), mChain(chain), mId(id), mSessionId(sessionId),
+      // mDescriptor is set below
+      // mConfig is set by configure() and not used before then
+      mEffectInterface(NULL),
+      mStatus(NO_INIT), mState(IDLE),
+      // mMaxDisableWaitCnt is set by configure() and not used before then
+      // mDisableWaitCnt is set by process() and updateState() and not used before then
+      mSuspended(false)
 {
     ALOGV("Constructor %p", this);
     int lStatus;
@@ -7967,9 +7984,6 @@
         goto Error;
     }
 
-    if (mSessionId > AUDIO_SESSION_OUTPUT_MIX) {
-        mPinned = true;
-    }
     ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
     return;
 Error:
@@ -7997,38 +8011,41 @@
     }
 }
 
-status_t AudioFlinger::EffectModule::addHandle(const sp<EffectHandle>& handle)
+status_t AudioFlinger::EffectModule::addHandle(EffectHandle *handle)
 {
     status_t status;
 
     Mutex::Autolock _l(mLock);
     int priority = handle->priority();
     size_t size = mHandles.size();
-    sp<EffectHandle> h;
+    EffectHandle *controlHandle = NULL;
     size_t i;
     for (i = 0; i < size; i++) {
-        h = mHandles[i].promote();
-        if (h == 0) continue;
+        EffectHandle *h = mHandles[i];
+        if (h == NULL || h->destroyed_l()) continue;
+        // first non destroyed handle is considered in control
+        if (controlHandle == NULL)
+            controlHandle = h;
         if (h->priority() <= priority) break;
     }
     // if inserted in first place, move effect control from previous owner to this handle
     if (i == 0) {
         bool enabled = false;
-        if (h != 0) {
-            enabled = h->enabled();
-            h->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
+        if (controlHandle != NULL) {
+            enabled = controlHandle->enabled();
+            controlHandle->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
         }
         handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
         status = NO_ERROR;
     } else {
         status = ALREADY_EXISTS;
     }
-    ALOGV("addHandle() %p added handle %p in position %d", this, handle.get(), i);
+    ALOGV("addHandle() %p added handle %p in position %d", this, handle, i);
     mHandles.insertAt(handle, i);
     return status;
 }
 
-size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
+size_t AudioFlinger::EffectModule::removeHandle(EffectHandle *handle)
 {
     Mutex::Autolock _l(mLock);
     size_t size = mHandles.size();
@@ -8039,43 +8056,44 @@
     if (i == size) {
         return size;
     }
-    ALOGV("removeHandle() %p removed handle %p in position %d", this, handle.unsafe_get(), i);
+    ALOGV("removeHandle() %p removed handle %p in position %d", this, handle, i);
 
-    bool enabled = false;
-    EffectHandle *hdl = handle.unsafe_get();
-    if (hdl != NULL) {
-        ALOGV("removeHandle() unsafe_get OK");
-        enabled = hdl->enabled();
-    }
     mHandles.removeAt(i);
-    size = mHandles.size();
     // if removed from first place, move effect control from this handle to next in line
-    if (i == 0 && size != 0) {
-        sp<EffectHandle> h = mHandles[0].promote();
-        if (h != 0) {
-            h->setControl(true /*hasControl*/, true /*signal*/ , enabled /*enabled*/);
+    if (i == 0) {
+        EffectHandle *h = controlHandle_l();
+        if (h != NULL) {
+            h->setControl(true /*hasControl*/, true /*signal*/ , handle->enabled() /*enabled*/);
         }
     }
 
     // Prevent calls to process() and other functions on effect interface from now on.
     // The effect engine will be released by the destructor when the last strong reference on
     // this object is released which can happen after next process is called.
-    if (size == 0 && !mPinned) {
+    if (mHandles.size() == 0 && !mPinned) {
         mState = DESTROYED;
     }
 
     return size;
 }
 
-sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle()
+// must be called with EffectModule::mLock held
+AudioFlinger::EffectHandle *AudioFlinger::EffectModule::controlHandle_l()
 {
-    Mutex::Autolock _l(mLock);
-    return mHandles.size() != 0 ? mHandles[0].promote() : 0;
+    // the first valid handle in the list has control over the module
+    for (size_t i = 0; i < mHandles.size(); i++) {
+        EffectHandle *h = mHandles[i];
+        if (h != NULL && !h->destroyed_l()) {
+            return h;
+        }
+    }
+
+    return NULL;
 }
 
-void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle, bool unpinIfLast)
+size_t AudioFlinger::EffectModule::disconnect(EffectHandle *handle, bool unpinIfLast)
 {
-    ALOGV("disconnect() %p handle %p", this, handle.unsafe_get());
+    ALOGV("disconnect() %p handle %p", this, handle);
     // keep a strong reference on this EffectModule to avoid calling the
     // destructor before we exit
     sp<EffectModule> keep(this);
@@ -8085,6 +8103,7 @@
             thread->disconnectEffect(keep, handle, unpinIfLast);
         }
     }
+    return mHandles.size();
 }
 
 void AudioFlinger::EffectModule::updateState() {
@@ -8394,8 +8413,8 @@
     if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
         uint32_t size = (replySize == NULL) ? 0 : *replySize;
         for (size_t i = 1; i < mHandles.size(); i++) {
-            sp<EffectHandle> h = mHandles[i].promote();
-            if (h != 0) {
+            EffectHandle *h = mHandles[i];
+            if (h != NULL && !h->destroyed_l()) {
                 h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData);
             }
         }
@@ -8405,8 +8424,14 @@
 
 status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
 {
-
     Mutex::Autolock _l(mLock);
+    return setEnabled_l(enabled);
+}
+
+// must be called with EffectModule::mLock held
+status_t AudioFlinger::EffectModule::setEnabled_l(bool enabled)
+{
+
     ALOGV("setEnabled %p enabled %d", this, enabled);
 
     if (enabled != isEnabled()) {
@@ -8441,8 +8466,8 @@
             return NO_ERROR; // simply ignore as we are being destroyed
         }
         for (size_t i = 1; i < mHandles.size(); i++) {
-            sp<EffectHandle> h = mHandles[i].promote();
-            if (h != 0) {
+            EffectHandle *h = mHandles[i];
+            if (h != NULL && !h->destroyed_l()) {
                 h->setEnabled(enabled);
             }
         }
@@ -8591,6 +8616,22 @@
     return mSuspended;
 }
 
+bool AudioFlinger::EffectModule::purgeHandles()
+{
+    bool enabled = false;
+    Mutex::Autolock _l(mLock);
+    for (size_t i = 0; i < mHandles.size(); i++) {
+        EffectHandle *handle = mHandles[i];
+        if (handle != NULL && !handle->destroyed_l()) {
+            handle->effect().clear();
+            if (handle->hasControl()) {
+                enabled = handle->enabled();
+            }
+        }
+    }
+    return enabled;
+}
+
 status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
@@ -8657,8 +8698,8 @@
     result.append(buffer);
     result.append("\t\t\tPid   Priority Ctrl Locked client server\n");
     for (size_t i = 0; i < mHandles.size(); ++i) {
-        sp<EffectHandle> handle = mHandles[i].promote();
-        if (handle != 0) {
+        EffectHandle *handle = mHandles[i];
+        if (handle != NULL && !handle->destroyed_l()) {
             handle->dump(buffer, SIZE);
             result.append(buffer);
         }
@@ -8688,7 +8729,7 @@
                                         int32_t priority)
     : BnEffect(),
     mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
-    mPriority(priority), mHasControl(false), mEnabled(false)
+    mPriority(priority), mHasControl(false), mEnabled(false), mDestroyed(false)
 {
     ALOGV("constructor %p", this);
 
@@ -8713,8 +8754,15 @@
 AudioFlinger::EffectHandle::~EffectHandle()
 {
     ALOGV("Destructor %p", this);
+
+    if (mEffect == 0) {
+        mDestroyed = true;
+        return;
+    }
+    mEffect->lock();
+    mDestroyed = true;
+    mEffect->unlock();
     disconnect(false);
-    ALOGV("Destructor DONE %p", this);
 }
 
 status_t AudioFlinger::EffectHandle::enable()
@@ -8785,9 +8833,8 @@
     if (mEffect == 0) {
         return;
     }
-    mEffect->disconnect(this, unpinIfLast);
-
-    if (mHasControl && mEnabled) {
+    // restore suspended effects if the disconnected handle was enabled and the last one.
+    if ((mEffect->disconnect(this, unpinIfLast) == 0) && mEnabled) {
         sp<ThreadBase> thread = mEffect->thread().promote();
         if (thread != 0) {
             thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
@@ -9370,10 +9417,12 @@
                 sp<EffectModule> effect = desc->mEffect.promote();
                 if (effect != 0) {
                     effect->setSuspended(false);
-                    sp<EffectHandle> handle = effect->controlHandle();
-                    if (handle != 0) {
-                        effect->setEnabled(handle->enabled());
+                    effect->lock();
+                    EffectHandle *handle = effect->controlHandle_l();
+                    if (handle != NULL && !handle->destroyed_l()) {
+                        effect->setEnabled_l(handle->enabled());
                     }
+                    effect->unlock();
                 }
                 desc->mEffect.clear();
             }
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 384306c..b8bb69e 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -91,7 +91,7 @@
                                 audio_stream_type_t streamType,
                                 uint32_t sampleRate,
                                 audio_format_t format,
-                                uint32_t channelMask,
+                                audio_channel_mask_t channelMask,
                                 int frameCount,
                                 IAudioFlinger::track_flags_t flags,
                                 const sp<IMemory>& sharedBuffer,
@@ -105,7 +105,7 @@
                                 audio_io_handle_t input,
                                 uint32_t sampleRate,
                                 audio_format_t format,
-                                uint32_t channelMask,
+                                audio_channel_mask_t channelMask,
                                 int frameCount,
                                 IAudioFlinger::track_flags_t flags,
                                 int *sessionId,
@@ -142,7 +142,8 @@
 
     virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
 
-    virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const;
+    virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+                                               audio_channel_mask_t channelMask) const;
 
     virtual audio_io_handle_t openOutput(audio_module_handle_t module,
                                          audio_devices_t *pDevices,
@@ -253,6 +254,7 @@
                                         int listenerSession,
                                         sync_event_callback_t callBack,
                                         void *cookie);
+
 private:
                audio_mode_t getMode() const { return mMode; }
 
@@ -482,13 +484,19 @@
         };
 
         virtual     status_t    initCheck() const = 0;
+
+                    // static externally-visible
                     type_t      type() const { return mType; }
+                    audio_io_handle_t id() const { return mId;}
+
+                    // dynamic externally-visible
                     uint32_t    sampleRate() const { return mSampleRate; }
                     int         channelCount() const { return mChannelCount; }
                     audio_format_t format() const { return mFormat; }
                     // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
                     // and returns the normal mix buffer's frame count.  No API for HAL frame count.
                     size_t      frameCount() const { return mNormalFrameCount; }
+
                     void        wakeUp()    { mWaitWorkCV.broadcast(); }
         // Should be "virtual status_t requestExitAndWait()" and override same
         // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
@@ -500,9 +508,11 @@
                     void        sendConfigEvent(int event, int param = 0);
                     void        sendConfigEvent_l(int event, int param = 0);
                     void        processConfigEvents();
-                    audio_io_handle_t id() const { return mId;}
+
+                    // see note at declaration of mStandby and mDevice
                     bool        standby() const { return mStandby; }
-                    uint32_t    device() const { return mDevice; }
+                    audio_devices_t device() const { return mDevice; }
+
         virtual     audio_stream_t* stream() const = 0;
 
                     sp<EffectHandle> createEffect_l(
@@ -514,7 +524,7 @@
                                         int *enabled,
                                         status_t *status);
                     void disconnectEffect(const sp< EffectModule>& effect,
-                                          const wp<EffectHandle>& handle,
+                                          EffectHandle *handle,
                                           bool unpinIfLast);
 
                     // return values for hasAudioSession (bit field)
@@ -543,6 +553,7 @@
                     // set audio mode to all effect chains
                     void setMode(audio_mode_t mode);
                     // get effect module with corresponding ID on specified audio session
+                    sp<AudioFlinger::EffectModule> getEffect(int sessionId, int effectId);
                     sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
                     // add and effect module. Also creates the effect chain is none exists for
                     // the effects audio session
@@ -644,11 +655,19 @@
                     status_t                mParamStatus;
 
                     Vector<ConfigEvent>     mConfigEvents;
-                    bool                    mStandby;
+
+                    // These fields are written and read by thread itself without lock or barrier,
+                    // and read by other threads without lock or barrier via standby() and device().
+                    // Because of the absence of a lock or barrier, any other thread that reads
+                    // these fields must use the information in isolation, or be prepared to deal
+                    // with possibility that it might be inconsistent with other information.
+                    bool                    mStandby;   // Whether thread is currently in standby.
+                    audio_devices_t         mDevice;    // output device for PlaybackThread
+                                                        // input + output devices for RecordThread
+
                     const audio_io_handle_t mId;
                     Vector< sp<EffectChain> > mEffectChains;
-                    uint32_t                mDevice;    // output device for PlaybackThread
-                                                        // input + output devices for RecordThread
+
                     static const int        kNameLength = 16;   // prctl(PR_SET_NAME) limit
                     char                    mName[kNameLength];
                     sp<IPowerManager>       mPowerManager;
@@ -1016,6 +1035,8 @@
 
                     virtual status_t setSyncEvent(const sp<SyncEvent>& event);
                     virtual bool     isValidSyncEvent(const sp<SyncEvent>& event);
+                            void     invalidateTracks(audio_stream_type_t streamType);
+
 
     protected:
         int16_t*                        mMixBuffer;
@@ -1098,7 +1119,6 @@
 
         // FIXME move these declarations into the specific sub-class that needs them
         // MIXER only
-        bool                            longStandbyExit;
         uint32_t                        sleepTimeShift;
 
         // same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
@@ -1143,7 +1163,6 @@
 
         // Thread virtuals
 
-                    void        invalidateTracks(audio_stream_type_t streamType);
         virtual     bool        checkForNewParameters_l();
         virtual     status_t    dumpInternals(int fd, const Vector<String16>& args);
 
@@ -1165,9 +1184,6 @@
 
                     AudioMixer* mAudioMixer;    // normal mixer
     private:
-#ifdef SOAKER
-                    Thread*     mSoaker;
-#endif
                     // one-time initialization, no locks required
                     FastMixer*  mFastMixer;         // non-NULL if there is also a fast mixer
                     sp<AudioWatchdog> mAudioWatchdog; // non-0 if there is an audio watchdog thread
@@ -1287,6 +1303,8 @@
               PlaybackThread *primaryPlaybackThread_l() const;
               uint32_t primaryOutputDevice_l() const;
 
+              sp<PlaybackThread> getEffectThread_l(int sessionId, int EffectId);
+
     // server side of the client's IAudioTrack
     class TrackHandle : public android::BnAudioTrack {
     public:
@@ -1506,6 +1524,7 @@
             return mSessionId;
         }
         status_t    setEnabled(bool enabled);
+        status_t    setEnabled_l(bool enabled);
         bool isEnabled() const;
         bool isProcessEnabled() const;
 
@@ -1517,9 +1536,9 @@
         void        setThread(const wp<ThreadBase>& thread) { mThread = thread; }
         const wp<ThreadBase>& thread() { return mThread; }
 
-        status_t addHandle(const sp<EffectHandle>& handle);
-        void disconnect(const wp<EffectHandle>& handle, bool unpinIfLast);
-        size_t removeHandle (const wp<EffectHandle>& handle);
+        status_t addHandle(EffectHandle *handle);
+        size_t disconnect(EffectHandle *handle, bool unpinIfLast);
+        size_t removeHandle(EffectHandle *handle);
 
         effect_descriptor_t& desc() { return mDescriptor; }
         wp<EffectChain>&     chain() { return mChain; }
@@ -1532,10 +1551,13 @@
         void             setSuspended(bool suspended);
         bool             suspended() const;
 
-        sp<EffectHandle> controlHandle();
+        EffectHandle*    controlHandle_l();
 
         bool             isPinned() const { return mPinned; }
         void             unPin() { mPinned = false; }
+        bool             purgeHandles();
+        void             lock() { mLock.lock(); }
+        void             unlock() { mLock.unlock(); }
 
         status_t         dump(int fd, const Vector<String16>& args);
 
@@ -1555,14 +1577,14 @@
 mutable Mutex               mLock;      // mutex for process, commands and handles list protection
         wp<ThreadBase>      mThread;    // parent thread
         wp<EffectChain>     mChain;     // parent effect chain
-        int                 mId;        // this instance unique ID
-        int                 mSessionId; // audio session ID
+        const int           mId;        // this instance unique ID
+        const int           mSessionId; // audio session ID
         effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
         effect_config_t     mConfig;    // input and output audio configuration
         effect_handle_t  mEffectInterface; // Effect module C API
         status_t            mStatus;    // initialization status
         effect_state        mState;     // current activation state
-        Vector< wp<EffectHandle> > mHandles;    // list of client handles
+        Vector<EffectHandle *> mHandles;    // list of client handles
                     // First handle in mHandles has highest priority and controls the effect module
         uint32_t mMaxDisableWaitCnt;    // maximum grace period before forcing an effect off after
                                         // sending disable command.
@@ -1620,6 +1642,8 @@
         int priority() const { return mPriority; }
         bool hasControl() const { return mHasControl; }
         sp<EffectModule> effect() const { return mEffect; }
+        // destroyed_l() must be called with the associated EffectModule mLock held
+        bool destroyed_l() const { return mDestroyed; }
 
         void dump(char* buffer, size_t size);
 
@@ -1638,6 +1662,8 @@
         bool mHasControl;                   // true if this handle is controlling the effect
         bool mEnabled;                      // cached enable state: needed when the effect is
                                             // restored after being suspended
+        bool mDestroyed;                    // Set to true by destructor. Access with EffectModule
+                                            // mLock held
     };
 
     // the EffectChain class represents a group of effects associated to one audio session.
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index c32fc6b..02b531c 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -272,7 +272,6 @@
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     uint32_t channels,
-                                    audio_in_acoustics_t acoustics,
                                     int audioSession)
 {
     if (mpAudioPolicy == NULL) {
@@ -283,8 +282,9 @@
         return 0;
     }
     Mutex::Autolock _l(mLock);
+    // the audio_in_acoustics_t parameter is ignored by get_input()
     audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
-                                                       format, channels, acoustics);
+                                                       format, channels, (audio_in_acoustics_t) 0);
 
     if (input == 0) {
         return input;
@@ -1424,7 +1424,7 @@
     return af->restoreOutput(output);
 }
 
-// deprecated: replaced by aps_open_input_on_module()
+// deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored
 static audio_io_handle_t aps_open_input(void *service,
                                         audio_devices_t *pDevices,
                                         uint32_t *pSamplingRate,
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index fbca000..b4924fc 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -78,8 +78,6 @@
                                     uint32_t samplingRate = 0,
                                     audio_format_t format = AUDIO_FORMAT_DEFAULT,
                                     uint32_t channels = 0,
-                                    audio_in_acoustics_t acoustics =
-                                            (audio_in_acoustics_t)0 /*AUDIO_IN_ACOUSTICS_NONE*/,
                                     int audioSession = 0);
     virtual status_t startInput(audio_io_handle_t input);
     virtual status_t stopInput(audio_io_handle_t input);
diff --git a/services/audioflinger/Soaker.h b/services/audioflinger/Soaker.h
deleted file mode 100644
index 43d9d2f..0000000
--- a/services/audioflinger/Soaker.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_AUDIO_SOAKER_H
-#define _ANDROID_AUDIO_SOAKER_H
-
-#include <utils/Thread.h>
-
-namespace android {
-
-class Soaker : public Thread {
-public:
-    Soaker() : Thread() { }
-    virtual ~Soaker() { }
-protected:
-    virtual bool threadLoop() {
-        int j = 0;
-        for (;;) {
-            for (int i = 0; i < 10000; ++i) {
-                j += i * i;
-            }
-            if (exitPending()) {
-                return false;
-            }
-        }
-        return j < 555555;
-    }
-};
-
-}   // namespace android
-
-#endif  // _ANDROID_AUDIO_SOAKER_H
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 9f713fa..8cccf49 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -22,6 +22,7 @@
     libcamera_client \
     libgui \
     libhardware \
+    libsync \
     libcamera_metadata
 
 LOCAL_C_INCLUDES += \
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 5a37c8d..8d07eee 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -758,7 +758,7 @@
     ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
     uint32_t bufferIdx = 0;
     for (; bufferIdx < mTotalBuffers; bufferIdx++) {
-        res = mConsumerInterface->dequeueBuffer(mConsumerInterface.get(),
+        res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
                 &anwBuffers[bufferIdx]);
         if (res != OK) {
             ALOGE("%s: Unable to dequeue buffer %d for initial registration for"
@@ -766,15 +766,6 @@
             goto cleanUpBuffers;
         }
 
-        res = mConsumerInterface->lockBuffer(mConsumerInterface.get(),
-                anwBuffers[bufferIdx]);
-        if (res != OK) {
-            ALOGE("%s: Unable to lock buffer %d for initial registration for"
-                    "stream %d", __FUNCTION__, bufferIdx, mId);
-            bufferIdx++;
-            goto cleanUpBuffers;
-        }
-
         buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
     }
 
@@ -792,7 +783,7 @@
 cleanUpBuffers:
     for (uint32_t i = 0; i < bufferIdx; i++) {
         res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
-                anwBuffers[i]);
+                anwBuffers[i], -1);
         if (res != OK) {
             ALOGE("%s: Unable to cancel buffer %d after registration",
                     __FUNCTION__, i);
@@ -878,9 +869,7 @@
 
     ANativeWindow *a = toANW(w);
     ANativeWindowBuffer* anb;
-    res = a->dequeueBuffer(a, &anb);
-    if (res != OK) return res;
-    res = a->lockBuffer(a, anb);
+    res = native_window_dequeue_buffer_and_wait(a, &anb);
     if (res != OK) return res;
 
     *buffer = &(anb->handle);
@@ -911,7 +900,7 @@
         return err;
     }
     err = a->queueBuffer(a,
-            container_of(buffer, ANativeWindowBuffer, handle));
+            container_of(buffer, ANativeWindowBuffer, handle), -1);
     if (err != OK) {
         ALOGE("%s: Error queueing buffer to native window: %s (%d)",
                 __FUNCTION__, strerror(-err), err);
@@ -933,7 +922,7 @@
     stream->mActiveBuffers--;
     ANativeWindow *a = toANW(w);
     return a->cancelBuffer(a,
-            container_of(buffer, ANativeWindowBuffer, handle));
+            container_of(buffer, ANativeWindowBuffer, handle), -1);
 }
 
 int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 87a0802..05ac9fa 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -569,7 +569,7 @@
         int rc;
         ANativeWindow *a = anw(w);
         ANativeWindowBuffer* anb;
-        rc = a->dequeueBuffer(a, &anb);
+        rc = native_window_dequeue_buffer_and_wait(a, &anb);
         if (!rc) {
             *buffer = &anb->handle;
             *stride = anb->stride;
@@ -587,8 +587,7 @@
                       buffer_handle_t* buffer)
     {
         ANativeWindow *a = anw(w);
-        return a->lockBuffer(a,
-                  container_of(buffer, ANativeWindowBuffer, handle));
+        return 0;
     }
 
     static int __enqueue_buffer(struct preview_stream_ops* w,
@@ -596,7 +595,7 @@
     {
         ANativeWindow *a = anw(w);
         return a->queueBuffer(a,
-                  container_of(buffer, ANativeWindowBuffer, handle));
+                  container_of(buffer, ANativeWindowBuffer, handle), -1);
     }
 
     static int __cancel_buffer(struct preview_stream_ops* w,
@@ -604,7 +603,7 @@
     {
         ANativeWindow *a = anw(w);
         return a->cancelBuffer(a,
-                  container_of(buffer, ANativeWindowBuffer, handle));
+                  container_of(buffer, ANativeWindowBuffer, handle), -1);
     }
 
     static int __set_buffer_count(struct preview_stream_ops* w, int count)