Merge "Invalidate text display list when text properties change."
diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl
index a45ec54..31dc965a 100644
--- a/core/java/android/net/INetworkPolicyListener.aidl
+++ b/core/java/android/net/INetworkPolicyListener.aidl
@@ -21,5 +21,6 @@
 
     void onUidRulesChanged(int uid, int uidRules);
     void onMeteredIfacesChanged(in String[] meteredIfaces);
+    void onRestrictBackgroundChanged(boolean restrictBackground);
 
 }
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index fa4dd25..1e92b43 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -723,6 +723,7 @@
 
     @Override
     public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
+        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
         // Shaders are ignored when drawing patches
         int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
         final int nativePaint = paint == null ? 0 : paint.mNativePaint;
@@ -736,6 +737,7 @@
 
     @Override
     public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
+        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         final int nativePaint = paint == null ? 0 : paint.mNativePaint;
@@ -748,6 +750,7 @@
 
     @Override
     public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
+        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         final int nativePaint = paint == null ? 0 : paint.mNativePaint;
@@ -761,6 +764,7 @@
 
     @Override
     public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
+        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         final int nativePaint = paint == null ? 0 : paint.mNativePaint;
@@ -784,6 +788,7 @@
 
     @Override
     public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
+        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         final int nativePaint = paint == null ? 0 : paint.mNativePaint;
@@ -832,6 +837,7 @@
     @Override
     public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
             int vertOffset, int[] colors, int colorOffset, Paint paint) {
+        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
         if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
             throw new ArrayIndexOutOfBoundsException();
         }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8d32edc..7658d04 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12734,9 +12734,9 @@
      * </p>
      *
      * <p>
-     * The actual mesurement work of a view is performed in
+     * The actual measurement work of a view is performed in
      * {@link #onMeasure(int, int)}, called by this method. Therefore, only
-     * {@link #onMeasure(int, int)} can and must be overriden by subclasses.
+     * {@link #onMeasure(int, int)} can and must be overridden by subclasses.
      * </p>
      *
      *
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 53107cb..99349b0 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4838,10 +4838,14 @@
         int extendedPaddingTop = getExtendedPaddingTop();
         int extendedPaddingBottom = getExtendedPaddingBottom();
 
+        final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop;
+        final int maxScrollY = mLayout.getHeight() - vspace;
+
         float clipLeft = compoundPaddingLeft + scrollX;
-        float clipTop = extendedPaddingTop + scrollY;
+        float clipTop = (scrollY == 0) ? 0 : extendedPaddingTop + scrollY;
         float clipRight = right - left - compoundPaddingRight + scrollX;
-        float clipBottom = bottom - top - extendedPaddingBottom + scrollY;
+        float clipBottom = bottom - top + scrollY -
+                ((scrollY == maxScrollY) ? 0 : extendedPaddingBottom);
 
         if (mShadowRadius != 0) {
             clipLeft += Math.min(0, mShadowDx - mShadowRadius);
diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd
index a2313b3..d51a378 100644
--- a/docs/html/guide/topics/ui/menus.jd
+++ b/docs/html/guide/topics/ui/menus.jd
@@ -17,7 +17,7 @@
   <li><a href="#context-menu">Creating Contextual Menus</a>
     <ol>
       <li><a href="#FloatingContextMenu">Creating a floating context menu</a></li>
-      <li><a href="#CAB">Using the contextual action bar</a></li>
+      <li><a href="#CAB">Using the contextual action mode</a></li>
     </ol>
   </li>
   <li><a href="#PopupMenu">Creating a Popup Menu</a>
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 07bf7bf..9622bd2 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -623,7 +623,7 @@
                         jint srcAlloc, jint srcXoff, jint srcYoff,
                         jint srcMip, jint srcFace)
 {
-    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff, dstYoff,"
+    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
             " dstMip(%i), dstFace(%i), width(%i), height(%i),"
             " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
             con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index 7b0b443..02dfc1b 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -108,7 +108,8 @@
      * Returned value
      *   *descriptor updated with effect descriptor
      */
-    static status_t getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor);
+    static status_t getEffectDescriptor(const effect_uuid_t *uuid,
+                                        effect_descriptor_t *descriptor) /*const*/;
 
 
     /*
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index c8c5dba..ca57f9e 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -344,7 +344,6 @@
         virtual status_t    readyToRun() { return NO_ERROR; }
         virtual void        onFirstRef() {}
         AudioRecord& mReceiver;
-        Mutex       mLock;
     };
 
             bool processAudioBuffer(const sp<ClientRecordThread>& thread);
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 74a1e62..da99620 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -55,8 +55,10 @@
     static status_t getMasterMute(bool* mute);
 
     // set/get stream volume on specified output
-    static status_t setStreamVolume(audio_stream_type_t stream, float value, int output);
-    static status_t getStreamVolume(audio_stream_type_t stream, float* volume, int output);
+    static status_t setStreamVolume(audio_stream_type_t stream, float value,
+                                    audio_io_handle_t output);
+    static status_t getStreamVolume(audio_stream_type_t stream, float* volume,
+                                    audio_io_handle_t output);
 
     // mute/unmute stream
     static status_t setStreamMute(audio_stream_type_t stream, bool mute);
@@ -217,7 +219,7 @@
 
         // indicate a change in the configuration of an output or input: keeps the cached
         // values for output/input parameters upto date in client process
-        virtual void ioConfigChanged(int event, int ioHandle, void *param2);
+        virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, void *param2);
     };
 
     class AudioPolicyServiceClient: public IBinder::DeathRecipient
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 02c85cd..11db81b 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -273,18 +273,18 @@
      * left and right volumes. Levels must be >= 0.0 and <= 1.0.
      */
             status_t    setVolume(float left, float right);
-            void        getVolume(float* left, float* right);
+            void        getVolume(float* left, float* right) const;
 
     /* Set the send level for this track. An auxiliary effect should be attached
      * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0.
      */
             status_t    setAuxEffectSendLevel(float level);
-            void        getAuxEffectSendLevel(float* level);
+            void        getAuxEffectSendLevel(float* level) const;
 
     /* Set sample rate for this track, mostly used for games' sound effects
      */
             status_t    setSampleRate(int sampleRate);
-            uint32_t    getSampleRate();
+            uint32_t    getSampleRate() const;
 
     /* Enables looping and sets the start and end points of looping.
      *
@@ -299,7 +299,7 @@
      *          (loopEnd-loopStart) <= framecount()
      */
             status_t    setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount);
-            status_t    getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount);
+            status_t    getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) const;
 
     /* Sets marker position. When playback reaches the number of frames specified, a callback with
      * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker
@@ -315,7 +315,7 @@
      *  - INVALID_OPERATION: the AudioTrack has no callback installed.
      */
             status_t    setMarkerPosition(uint32_t marker);
-            status_t    getMarkerPosition(uint32_t *marker);
+            status_t    getMarkerPosition(uint32_t *marker) const;
 
 
     /* Sets position update period. Every time the number of frames specified has been played,
@@ -333,7 +333,7 @@
      *  - INVALID_OPERATION: the AudioTrack has no callback installed.
      */
             status_t    setPositionUpdatePeriod(uint32_t updatePeriod);
-            status_t    getPositionUpdatePeriod(uint32_t *updatePeriod);
+            status_t    getPositionUpdatePeriod(uint32_t *updatePeriod) const;
 
     /* Sets playback head position within AudioTrack buffer. The new position is specified
      * in number of frames.
@@ -384,7 +384,7 @@
      * Returned value:
      *  AudioTrack session ID.
      */
-            int    getSessionId();
+            int    getSessionId() const;
 
     /* Attach track auxiliary output to specified effect. Use effectId = 0
      * to detach track from effect.
@@ -446,7 +446,6 @@
         virtual status_t    readyToRun();
         virtual void        onFirstRef();
         AudioTrack& mReceiver;
-        Mutex       mLock;
     };
 
             bool processAudioBuffer(const sp<AudioTrackThread>& thread);
diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
index 8ae13cc..df83995 100644
--- a/include/media/EffectsFactoryApi.h
+++ b/include/media/EffectsFactoryApi.h
@@ -109,7 +109,7 @@
 //        *pHandle:         updated with the effect handle.
 //
 ////////////////////////////////////////////////////////////////////////////////
-int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle);
+int EffectCreate(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle);
 
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -151,7 +151,7 @@
 //        *pDescriptor:     updated with the effect descriptor.
 //
 ////////////////////////////////////////////////////////////////////////////////
-int EffectGetDescriptor(effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor);
+int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor);
 
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -167,7 +167,7 @@
 //                           1 if uuid is equal to EFFECT_UUID_NULL.
 //
 ////////////////////////////////////////////////////////////////////////////////
-int EffectIsNullUuid(effect_uuid_t *pEffectUuid);
+int EffectIsNullUuid(const effect_uuid_t *pEffectUuid);
 
 #if __cplusplus
 }  // extern "C"
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 760595c..433ce7c 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -27,6 +27,7 @@
 #include <media/IAudioTrack.h>
 #include <media/IAudioRecord.h>
 #include <media/IAudioFlingerClient.h>
+#include <system/audio.h>
 #include <hardware/audio_effect.h>
 #include <media/IEffect.h>
 #include <media/IEffectClient.h>
@@ -53,13 +54,13 @@
                                 int frameCount,
                                 uint32_t flags,
                                 const sp<IMemory>& sharedBuffer,
-                                int output,
+                                audio_io_handle_t output,
                                 int *sessionId,
                                 status_t *status) = 0;
 
     virtual sp<IAudioRecord> openRecord(
                                 pid_t pid,
-                                int input,
+                                audio_io_handle_t input,
                                 uint32_t sampleRate,
                                 audio_format_t format,
                                 uint32_t channelMask,
@@ -71,11 +72,11 @@
     /* query the audio hardware state. This state never changes,
      * and therefore can be cached.
      */
-    virtual     uint32_t    sampleRate(int output) const = 0;
-    virtual     int         channelCount(int output) const = 0;
-    virtual     audio_format_t format(int output) const = 0;
-    virtual     size_t      frameCount(int output) const = 0;
-    virtual     uint32_t    latency(int output) const = 0;
+    virtual     uint32_t    sampleRate(audio_io_handle_t output) const = 0;
+    virtual     int         channelCount(audio_io_handle_t output) const = 0;
+    virtual     audio_format_t format(audio_io_handle_t output) const = 0;
+    virtual     size_t      frameCount(audio_io_handle_t output) const = 0;
+    virtual     uint32_t    latency(audio_io_handle_t output) const = 0;
 
     /* set/get the audio hardware state. This will probably be used by
      * the preference panel, mostly.
@@ -89,10 +90,12 @@
     /* set/get stream type state. This will probably be used by
      * the preference panel, mostly.
      */
-    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value, int output) = 0;
+    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value,
+                                    audio_io_handle_t output) = 0;
     virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted) = 0;
 
-    virtual     float       streamVolume(audio_stream_type_t stream, int output) const = 0;
+    virtual     float       streamVolume(audio_stream_type_t stream,
+                                    audio_io_handle_t output) const = 0;
     virtual     bool        streamMute(audio_stream_type_t stream) const = 0;
 
     // set audio mode
@@ -102,63 +105,68 @@
     virtual     status_t    setMicMute(bool state) = 0;
     virtual     bool        getMicMute() const = 0;
 
-    virtual     status_t    setParameters(int ioHandle, const String8& keyValuePairs) = 0;
-    virtual     String8     getParameters(int ioHandle, const String8& keys) = 0;
+    virtual     status_t    setParameters(audio_io_handle_t ioHandle,
+                                    const String8& keyValuePairs) = 0;
+    virtual     String8     getParameters(audio_io_handle_t ioHandle, const String8& keys) const = 0;
 
     // register a current process for audio output change notifications
     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) = 0;
+    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const = 0;
 
-    virtual int openOutput(uint32_t *pDevices,
+    virtual audio_io_handle_t openOutput(uint32_t *pDevices,
                                     uint32_t *pSamplingRate,
                                     audio_format_t *pFormat,
                                     uint32_t *pChannels,
                                     uint32_t *pLatencyMs,
                                     uint32_t flags) = 0;
-    virtual int openDuplicateOutput(int output1, int output2) = 0;
-    virtual status_t closeOutput(int output) = 0;
-    virtual status_t suspendOutput(int output) = 0;
-    virtual status_t restoreOutput(int output) = 0;
+    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+                                    audio_io_handle_t output2) = 0;
+    virtual status_t closeOutput(audio_io_handle_t output) = 0;
+    virtual status_t suspendOutput(audio_io_handle_t output) = 0;
+    virtual status_t restoreOutput(audio_io_handle_t output) = 0;
 
-    virtual int openInput(uint32_t *pDevices,
+    virtual audio_io_handle_t openInput(uint32_t *pDevices,
                                     uint32_t *pSamplingRate,
                                     audio_format_t *pFormat,
                                     uint32_t *pChannels,
                                     audio_in_acoustics_t acoustics) = 0;
-    virtual status_t closeInput(int input) = 0;
+    virtual status_t closeInput(audio_io_handle_t input) = 0;
 
-    virtual status_t setStreamOutput(audio_stream_type_t stream, int output) = 0;
+    virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) = 0;
 
     virtual status_t setVoiceVolume(float volume) = 0;
 
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) = 0;
+    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+                                    audio_io_handle_t output) const = 0;
 
-    virtual unsigned int  getInputFramesLost(int ioHandle) = 0;
+    virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
 
     virtual int newAudioSessionId() = 0;
 
     virtual void acquireAudioSessionId(int audioSession) = 0;
     virtual void releaseAudioSessionId(int audioSession) = 0;
 
-    virtual status_t queryNumberEffects(uint32_t *numEffects) = 0;
+    virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0;
 
-    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) = 0;
+    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const = 0;
 
-    virtual status_t getEffectDescriptor(effect_uuid_t *pEffectUUID, effect_descriptor_t *pDescriptor) = 0;
+    virtual status_t getEffectDescriptor(const effect_uuid_t *pEffectUUID,
+                                        effect_descriptor_t *pDescriptor) const = 0;
 
     virtual sp<IEffect> createEffect(pid_t pid,
                                     effect_descriptor_t *pDesc,
                                     const sp<IEffectClient>& client,
                                     int32_t priority,
-                                    int output,
+                                    audio_io_handle_t output,
                                     int sessionId,
                                     status_t *status,
                                     int *id,
                                     int *enabled) = 0;
 
-    virtual status_t moveEffects(int session, int srcOutput, int dstOutput) = 0;
+    virtual status_t moveEffects(int session, audio_io_handle_t srcOutput,
+                                    audio_io_handle_t dstOutput) = 0;
 };
 
 
diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h
index aa0cdcf..f3b4df1 100644
--- a/include/media/IAudioFlingerClient.h
+++ b/include/media/IAudioFlingerClient.h
@@ -21,6 +21,7 @@
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <utils/KeyedVector.h>
+#include <system/audio.h>
 
 namespace android {
 
@@ -32,7 +33,7 @@
     DECLARE_META_INTERFACE(AudioFlingerClient);
 
     // Notifies a change of audio input/output configuration.
-    virtual void ioConfigChanged(int event, int ioHandle, void *param2) = 0;
+    virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, void *param2) = 0;
 
 };
 
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index dd97ce4..23226c0 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -54,6 +54,7 @@
 #define CBLK_RESTORED_ON        0x0040  // track has been restored after invalidation
 #define CBLK_RESTORED_OFF       0x0040  // by AudioFlinger
 
+// Important: do not add any virtual methods, including ~
 struct audio_track_cblk_t
 {
 
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 6c9a620..f242f18 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -55,43 +55,51 @@
             void        set(uint32_t w, uint32_t h);
         
             Region&     orSelf(const Rect& rhs);
+            Region&     xorSelf(const Rect& rhs);
             Region&     andSelf(const Rect& rhs);
             Region&     subtractSelf(const Rect& rhs);
 
             // boolean operators, applied on this
             Region&     orSelf(const Region& rhs);
+            Region&     xorSelf(const Region& rhs);
             Region&     andSelf(const Region& rhs);
             Region&     subtractSelf(const Region& rhs);
 
             // boolean operators
     const   Region      merge(const Rect& rhs) const;
+    const   Region      mergeExclusive(const Rect& rhs) const;
     const   Region      intersect(const Rect& rhs) const;
     const   Region      subtract(const Rect& rhs) const;
 
             // boolean operators
     const   Region      merge(const Region& rhs) const;
+    const   Region      mergeExclusive(const Region& rhs) const;
     const   Region      intersect(const Region& rhs) const;
     const   Region      subtract(const Region& rhs) const;
 
             // these translate rhs first
             Region&     translateSelf(int dx, int dy);
             Region&     orSelf(const Region& rhs, int dx, int dy);
+            Region&     xorSelf(const Region& rhs, int dx, int dy);
             Region&     andSelf(const Region& rhs, int dx, int dy);
             Region&     subtractSelf(const Region& rhs, int dx, int dy);
 
             // these translate rhs first
     const   Region      translate(int dx, int dy) const;
     const   Region      merge(const Region& rhs, int dx, int dy) const;
+    const   Region      mergeExclusive(const Region& rhs, int dx, int dy) const;
     const   Region      intersect(const Region& rhs, int dx, int dy) const;
     const   Region      subtract(const Region& rhs, int dx, int dy) const;
 
     // convenience operators overloads
     inline  const Region      operator | (const Region& rhs) const;
+    inline  const Region      operator ^ (const Region& rhs) const;
     inline  const Region      operator & (const Region& rhs) const;
     inline  const Region      operator - (const Region& rhs) const;
     inline  const Region      operator + (const Point& pt) const;
 
     inline  Region&     operator |= (const Region& rhs);
+    inline  Region&     operator ^= (const Region& rhs);
     inline  Region&     operator &= (const Region& rhs);
     inline  Region&     operator -= (const Region& rhs);
     inline  Region&     operator += (const Point& pt);
@@ -158,6 +166,9 @@
 const Region Region::operator | (const Region& rhs) const {
     return merge(rhs);
 }
+const Region Region::operator ^ (const Region& rhs) const {
+    return mergeExclusive(rhs);
+}
 const Region Region::operator & (const Region& rhs) const {
     return intersect(rhs);
 }
@@ -172,6 +183,9 @@
 Region& Region::operator |= (const Region& rhs) {
     return orSelf(rhs);
 }
+Region& Region::operator ^= (const Region& rhs) {
+    return xorSelf(rhs);
+}
 Region& Region::operator &= (const Region& rhs) {
     return andSelf(rhs);
 }
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index a85362d..de2c674 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -31,6 +31,7 @@
     transform = &mTransformRoot;
     clipRect = &mClipRectRoot;
     region = NULL;
+    clipRegion = NULL;
 }
 
 /**
@@ -42,6 +43,8 @@
         invisible(s->invisible), empty(false),
         viewport(s->viewport), height(s->height) {
 
+    clipRegion = NULL;
+
     if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
         mTransformRoot.load(*s->transform);
         transform = &mTransformRoot;
@@ -52,8 +55,17 @@
     if (saveFlags & SkCanvas::kClip_SaveFlag) {
         mClipRectRoot.set(*s->clipRect);
         clipRect = &mClipRectRoot;
+#if STENCIL_BUFFER_SIZE
+        if (s->clipRegion) {
+            mClipRegionRoot.merge(*s->clipRegion);
+            clipRegion = &mClipRegionRoot;
+        }
+#endif
     } else {
         clipRect = s->clipRect;
+#if STENCIL_BUFFER_SIZE
+        clipRegion = s->clipRegion;
+#endif
     }
 
     if (s->flags & Snapshot::kFlagFboTarget) {
@@ -68,6 +80,77 @@
 // Clipping
 ///////////////////////////////////////////////////////////////////////////////
 
+void Snapshot::ensureClipRegion() {
+#if STENCIL_BUFFER_SIZE
+    if (!clipRegion) {
+        clipRegion = &mClipRegionRoot;
+        android::Rect tmp(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
+        clipRegion->set(tmp);
+    }
+#endif
+}
+
+void Snapshot::copyClipRectFromRegion() {
+#if STENCIL_BUFFER_SIZE
+    if (!clipRegion->isEmpty()) {
+        android::Rect bounds(clipRegion->bounds());
+        clipRect->set(bounds.left, bounds.top, bounds.right, bounds.bottom);
+
+        if (clipRegion->isRect()) {
+            clipRegion->clear();
+            clipRegion = NULL;
+        }
+    } else {
+        clipRect->setEmpty();
+        clipRegion = NULL;
+    }
+#endif
+}
+
+bool Snapshot::clipRegionOr(float left, float top, float right, float bottom) {
+#if STENCIL_BUFFER_SIZE
+    android::Rect tmp(left, top, right, bottom);
+    clipRegion->orSelf(tmp);
+    copyClipRectFromRegion();
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool Snapshot::clipRegionXor(float left, float top, float right, float bottom) {
+#if STENCIL_BUFFER_SIZE
+    android::Rect tmp(left, top, right, bottom);
+    clipRegion->xorSelf(tmp);
+    copyClipRectFromRegion();
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool Snapshot::clipRegionAnd(float left, float top, float right, float bottom) {
+#if STENCIL_BUFFER_SIZE
+    android::Rect tmp(left, top, right, bottom);
+    clipRegion->andSelf(tmp);
+    copyClipRectFromRegion();
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool Snapshot::clipRegionNand(float left, float top, float right, float bottom) {
+#if STENCIL_BUFFER_SIZE
+    android::Rect tmp(left, top, right, bottom);
+    clipRegion->subtractSelf(tmp);
+    copyClipRectFromRegion();
+    return true;
+#else
+    return false;
+#endif
+}
+
 bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
     Rect r(left, top, right, bottom);
     transform->mapRect(r);
@@ -77,32 +160,46 @@
 bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
     bool clipped = false;
 
-    // NOTE: The unimplemented operations require support for regions
-    // Supporting regions would require using a stencil buffer instead
-    // of the scissor. The stencil buffer itself is not too expensive
-    // (memory cost excluded) but on fillrate limited devices, managing
-    // the stencil might have a negative impact on the framerate.
     switch (op) {
-        case SkRegion::kDifference_Op:
+        case SkRegion::kDifference_Op: {
+            ensureClipRegion();
+            clipped = clipRegionNand(r.left, r.top, r.right, r.bottom);
             break;
-        case SkRegion::kIntersect_Op:
-            clipped = clipRect->intersect(r);
-            if (!clipped) {
-                clipRect->setEmpty();
-                clipped = true;
+        }
+        case SkRegion::kIntersect_Op: {
+            if (CC_UNLIKELY(clipRegion)) {
+                clipped = clipRegionOr(r.left, r.top, r.right, r.bottom);
+            } else {
+                clipped = clipRect->intersect(r);
+                if (!clipped) {
+                    clipRect->setEmpty();
+                    clipped = true;
+                }
             }
             break;
-        case SkRegion::kUnion_Op:
-            clipped = clipRect->unionWith(r);
+        }
+        case SkRegion::kUnion_Op: {
+            if (CC_UNLIKELY(clipRegion)) {
+                clipped = clipRegionAnd(r.left, r.top, r.right, r.bottom);
+            } else {
+                clipped = clipRect->unionWith(r);
+            }
             break;
-        case SkRegion::kXOR_Op:
+        }
+        case SkRegion::kXOR_Op: {
+            ensureClipRegion();
+            clipped = clipRegionXor(r.left, r.top, r.right, r.bottom);
             break;
-        case SkRegion::kReverseDifference_Op:
+        }
+        case SkRegion::kReverseDifference_Op: {
+            // TODO!!!!!!!
             break;
-        case SkRegion::kReplace_Op:
-            clipRect->set(r);
+        }
+        case SkRegion::kReplace_Op: {
+            setClip(r.left, r.top, r.right, r.bottom);
             clipped = true;
             break;
+        }
     }
 
     if (clipped) {
@@ -114,6 +211,12 @@
 
 void Snapshot::setClip(float left, float top, float right, float bottom) {
     clipRect->set(left, top, right, bottom);
+#if STENCIL_BUFFER_SIZE
+    if (clipRegion) {
+        clipRegion->clear();
+        clipRegion = NULL;
+    }
+#endif
     flags |= Snapshot::kFlagClipSet;
 }
 
@@ -129,8 +232,7 @@
 
 void Snapshot::resetClip(float left, float top, float right, float bottom) {
     clipRect = &mClipRectRoot;
-    clipRect->set(left, top, right, bottom);
-    flags |= Snapshot::kFlagClipSet;
+    setClip(left, top, right, bottom);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index c94af7e..b2bc879 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -181,7 +181,7 @@
     mat4* transform;
 
     /**
-     * Current clip region. The clip is stored in canvas-space coordinates,
+     * Current clip rect. The clip is stored in canvas-space coordinates,
      * (screen-space coordinates in the regular case.)
      *
      * This is a reference to a rect owned by this snapshot or another
@@ -190,6 +190,17 @@
     Rect* clipRect;
 
     /**
+     * Current clip region. The clip is stored in canvas-space coordinates,
+     * (screen-space coordinates in the regular case.)
+     *
+     * This is a reference to a region owned by this snapshot or another
+     * snapshot. This pointer must not be freed. See ::mClipRegionRoot.
+     *
+     * This field is used only if STENCIL_BUFFER_SIZE is > 0.
+     */
+    Region* clipRegion;
+
+    /**
      * The ancestor layer's dirty region.
      *
      * This is a reference to a region owned by a layer. This pointer must
@@ -198,10 +209,22 @@
     Region* region;
 
 private:
+    void ensureClipRegion();
+    void copyClipRectFromRegion();
+
+    bool clipRegionOr(float left, float top, float right, float bottom);
+    bool clipRegionXor(float left, float top, float right, float bottom);
+    bool clipRegionAnd(float left, float top, float right, float bottom);
+    bool clipRegionNand(float left, float top, float right, float bottom);
+
     mat4 mTransformRoot;
     Rect mClipRectRoot;
     Rect mLocalClip;
 
+#if STENCIL_BUFFER_SIZE
+    Region mClipRegionRoot;
+#endif
+
 }; // class Snapshot
 
 }; // namespace uirenderer
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 58d3e5c..2166ce7 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -89,7 +89,6 @@
 	rsFifoSocket.cpp \
 	rsFileA3D.cpp \
 	rsFont.cpp \
-	rsLocklessFifo.cpp \
 	rsObjectBase.cpp \
 	rsMatrix2x2.cpp \
 	rsMatrix3x3.cpp \
@@ -128,7 +127,7 @@
 	driver/rsdShaderCache.cpp \
 	driver/rsdVertexArray.cpp
 
-LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo
+LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo libgui
 
 LOCAL_STATIC_LIBRARIES := libdex libft2
 
@@ -196,7 +195,6 @@
 	rsFifoSocket.cpp \
 	rsFileA3D.cpp \
 	rsFont.cpp \
-	rsLocklessFifo.cpp \
 	rsObjectBase.cpp \
 	rsMatrix2x2.cpp \
 	rsMatrix3x3.cpp \
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index 7acc054..368dd710 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -215,6 +215,8 @@
     ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
     checkEglError("eglGetConfigs", ret);
 
+    eglSwapInterval(dc->gl.egl.display, 0);
+
     if (numConfigs) {
         EGLConfig* const configs = new EGLConfig[numConfigs];
 
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 6887b22..ffb1196 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -115,6 +115,7 @@
 	}
 
 ContextDestroyWorker {
+        sync
 }
 
 AssignName {
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index ad2ff0f..04284dd 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -18,6 +18,7 @@
 #include "rsContext.h"
 #include "rsThreadIO.h"
 #include <ui/FramebufferNativeWindow.h>
+#include <gui/DisplayEventReceiver.h>
 
 #include <sys/types.h>
 #include <sys/resource.h>
@@ -245,42 +246,55 @@
     }
 
     rsc->mRunning = true;
-    bool mDraw = true;
-    bool doWait = true;
-
-    uint64_t targetTime = rsc->getTime();
-    while (!rsc->mExit) {
-        uint64_t waitTime = 0;
-        uint64_t now = rsc->getTime();
-        if (!doWait) {
-            if (now < targetTime) {
-                waitTime = targetTime - now;
-                doWait = true;
-            }
+    if (!rsc->mIsGraphicsContext) {
+        while (!rsc->mExit) {
+            rsc->mIO.playCoreCommands(rsc, true, -1);
         }
+    } else {
+#ifndef ANDROID_RS_SERIALIZE
+        DisplayEventReceiver displayEvent;
+        DisplayEventReceiver::Event eventBuffer[1];
+#endif
+        int vsyncRate = 0;
+        int targetRate = 0;
 
-        mDraw |= rsc->mIO.playCoreCommands(rsc, doWait, waitTime);
-        mDraw &= (rsc->mRootScript.get() != NULL);
-        mDraw &= rsc->mHasSurface;
+        bool drawOnce = false;
+        while (!rsc->mExit) {
+            rsc->timerSet(RS_TIMER_IDLE);
 
-        if (mDraw && rsc->mIsGraphicsContext) {
-            uint64_t delay = rsc->runRootScript() * 1000000;
-            targetTime = rsc->getTime() + delay;
-            doWait = (delay == 0);
-
-            if (rsc->props.mLogVisual) {
-                rsc->displayDebugStats();
+#ifndef ANDROID_RS_SERIALIZE
+            if (vsyncRate != targetRate) {
+                displayEvent.setVsyncRate(targetRate);
+                vsyncRate = targetRate;
+            }
+            if (targetRate) {
+                drawOnce |= rsc->mIO.playCoreCommands(rsc, true, displayEvent.getFd());
+                while (displayEvent.getEvents(eventBuffer, 1) != 0) {
+                    //ALOGE("vs2 time past %lld", (rsc->getTime() - eventBuffer[0].header.timestamp) / 1000000);
+                }
+            } else
+#endif
+            {
+                drawOnce |= rsc->mIO.playCoreCommands(rsc, true, -1);
             }
 
-            mDraw = !rsc->mPaused;
-            rsc->timerSet(RS_TIMER_CLEAR_SWAP);
-            rsc->mHal.funcs.swap(rsc);
-            rsc->timerFrame();
-            rsc->timerSet(RS_TIMER_INTERNAL);
-            rsc->timerPrint();
-            rsc->timerReset();
-        } else {
-            doWait = true;
+            if ((rsc->mRootScript.get() != NULL) && rsc->mHasSurface &&
+                (targetRate || drawOnce) && !rsc->mPaused) {
+
+                drawOnce = false;
+                targetRate = ((rsc->runRootScript() + 15) / 16);
+
+                if (rsc->props.mLogVisual) {
+                    rsc->displayDebugStats();
+                }
+
+                rsc->timerSet(RS_TIMER_CLEAR_SWAP);
+                rsc->mHal.funcs.swap(rsc);
+                rsc->timerFrame();
+                rsc->timerSet(RS_TIMER_INTERNAL);
+                rsc->timerPrint();
+                rsc->timerReset();
+            }
         }
     }
 
@@ -315,8 +329,8 @@
          mFBOCache.deinit(this);
     }
     ObjectBase::freeAllChildren(this);
-    //ALOGV("destroyWorkerThreadResources 2");
     mExit = true;
+    //ALOGV("destroyWorkerThreadResources 2");
 }
 
 void Context::printWatchdogInfo(void *ctx) {
@@ -382,7 +396,7 @@
     pthread_mutex_lock(&gInitMutex);
 
     mIO.init();
-    mIO.setTimoutCallback(printWatchdogInfo, this, 2e9);
+    mIO.setTimeoutCallback(printWatchdogInfo, this, 2e9);
 
     dev->addContext(this);
     mDev = dev;
@@ -434,14 +448,12 @@
     ALOGV("%p Context::~Context", this);
 
     if (!mIsContextLite) {
-        mIO.coreFlush();
-        rsAssert(mExit);
-        mExit = true;
         mPaused = false;
         void *res;
 
         mIO.shutdown();
         int status = pthread_join(mThreadId, &res);
+        rsAssert(mExit);
 
         if (mHal.funcs.shutdownDriver) {
             mHal.funcs.shutdownDriver(this);
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 61c29f9..a844a20 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -39,7 +39,6 @@
 #include "rsFBOCache.h"
 
 #include "rsgApiStructs.h"
-#include "rsLocklessFifo.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
diff --git a/libs/rs/rsFifo.cpp b/libs/rs/rsFifo.cpp
deleted file mode 100644
index 3d5d8c4..0000000
--- a/libs/rs/rsFifo.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#include "rsFifoSocket.h"
-#include "utils/Timers.h"
-#include "utils/StopWatch.h"
-
-using namespace android;
-using namespace android::renderscript;
-
-Fifo::Fifo() {
-
-}
-
-Fifo::~Fifo() {
-
-}
-
diff --git a/libs/rs/rsFifo.h b/libs/rs/rsFifo.h
index f924b95..911f446 100644
--- a/libs/rs/rsFifo.h
+++ b/libs/rs/rsFifo.h
@@ -35,9 +35,9 @@
     virtual ~Fifo();
 
 public:
-    void virtual writeAsync(const void *data, size_t bytes) = 0;
+    bool virtual writeAsync(const void *data, size_t bytes, bool waitForSpace = true) = 0;
     void virtual writeWaitReturn(void *ret, size_t retSize) = 0;
-    size_t virtual read(void *data, size_t bytes) = 0;
+    size_t virtual read(void *data, size_t bytes, bool doWait = true, uint64_t timeToWait = 0) = 0;
     void virtual readReturn(const void *data, size_t bytes) = 0;
 
     void virtual flush() = 0;
diff --git a/libs/rs/rsFifoSocket.cpp b/libs/rs/rsFifoSocket.cpp
index 163a44b..bd511cf 100644
--- a/libs/rs/rsFifoSocket.cpp
+++ b/libs/rs/rsFifoSocket.cpp
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <poll.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 
@@ -29,55 +30,79 @@
 using namespace android::renderscript;
 
 FifoSocket::FifoSocket() {
-    sequence = 1;
+    mShutdown = false;
 }
 
 FifoSocket::~FifoSocket() {
 
 }
 
-bool FifoSocket::init() {
+bool FifoSocket::init(bool supportNonBlocking, bool supportReturnValues, size_t maxDataSize) {
     int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
     return false;
 }
 
 void FifoSocket::shutdown() {
+    mShutdown = true;
+    uint64_t d = 0;
+    ::send(sv[0], &d, sizeof(d), 0);
+    ::send(sv[1], &d, sizeof(d), 0);
+    close(sv[0]);
+    close(sv[1]);
 }
 
-void FifoSocket::writeAsync(const void *data, size_t bytes) {
+bool FifoSocket::writeAsync(const void *data, size_t bytes, bool waitForSpace) {
     if (bytes == 0) {
-        return;
+        return true;
     }
     //ALOGE("writeAsync %p %i", data, bytes);
     size_t ret = ::send(sv[0], data, bytes, 0);
     //ALOGE("writeAsync ret %i", ret);
     rsAssert(ret == bytes);
+    return true;
 }
 
 void FifoSocket::writeWaitReturn(void *retData, size_t retBytes) {
+    if (mShutdown) {
+        return;
+    }
+
     //ALOGE("writeWaitReturn %p %i", retData, retBytes);
-    size_t ret = ::recv(sv[0], retData, retBytes, 0);
+    size_t ret = ::recv(sv[0], retData, retBytes, MSG_WAITALL);
     //ALOGE("writeWaitReturn %i", ret);
     rsAssert(ret == retBytes);
 }
 
 size_t FifoSocket::read(void *data, size_t bytes) {
+    if (mShutdown) {
+        return 0;
+    }
+
     //ALOGE("read %p %i", data, bytes);
-    size_t ret = ::recv(sv[1], data, bytes, 0);
-    rsAssert(ret == bytes);
-    //ALOGE("read ret %i", ret);
+    size_t ret = ::recv(sv[1], data, bytes, MSG_WAITALL);
+    rsAssert(ret == bytes || mShutdown);
+    //ALOGE("read ret %i  bytes %i", ret, bytes);
+    if (mShutdown) {
+        ret = 0;
+    }
     return ret;
 }
 
-void FifoSocket::readReturn(const void *data, size_t bytes) {
-    ALOGE("readReturn %p %Zu", data, bytes);
-    size_t ret = ::send(sv[1], data, bytes, 0);
-    ALOGE("readReturn %Zu", ret);
-    rsAssert(ret == bytes);
+bool FifoSocket::isEmpty() {
+    struct pollfd p;
+    p.fd = sv[1];
+    p.events = POLLIN;
+    int r = poll(&p, 1, 0);
+    //ALOGE("poll r=%i", r);
+    return r == 0;
 }
 
 
-void FifoSocket::flush() {
+void FifoSocket::readReturn(const void *data, size_t bytes) {
+    //ALOGE("readReturn %p %Zu", data, bytes);
+    size_t ret = ::send(sv[1], data, bytes, 0);
+    //ALOGE("readReturn %Zu", ret);
+    //rsAssert(ret == bytes);
 }
 
 
diff --git a/libs/rs/rsFifoSocket.h b/libs/rs/rsFifoSocket.h
index 7df2b67..cac0a75 100644
--- a/libs/rs/rsFifoSocket.h
+++ b/libs/rs/rsFifoSocket.h
@@ -29,23 +29,23 @@
     FifoSocket();
     virtual ~FifoSocket();
 
-    bool init();
+    bool init(bool supportNonBlocking = true,
+              bool supportReturnValues = true,
+              size_t maxDataSize = 0);
     void shutdown();
 
+    bool writeAsync(const void *data, size_t bytes, bool waitForSpace = true);
+    void writeWaitReturn(void *ret, size_t retSize);
+    size_t read(void *data, size_t bytes);
+    void readReturn(const void *data, size_t bytes);
+    bool isEmpty();
 
-
-    void virtual writeAsync(const void *data, size_t bytes);
-    void virtual writeWaitReturn(void *ret, size_t retSize);
-    size_t virtual read(void *data, size_t bytes);
-    void virtual readReturn(const void *data, size_t bytes);
-
-    void virtual flush();
+    int getWriteFd() {return sv[0];}
+    int getReadFd() {return sv[1];}
 
 protected:
     int sv[2];
-    uint32_t sequence;
-
-
+    bool mShutdown;
 };
 
 }
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
deleted file mode 100644
index 0466d8b..0000000
--- a/libs/rs/rsLocklessFifo.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#include "rsLocklessFifo.h"
-#include "utils/Timers.h"
-#include "utils/StopWatch.h"
-
-using namespace android;
-using namespace android::renderscript;
-
-LocklessCommandFifo::LocklessCommandFifo() : mBuffer(0), mInitialized(false) {
-    mTimeoutCallback = NULL;
-    mTimeoutCallbackData = NULL;
-    mTimeoutWait = 0;
-}
-
-LocklessCommandFifo::~LocklessCommandFifo() {
-    if (!mInShutdown && mInitialized) {
-        shutdown();
-    }
-    if (mBuffer) {
-        free(mBuffer);
-    }
-}
-
-void LocklessCommandFifo::shutdown() {
-    mInShutdown = true;
-    mSignalToWorker.set();
-}
-
-bool LocklessCommandFifo::init(uint32_t sizeInBytes) {
-    // Add room for a buffer reset command
-    mBuffer = static_cast<uint8_t *>(malloc(sizeInBytes + 4));
-    if (!mBuffer) {
-        ALOGE("LocklessFifo allocation failure");
-        return false;
-    }
-
-    if (!mSignalToControl.init() || !mSignalToWorker.init()) {
-        ALOGE("Signal setup failed");
-        free(mBuffer);
-        return false;
-    }
-
-    mInShutdown = false;
-    mSize = sizeInBytes;
-    mPut = mBuffer;
-    mGet = mBuffer;
-    mEnd = mBuffer + (sizeInBytes) - 1;
-    //dumpState("init");
-    mInitialized = true;
-    return true;
-}
-
-uint32_t LocklessCommandFifo::getFreeSpace() const {
-    int32_t freeSpace = 0;
-    //dumpState("getFreeSpace");
-
-    if (mPut >= mGet) {
-        freeSpace = mEnd - mPut;
-    } else {
-        freeSpace = mGet - mPut;
-    }
-
-    if (freeSpace < 0) {
-        freeSpace = 0;
-    }
-    return freeSpace;
-}
-
-bool LocklessCommandFifo::isEmpty() const {
-    uint32_t p = android_atomic_acquire_load((int32_t *)&mPut);
-    return ((uint8_t *)p) == mGet;
-}
-
-
-void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) {
-    // Add space for command header and loop token;
-    sizeInBytes += 8;
-
-    //dumpState("reserve");
-    if (getFreeSpace() < sizeInBytes) {
-        makeSpace(sizeInBytes);
-    }
-
-    return mPut + 4;
-}
-
-void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) {
-    if (mInShutdown) {
-        return;
-    }
-    //dumpState("commit 1");
-    reinterpret_cast<uint16_t *>(mPut)[0] = command;
-    reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes;
-
-    int32_t s = ((sizeInBytes + 3) & ~3) + 4;
-    android_atomic_add(s, (int32_t *)&mPut);
-    //dumpState("commit 2");
-    mSignalToWorker.set();
-}
-
-void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) {
-    if (mInShutdown) {
-        return;
-    }
-
-    //char buf[1024];
-    //sprintf(buf, "RenderScript LocklessCommandFifo::commitSync  %p %i  %i", this, command, sizeInBytes);
-    //StopWatch compileTimer(buf);
-    commit(command, sizeInBytes);
-    flush();
-}
-
-void LocklessCommandFifo::flush() {
-    //dumpState("flush 1");
-    while (mPut != mGet) {
-        while (!mSignalToControl.wait(mTimeoutWait)) {
-            if (mTimeoutCallback) {
-                mTimeoutCallback(mTimeoutCallbackData);
-            }
-        }
-    }
-    //dumpState("flush 2");
-}
-
-void LocklessCommandFifo::setTimoutCallback(void (*cbk)(void *), void *data, uint64_t timeout) {
-    mTimeoutCallback = cbk;
-    mTimeoutCallbackData = data;
-    mTimeoutWait = timeout;
-}
-
-bool LocklessCommandFifo::wait(uint64_t timeout) {
-    while (isEmpty() && !mInShutdown) {
-        mSignalToControl.set();
-        return mSignalToWorker.wait(timeout);
-    }
-    return true;
-}
-
-const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData, uint64_t timeout) {
-    while (1) {
-        //dumpState("get");
-        wait(timeout);
-
-        if (isEmpty() || mInShutdown) {
-            *command = 0;
-            *bytesData = 0;
-            return NULL;
-        }
-
-        *command = reinterpret_cast<const uint16_t *>(mGet)[0];
-        *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1];
-        if (*command) {
-            // non-zero command is valid
-            return mGet+4;
-        }
-
-        // zero command means reset to beginning.
-        mGet = mBuffer;
-    }
-}
-
-void LocklessCommandFifo::next() {
-    uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
-
-    android_atomic_add(((bytes + 3) & ~3) + 4, (int32_t *)&mGet);
-    //mGet += ((bytes + 3) & ~3) + 4;
-    if (isEmpty()) {
-        mSignalToControl.set();
-    }
-    //dumpState("next");
-}
-
-bool LocklessCommandFifo::makeSpaceNonBlocking(uint32_t bytes) {
-    //dumpState("make space non-blocking");
-    if ((mPut+bytes) > mEnd) {
-        // Need to loop regardless of where get is.
-        if ((mGet > mPut) || (mBuffer+4 >= mGet)) {
-            return false;
-        }
-
-        // Toss in a reset then the normal wait for space will do the rest.
-        reinterpret_cast<uint16_t *>(mPut)[0] = 0;
-        reinterpret_cast<uint16_t *>(mPut)[1] = 0;
-        mPut = mBuffer;
-        mSignalToWorker.set();
-    }
-
-    // it will fit here so we just need to wait for space.
-    if (getFreeSpace() < bytes) {
-        return false;
-    }
-
-    return true;
-}
-
-void LocklessCommandFifo::makeSpace(uint32_t bytes) {
-    //dumpState("make space");
-    if ((mPut+bytes) > mEnd) {
-        // Need to loop regardless of where get is.
-        while ((mGet > mPut) || (mBuffer+4 >= mGet)) {
-            usleep(100);
-        }
-
-        // Toss in a reset then the normal wait for space will do the rest.
-        reinterpret_cast<uint16_t *>(mPut)[0] = 0;
-        reinterpret_cast<uint16_t *>(mPut)[1] = 0;
-        mPut = mBuffer;
-        mSignalToWorker.set();
-    }
-
-    // it will fit here so we just need to wait for space.
-    while (getFreeSpace() < bytes) {
-        usleep(100);
-    }
-
-}
-
-void LocklessCommandFifo::dumpState(const char *s) const {
-    ALOGV("%s %p  put %p, get %p,  buf %p,  end %p", s, this, mPut, mGet, mBuffer, mEnd);
-}
-
-void LocklessCommandFifo::printDebugData() const {
-    dumpState("printing fifo debug");
-    const uint32_t *pptr = (const uint32_t *)mGet;
-    pptr -= 8 * 4;
-    if (mGet < mBuffer) {
-        pptr = (const uint32_t *)mBuffer;
-    }
-
-
-    for (int ct=0; ct < 16; ct++) {
-        ALOGV("fifo %p = 0x%08x  0x%08x  0x%08x  0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
-        pptr += 4;
-    }
-
-}
diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h
deleted file mode 100644
index dafc512..0000000
--- a/libs/rs/rsLocklessFifo.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2009 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_RS_LOCKLESS_FIFO_H
-#define ANDROID_RS_LOCKLESS_FIFO_H
-
-
-#include "rsUtils.h"
-#include "rsSignal.h"
-
-namespace android {
-namespace renderscript {
-
-
-// A simple FIFO to be used as a producer / consumer between two
-// threads.  One is writer and one is reader.  The common cases
-// will not require locking.  It is not threadsafe for multiple
-// readers or writers by design.
-
-class LocklessCommandFifo {
-public:
-    bool init(uint32_t size);
-    void shutdown();
-    void setTimoutCallback(void (*)(void *), void *, uint64_t timeout);
-
-    void printDebugData() const;
-
-    LocklessCommandFifo();
-    ~LocklessCommandFifo();
-
-protected:
-    uint8_t * volatile mPut;
-    uint8_t * volatile mGet;
-    uint8_t * mBuffer;
-    uint8_t * mEnd;
-    uint8_t mSize;
-    bool mInShutdown;
-    bool mInitialized;
-
-    Signal mSignalToWorker;
-    Signal mSignalToControl;
-
-public:
-    void * reserve(uint32_t bytes);
-    void commit(uint32_t command, uint32_t bytes);
-    void commitSync(uint32_t command, uint32_t bytes);
-
-    void flush();
-    bool wait(uint64_t timeout = 0);
-
-    const void * get(uint32_t *command, uint32_t *bytesData, uint64_t timeout = 0);
-    void next();
-
-    void makeSpace(uint32_t bytes);
-    bool makeSpaceNonBlocking(uint32_t bytes);
-
-    bool isEmpty() const;
-    uint32_t getFreeSpace() const;
-
-private:
-    void dumpState(const char *) const;
-
-    void (*mTimeoutCallback)(void *);
-    void * mTimeoutCallbackData;
-    uint64_t mTimeoutWait;
-};
-
-
-}
-}
-#endif
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 1917774..8e4b988 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -18,227 +18,189 @@
 
 #include "rsThreadIO.h"
 
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <fcntl.h>
+#include <poll.h>
+
+
 using namespace android;
 using namespace android::renderscript;
 
-ThreadIO::ThreadIO() : mUsingSocket(false) {
+ThreadIO::ThreadIO() {
+    mRunning = true;
 }
 
 ThreadIO::~ThreadIO() {
 }
 
-void ThreadIO::init(bool useSocket) {
-    mUsingSocket = useSocket;
-    mToCore.init(16 * 1024);
-
-    if (mUsingSocket) {
-        mToClientSocket.init();
-        mToCoreSocket.init();
-    } else {
-        mToClient.init(1024);
-    }
+void ThreadIO::init() {
+    mToClient.init();
+    mToCore.init();
 }
 
 void ThreadIO::shutdown() {
-    //ALOGE("shutdown 1");
+    mRunning = false;
     mToCore.shutdown();
-    //ALOGE("shutdown 2");
-}
-
-void ThreadIO::coreFlush() {
-    //ALOGE("coreFlush 1");
-    if (mUsingSocket) {
-    } else {
-        mToCore.flush();
-    }
-    //ALOGE("coreFlush 2");
 }
 
 void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
     //ALOGE("coreHeader %i %i", cmdID, dataLen);
-    if (mUsingSocket) {
-        CoreCmdHeader hdr;
-        hdr.bytes = dataLen;
-        hdr.cmdID = cmdID;
-        mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
-    } else {
-        mCoreCommandSize = dataLen;
-        mCoreCommandID = cmdID;
-        mCoreDataPtr = (uint8_t *)mToCore.reserve(dataLen);
-        mCoreDataBasePtr = mCoreDataPtr;
-    }
-    //ALOGE("coreHeader ret %p", mCoreDataPtr);
-    return mCoreDataPtr;
-}
-
-void ThreadIO::coreData(const void *data, size_t dataLen) {
-    //ALOGE("coreData %p %i", data, dataLen);
-    mToCoreSocket.writeAsync(data, dataLen);
-    //ALOGE("coreData ret %p", mCoreDataPtr);
+    CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0];
+    hdr->bytes = dataLen;
+    hdr->cmdID = cmdID;
+    mSendLen = dataLen + sizeof(CoreCmdHeader);
+    //mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
+    //ALOGE("coreHeader ret ");
+    return &mSendBuffer[sizeof(CoreCmdHeader)];
 }
 
 void ThreadIO::coreCommit() {
-    //ALOGE("coreCommit %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
-    if (mUsingSocket) {
-    } else {
-        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
-        mToCore.commit(mCoreCommandID, mCoreCommandSize);
-    }
-    //ALOGE("coreCommit ret");
-}
-
-void ThreadIO::coreCommitSync() {
-    //ALOGE("coreCommitSync %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
-    if (mUsingSocket) {
-    } else {
-        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
-        mToCore.commitSync(mCoreCommandID, mCoreCommandSize);
-    }
-    //ALOGE("coreCommitSync ret");
+    mToCore.writeAsync(&mSendBuffer, mSendLen);
 }
 
 void ThreadIO::clientShutdown() {
-    //ALOGE("coreShutdown 1");
     mToClient.shutdown();
-    //ALOGE("coreShutdown 2");
 }
 
 void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
-    rsAssert(dataLen <= sizeof(mToCoreRet));
-    memcpy(&mToCoreRet, data, dataLen);
+    uint32_t buf;
+    if (data == NULL) {
+        data = &buf;
+        dataLen = sizeof(buf);
+    }
+
+    mToCore.readReturn(data, dataLen);
 }
 
 void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
-    memcpy(data, &mToCoreRet, dataLen);
+    uint32_t buf;
+    if (data == NULL) {
+        data = &buf;
+        dataLen = sizeof(buf);
+    }
+
+    mToCore.writeWaitReturn(data, dataLen);
 }
 
-void ThreadIO::setTimoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) {
-    mToCore.setTimoutCallback(cb, dat, timeout);
+void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) {
+    //mToCore.setTimeoutCallback(cb, dat, timeout);
 }
 
-
-bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait) {
+bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, int waitFd) {
     bool ret = false;
-    uint64_t startTime = con->getTime();
 
-    while (!mToCore.isEmpty() || waitForCommand) {
-        uint32_t cmdID = 0;
-        uint32_t cmdSize = 0;
-        if (con->props.mLogTimes) {
-            con->timerSet(Context::RS_TIMER_IDLE);
+    uint8_t buf[2 * 1024];
+    const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0];
+    const void * data = (const void *)&buf[sizeof(CoreCmdHeader)];
+
+    struct pollfd p[2];
+    p[0].fd = mToCore.getReadFd();
+    p[0].events = POLLIN;
+    p[0].revents = 0;
+    p[1].fd = waitFd;
+    p[1].events = POLLIN;
+    p[1].revents = 0;
+    int pollCount = 1;
+    if (waitFd >= 0) {
+        pollCount = 2;
+    }
+
+    if (con->props.mLogTimes) {
+        con->timerSet(Context::RS_TIMER_IDLE);
+    }
+
+    int waitTime = -1;
+    while (mRunning) {
+        int pr = poll(p, pollCount, waitTime);
+        if (pr <= 0) {
+            break;
         }
 
-        uint64_t delay = 0;
-        if (waitForCommand) {
-            delay = timeToWait - (con->getTime() - startTime);
-            if (delay > timeToWait) {
-                delay = 0;
+        if (p[0].revents) {
+            size_t r = mToCore.read(&buf[0], sizeof(CoreCmdHeader));
+            mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes);
+
+            if (r != sizeof(CoreCmdHeader)) {
+                // exception or timeout occurred.
+                break;
+            }
+
+            ret = true;
+            if (con->props.mLogTimes) {
+                con->timerSet(Context::RS_TIMER_INTERNAL);
+            }
+            waitForCommand = false;
+            //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes);
+
+            if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
+                rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
+                ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID);
+            }
+            gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes);
+
+            if (con->props.mLogTimes) {
+                con->timerSet(Context::RS_TIMER_IDLE);
+            }
+
+            if (waitFd < 0) {
+                // If we don't have a secondary wait object we should stop blocking now
+                // that at least one command has been processed.
+                waitTime = 0;
             }
         }
 
-        if (delay == 0 && timeToWait != 0 && mToCore.isEmpty()) {
+        if (p[1].revents && !p[0].revents) {
+            // We want to finish processing fifo events before processing the vsync.
+            // Otherwise we can end up falling behind and having tremendous lag.
             break;
         }
-
-        const void * data = mToCore.get(&cmdID, &cmdSize, delay);
-        if (!cmdSize) {
-            // exception or timeout occurred.
-            break;
-        }
-        ret = true;
-        if (con->props.mLogTimes) {
-            con->timerSet(Context::RS_TIMER_INTERNAL);
-        }
-        waitForCommand = false;
-        //ALOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
-
-        if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
-            rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
-            ALOGE("playCoreCommands error con %p, cmd %i", con, cmdID);
-            mToCore.printDebugData();
-        }
-        gPlaybackFuncs[cmdID](con, data, cmdSize << 2);
-        mToCore.next();
     }
     return ret;
 }
 
 RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
-    if (mUsingSocket) {
-        mToClientSocket.read(&mLastClientHeader, sizeof(mLastClientHeader));
-    } else {
-        size_t bytesData = 0;
-        const uint32_t *d = (const uint32_t *)mToClient.get(&mLastClientHeader.cmdID, (uint32_t*)&bytesData);
-        if (bytesData >= sizeof(uint32_t)) {
-            mLastClientHeader.userID = d[0];
-            mLastClientHeader.bytes = bytesData - sizeof(uint32_t);
-        } else {
-            mLastClientHeader.userID = 0;
-            mLastClientHeader.bytes = 0;
-        }
-    }
+    //ALOGE("getClientHeader");
+    mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader));
+
     receiveLen[0] = mLastClientHeader.bytes;
     usrID[0] = mLastClientHeader.userID;
+    //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]);
     return (RsMessageToClientType)mLastClientHeader.cmdID;
 }
 
 RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
                                 uint32_t *usrID, size_t bufferLen) {
+    //ALOGE("getClientPayload");
     receiveLen[0] = mLastClientHeader.bytes;
     usrID[0] = mLastClientHeader.userID;
     if (bufferLen < mLastClientHeader.bytes) {
         return RS_MESSAGE_TO_CLIENT_RESIZE;
     }
-    if (mUsingSocket) {
-        if (receiveLen[0]) {
-            mToClientSocket.read(data, receiveLen[0]);
-        }
-        return (RsMessageToClientType)mLastClientHeader.cmdID;
-    } else {
-        uint32_t bytesData = 0;
-        uint32_t commandID = 0;
-        const uint32_t *d = (const uint32_t *)mToClient.get(&commandID, &bytesData);
-        //ALOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
-        //ALOGE("getMessageToClient  %i %i", commandID, *subID);
-        if (bufferLen >= receiveLen[0]) {
-            memcpy(data, d+1, receiveLen[0]);
-            mToClient.next();
-            return (RsMessageToClientType)commandID;
-        }
+    if (receiveLen[0]) {
+        mToClient.read(data, receiveLen[0]);
     }
-    return RS_MESSAGE_TO_CLIENT_RESIZE;
+    //ALOGE("getClientPayload x");
+    return (RsMessageToClientType)mLastClientHeader.cmdID;
 }
 
 bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
                             size_t dataLen, bool waitForSpace) {
+
+    //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen);
     ClientCmdHeader hdr;
     hdr.bytes = dataLen;
     hdr.cmdID = cmdID;
     hdr.userID = usrID;
-    if (mUsingSocket) {
-        mToClientSocket.writeAsync(&hdr, sizeof(hdr));
-        if (dataLen) {
-            mToClientSocket.writeAsync(data, dataLen);
-        }
-        return true;
-    } else {
-        if (!waitForSpace) {
-            if (!mToClient.makeSpaceNonBlocking(dataLen + sizeof(hdr))) {
-                // Not enough room, and not waiting.
-                return false;
-            }
-        }
 
-        //ALOGE("sendMessageToClient 2");
-        uint32_t *p = (uint32_t *)mToClient.reserve(dataLen + sizeof(usrID));
-        p[0] = usrID;
-        if (dataLen > 0) {
-            memcpy(p+1, data, dataLen);
-        }
-        mToClient.commit(cmdID, dataLen + sizeof(usrID));
-        //ALOGE("sendMessageToClient 3");
-        return true;
+    mToClient.writeAsync(&hdr, sizeof(hdr));
+    if (dataLen) {
+        mToClient.writeAsync(data, dataLen);
     }
-    return false;
+
+    //ALOGE("sendToClient x");
+    return true;
 }
 
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
index ebce0ab..d56a1c9 100644
--- a/libs/rs/rsThreadIO.h
+++ b/libs/rs/rsThreadIO.h
@@ -18,7 +18,6 @@
 #define ANDROID_RS_THREAD_IO_H
 
 #include "rsUtils.h"
-#include "rsLocklessFifo.h"
 #include "rsFifoSocket.h"
 
 // ---------------------------------------------------------------------------
@@ -32,23 +31,17 @@
     ThreadIO();
     ~ThreadIO();
 
-    void init(bool useSocket = false);
+    void init();
     void shutdown();
 
     // Plays back commands from the client.
     // Returns true if any commands were processed.
-    bool playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait);
+    bool playCoreCommands(Context *con, bool waitForCommand, int waitFd);
 
-    void setTimoutCallback(void (*)(void *), void *, uint64_t timeout);
-    //LocklessCommandFifo mToCore;
+    void setTimeoutCallback(void (*)(void *), void *, uint64_t timeout);
 
-
-
-    void coreFlush();
     void * coreHeader(uint32_t, size_t dataLen);
-    void coreData(const void *data, size_t dataLen);
     void coreCommit();
-    void coreCommitSync();
     void coreSetReturn(const void *data, size_t dataLen);
     void coreGetReturn(void *data, size_t dataLen);
 
@@ -71,20 +64,16 @@
     } ClientCmdHeader;
     ClientCmdHeader mLastClientHeader;
 
-    size_t mCoreCommandSize;
-    uint32_t mCoreCommandID;
-    uint8_t * mCoreDataPtr;
-    uint8_t * mCoreDataBasePtr;
+    bool mRunning;
 
-    bool mUsingSocket;
-    LocklessCommandFifo mToClient;
-    LocklessCommandFifo mToCore;
-
-    FifoSocket mToClientSocket;
-    FifoSocket mToCoreSocket;
+    FifoSocket mToClient;
+    FifoSocket mToCore;
 
     intptr_t mToCoreRet;
 
+    size_t mSendLen;
+    uint8_t mSendBuffer[2 * 1024];
+
 };
 
 
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 6b84e56..385c8b5 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -256,7 +256,7 @@
                     fprintf(f, "        memcpy(payload, %s, %s_length);\n", vt->name, vt->name);
                     fprintf(f, "        cmd->%s = (", vt->name);
                     printVarType(f, vt);
-                    fprintf(f, ")payload;\n");
+                    fprintf(f, ")(payload - ((uint8_t *)&cmd[1]));\n");
                     fprintf(f, "        payload += %s_length;\n", vt->name);
                     fprintf(f, "    } else {\n");
                     fprintf(f, "        cmd->%s = %s;\n", vt->name, vt->name);
@@ -270,26 +270,19 @@
                 needFlush = 1;
             }
 
+            fprintf(f, "    io->coreCommit();\n");
             if (hasInlineDataPointers(api)) {
-                fprintf(f, "    if (dataSize < 1024) {\n");
-                fprintf(f, "        io->coreCommit();\n");
-                fprintf(f, "    } else {\n");
-                fprintf(f, "        io->coreCommitSync();\n");
+                fprintf(f, "    if (dataSize >= 1024) {\n");
+                fprintf(f, "        io->coreGetReturn(NULL, 0);\n");
                 fprintf(f, "    }\n");
-            } else {
-                fprintf(f, "    io->coreCommit");
-                if (needFlush) {
-                    fprintf(f, "Sync");
-                }
-                fprintf(f, "();\n");
-            }
-
-            if (api->ret.typeName[0]) {
+            } else if (api->ret.typeName[0]) {
                 fprintf(f, "\n    ");
                 printVarType(f, &api->ret);
                 fprintf(f, " ret;\n");
                 fprintf(f, "    io->coreGetReturn(&ret, sizeof(ret));\n");
                 fprintf(f, "    return ret;\n");
+            } else if (needFlush) {
+                fprintf(f, "    io->coreGetReturn(NULL, 0);\n");
             }
         }
         fprintf(f, "};\n\n");
@@ -434,6 +427,7 @@
 
     for (ct=0; ct < apiCount; ct++) {
         const ApiEntry * api = &apis[ct];
+        int needFlush = 0;
 
         if (api->direct) {
             continue;
@@ -444,6 +438,13 @@
         //fprintf(f, "    ALOGE(\"play command %s\\n\");\n", api->name);
         fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
 
+        if (hasInlineDataPointers(api)) {
+            fprintf(f, "    const uint8_t *baseData = 0;\n");
+            fprintf(f, "    if (cmdSizeBytes != sizeof(RS_CMD_%s)) {\n", api->name);
+            fprintf(f, "        baseData = &((const uint8_t *)vp)[sizeof(*cmd)];\n");
+            fprintf(f, "    }\n");
+        }
+
         fprintf(f, "    ");
         if (api->ret.typeName[0]) {
             fprintf(f, "\n    ");
@@ -453,12 +454,31 @@
         fprintf(f, "rsi_%s(con", api->name);
         for (ct2=0; ct2 < api->paramCount; ct2++) {
             const VarType *vt = &api->params[ct2];
-            fprintf(f, ",\n           cmd->%s", vt->name);
+            needFlush += vt->ptrLevel;
+
+            if (hasInlineDataPointers(api) && vt->ptrLevel) {
+                fprintf(f, ",\n           (const %s *)&baseData[(intptr_t)cmd->%s]", vt->typeName, vt->name);
+            } else {
+                fprintf(f, ",\n           cmd->%s", vt->name);
+            }
         }
         fprintf(f, ");\n");
 
-        if (api->ret.typeName[0]) {
+        if (hasInlineDataPointers(api)) {
+            fprintf(f, "    size_t totalSize = 0;\n");
+            for (ct2=0; ct2 < api->paramCount; ct2++) {
+                if (api->params[ct2].ptrLevel) {
+                    fprintf(f, "    totalSize += cmd->%s_length;\n", api->params[ct2].name);
+                }
+            }
+
+            fprintf(f, "    if ((totalSize != 0) && (cmdSizeBytes == sizeof(RS_CMD_%s))) {\n", api->name);
+            fprintf(f, "        con->mIO.coreSetReturn(NULL, 0);\n");
+            fprintf(f, "    }\n");
+        } else if (api->ret.typeName[0]) {
             fprintf(f, "    con->mIO.coreSetReturn(&ret, sizeof(ret));\n");
+        } else if (api->sync || needFlush) {
+            fprintf(f, "    con->mIO.coreSetReturn(NULL, 0);\n");
         }
 
         fprintf(f, "};\n\n");
@@ -466,6 +486,7 @@
 
     for (ct=0; ct < apiCount; ct++) {
         const ApiEntry * api = &apis[ct];
+        int needFlush = 0;
 
         fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name);
 
@@ -475,6 +496,7 @@
 
         for (ct2=0; ct2 < api->paramCount; ct2++) {
             const VarType *vt = &api->params[ct2];
+            needFlush += vt->ptrLevel;
             if (vt->ptrLevel == 1) {
                 fprintf(f, "    cmd.%s = (", vt->name);
                 printVarType(f, vt);
@@ -515,6 +537,8 @@
 
         if (api->ret.typeName[0]) {
             fprintf(f, "    f->readReturn(&ret, sizeof(ret));\n");
+        } else if (needFlush) {
+            fprintf(f, "    f->readReturn(NULL, 0);\n");
         }
 
         fprintf(f, "};\n\n");
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 8cd047a..6e2e731 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -126,6 +126,9 @@
 Region& Region::orSelf(const Rect& r) {
     return operationSelf(r, op_or);
 }
+Region& Region::xorSelf(const Rect& r) {
+    return operationSelf(r, op_xor);
+}
 Region& Region::andSelf(const Rect& r) {
     return operationSelf(r, op_and);
 }
@@ -143,6 +146,9 @@
 Region& Region::orSelf(const Region& rhs) {
     return operationSelf(rhs, op_or);
 }
+Region& Region::xorSelf(const Region& rhs) {
+    return operationSelf(rhs, op_xor);
+}
 Region& Region::andSelf(const Region& rhs) {
     return operationSelf(rhs, op_and);
 }
@@ -165,6 +171,9 @@
 const Region Region::merge(const Rect& rhs) const {
     return operation(rhs, op_or);
 }
+const Region Region::mergeExclusive(const Rect& rhs) const {
+    return operation(rhs, op_xor);
+}
 const Region Region::intersect(const Rect& rhs) const {
     return operation(rhs, op_and);
 }
@@ -182,6 +191,9 @@
 const Region Region::merge(const Region& rhs) const {
     return operation(rhs, op_or);
 }
+const Region Region::mergeExclusive(const Region& rhs) const {
+    return operation(rhs, op_xor);
+}
 const Region Region::intersect(const Region& rhs) const {
     return operation(rhs, op_and);
 }
@@ -205,6 +217,9 @@
 Region& Region::orSelf(const Region& rhs, int dx, int dy) {
     return operationSelf(rhs, dx, dy, op_or);
 }
+Region& Region::xorSelf(const Region& rhs, int dx, int dy) {
+    return operationSelf(rhs, dx, dy, op_xor);
+}
 Region& Region::andSelf(const Region& rhs, int dx, int dy) {
     return operationSelf(rhs, dx, dy, op_and);
 }
@@ -222,6 +237,9 @@
 const Region Region::merge(const Region& rhs, int dx, int dy) const {
     return operation(rhs, dx, dy, op_or);
 }
+const Region Region::mergeExclusive(const Region& rhs, int dx, int dy) const {
+    return operation(rhs, dx, dy, op_xor);
+}
 const Region Region::intersect(const Region& rhs, int dx, int dy) const {
     return operation(rhs, dx, dy, op_and);
 }
@@ -421,6 +439,7 @@
     SkRegion::Op sk_op;
     switch (op) {
         case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break;
+        case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break;
         case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break;
         case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break;
     }
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index 77b8424..ecb455a 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -23,9 +23,4 @@
 
 LOCAL_PACKAGE_NAME := AccessoryChat
 
-LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory
-
-# Force an old SDK version to make sure we aren't using newer UsbManager APIs
-LOCAL_SDK_VERSION := 8
-
 include $(BUILD_PACKAGE)
diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
index 802b715..6667eba 100644
--- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml
+++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml
@@ -17,8 +17,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.accessorychat">
 
+    <uses-feature android:name="android.hardware.usb.accessory" />
+
     <application android:label="Accessory Chat">
-        <uses-library android:name="com.android.future.usb.accessory" />
 
         <activity android:name="AccessoryChat" android:label="Accessory Chat">
             <intent-filter>
@@ -35,5 +36,5 @@
                 android:resource="@xml/accessory_filter" />
         </activity>
     </application>
-    <uses-sdk android:minSdkVersion="10" />
+    <uses-sdk android:minSdkVersion="12" />
 </manifest>
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
index 85b52dd..06b477f 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
+++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c
@@ -98,7 +98,7 @@
     vendorId = usb_device_get_vendor_id(device);
     productId = usb_device_get_product_id(device);
 
-    if (vendorId == 0x18D1 || vendorId == 0x22B8) {
+    if (vendorId == 0x18D1 || vendorId == 0x22B8 || vendorId == 0x04e8) {
         if (!sDevice && (productId == 0x2D00 || productId == 0x2D01)) {
             struct usb_descriptor_header* desc;
             struct usb_descriptor_iter iter;
diff --git a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
index c3f4fa3..bf0cef0 100644
--- a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
+++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java
@@ -33,8 +33,8 @@
 import android.widget.EditText;
 import android.widget.TextView;
 
-import com.android.future.usb.UsbAccessory;
-import com.android.future.usb.UsbManager;
+import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbAccessory;
 
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -64,9 +64,11 @@
         public void onReceive(Context context, Intent intent) {
             if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
                 synchronized (this) {
-                    UsbAccessory accessory = UsbManager.getAccessory(intent);
+                    UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
                     if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
-                        openAccessory(accessory);
+                        if (accessory != null) {
+                            openAccessory(accessory);
+                        }
                     } else {
                         Log.d(TAG, "permission denied for accessory " + accessory);
                     }
@@ -80,7 +82,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mUsbManager = UsbManager.getInstance(this);
+        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
         mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
         IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
         registerReceiver(mUsbReceiver, filter);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 9dc9cef..69ca58b 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1150,9 +1150,44 @@
         }
     }
 
+    static class MediaBulkDeleter {
+        StringBuilder idList = new StringBuilder();
+        IContentProvider mProvider;
+        Uri mBaseUri;
+
+        public MediaBulkDeleter(IContentProvider provider, Uri baseUri) {
+            mProvider = provider;
+            mBaseUri = baseUri;
+        }
+
+        public void delete(long id) throws RemoteException {
+            if (idList.length() != 0) {
+                idList.append(",");
+            }
+            idList.append(id);
+            if (idList.length() > 1024) {
+                flush();
+            }
+        }
+        public void flush() throws RemoteException {
+            int numrows = mProvider.delete(mBaseUri, MediaStore.MediaColumns._ID + " IN (" +
+                    idList.toString() + ")", null);
+            //Log.i("@@@@@@@@@", "rows deleted: " + numrows);
+            idList.setLength(0);
+        }
+    }
+
     private void postscan(String[] directories) throws RemoteException {
         Iterator<FileCacheEntry> iterator = mFileCache.values().iterator();
 
+        // Tell the provider to not delete the file.
+        // If the file is truly gone the delete is unnecessary, and we want to avoid
+        // accidentally deleting files that are really there (this may happen if the
+        // filesystem is mounted and unmounted while the scanner is running).
+        Uri.Builder builder = mFilesUri.buildUpon();
+        builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false");
+        MediaBulkDeleter deleter = new MediaBulkDeleter(mMediaProvider, builder.build());
+
         while (iterator.hasNext()) {
             FileCacheEntry entry = iterator.next();
             String path = entry.mPath;
@@ -1176,15 +1211,6 @@
             }
 
             if (fileMissing) {
-                // Tell the provider to not delete the file.
-                // If the file is truly gone the delete is unnecessary, and we want to avoid
-                // accidentally deleting files that are really there (this may happen if the
-                // filesystem is mounted and unmounted while the scanner is running).
-                Uri.Builder builder = mFilesUri.buildUpon();
-                builder.appendEncodedPath(String.valueOf(entry.mRowId));
-                builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false");
-                Uri missingUri = builder.build();
-
                 // do not delete missing playlists, since they may have been modified by the user.
                 // the user can delete them in the media player instead.
                 // instead, clear the path and lastModified fields in the row
@@ -1192,15 +1218,17 @@
                 int fileType = (mediaFileType == null ? 0 : mediaFileType.fileType);
 
                 if (!MediaFile.isPlayListFileType(fileType)) {
-                    mMediaProvider.delete(missingUri, null, null);
+                    deleter.delete(entry.mRowId);
                     iterator.remove();
                     if (entry.mPath.toLowerCase(Locale.US).endsWith("/.nomedia")) {
+                        deleter.flush();
                         File f = new File(path);
                         mMediaProvider.call(MediaStore.UNHIDE_CALL, f.getParent(), null);
                     }
                 }
             }
         }
+        deleter.flush();
 
         // handle playlists last, after we know what media files are on the storage.
         if (mProcessPlaylists) {
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index 9f6599f..59cd9e3 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -53,8 +53,8 @@
 static lib_entry_t *getLibrary(const char *path);
 static void resetEffectEnumeration();
 static uint32_t updateNumEffects();
-static int findEffect(effect_uuid_t *type,
-               effect_uuid_t *uuid,
+static int findEffect(const effect_uuid_t *type,
+               const effect_uuid_t *uuid,
                lib_entry_t **lib,
                effect_descriptor_t **desc);
 static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len);
@@ -236,7 +236,7 @@
     return ret;
 }
 
-int EffectGetDescriptor(effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
+int EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
 {
     lib_entry_t *l = NULL;
     effect_descriptor_t *d = NULL;
@@ -257,7 +257,7 @@
     return ret;
 }
 
-int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
+int EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
 {
     list_elem_t *e = gLibraryList;
     lib_entry_t *l = NULL;
@@ -372,7 +372,7 @@
     return ret;
 }
 
-int EffectIsNullUuid(effect_uuid_t *uuid)
+int EffectIsNullUuid(const effect_uuid_t *uuid)
 {
     if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
         return 0;
@@ -628,8 +628,8 @@
     return cnt;
 }
 
-int findEffect(effect_uuid_t *type,
-               effect_uuid_t *uuid,
+int findEffect(const effect_uuid_t *type,
+               const effect_uuid_t *uuid,
                lib_entry_t **lib,
                effect_descriptor_t **desc)
 {
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 108d36a..3714283 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -195,7 +195,7 @@
     return 0;
 }     /* end EffectQueryEffect */
 
-extern "C" int EffectCreate(effect_uuid_t       *uuid,
+extern "C" int EffectCreate(const effect_uuid_t *uuid,
                             int32_t             sessionId,
                             int32_t             ioId,
                             effect_handle_t  *pHandle){
@@ -471,7 +471,7 @@
 
 } /* end EffectRelease */
 
-extern "C" int EffectGetDescriptor(effect_uuid_t       *uuid,
+extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
                                    effect_descriptor_t *pDescriptor) {
     const effect_descriptor_t *desc = NULL;
 
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 09cd5cc..358357e 100755
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -210,7 +210,7 @@
     return 0;
 }     /* end EffectQueryEffect */
 
-extern "C" int EffectCreate(effect_uuid_t       *uuid,
+extern "C" int EffectCreate(const effect_uuid_t *uuid,
                             int32_t             sessionId,
                             int32_t             ioId,
                             effect_handle_t  *pHandle){
@@ -317,7 +317,7 @@
     return 0;
 } /* end EffectRelease */
 
-extern "C" int EffectGetDescriptor(effect_uuid_t       *uuid,
+extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
                                    effect_descriptor_t *pDescriptor) {
     int i;
     int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 9fd6764..4d94a75 100755
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -1072,7 +1072,7 @@
     return sInitStatus;
 }
 
-const effect_descriptor_t *PreProc_GetDescriptor(effect_uuid_t *uuid)
+const effect_descriptor_t *PreProc_GetDescriptor(const effect_uuid_t *uuid)
 {
     size_t i;
     for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
@@ -1568,7 +1568,7 @@
     return 0;
 }
 
-int PreProcessingLib_Create(effect_uuid_t       *uuid,
+int PreProcessingLib_Create(const effect_uuid_t *uuid,
                             int32_t             sessionId,
                             int32_t             ioId,
                             effect_handle_t  *pInterface)
@@ -1620,7 +1620,7 @@
     return Session_ReleaseEffect(fx->session, fx);
 }
 
-int PreProcessingLib_GetDescriptor(effect_uuid_t       *uuid,
+int PreProcessingLib_GetDescriptor(const effect_uuid_t *uuid,
                                    effect_descriptor_t *pDescriptor) {
 
     if (pDescriptor == NULL || uuid == NULL){
diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp
index 5241660..35a4a61 100644
--- a/media/libeffects/testlibs/EffectEqualizer.cpp
+++ b/media/libeffects/testlibs/EffectEqualizer.cpp
@@ -140,7 +140,7 @@
     return 0;
 } /* end EffectQueryNext */
 
-extern "C" int EffectCreate(effect_uuid_t *uuid,
+extern "C" int EffectCreate(const effect_uuid_t *uuid,
                             int32_t sessionId,
                             int32_t ioId,
                             effect_handle_t *pHandle) {
@@ -195,7 +195,7 @@
     return 0;
 } /* end EffectRelease */
 
-extern "C" int EffectGetDescriptor(effect_uuid_t       *uuid,
+extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
                                    effect_descriptor_t *pDescriptor) {
 
     if (pDescriptor == NULL || uuid == NULL){
diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c
index ebb72c1..8351712 100644
--- a/media/libeffects/testlibs/EffectReverb.c
+++ b/media/libeffects/testlibs/EffectReverb.c
@@ -111,7 +111,7 @@
     return 0;
 }
 
-int EffectCreate(effect_uuid_t *uuid,
+int EffectCreate(const effect_uuid_t *uuid,
         int32_t sessionId,
         int32_t ioId,
         effect_handle_t *pHandle) {
@@ -182,7 +182,7 @@
     return 0;
 }
 
-int EffectGetDescriptor(effect_uuid_t       *uuid,
+int EffectGetDescriptor(const effect_uuid_t *uuid,
                         effect_descriptor_t *pDescriptor) {
     int i;
     int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h
index 5137074..1fb14a7 100644
--- a/media/libeffects/testlibs/EffectReverb.h
+++ b/media/libeffects/testlibs/EffectReverb.h
@@ -303,12 +303,12 @@
 int EffectQueryNumberEffects(uint32_t *pNumEffects);
 int EffectQueryEffect(uint32_t index,
                       effect_descriptor_t *pDescriptor);
-int EffectCreate(effect_uuid_t *effectUID,
+int EffectCreate(const effect_uuid_t *effectUID,
                  int32_t sessionId,
                  int32_t ioId,
                  effect_handle_t *pHandle);
 int EffectRelease(effect_handle_t handle);
-int EffectGetDescriptor(effect_uuid_t       *uuid,
+int EffectGetDescriptor(const effect_uuid_t *uuid,
                         effect_descriptor_t *pDescriptor);
 
 static int Reverb_Process(effect_handle_t self,
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 5d70a9b..51c8b68 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -190,7 +190,7 @@
     return 0;
 }
 
-int VisualizerLib_Create(effect_uuid_t *uuid,
+int VisualizerLib_Create(const effect_uuid_t *uuid,
                          int32_t sessionId,
                          int32_t ioId,
                          effect_handle_t *pHandle) {
@@ -240,7 +240,7 @@
     return 0;
 }
 
-int VisualizerLib_GetDescriptor(effect_uuid_t       *uuid,
+int VisualizerLib_GetDescriptor(const effect_uuid_t *uuid,
                                 effect_descriptor_t *pDescriptor) {
 
     if (pDescriptor == NULL || uuid == NULL){
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index a242846..6549ce6 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -412,7 +412,8 @@
     return af->queryEffect(index, descriptor);
 }
 
-status_t AudioEffect::getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor)
+status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid,
+        effect_descriptor_t *descriptor) /*const*/
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
     if (af == 0) return PERMISSION_DENIED;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index c96bc76..b74b3e3 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -293,7 +293,6 @@
                 return WOULD_BLOCK;
             }
         }
-        t->mLock.lock();
      }
 
     AutoMutex lock(mLock);
@@ -334,10 +333,6 @@
         }
     }
 
-    if (t != 0) {
-        t->mLock.unlock();
-    }
-
     return ret;
 }
 
@@ -347,10 +342,6 @@
 
     ALOGV("stop");
 
-    if (t != 0) {
-        t->mLock.lock();
-    }
-
     AutoMutex lock(mLock);
     if (mActive == 1) {
         mActive = 0;
@@ -367,10 +358,6 @@
         }
     }
 
-    if (t != 0) {
-        t->mLock.unlock();
-    }
-
     return NO_ERROR;
 }
 
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 110a294..ec4c044 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -121,7 +121,8 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value, int output)
+status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value,
+        audio_io_handle_t output)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -139,7 +140,8 @@
     return NO_ERROR;
 }
 
-status_t AudioSystem::getStreamVolume(audio_stream_type_t stream, float* volume, int output)
+status_t AudioSystem::getStreamVolume(audio_stream_type_t stream, float* volume,
+        audio_io_handle_t output)
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -402,7 +404,8 @@
     ALOGW("AudioFlinger server died!");
 }
 
-void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, int ioHandle, void *param2) {
+void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle_t ioHandle,
+        void *param2) {
     ALOGV("ioConfigChanged() event %d", event);
     OutputDescriptor *desc;
     audio_stream_type_t stream;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 8c33f41..087d7b2 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -345,7 +345,6 @@
                 return;
             }
         }
-        t->mLock.lock();
      }
 
     AutoMutex lock(mLock);
@@ -396,9 +395,6 @@
         }
     }
 
-    if (t != 0) {
-        t->mLock.unlock();
-    }
 }
 
 void AudioTrack::stop()
@@ -406,9 +402,6 @@
     sp<AudioTrackThread> t = mAudioTrackThread;
 
     ALOGV("stop %p", this);
-    if (t != 0) {
-        t->mLock.lock();
-    }
 
     AutoMutex lock(mLock);
     if (mActive) {
@@ -434,9 +427,6 @@
         }
     }
 
-    if (t != 0) {
-        t->mLock.unlock();
-    }
 }
 
 bool AudioTrack::stopped() const
@@ -506,7 +496,7 @@
     return NO_ERROR;
 }
 
-void AudioTrack::getVolume(float* left, float* right)
+void AudioTrack::getVolume(float* left, float* right) const
 {
     if (left != NULL) {
         *left  = mVolume[LEFT];
@@ -531,7 +521,7 @@
     return NO_ERROR;
 }
 
-void AudioTrack::getAuxEffectSendLevel(float* level)
+void AudioTrack::getAuxEffectSendLevel(float* level) const
 {
     if (level != NULL) {
         *level  = mSendLevel;
@@ -553,7 +543,7 @@
     return NO_ERROR;
 }
 
-uint32_t AudioTrack::getSampleRate()
+uint32_t AudioTrack::getSampleRate() const
 {
     AutoMutex lock(mLock);
     return mCblk->sampleRate;
@@ -601,7 +591,7 @@
     return NO_ERROR;
 }
 
-status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount)
+status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) const
 {
     AutoMutex lock(mLock);
     if (loopStart != NULL) {
@@ -631,7 +621,7 @@
     return NO_ERROR;
 }
 
-status_t AudioTrack::getMarkerPosition(uint32_t *marker)
+status_t AudioTrack::getMarkerPosition(uint32_t *marker) const
 {
     if (marker == NULL) return BAD_VALUE;
 
@@ -652,7 +642,7 @@
     return NO_ERROR;
 }
 
-status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod)
+status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const
 {
     if (updatePeriod == NULL) return BAD_VALUE;
 
@@ -712,7 +702,7 @@
             mCblk->sampleRate, mFormat, mChannelMask, (audio_policy_output_flags_t)mFlags);
 }
 
-int AudioTrack::getSessionId()
+int AudioTrack::getSessionId() const
 {
     return mSessionId;
 }
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index fc5520f..c3252e7 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -89,7 +89,7 @@
                                 int frameCount,
                                 uint32_t flags,
                                 const sp<IMemory>& sharedBuffer,
-                                int output,
+                                audio_io_handle_t output,
                                 int *sessionId,
                                 status_t *status)
     {
@@ -104,7 +104,7 @@
         data.writeInt32(frameCount);
         data.writeInt32(flags);
         data.writeStrongBinder(sharedBuffer->asBinder());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         int lSessionId = 0;
         if (sessionId != NULL) {
             lSessionId = *sessionId;
@@ -129,7 +129,7 @@
 
     virtual sp<IAudioRecord> openRecord(
                                 pid_t pid,
-                                int input,
+                                audio_io_handle_t input,
                                 uint32_t sampleRate,
                                 audio_format_t format,
                                 uint32_t channelMask,
@@ -142,7 +142,7 @@
         sp<IAudioRecord> record;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(pid);
-        data.writeInt32(input);
+        data.writeInt32((int32_t) input);
         data.writeInt32(sampleRate);
         data.writeInt32(format);
         data.writeInt32(channelMask);
@@ -170,47 +170,47 @@
         return record;
     }
 
-    virtual uint32_t sampleRate(int output) const
+    virtual uint32_t sampleRate(audio_io_handle_t output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(SAMPLE_RATE, data, &reply);
         return reply.readInt32();
     }
 
-    virtual int channelCount(int output) const
+    virtual int channelCount(audio_io_handle_t output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(CHANNEL_COUNT, data, &reply);
         return reply.readInt32();
     }
 
-    virtual audio_format_t format(int output) const
+    virtual audio_format_t format(audio_io_handle_t output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(FORMAT, data, &reply);
         return (audio_format_t) reply.readInt32();
     }
 
-    virtual size_t frameCount(int output) const
+    virtual size_t frameCount(audio_io_handle_t output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(FRAME_COUNT, data, &reply);
         return reply.readInt32();
     }
 
-    virtual uint32_t latency(int output) const
+    virtual uint32_t latency(audio_io_handle_t output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(LATENCY, data, &reply);
         return reply.readInt32();
     }
@@ -249,13 +249,14 @@
         return reply.readInt32();
     }
 
-    virtual status_t setStreamVolume(audio_stream_type_t stream, float value, int output)
+    virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
+            audio_io_handle_t output)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32((int32_t) stream);
         data.writeFloat(value);
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(SET_STREAM_VOLUME, data, &reply);
         return reply.readInt32();
     }
@@ -270,12 +271,12 @@
         return reply.readInt32();
     }
 
-    virtual float streamVolume(audio_stream_type_t stream, int output) const
+    virtual float streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32((int32_t) stream);
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(STREAM_VOLUME, data, &reply);
         return reply.readFloat();
     }
@@ -315,21 +316,21 @@
         return reply.readInt32();
     }
 
-    virtual status_t setParameters(int ioHandle, const String8& keyValuePairs)
+    virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(ioHandle);
+        data.writeInt32((int32_t) ioHandle);
         data.writeString8(keyValuePairs);
         remote()->transact(SET_PARAMETERS, data, &reply);
         return reply.readInt32();
     }
 
-    virtual String8 getParameters(int ioHandle, const String8& keys)
+    virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(ioHandle);
+        data.writeInt32((int32_t) ioHandle);
         data.writeString8(keys);
         remote()->transact(GET_PARAMETERS, data, &reply);
         return reply.readString8();
@@ -343,7 +344,7 @@
         remote()->transact(REGISTER_CLIENT, data, &reply);
     }
 
-    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount)
+    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -354,7 +355,7 @@
         return reply.readInt32();
     }
 
-    virtual int openOutput(uint32_t *pDevices,
+    virtual audio_io_handle_t openOutput(uint32_t *pDevices,
                             uint32_t *pSamplingRate,
                             audio_format_t *pFormat,
                             uint32_t *pChannels,
@@ -376,8 +377,8 @@
         data.writeInt32(latency);
         data.writeInt32(flags);
         remote()->transact(OPEN_OUTPUT, data, &reply);
-        int  output = reply.readInt32();
-        ALOGV("openOutput() returned output, %p", output);
+        audio_io_handle_t output = (audio_io_handle_t) reply.readInt32();
+        ALOGV("openOutput() returned output, %d", output);
         devices = reply.readInt32();
         if (pDevices) *pDevices = devices;
         samplingRate = reply.readInt32();
@@ -391,44 +392,45 @@
         return output;
     }
 
-    virtual int openDuplicateOutput(int output1, int output2)
+    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+            audio_io_handle_t output2)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output1);
-        data.writeInt32(output2);
+        data.writeInt32((int32_t) output1);
+        data.writeInt32((int32_t) output2);
         remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply);
-        return reply.readInt32();
+        return (audio_io_handle_t) reply.readInt32();
     }
 
-    virtual status_t closeOutput(int output)
+    virtual status_t closeOutput(audio_io_handle_t output)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(CLOSE_OUTPUT, data, &reply);
         return reply.readInt32();
     }
 
-    virtual status_t suspendOutput(int output)
+    virtual status_t suspendOutput(audio_io_handle_t output)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(SUSPEND_OUTPUT, data, &reply);
         return reply.readInt32();
     }
 
-    virtual status_t restoreOutput(int output)
+    virtual status_t restoreOutput(audio_io_handle_t output)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(RESTORE_OUTPUT, data, &reply);
         return reply.readInt32();
     }
 
-    virtual int openInput(uint32_t *pDevices,
+    virtual audio_io_handle_t openInput(uint32_t *pDevices,
                             uint32_t *pSamplingRate,
                             audio_format_t *pFormat,
                             uint32_t *pChannels,
@@ -447,7 +449,7 @@
         data.writeInt32(channels);
         data.writeInt32((int32_t) acoustics);
         remote()->transact(OPEN_INPUT, data, &reply);
-        int input = reply.readInt32();
+        audio_io_handle_t input = (audio_io_handle_t) reply.readInt32();
         devices = reply.readInt32();
         if (pDevices) *pDevices = devices;
         samplingRate = reply.readInt32();
@@ -468,12 +470,12 @@
         return reply.readInt32();
     }
 
-    virtual status_t setStreamOutput(audio_stream_type_t stream, int output)
+    virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32((int32_t) stream);
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(SET_STREAM_OUTPUT, data, &reply);
         return reply.readInt32();
     }
@@ -487,11 +489,12 @@
         return reply.readInt32();
     }
 
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output)
+    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+            audio_io_handle_t output) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         remote()->transact(GET_RENDER_POSITION, data, &reply);
         status_t status = reply.readInt32();
         if (status == NO_ERROR) {
@@ -507,11 +510,11 @@
         return status;
     }
 
-    virtual unsigned int getInputFramesLost(int ioHandle)
+    virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        data.writeInt32(ioHandle);
+        data.writeInt32((int32_t) ioHandle);
         remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
         return reply.readInt32();
     }
@@ -544,7 +547,7 @@
         remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply);
     }
 
-    virtual status_t queryNumberEffects(uint32_t *numEffects)
+    virtual status_t queryNumberEffects(uint32_t *numEffects) const
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -562,7 +565,7 @@
         return NO_ERROR;
     }
 
-    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
+    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const
     {
         if (pDescriptor == NULL) {
             return BAD_VALUE;
@@ -582,7 +585,8 @@
         return NO_ERROR;
     }
 
-    virtual status_t getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *pDescriptor)
+    virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
+            effect_descriptor_t *pDescriptor) const
     {
         if (pUuid == NULL || pDescriptor == NULL) {
             return BAD_VALUE;
@@ -606,7 +610,7 @@
                                     effect_descriptor_t *pDesc,
                                     const sp<IEffectClient>& client,
                                     int32_t priority,
-                                    int output,
+                                    audio_io_handle_t output,
                                     int sessionId,
                                     status_t *status,
                                     int *id,
@@ -627,7 +631,7 @@
         data.write(pDesc, sizeof(effect_descriptor_t));
         data.writeStrongBinder(client->asBinder());
         data.writeInt32(priority);
-        data.writeInt32(output);
+        data.writeInt32((int32_t) output);
         data.writeInt32(sessionId);
 
         status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);
@@ -653,13 +657,14 @@
         return effect;
     }
 
-    virtual status_t moveEffects(int session, int srcOutput, int dstOutput)
+    virtual status_t moveEffects(int session, audio_io_handle_t srcOutput,
+            audio_io_handle_t dstOutput)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(session);
-        data.writeInt32(srcOutput);
-        data.writeInt32(dstOutput);
+        data.writeInt32((int32_t) srcOutput);
+        data.writeInt32((int32_t) dstOutput);
         remote()->transact(MOVE_EFFECTS, data, &reply);
         return reply.readInt32();
     }
@@ -683,7 +688,7 @@
             size_t bufferCount = data.readInt32();
             uint32_t flags = data.readInt32();
             sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
-            int output = data.readInt32();
+            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
             int sessionId = data.readInt32();
             status_t status;
             sp<IAudioTrack> track = createTrack(pid,
@@ -697,7 +702,7 @@
         case OPEN_RECORD: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             pid_t pid = data.readInt32();
-            int input = data.readInt32();
+            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();
@@ -714,27 +719,27 @@
         } break;
         case SAMPLE_RATE: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( sampleRate(data.readInt32()) );
+            reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
         case CHANNEL_COUNT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( channelCount(data.readInt32()) );
+            reply->writeInt32( channelCount((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
         case FORMAT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( format(data.readInt32()) );
+            reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
         case FRAME_COUNT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( frameCount(data.readInt32()) );
+            reply->writeInt32( frameCount((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
         case LATENCY: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32( latency(data.readInt32()) );
+            reply->writeInt32( latency((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
          case SET_MASTER_VOLUME: {
@@ -761,7 +766,7 @@
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             int stream = data.readInt32();
             float volume = data.readFloat();
-            int output = data.readInt32();
+            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
             reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) );
             return NO_ERROR;
         } break;
@@ -803,14 +808,14 @@
         } break;
         case SET_PARAMETERS: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int ioHandle = data.readInt32();
+            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
             String8 keyValuePairs(data.readString8());
             reply->writeInt32(setParameters(ioHandle, keyValuePairs));
             return NO_ERROR;
          } break;
         case GET_PARAMETERS: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int ioHandle = data.readInt32();
+            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
             String8 keys(data.readString8());
             reply->writeString8(getParameters(ioHandle, keys));
             return NO_ERROR;
@@ -838,14 +843,14 @@
             uint32_t channels = data.readInt32();
             uint32_t latency = data.readInt32();
             uint32_t flags = data.readInt32();
-            int output = openOutput(&devices,
+            audio_io_handle_t output = openOutput(&devices,
                                      &samplingRate,
                                      &format,
                                      &channels,
                                      &latency,
                                      flags);
             ALOGV("OPEN_OUTPUT output, %p", output);
-            reply->writeInt32(output);
+            reply->writeInt32((int32_t) output);
             reply->writeInt32(devices);
             reply->writeInt32(samplingRate);
             reply->writeInt32(format);
@@ -855,24 +860,24 @@
         } break;
         case OPEN_DUPLICATE_OUTPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int output1 = data.readInt32();
-            int output2 = data.readInt32();
-            reply->writeInt32(openDuplicateOutput(output1, output2));
+            audio_io_handle_t output1 = (audio_io_handle_t) data.readInt32();
+            audio_io_handle_t output2 = (audio_io_handle_t) data.readInt32();
+            reply->writeInt32((int32_t) openDuplicateOutput(output1, output2));
             return NO_ERROR;
         } break;
         case CLOSE_OUTPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(closeOutput(data.readInt32()));
+            reply->writeInt32(closeOutput((audio_io_handle_t) data.readInt32()));
             return NO_ERROR;
         } break;
         case SUSPEND_OUTPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(suspendOutput(data.readInt32()));
+            reply->writeInt32(suspendOutput((audio_io_handle_t) data.readInt32()));
             return NO_ERROR;
         } break;
         case RESTORE_OUTPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(restoreOutput(data.readInt32()));
+            reply->writeInt32(restoreOutput((audio_io_handle_t) data.readInt32()));
             return NO_ERROR;
         } break;
         case OPEN_INPUT: {
@@ -883,12 +888,12 @@
             uint32_t channels = data.readInt32();
             audio_in_acoustics_t acoustics = (audio_in_acoustics_t) data.readInt32();
 
-            int input = openInput(&devices,
+            audio_io_handle_t input = openInput(&devices,
                                      &samplingRate,
                                      &format,
                                      &channels,
                                      acoustics);
-            reply->writeInt32(input);
+            reply->writeInt32((int32_t) input);
             reply->writeInt32(devices);
             reply->writeInt32(samplingRate);
             reply->writeInt32(format);
@@ -897,13 +902,13 @@
         } break;
         case CLOSE_INPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            reply->writeInt32(closeInput(data.readInt32()));
+            reply->writeInt32(closeInput((audio_io_handle_t) data.readInt32()));
             return NO_ERROR;
         } break;
         case SET_STREAM_OUTPUT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             uint32_t stream = data.readInt32();
-            int output = data.readInt32();
+            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
             reply->writeInt32(setStreamOutput((audio_stream_type_t) stream, output));
             return NO_ERROR;
         } break;
@@ -915,7 +920,7 @@
         } break;
         case GET_RENDER_POSITION: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int output = data.readInt32();
+            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
             uint32_t halFrames;
             uint32_t dspFrames;
             status_t status = getRenderPosition(&halFrames, &dspFrames, output);
@@ -928,7 +933,7 @@
         }
         case GET_INPUT_FRAMES_LOST: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-            int ioHandle = data.readInt32();
+            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
             reply->writeInt32(getInputFramesLost(ioHandle));
             return NO_ERROR;
         } break;
@@ -988,7 +993,7 @@
             data.read(&desc, sizeof(effect_descriptor_t));
             sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
             int32_t priority = data.readInt32();
-            int output = data.readInt32();
+            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
             int sessionId = data.readInt32();
             status_t status;
             int id;
@@ -1005,8 +1010,8 @@
         case MOVE_EFFECTS: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             int session = data.readInt32();
-            int srcOutput = data.readInt32();
-            int dstOutput = data.readInt32();
+            audio_io_handle_t srcOutput = (audio_io_handle_t) data.readInt32();
+            audio_io_handle_t dstOutput = (audio_io_handle_t) data.readInt32();
             reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
             return NO_ERROR;
         } break;
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp
index 9458bc0..ce28b33 100644
--- a/media/libmedia/IAudioFlingerClient.cpp
+++ b/media/libmedia/IAudioFlingerClient.cpp
@@ -39,12 +39,12 @@
     {
     }
 
-    void ioConfigChanged(int event, int ioHandle, void *param2)
+    void ioConfigChanged(int event, audio_io_handle_t ioHandle, void *param2)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlingerClient::getInterfaceDescriptor());
         data.writeInt32(event);
-        data.writeInt32(ioHandle);
+        data.writeInt32((int32_t) ioHandle);
         if (event == AudioSystem::STREAM_CONFIG_CHANGED) {
             uint32_t stream = *(uint32_t *)param2;
             ALOGV("ioConfigChanged stream %d", stream);
@@ -72,7 +72,7 @@
     case IO_CONFIG_CHANGED: {
             CHECK_INTERFACE(IAudioFlingerClient, data, reply);
             int event = data.readInt32();
-            int ioHandle = data.readInt32();
+            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
             void *param2 = NULL;
             AudioSystem::OutputDescriptor desc;
             uint32_t stream;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f71ba0a..d05e9d9 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -245,7 +245,6 @@
         audio_hw_device_t *dev = mAudioHwDevs[i];
         audio_hw_device_close(dev);
     }
-    mAudioHwDevs.clear();
 }
 
 audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(uint32_t devices)
@@ -384,7 +383,7 @@
         int frameCount,
         uint32_t flags,
         const sp<IMemory>& sharedBuffer,
-        int output,
+        audio_io_handle_t output,
         int *sessionId,
         status_t *status)
 {
@@ -477,7 +476,7 @@
     return trackHandle;
 }
 
-uint32_t AudioFlinger::sampleRate(int output) const
+uint32_t AudioFlinger::sampleRate(audio_io_handle_t output) const
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -488,7 +487,7 @@
     return thread->sampleRate();
 }
 
-int AudioFlinger::channelCount(int output) const
+int AudioFlinger::channelCount(audio_io_handle_t output) const
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -499,7 +498,7 @@
     return thread->channelCount();
 }
 
-audio_format_t AudioFlinger::format(int output) const
+audio_format_t AudioFlinger::format(audio_io_handle_t output) const
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -510,7 +509,7 @@
     return thread->format();
 }
 
-size_t AudioFlinger::frameCount(int output) const
+size_t AudioFlinger::frameCount(audio_io_handle_t output) const
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -521,7 +520,7 @@
     return thread->frameCount();
 }
 
-uint32_t AudioFlinger::latency(int output) const
+uint32_t AudioFlinger::latency(audio_io_handle_t output) const
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -655,7 +654,8 @@
     return masterMute_l();
 }
 
-status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, int output)
+status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
+        audio_io_handle_t output)
 {
     // check calling permissions
     if (!settingsAllowed()) {
@@ -710,7 +710,7 @@
     return NO_ERROR;
 }
 
-float AudioFlinger::streamVolume(audio_stream_type_t stream, int output) const
+float AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
 {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
         return 0.0f;
@@ -740,7 +740,7 @@
     return mStreamTypes[stream].mute;
 }
 
-status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
+status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
 {
     status_t result;
 
@@ -809,14 +809,13 @@
             }
         }
     }
-    if (thread != NULL) {
-        result = thread->setParameters(keyValuePairs);
-        return result;
+    if (thread != 0) {
+        return thread->setParameters(keyValuePairs);
     }
     return BAD_VALUE;
 }
 
-String8 AudioFlinger::getParameters(int ioHandle, const String8& keys)
+String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
 {
 //    ALOGV("getParameters() io %d, keys %s, tid %d, calling tid %d",
 //            ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
@@ -846,7 +845,7 @@
     return String8("");
 }
 
-size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount)
+size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const
 {
     status_t ret = initCheck();
     if (ret != NO_ERROR) {
@@ -856,7 +855,7 @@
     return mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, sampleRate, format, channelCount);
 }
 
-unsigned int AudioFlinger::getInputFramesLost(int ioHandle)
+unsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
 {
     if (ioHandle == 0) {
         return 0;
@@ -891,7 +890,8 @@
     return ret;
 }
 
-status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output)
+status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+        audio_io_handle_t output) const
 {
     status_t status;
 
@@ -910,7 +910,7 @@
 
     Mutex::Autolock _l(mLock);
 
-    int pid = IPCThreadState::self()->getCallingPid();
+    pid_t pid = IPCThreadState::self()->getCallingPid();
     if (mNotificationClients.indexOfKey(pid) < 0) {
         sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                             client,
@@ -966,7 +966,7 @@
 }
 
 // audioConfigChanged_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2)
+void AudioFlinger::audioConfigChanged_l(int event, audio_io_handle_t ioHandle, void *param2)
 {
     size_t size = mNotificationClients.size();
     for (size_t i = 0; i < size; i++) {
@@ -985,8 +985,8 @@
 
 // ----------------------------------------------------------------------------
 
-AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device,
-        type_t type)
+AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
+        uint32_t device, type_t type)
     :   Thread(false),
         mType(type),
         mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0),
@@ -1027,26 +1027,6 @@
     requestExitAndWait();
 }
 
-uint32_t AudioFlinger::ThreadBase::sampleRate() const
-{
-    return mSampleRate;
-}
-
-int AudioFlinger::ThreadBase::channelCount() const
-{
-    return (int)mChannelCount;
-}
-
-audio_format_t AudioFlinger::ThreadBase::format() const
-{
-    return mFormat;
-}
-
-size_t AudioFlinger::ThreadBase::frameCount() const
-{
-    return mFrameCount;
-}
-
 status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
 {
     status_t status;
@@ -1248,8 +1228,7 @@
 void AudioFlinger::ThreadBase::setEffectSuspended_l(
         const effect_uuid_t *type, bool suspend, int sessionId)
 {
-    sp<EffectChain> chain;
-    chain = getEffectChain_l(sessionId);
+    sp<EffectChain> chain = getEffectChain_l(sessionId);
     if (chain != 0) {
         if (type != NULL) {
             chain->setEffectSuspended_l(type, suspend);
@@ -1377,7 +1356,7 @@
 
 AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
                                              AudioStreamOut* output,
-                                             int id,
+                                             audio_io_handle_t id,
                                              uint32_t device,
                                              type_t type)
     :   ThreadBase(audioFlinger, id, device, type),
@@ -1611,16 +1590,6 @@
     return NO_ERROR;
 }
 
-float AudioFlinger::PlaybackThread::masterVolume() const
-{
-    return mMasterVolume;
-}
-
-bool AudioFlinger::PlaybackThread::masterMute() const
-{
-    return mMasterMute;
-}
-
 status_t AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
 {
     mStreamTypes[stream].volume = value;
@@ -1853,7 +1822,7 @@
 // ----------------------------------------------------------------------------
 
 AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
-        int id, uint32_t device, type_t type)
+        audio_io_handle_t id, uint32_t device, type_t type)
     :   PlaybackThread(audioFlinger, output, id, device, type),
         mAudioMixer(new AudioMixer(mFrameCount, mSampleRate)),
         mPrevMixerStatus(MIXER_IDLE)
@@ -2520,7 +2489,8 @@
 }
 
 // ----------------------------------------------------------------------------
-AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
+AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
+        AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
     :   PlaybackThread(audioFlinger, output, id, device, DIRECT)
         // mLeftVolFloat, mRightVolFloat
         // mLeftVolShort, mRightVolShort
@@ -3002,7 +2972,7 @@
 // ----------------------------------------------------------------------------
 
 AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
-        AudioFlinger::MixerThread* mainThread, int id)
+        AudioFlinger::MixerThread* mainThread, audio_io_handle_t id)
     :   MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device(), DUPLICATING),
         mWaitTimeMs(UINT_MAX)
 {
@@ -3014,7 +2984,6 @@
     for (size_t i = 0; i < mOutputTracks.size(); i++) {
         mOutputTracks[i]->destroy();
     }
-    mOutputTracks.clear();
 }
 
 bool AudioFlinger::DuplicatingThread::threadLoop()
@@ -3206,7 +3175,7 @@
     mWaitTimeMs = UINT_MAX;
     for (size_t i = 0; i < mOutputTracks.size(); i++) {
         sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
-        if (strong != NULL) {
+        if (strong != 0) {
             uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
             if (waitTimeMs < mWaitTimeMs) {
                 mWaitTimeMs = waitTimeMs;
@@ -3259,7 +3228,6 @@
         // mBufferEnd
         mFrameCount(0),
         mState(IDLE),
-        mClientTid(-1),
         mFormat(format),
         mFlags(flags & ~SYSTEM_FLAGS_MASK),
         mSessionId(sessionId)
@@ -3324,15 +3292,19 @@
 AudioFlinger::ThreadBase::TrackBase::~TrackBase()
 {
     if (mCblk != NULL) {
-        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
-        if (mClient == NULL) {
+        if (mClient == 0) {
             delete mCblk;
+        } else {
+            mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
         }
     }
-    mCblkMemory.clear();            // and free the shared memory
-    if (mClient != NULL) {
+    mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
+    if (mClient != 0) {
         // Client destructor must run with AudioFlinger mutex locked
         Mutex::Autolock _l(mClient->audioFlinger()->mLock);
+        // If the client's reference count drops to zero, the associated destructor
+        // must run with AudioFlinger lock held. Thus the explicit clear() rather than
+        // relying on the automatic clear() at end of scope.
         mClient.clear();
     }
 }
@@ -3368,23 +3340,10 @@
     ALOGV("TrackBase::reset");
 }
 
-sp<IMemory> AudioFlinger::ThreadBase::TrackBase::getCblk() const
-{
-    return mCblkMemory;
-}
-
 int AudioFlinger::ThreadBase::TrackBase::sampleRate() const {
     return (int)mCblk->sampleRate;
 }
 
-int AudioFlinger::ThreadBase::TrackBase::channelCount() const {
-    return (const int)mChannelCount;
-}
-
-uint32_t AudioFlinger::ThreadBase::TrackBase::channelMask() const {
-    return mChannelMask;
-}
-
 void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
     audio_track_cblk_t* cblk = this->cblk();
     size_t frameSize = cblk->frameSize;
@@ -3486,7 +3445,7 @@
     uint32_t vlr = mCblk->getVolumeLR();
     snprintf(buffer, size, "   %05d %05d %03u %03u 0x%08x %05u   %04u %1d %1d %1d %05u %05u %05u  0x%08x 0x%08x 0x%08x 0x%08x\n",
             mName - AudioMixer::TRACK0,
-            (mClient == NULL) ? getpid() : mClient->pid(),
+            (mClient == 0) ? getpid() : mClient->pid(),
             mStreamType,
             mFormat,
             mChannelMask,
@@ -3813,7 +3772,7 @@
 void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
 {
     snprintf(buffer, size, "   %05d %03u 0x%08x %05d   %04u %01d %05u  %08x %08x\n",
-            (mClient == NULL) ? getpid() : mClient->pid(),
+            (mClient == 0) ? getpid() : mClient->pid(),
             mFormat,
             mChannelMask,
             mSessionId,
@@ -4160,7 +4119,7 @@
 
 sp<IAudioRecord> AudioFlinger::openRecord(
         pid_t pid,
-        int input,
+        audio_io_handle_t input,
         uint32_t sampleRate,
         audio_format_t format,
         uint32_t channelMask,
@@ -4277,7 +4236,7 @@
                                          AudioStreamIn *input,
                                          uint32_t sampleRate,
                                          uint32_t channels,
-                                         int id,
+                                         audio_io_handle_t id,
                                          uint32_t device) :
     ThreadBase(audioFlinger, id, device, RECORD),
     mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
@@ -4528,7 +4487,7 @@
         track = new RecordTrack(this, client, sampleRate,
                       format, channelMask, frameCount, flags, sessionId);
 
-        if (track->getCblk() == NULL) {
+        if (track->getCblk() == 0) {
             lStatus = NO_MEMORY;
             goto Exit;
         }
@@ -4631,7 +4590,6 @@
     const size_t SIZE = 256;
     char buffer[SIZE];
     String8 result;
-    pid_t pid = 0;
 
     snprintf(buffer, SIZE, "\nInput thread %p internals\n", this);
     result.append(buffer);
@@ -4938,7 +4896,7 @@
 
 // ----------------------------------------------------------------------------
 
-int AudioFlinger::openOutput(uint32_t *pDevices,
+audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
                                 uint32_t *pSamplingRate,
                                 audio_format_t *pFormat,
                                 uint32_t *pChannels,
@@ -4984,7 +4942,7 @@
     mHardwareStatus = AUDIO_HW_IDLE;
     if (outStream != NULL) {
         AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
-        int id = nextUniqueId();
+        audio_io_handle_t id = nextUniqueId();
 
         if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) ||
             (format != AUDIO_FORMAT_PCM_16_BIT) ||
@@ -5010,7 +4968,8 @@
     return 0;
 }
 
-int AudioFlinger::openDuplicateOutput(int output1, int output2)
+audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
+        audio_io_handle_t output2)
 {
     Mutex::Autolock _l(mLock);
     MixerThread *thread1 = checkMixerThread_l(output1);
@@ -5021,7 +4980,7 @@
         return 0;
     }
 
-    int id = nextUniqueId();
+    audio_io_handle_t id = nextUniqueId();
     DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
     thread->addOutputTrack(thread2);
     mPlaybackThreads.add(id, thread);
@@ -5030,7 +4989,7 @@
     return id;
 }
 
-status_t AudioFlinger::closeOutput(int output)
+status_t AudioFlinger::closeOutput(audio_io_handle_t output)
 {
     // keep strong reference on the playback thread so that
     // it is not destroyed while exit() is executed
@@ -5068,7 +5027,7 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::suspendOutput(int output)
+status_t AudioFlinger::suspendOutput(audio_io_handle_t output)
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -5083,7 +5042,7 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::restoreOutput(int output)
+status_t AudioFlinger::restoreOutput(audio_io_handle_t output)
 {
     Mutex::Autolock _l(mLock);
     PlaybackThread *thread = checkPlaybackThread_l(output);
@@ -5099,7 +5058,7 @@
     return NO_ERROR;
 }
 
-int AudioFlinger::openInput(uint32_t *pDevices,
+audio_io_handle_t AudioFlinger::openInput(uint32_t *pDevices,
                                 uint32_t *pSamplingRate,
                                 audio_format_t *pFormat,
                                 uint32_t *pChannels,
@@ -5155,7 +5114,7 @@
     if (inStream != NULL) {
         AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
 
-        int id = nextUniqueId();
+        audio_io_handle_t id = nextUniqueId();
         // Start record thread
         // RecorThread require both input and output device indication to forward to audio
         // pre processing modules
@@ -5182,7 +5141,7 @@
     return 0;
 }
 
-status_t AudioFlinger::closeInput(int input)
+status_t AudioFlinger::closeInput(audio_io_handle_t input)
 {
     // keep strong reference on the record thread so that
     // it is not destroyed while exit() is executed
@@ -5210,7 +5169,7 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, int output)
+status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
 {
     Mutex::Autolock _l(mLock);
     MixerThread *dstThread = checkMixerThread_l(output);
@@ -5246,7 +5205,7 @@
 void AudioFlinger::acquireAudioSessionId(int audioSession)
 {
     Mutex::Autolock _l(mLock);
-    int caller = IPCThreadState::self()->getCallingPid();
+    pid_t caller = IPCThreadState::self()->getCallingPid();
     ALOGV("acquiring %d from %d", audioSession, caller);
     int num = mAudioSessionRefs.size();
     for (int i = 0; i< num; i++) {
@@ -5264,7 +5223,7 @@
 void AudioFlinger::releaseAudioSessionId(int audioSession)
 {
     Mutex::Autolock _l(mLock);
-    int caller = IPCThreadState::self()->getCallingPid();
+    pid_t caller = IPCThreadState::self()->getCallingPid();
     ALOGV("releasing %d from %d", audioSession, caller);
     int num = mAudioSessionRefs.size();
     for (int i = 0; i< num; i++) {
@@ -5348,7 +5307,7 @@
 }
 
 // checkPlaybackThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(int output) const
+AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
 {
     PlaybackThread *thread = NULL;
     if (mPlaybackThreads.indexOfKey(output) >= 0) {
@@ -5358,7 +5317,7 @@
 }
 
 // checkMixerThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(int output) const
+AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
 {
     PlaybackThread *thread = checkPlaybackThread_l(output);
     if (thread != NULL) {
@@ -5370,7 +5329,7 @@
 }
 
 // checkRecordThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(int input) const
+AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
 {
     RecordThread *thread = NULL;
     if (mRecordThreads.indexOfKey(input) >= 0) {
@@ -5413,19 +5372,20 @@
 // ----------------------------------------------------------------------------
 
 
-status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects)
+status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
 {
     Mutex::Autolock _l(mLock);
     return EffectQueryNumberEffects(numEffects);
 }
 
-status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
+status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
 {
     Mutex::Autolock _l(mLock);
     return EffectQueryEffect(index, descriptor);
 }
 
-status_t AudioFlinger::getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *descriptor)
+status_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
+        effect_descriptor_t *descriptor) const
 {
     Mutex::Autolock _l(mLock);
     return EffectGetDescriptor(pUuid, descriptor);
@@ -5436,7 +5396,7 @@
         effect_descriptor_t *pDesc,
         const sp<IEffectClient>& effectClient,
         int32_t priority,
-        int io,
+        audio_io_handle_t io,
         int sessionId,
         status_t *status,
         int *id,
@@ -5623,7 +5583,8 @@
     return handle;
 }
 
-status_t AudioFlinger::moveEffects(int sessionId, int srcOutput, int dstOutput)
+status_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput,
+        audio_io_handle_t dstOutput)
 {
     ALOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
             sessionId, srcOutput, dstOutput);
@@ -5674,7 +5635,7 @@
 
     // transfer all effects one by one so that new effect chain is created on new thread with
     // correct buffer sizes and audio parameters and effect engines reconfigured accordingly
-    int dstOutput = dstThread->id();
+    audio_io_handle_t dstOutput = dstThread->id();
     sp<EffectChain> dstChain;
     uint32_t strategy = 0; // prevent compiler warning
     sp<EffectModule> effect = chain->getEffectFromId_l(0);
@@ -5830,13 +5791,8 @@
 
 sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
 {
-    sp<EffectModule> effect;
-
     sp<EffectChain> chain = getEffectChain_l(sessionId);
-    if (chain != 0) {
-        effect = chain->getEffectFromId_l(effectId);
-    }
-    return effect;
+    return chain != 0 ? chain->getEffectFromId_l(effectId) : 0;
 }
 
 // PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
@@ -5921,16 +5877,13 @@
 
 sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(int sessionId)
 {
-    sp<EffectChain> chain;
-
     size_t size = mEffectChains.size();
     for (size_t i = 0; i < size; i++) {
         if (mEffectChains[i]->sessionId() == sessionId) {
-            chain = mEffectChains[i];
-            break;
+            return mEffectChains[i];
         }
     }
-    return chain;
+    return 0;
 }
 
 void AudioFlinger::ThreadBase::setMode(audio_mode_t mode)
@@ -6263,11 +6216,7 @@
 sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle()
 {
     Mutex::Autolock _l(mLock);
-    sp<EffectHandle> handle;
-    if (mHandles.size() != 0) {
-        handle = mHandles[0].promote();
-    }
-    return handle;
+    return mHandles.size() != 0 ? mHandles[0].promote() : 0;
 }
 
 void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle, bool unpiniflast)
@@ -6622,7 +6571,7 @@
     return NO_ERROR;
 }
 
-bool AudioFlinger::EffectModule::isEnabled()
+bool AudioFlinger::EffectModule::isEnabled() const
 {
     switch (mState) {
     case RESTART:
@@ -6638,7 +6587,7 @@
     }
 }
 
-bool AudioFlinger::EffectModule::isProcessEnabled()
+bool AudioFlinger::EffectModule::isProcessEnabled() const
 {
     switch (mState) {
     case RESTART:
@@ -6970,9 +6919,10 @@
     mEffect.clear();
     if (mClient != 0) {
         if (mCblk != NULL) {
+            // unlike ~TrackBase(), mCblk is never a local new, so don't delete
             mCblk->~effect_param_cblk_t();   // destroy our shared-structure.
         }
-        mCblkMemory.clear();            // and free the shared memory
+        mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
         Mutex::Autolock _l(mClient->audioFlinger()->mLock);
         mClient.clear();
     }
@@ -7054,10 +7004,6 @@
     return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
 }
 
-sp<IMemory> AudioFlinger::EffectHandle::getCblk() const {
-    return mCblkMemory;
-}
-
 void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
 {
     ALOGV("setControl %p control %d", this, hasControl);
@@ -7102,7 +7048,7 @@
     bool locked = mCblk != NULL && tryLock(mCblk->lock);
 
     snprintf(buffer, size, "\t\t\t%05d %05d    %01u    %01u      %05u  %05u\n",
-            (mClient == NULL) ? getpid() : mClient->pid(),
+            (mClient == 0) ? getpid() : mClient->pid(),
             mPriority,
             mHasControl,
             !locked,
@@ -7144,48 +7090,42 @@
 // getEffectFromDesc_l() must be called with ThreadBase::mLock held
 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(effect_descriptor_t *descriptor)
 {
-    sp<EffectModule> effect;
     size_t size = mEffects.size();
 
     for (size_t i = 0; i < size; i++) {
         if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
-            effect = mEffects[i];
-            break;
+            return mEffects[i];
         }
     }
-    return effect;
+    return 0;
 }
 
 // getEffectFromId_l() must be called with ThreadBase::mLock held
 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
 {
-    sp<EffectModule> effect;
     size_t size = mEffects.size();
 
     for (size_t i = 0; i < size; i++) {
         // by convention, return first effect if id provided is 0 (0 is never a valid id)
         if (id == 0 || mEffects[i]->id() == id) {
-            effect = mEffects[i];
-            break;
+            return mEffects[i];
         }
     }
-    return effect;
+    return 0;
 }
 
 // getEffectFromType_l() must be called with ThreadBase::mLock held
 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
         const effect_uuid_t *type)
 {
-    sp<EffectModule> effect;
     size_t size = mEffects.size();
 
     for (size_t i = 0; i < size; i++) {
         if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
-            effect = mEffects[i];
-            break;
+            return mEffects[i];
         }
     }
-    return effect;
+    return 0;
 }
 
 // Must be called with EffectChain::mLock locked
@@ -7626,12 +7566,8 @@
 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
                                                             const effect_uuid_t *type)
 {
-    sp<EffectModule> effect;
-    effect = getEffectFromType_l(type);
-    if (effect != 0 && !effect->isEnabled()) {
-        effect.clear();
-    }
-    return effect;
+    sp<EffectModule> effect = getEffectFromType_l(type);
+    return effect != 0 && effect->isEnabled() ? effect : 0;
 }
 
 void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 3f3188c..dac9986 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -77,15 +77,15 @@
                                 int frameCount,
                                 uint32_t flags,
                                 const sp<IMemory>& sharedBuffer,
-                                int output,
+                                audio_io_handle_t output,
                                 int *sessionId,
                                 status_t *status);
 
-    virtual     uint32_t    sampleRate(int output) const;
-    virtual     int         channelCount(int output) const;
-    virtual     audio_format_t format(int output) const;
-    virtual     size_t      frameCount(int output) const;
-    virtual     uint32_t    latency(int output) const;
+    virtual     uint32_t    sampleRate(audio_io_handle_t output) const;
+    virtual     int         channelCount(audio_io_handle_t output) const;
+    virtual     audio_format_t format(audio_io_handle_t output) const;
+    virtual     size_t      frameCount(audio_io_handle_t output) const;
+    virtual     uint32_t    latency(audio_io_handle_t output) const;
 
     virtual     status_t    setMasterVolume(float value);
     virtual     status_t    setMasterMute(bool muted);
@@ -93,10 +93,12 @@
     virtual     float       masterVolume() const;
     virtual     bool        masterMute() const;
 
-    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value, int output);
+    virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value,
+                                            audio_io_handle_t output);
     virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted);
 
-    virtual     float       streamVolume(audio_stream_type_t stream, int output) const;
+    virtual     float       streamVolume(audio_stream_type_t stream,
+                                         audio_io_handle_t output) const;
     virtual     bool        streamMute(audio_stream_type_t stream) const;
 
     virtual     status_t    setMode(audio_mode_t mode);
@@ -104,42 +106,44 @@
     virtual     status_t    setMicMute(bool state);
     virtual     bool        getMicMute() const;
 
-    virtual     status_t    setParameters(int ioHandle, const String8& keyValuePairs);
-    virtual     String8     getParameters(int ioHandle, const String8& keys);
+    virtual     status_t    setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs);
+    virtual     String8     getParameters(audio_io_handle_t ioHandle, const String8& keys) const;
 
     virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
 
-    virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount);
-    virtual     unsigned int  getInputFramesLost(int ioHandle);
+    virtual     size_t      getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const;
+    virtual     unsigned int  getInputFramesLost(audio_io_handle_t ioHandle) const;
 
-    virtual int openOutput(uint32_t *pDevices,
+    virtual audio_io_handle_t openOutput(uint32_t *pDevices,
                                     uint32_t *pSamplingRate,
                                     audio_format_t *pFormat,
                                     uint32_t *pChannels,
                                     uint32_t *pLatencyMs,
                                     uint32_t flags);
 
-    virtual int openDuplicateOutput(int output1, int output2);
+    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+                                                  audio_io_handle_t output2);
 
-    virtual status_t closeOutput(int output);
+    virtual status_t closeOutput(audio_io_handle_t output);
 
-    virtual status_t suspendOutput(int output);
+    virtual status_t suspendOutput(audio_io_handle_t output);
 
-    virtual status_t restoreOutput(int output);
+    virtual status_t restoreOutput(audio_io_handle_t output);
 
-    virtual int openInput(uint32_t *pDevices,
+    virtual audio_io_handle_t openInput(uint32_t *pDevices,
                             uint32_t *pSamplingRate,
                             audio_format_t *pFormat,
                             uint32_t *pChannels,
                             audio_in_acoustics_t acoustics);
 
-    virtual status_t closeInput(int input);
+    virtual status_t closeInput(audio_io_handle_t input);
 
-    virtual status_t setStreamOutput(audio_stream_type_t stream, int output);
+    virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output);
 
     virtual status_t setVoiceVolume(float volume);
 
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output);
+    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+                                       audio_io_handle_t output) const;
 
     virtual int newAudioSessionId();
 
@@ -147,23 +151,25 @@
 
     virtual void releaseAudioSessionId(int audioSession);
 
-    virtual status_t queryNumberEffects(uint32_t *numEffects);
+    virtual status_t queryNumberEffects(uint32_t *numEffects) const;
 
-    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
+    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor) const;
 
-    virtual status_t getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *descriptor);
+    virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
+                                         effect_descriptor_t *descriptor) const;
 
     virtual sp<IEffect> createEffect(pid_t pid,
                         effect_descriptor_t *pDesc,
                         const sp<IEffectClient>& effectClient,
                         int32_t priority,
-                        int io,
+                        audio_io_handle_t io,
                         int sessionId,
                         status_t *status,
                         int *id,
                         int *enabled);
 
-    virtual status_t moveEffects(int sessionId, int srcOutput, int dstOutput);
+    virtual status_t moveEffects(int sessionId, audio_io_handle_t srcOutput,
+                        audio_io_handle_t dstOutput);
 
     enum hardware_call_state {
         AUDIO_HW_IDLE = 0,
@@ -187,7 +193,7 @@
     // record interface
     virtual sp<IAudioRecord> openRecord(
                                 pid_t pid,
-                                int input,
+                                audio_io_handle_t input,
                                 uint32_t sampleRate,
                                 audio_format_t format,
                                 uint32_t channelMask,
@@ -204,7 +210,7 @@
 
                audio_mode_t getMode() const { return mMode; }
 
-                bool        btNrecIsOff() { return mBtNrecIsOff; }
+                bool        btNrecIsOff() const { return mBtNrecIsOff; }
 
 private:
 
@@ -228,7 +234,7 @@
         virtual             ~Client();
         sp<MemoryDealer>    heap() const;
         pid_t               pid() const { return mPid; }
-        sp<AudioFlinger>    audioFlinger() { return mAudioFlinger; }
+        sp<AudioFlinger>    audioFlinger() const { return mAudioFlinger; }
 
     private:
                             Client(const Client&);
@@ -285,7 +291,7 @@
             RECORD              // Thread class is RecordThread
         };
 
-        ThreadBase (const sp<AudioFlinger>& audioFlinger, int id, uint32_t device, type_t type);
+        ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, uint32_t device, type_t type);
         virtual             ~ThreadBase();
 
         status_t dumpBase(int fd, const Vector<String16>& args);
@@ -322,13 +328,13 @@
                                         uint32_t flags,
                                         const sp<IMemory>& sharedBuffer,
                                         int sessionId);
-                                ~TrackBase();
+            virtual             ~TrackBase();
 
             virtual status_t    start() = 0;
             virtual void        stop() = 0;
-                    sp<IMemory> getCblk() const;
+                    sp<IMemory> getCblk() const { return mCblkMemory; }
                     audio_track_cblk_t* cblk() const { return mCblk; }
-                    int         sessionId() { return mSessionId; }
+                    int         sessionId() const { return mSessionId; }
 
         protected:
             friend class ThreadBase;
@@ -348,11 +354,11 @@
                 return mFormat;
             }
 
-            int channelCount() const ;
+            int channelCount() const { return mChannelCount; }
 
-            uint32_t channelMask() const;
+            uint32_t channelMask() const { return mChannelMask; }
 
-            int sampleRate() const;
+            int sampleRate() const; // FIXME inline after cblk sr moved
 
             void* getBuffer(uint32_t offset, uint32_t frames) const;
 
@@ -376,7 +382,6 @@
             uint32_t            mFrameCount;
             // we don't really need a lock for these
             track_state         mState;
-            int                 mClientTid;
             const audio_format_t mFormat;
             uint32_t            mFlags;
             const int           mSessionId;
@@ -409,10 +414,10 @@
 
         virtual     status_t    initCheck() const = 0;
                     type_t      type() const { return mType; }
-                    uint32_t    sampleRate() const;
-                    int         channelCount() const;
-                    audio_format_t format() const;
-                    size_t      frameCount() const;
+                    uint32_t    sampleRate() const { return mSampleRate; }
+                    int         channelCount() const { return mChannelCount; }
+                    audio_format_t format() const { return mFormat; }
+                    size_t      frameCount() const { return mFrameCount; }
                     void        wakeUp()    { mWaitWorkCV.broadcast(); }
                     void        exit();
         virtual     bool        checkForNewParameters_l() = 0;
@@ -422,7 +427,7 @@
                     void        sendConfigEvent(int event, int param = 0);
                     void        sendConfigEvent_l(int event, int param = 0);
                     void        processConfigEvents();
-                    int         id() const { return mId;}
+                    audio_io_handle_t id() const { return mId;}
                     bool        standby() { return mStandby; }
                     uint32_t    device() { return mDevice; }
         virtual     audio_stream_t* stream() = 0;
@@ -544,7 +549,7 @@
                     status_t                mParamStatus;
                     Vector<ConfigEvent>     mConfigEvents;
                     bool                    mStandby;
-                    int                     mId;
+                    const audio_io_handle_t mId;
                     bool                    mExiting;
                     Vector< sp<EffectChain> > mEffectChains;
                     uint32_t                mDevice;    // output device for PlaybackThread
@@ -581,7 +586,7 @@
                                         int frameCount,
                                         const sp<IMemory>& sharedBuffer,
                                         int sessionId);
-                                ~Track();
+            virtual             ~Track();
 
                     void        dump(char* buffer, size_t size);
             virtual status_t    start();
@@ -600,10 +605,10 @@
                     }
                     status_t    attachAuxEffect(int EffectId);
                     void        setAuxBuffer(int EffectId, int32_t *buffer);
-                    int32_t     *auxBuffer() { return mAuxBuffer; }
+                    int32_t     *auxBuffer() const { return mAuxBuffer; }
                     void        setMainBuffer(int16_t *buffer) { mMainBuffer = buffer; }
-                    int16_t     *mainBuffer() { return mMainBuffer; }
-                    int         auxEffectId() { return mAuxEffectId; }
+                    int16_t     *mainBuffer() const { return mMainBuffer; }
+                    int         auxEffectId() const { return mAuxEffectId; }
 
 
         protected:
@@ -617,7 +622,7 @@
                                 Track& operator = (const Track&);
 
             virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-            bool isMuted() { return mMute; }
+            bool isMuted() const { return mMute; }
             bool isPausing() const {
                 return mState == PAUSING;
             }
@@ -664,14 +669,14 @@
                                         audio_format_t format,
                                         uint32_t channelMask,
                                         int frameCount);
-                                ~OutputTrack();
+            virtual             ~OutputTrack();
 
             virtual status_t    start();
             virtual void        stop();
                     bool        write(int16_t* data, uint32_t frames);
-                    bool        bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
-                    bool        isActive() { return mActive; }
-            const wp<ThreadBase>& thread() { return mThread; }
+                    bool        bufferQueueEmpty() const { return (mBufferQueue.size() == 0) ? true : false; }
+                    bool        isActive() const { return mActive; }
+            const wp<ThreadBase>& thread() const { return mThread; }
 
         private:
 
@@ -691,8 +696,8 @@
             DuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
         };  // end of OutputTrack
 
-        PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id,
-                        uint32_t device, type_t type);
+        PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+                        audio_io_handle_t id, uint32_t device, type_t type);
         virtual             ~PlaybackThread();
 
         virtual     status_t    dump(int fd, const Vector<String16>& args);
@@ -708,8 +713,8 @@
         virtual     status_t    setMasterVolume(float value);
         virtual     status_t    setMasterMute(bool muted);
 
-        virtual     float       masterVolume() const;
-        virtual     bool        masterMute() const;
+        virtual     float       masterVolume() const { return mMasterVolume; }
+        virtual     bool        masterMute() const { return mMasterMute; }
 
         virtual     status_t    setStreamVolume(audio_stream_type_t stream, float value);
         virtual     status_t    setStreamMute(audio_stream_type_t stream, bool muted);
@@ -738,7 +743,7 @@
         virtual     String8     getParameters(const String8& keys);
         virtual     void        audioConfigChanged_l(int event, int param = 0);
         virtual     status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
-                    int16_t     *mixBuffer() { return mMixBuffer; };
+                    int16_t     *mixBuffer() const { return mMixBuffer; };
 
         virtual     void detachAuxEffect_l(int effectId);
                     status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track,
@@ -817,7 +822,7 @@
     public:
         MixerThread (const sp<AudioFlinger>& audioFlinger,
                      AudioStreamOut* output,
-                     int id,
+                     audio_io_handle_t id,
                      uint32_t device,
                      type_t type = MIXER);
         virtual             ~MixerThread();
@@ -844,8 +849,9 @@
     class DirectOutputThread : public PlaybackThread {
     public:
 
-        DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device);
-        ~DirectOutputThread();
+        DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
+                            audio_io_handle_t id, uint32_t device);
+        virtual                 ~DirectOutputThread();
 
         // Thread virtuals
         virtual     bool        threadLoop();
@@ -870,8 +876,9 @@
 
     class DuplicatingThread : public MixerThread {
     public:
-        DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, int id);
-        ~DuplicatingThread();
+        DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread,
+                           audio_io_handle_t id);
+        virtual                 ~DuplicatingThread();
 
         // Thread virtuals
         virtual     bool        threadLoop();
@@ -889,13 +896,16 @@
                     uint32_t    mWaitTimeMs;
     };
 
-              PlaybackThread *checkPlaybackThread_l(int output) const;
-              MixerThread *checkMixerThread_l(int output) const;
-              RecordThread *checkRecordThread_l(int input) const;
-              float streamVolumeInternal(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; }
-              void audioConfigChanged_l(int event, int ioHandle, void *param2);
+              PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const;
+              MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
+              RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
+              float streamVolumeInternal(audio_stream_type_t stream) const
+                                { return mStreamTypes[stream].volume; }
+              void audioConfigChanged_l(int event, audio_io_handle_t ioHandle, void *param2);
 
+              // allocate an audio_io_handle_t, session ID, or effect ID
               uint32_t nextUniqueId();
+
               status_t moveEffectChain_l(int sessionId,
                                      AudioFlinger::PlaybackThread *srcThread,
                                      AudioFlinger::PlaybackThread *dstThread,
@@ -946,7 +956,7 @@
                                         int frameCount,
                                         uint32_t flags,
                                         int sessionId);
-                                ~RecordTrack();
+            virtual             ~RecordTrack();
 
             virtual status_t    start();
             virtual void        stop();
@@ -973,9 +983,9 @@
                         AudioStreamIn *input,
                         uint32_t sampleRate,
                         uint32_t channels,
-                        int id,
+                        audio_io_handle_t id,
                         uint32_t device);
-                ~RecordThread();
+                virtual     ~RecordThread();
 
         virtual bool        threadLoop();
         virtual status_t    readyToRun();
@@ -1064,7 +1074,7 @@
                         effect_descriptor_t *desc,
                         int id,
                         int sessionId);
-        ~EffectModule();
+        virtual ~EffectModule();
 
         enum effect_state {
             IDLE,
@@ -1076,7 +1086,7 @@
             DESTROYED
         };
 
-        int         id() { return mId; }
+        int         id() const { return mId; }
         void process();
         void updateState();
         status_t command(uint32_t cmdCode,
@@ -1094,12 +1104,12 @@
         uint32_t status() {
             return mStatus;
         }
-        int sessionId() {
+        int sessionId() const {
             return mSessionId;
         }
         status_t    setEnabled(bool enabled);
-        bool isEnabled();
-        bool isProcessEnabled();
+        bool isEnabled() const;
+        bool isProcessEnabled() const;
 
         void        setInBuffer(int16_t *buffer) { mConfig.inputCfg.buffer.s16 = buffer; }
         int16_t     *inBuffer() { return mConfig.inputCfg.buffer.s16; }
@@ -1126,7 +1136,7 @@
 
         sp<EffectHandle> controlHandle();
 
-        bool             isPinned() { return mPinned; }
+        bool             isPinned() const { return mPinned; }
         void             unPin() { mPinned = false; }
 
         status_t         dump(int fd, const Vector<String16>& args);
@@ -1187,7 +1197,7 @@
                                  void *pReplyData);
         virtual void disconnect();
         virtual void disconnect(bool unpiniflast);
-        virtual sp<IMemory> getCblk() const;
+        virtual sp<IMemory> getCblk() const { return mCblkMemory; }
         virtual status_t onTransact(uint32_t code, const Parcel& data,
                 Parcel* reply, uint32_t flags);
 
@@ -1203,13 +1213,13 @@
                              uint32_t replySize,
                              void *pReplyData);
         void setEnabled(bool enabled);
-        bool enabled() { return mEnabled; }
+        bool enabled() const { return mEnabled; }
 
         // Getters
-        int id() { return mEffect->id(); }
-        int priority() { return mPriority; }
-        bool hasControl() { return mHasControl; }
-        sp<EffectModule> effect() { return mEffect; }
+        int id() const { return mEffect->id(); }
+        int priority() const { return mPriority; }
+        bool hasControl() const { return mHasControl; }
+        sp<EffectModule> effect() const { return mEffect; }
 
         void dump(char* buffer, size_t size);
 
@@ -1241,7 +1251,7 @@
     class EffectChain: public RefBase {
     public:
         EffectChain(const wp<ThreadBase>& wThread, int sessionId);
-        ~EffectChain();
+        virtual ~EffectChain();
 
         // special key used for an entry in mSuspendedEffects keyed vector
         // corresponding to a suspend all request.
@@ -1263,7 +1273,7 @@
         status_t addEffect_l(const sp<EffectModule>& handle);
         size_t removeEffect_l(const sp<EffectModule>& handle);
 
-        int sessionId() { return mSessionId; }
+        int sessionId() const { return mSessionId; }
         void setSessionId(int sessionId) { mSessionId = sessionId; }
 
         sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
@@ -1277,26 +1287,26 @@
             mInBuffer = buffer;
             mOwnInBuffer = ownsBuffer;
         }
-        int16_t *inBuffer() {
+        int16_t *inBuffer() const {
             return mInBuffer;
         }
         void setOutBuffer(int16_t *buffer) {
             mOutBuffer = buffer;
         }
-        int16_t *outBuffer() {
+        int16_t *outBuffer() const {
             return mOutBuffer;
         }
 
         void incTrackCnt() { android_atomic_inc(&mTrackCnt); }
         void decTrackCnt() { android_atomic_dec(&mTrackCnt); }
-        int32_t trackCnt() { return mTrackCnt;}
+        int32_t trackCnt() const { return mTrackCnt;}
 
         void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt);
                                    mTailBufferCount = mMaxTailBuffers; }
         void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); }
-        int32_t activeTrackCnt() { return mActiveTrackCnt;}
+        int32_t activeTrackCnt() const { return mActiveTrackCnt;}
 
-        uint32_t strategy() { return mStrategy; }
+        uint32_t strategy() const { return mStrategy; }
         void setStrategy(uint32_t strategy)
                  { mStrategy = strategy; }
 
@@ -1401,14 +1411,14 @@
     mutable     hardware_call_state                 mHardwareStatus;    // for dump only
 
 
-                DefaultKeyedVector< int, sp<PlaybackThread> >  mPlaybackThreads;
+                DefaultKeyedVector< audio_io_handle_t, sp<PlaybackThread> >  mPlaybackThreads;
                 PlaybackThread::stream_type_t       mStreamTypes[AUDIO_STREAM_CNT];
 
                 // both are protected by mLock
                 float                               mMasterVolume;
                 bool                                mMasterMute;
 
-                DefaultKeyedVector< int, sp<RecordThread> >    mRecordThreads;
+                DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> >    mRecordThreads;
 
                 DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;
                 volatile int32_t                    mNextUniqueId;
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 0b9f8ba..191520a 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -68,7 +68,7 @@
         // t->prevAuxLevel
         // t->frameCount
         t->channelCount = 2;
-        t->enabled = 0;
+        t->enabled = false;
         t->format = 16;
         t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
         t->bufferProvider = NULL;
@@ -121,8 +121,8 @@
     assert(uint32_t(name) < MAX_NUM_TRACKS);
     ALOGV("deleteTrackName(%d)", name);
     track_t& track(mState.tracks[ name ]);
-    if (track.enabled != 0) {
-        track.enabled = 0;
+    if (track.enabled) {
+        track.enabled = false;
         invalidateState(1<<name);
     }
     if (track.resampler != NULL) {
@@ -143,8 +143,8 @@
     assert(uint32_t(name) < MAX_NUM_TRACKS);
     track_t& track = mState.tracks[name];
 
-    if (track.enabled != 1) {
-        track.enabled = 1;
+    if (!track.enabled) {
+        track.enabled = true;
         ALOGV("enable(%d)", name);
         invalidateState(1 << name);
     }
@@ -156,8 +156,8 @@
     assert(uint32_t(name) < MAX_NUM_TRACKS);
     track_t& track = mState.tracks[name];
 
-    if (track.enabled != 0) {
-        track.enabled = 0;
+    if (track.enabled) {
+        track.enabled = false;
         ALOGV("disable(%d)", name);
         invalidateState(1 << name);
     }
@@ -296,18 +296,6 @@
     return false;
 }
 
-bool AudioMixer::track_t::doesResample() const
-{
-    return resampler != NULL;
-}
-
-void AudioMixer::track_t::resetResampler()
-{
-    if (resampler != NULL) {
-        resampler->reset();
-    }
-}
-
 inline
 void AudioMixer::track_t::adjustVolumeRamp(bool aux)
 {
@@ -327,20 +315,11 @@
     }
 }
 
-size_t AudioMixer::track_t::getUnreleasedFrames()
-{
-    if (resampler != NULL) {
-        return resampler->getUnreleasedFrames();
-    }
-    return 0;
-}
-
-size_t AudioMixer::getUnreleasedFrames(int name)
+size_t AudioMixer::getUnreleasedFrames(int name) const
 {
     name -= TRACK0;
     if (uint32_t(name) < MAX_NUM_TRACKS) {
-        track_t& track(mState.tracks[name]);
-        return track.getUnreleasedFrames();
+        return mState.tracks[name].getUnreleasedFrames();
     }
     return 0;
 }
@@ -383,9 +362,9 @@
 
     // compute everything we need...
     int countActiveTracks = 0;
-    int all16BitsStereoNoResample = 1;
-    int resampling = 0;
-    int volumeRamp = 0;
+    bool all16BitsStereoNoResample = true;
+    bool resampling = false;
+    bool volumeRamp = false;
     uint32_t en = state->enabledTracks;
     while (en) {
         const int i = 31 - __builtin_clz(en);
@@ -402,7 +381,7 @@
         }
 
         if (t.volumeInc[0]|t.volumeInc[1]) {
-            volumeRamp = 1;
+            volumeRamp = true;
         } else if (!t.doesResample() && t.volumeRL == 0) {
             n |= NEEDS_MUTE_ENABLED;
         }
@@ -412,16 +391,16 @@
             t.hook = track__nop;
         } else {
             if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
-                all16BitsStereoNoResample = 0;
+                all16BitsStereoNoResample = false;
             }
             if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
-                all16BitsStereoNoResample = 0;
-                resampling = 1;
+                all16BitsStereoNoResample = false;
+                resampling = true;
                 t.hook = track__genericResample;
             } else {
                 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
                     t.hook = track__16BitsMono;
-                    all16BitsStereoNoResample = 0;
+                    all16BitsStereoNoResample = false;
                 }
                 if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
                     t.hook = track__16BitsStereo;
@@ -469,7 +448,7 @@
     // Now that the volume ramp has been done, set optimal state and
     // track hooks for subsequent mixer process
     if (countActiveTracks) {
-        int allMuted = 1;
+        bool allMuted = true;
         uint32_t en = state->enabledTracks;
         while (en) {
             const int i = 31 - __builtin_clz(en);
@@ -480,7 +459,7 @@
                 t.needs |= NEEDS_MUTE_ENABLED;
                 t.hook = track__nop;
             } else {
-                allMuted = 0;
+                allMuted = false;
             }
         }
         if (allMuted) {
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 84f6330..c709686 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -33,7 +33,7 @@
 public:
                             AudioMixer(size_t frameCount, uint32_t sampleRate);
 
-                            ~AudioMixer();
+    /*virtual*/             ~AudioMixer();  // non-virtual saves a v-table, restore if sub-classed
 
     static const uint32_t MAX_NUM_TRACKS = 32;
     static const uint32_t MAX_NUM_CHANNELS = 2;
@@ -83,7 +83,7 @@
 
     uint32_t    trackNames() const { return mTrackNames; }
 
-    size_t      getUnreleasedFrames(int name);
+    size_t      getUnreleasedFrames(int name) const;
 
 private:
 
@@ -153,10 +153,11 @@
         int32_t*           auxBuffer;
 
         bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
-        bool        doesResample() const;
-        void        resetResampler();
+        bool        doesResample() const { return resampler != NULL; }
+        void        resetResampler() { if (resampler != NULL) resampler->reset(); }
         void        adjustVolumeRamp(bool aux);
-        size_t      getUnreleasedFrames();
+        size_t      getUnreleasedFrames() const { return resampler != NULL ?
+                                                    resampler->getUnreleasedFrames() : 0; };
     };
 
     // pad to 32-bytes to fill cache line
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 1dddbb3..10efd85 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -819,7 +819,7 @@
 
 status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
                                                                float volume,
-                                                               int output,
+                                                               audio_io_handle_t output,
                                                                int delayMs)
 {
     status_t status = NO_ERROR;
@@ -849,7 +849,7 @@
     return status;
 }
 
-status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
+status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
                                                                    const char *keyValuePairs,
                                                                    int delayMs)
 {
@@ -1019,7 +1019,7 @@
                                        const char *keyValuePairs,
                                        int delayMs)
 {
-    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs,
+    mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
                                            delayMs);
 }
 
@@ -1029,7 +1029,7 @@
                                         int delayMs)
 {
     return (int)mAudioCommandThread->volumeCommand(stream, volume,
-                                                   (int)output, delayMs);
+                                                   output, delayMs);
 }
 
 int AudioPolicyService::startTone(audio_policy_tone_t tone,
@@ -1362,7 +1362,7 @@
                                              audio_policy_output_flags_t flags)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL) {
+    if (af == 0) {
         ALOGW("%s: could not get AudioFlinger", __func__);
         return 0;
     }
@@ -1376,7 +1376,7 @@
                                                  audio_io_handle_t output2)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL) {
+    if (af == 0) {
         ALOGW("%s: could not get AudioFlinger", __func__);
         return 0;
     }
@@ -1386,7 +1386,7 @@
 static int aps_close_output(void *service, audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL)
+    if (af == 0)
         return PERMISSION_DENIED;
 
     return af->closeOutput(output);
@@ -1395,7 +1395,7 @@
 static int aps_suspend_output(void *service, audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL) {
+    if (af == 0) {
         ALOGW("%s: could not get AudioFlinger", __func__);
         return PERMISSION_DENIED;
     }
@@ -1406,7 +1406,7 @@
 static int aps_restore_output(void *service, audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL) {
+    if (af == 0) {
         ALOGW("%s: could not get AudioFlinger", __func__);
         return PERMISSION_DENIED;
     }
@@ -1422,7 +1422,7 @@
                                             audio_in_acoustics_t acoustics)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL) {
+    if (af == 0) {
         ALOGW("%s: could not get AudioFlinger", __func__);
         return 0;
     }
@@ -1434,7 +1434,7 @@
 static int aps_close_input(void *service, audio_io_handle_t input)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL)
+    if (af == 0)
         return PERMISSION_DENIED;
 
     return af->closeInput(input);
@@ -1444,7 +1444,7 @@
                                      audio_io_handle_t output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL)
+    if (af == 0)
         return PERMISSION_DENIED;
 
     return af->setStreamOutput(stream, output);
@@ -1455,10 +1455,10 @@
                                 audio_io_handle_t dst_output)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == NULL)
+    if (af == 0)
         return PERMISSION_DENIED;
 
-    return af->moveEffects(session, (int)src_output, (int)dst_output);
+    return af->moveEffects(session, src_output, dst_output);
 }
 
 static char * aps_get_parameters(void *service, audio_io_handle_t io_handle,
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 62219e5..fdaf576 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -174,8 +174,10 @@
                     void        startToneCommand(ToneGenerator::tone_type type,
                                                  audio_stream_type_t stream);
                     void        stopToneCommand();
-                    status_t    volumeCommand(audio_stream_type_t stream, float volume, int output, int delayMs = 0);
-                    status_t    parametersCommand(int ioHandle, const char *keyValuePairs, int delayMs = 0);
+                    status_t    volumeCommand(audio_stream_type_t stream, float volume,
+                                            audio_io_handle_t output, int delayMs = 0);
+                    status_t    parametersCommand(audio_io_handle_t ioHandle,
+                                            const char *keyValuePairs, int delayMs = 0);
                     status_t    voiceVolumeCommand(float volume, int delayMs = 0);
                     void        insertCommand_l(AudioCommand *command, int delayMs = 0);
 
@@ -207,12 +209,12 @@
         public:
             audio_stream_type_t mStream;
             float mVolume;
-            int mIO;
+            audio_io_handle_t mIO;
         };
 
         class ParametersData {
         public:
-            int mIO;
+            audio_io_handle_t mIO;
             String8 mKeyValuePairs;
         };
 
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index feacd96..6e17a4a3 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -130,12 +130,6 @@
     mVolume[0] = mVolume[1] = 0;
     mBuffer.frameCount = 0;
 
-    // save format for quick lookup
-    if (inChannelCount == 1) {
-        mFormat = MONO_16_BIT;
-    } else {
-        mFormat = STEREO_16_BIT;
-    }
 }
 
 AudioResampler::~AudioResampler() {
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index ffa690a..ee171ff 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -54,7 +54,7 @@
             AudioBufferProvider* provider) = 0;
 
     virtual void reset();
-    virtual size_t getUnreleasedFrames() { return mInputIndex; }
+    virtual size_t getUnreleasedFrames() const { return mInputIndex; }
 
 protected:
     // number of bits for phase fraction - 30 bits allows nearly 2x downsampling
@@ -66,7 +66,6 @@
     // multiplier to calculate fixed point phase increment
     static const double kPhaseMultiplier = 1L << kNumPhaseBits;
 
-    enum format {MONO_16_BIT, STEREO_16_BIT};
     AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate);
 
     // prevent copying
@@ -83,7 +82,6 @@
         uint32_t mVolumeRL;
     };
     int16_t mTargetVolume[2];
-    format mFormat;
     size_t mInputIndex;
     int32_t mPhaseIncrement;
     uint32_t mPhaseFraction;
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
index 0e1bc44..f0a07b8 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -31,7 +31,7 @@
 public:
     AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate);
 
-    ~AudioResamplerSinc();
+    virtual ~AudioResamplerSinc();
 
     virtual void resample(int32_t* out, size_t outFrameCount,
             AudioBufferProvider* provider);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index a372fb8..eab60a7 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -1394,9 +1394,7 @@
     private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
         @Override
         public void onUidRulesChanged(int uid, int uidRules) {
-            // only someone like NPMS should only be calling us
-            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
-
+            // caller is NPMS, since we only register with them
             if (LOGD_RULES) {
                 log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
             }
@@ -1415,9 +1413,7 @@
 
         @Override
         public void onMeteredIfacesChanged(String[] meteredIfaces) {
-            // only someone like NPMS should only be calling us
-            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
-
+            // caller is NPMS, since we only register with them
             if (LOGD_RULES) {
                 log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
             }
@@ -1429,6 +1425,27 @@
                 }
             }
         }
+
+        @Override
+        public void onRestrictBackgroundChanged(boolean restrictBackground) {
+            // caller is NPMS, since we only register with them
+            if (LOGD_RULES) {
+                log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
+            }
+
+            // kick off connectivity change broadcast for active network, since
+            // global background policy change is radical.
+            final int networkType = mActiveDefaultNetwork;
+            if (isNetworkTypeValid(networkType)) {
+                final NetworkStateTracker tracker = mNetTrackers[networkType];
+                if (tracker != null) {
+                    final NetworkInfo info = tracker.getNetworkInfo();
+                    if (info != null && info.isConnected()) {
+                        sendConnectedBroadcast(info);
+                    }
+                }
+            }
+        }
     };
 
     /**
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 9772d6a..a890068 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -195,6 +195,7 @@
     private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 3;
     private static final int MSG_PROCESS_DIED = 4;
     private static final int MSG_LIMIT_REACHED = 5;
+    private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
 
     private final Context mContext;
     private final IActivityManager mActivityManager;
@@ -1225,6 +1226,9 @@
             updateNotificationsLocked();
             writePolicyLocked();
         }
+
+        mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0)
+                .sendToTarget();
     }
 
     @Override
@@ -1573,6 +1577,20 @@
                     }
                     return true;
                 }
+                case MSG_RESTRICT_BACKGROUND_CHANGED: {
+                    final boolean restrictBackground = msg.arg1 != 0;
+                    final int length = mListeners.beginBroadcast();
+                    for (int i = 0; i < length; i++) {
+                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
+                        if (listener != null) {
+                            try {
+                                listener.onRestrictBackgroundChanged(restrictBackground);
+                            } catch (RemoteException e) {
+                            }
+                        }
+                    }
+                    mListeners.finishBroadcast();
+                }
                 default: {
                     return false;
                 }
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
index e7ba358..240cc1c 100644
--- a/services/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -51,6 +51,7 @@
 public class NetworkStatsRecorder {
     private static final String TAG = "NetworkStatsRecorder";
     private static final boolean LOGD = true;
+    private static final boolean LOGV = false;
 
     private final FileRotator mRotator;
     private final NonMonotonicObserver<String> mObserver;
@@ -170,7 +171,7 @@
 
         mLastSnapshot = snapshot;
 
-        if (LOGD && unknownIfaces.size() > 0) {
+        if (LOGV && unknownIfaces.size() > 0) {
             Slog.w(TAG, "unknown interfaces " + unknownIfaces + ", ignoring those stats");
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 893d7a8..35cdf9b 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -715,4 +715,7 @@
                 "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
         return retVal;
     }
+
+    @Override
+    public void testingEmergencyCall() {}
 }
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
index 31f9e18..958481c 100644
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ b/telephony/java/com/android/internal/telephony/CallTracker.java
@@ -19,6 +19,8 @@
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
+import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.telephony.CommandException;
@@ -116,6 +118,48 @@
         return pendingOperations == 0;
     }
 
+    /**
+     * Routine called from dial to check if the number is a test Emergency number
+     * and if so remap the number. This allows a short emergency number to be remapped
+     * to a regular number for testing how the frameworks handles emergency numbers
+     * without actually calling an emergency number.
+     *
+     * This is not a full test and is not a substitute for testing real emergency
+     * numbers but can be useful.
+     *
+     * To use this feature set a system property ril.test.emergencynumber to a pair of
+     * numbers separated by a colon. If the first number matches the number parameter
+     * this routine returns the second number. Example:
+     *
+     * ril.test.emergencynumber=112:1-123-123-45678
+     *
+     * To test Dial 112 take call then hang up on MO device to enter ECM
+     * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
+     *
+     * @param number to test if it should be remapped
+     * @return the same number or the remapped number.
+     */
+    protected String checkForTestEmergencyNumber(String dialString) {
+        String testEn = SystemProperties.get("ril.test.emergencynumber");
+        if (DBG_POLL) {
+            log("checkForTestEmergencyNumber: dialString=" + dialString +
+                " testEn=" + testEn);
+        }
+        if (!TextUtils.isEmpty(testEn)) {
+            String values[] = testEn.split(":");
+            log("checkForTestEmergencyNumber: values.length=" + values.length);
+            if (values.length == 2) {
+                if (values[0].equals(
+                        android.telephony.PhoneNumberUtils.stripSeparators(dialString))) {
+                    cm.testingEmergencyCall();
+                    log("checkForTestEmergencyNumber: remap " +
+                            dialString + " to " + values[1]);
+                    dialString = values[1];
+                }
+            }
+        }
+        return dialString;
+    }
 
     //***** Overridden from Handler
     public abstract void handleMessage (Message msg);
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index a0efab2..f7757b3 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -1571,4 +1571,9 @@
      * @param response a callback message with the String response in the obj field
      */
     public void requestIsimAuthentication(String nonce, Message response);
+
+    /**
+     * Notifiy that we are testing an emergency call
+     */
+    public void testingEmergencyCall();
 }
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 664a091..5d76484 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -225,7 +225,8 @@
     //       having to have different values for GSM and
     //       CDMA. If so we can then remove the need for
     //       getActionIntentReconnectAlarm.
-    protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
+    protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
+        "reconnect_alarm_extra_reason";
 
     // Used for debugging. Send the INTENT with an optional counter value with the number
     // of times the setup is to fail before succeeding. If the counter isn't passed the
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index f587fe1..5afc1f3 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -60,6 +60,7 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * {@hide}
@@ -232,6 +233,9 @@
 
     Object     mLastNITZTimeInfo;
 
+    // When we are testing emergency calls
+    AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
+
     //***** Events
 
     static final int EVENT_SEND                 = 1;
@@ -2213,7 +2217,16 @@
             case RIL_REQUEST_GET_IMSI: ret =  responseString(p); break;
             case RIL_REQUEST_HANGUP: ret =  responseVoid(p); break;
             case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret =  responseVoid(p); break;
-            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: ret =  responseVoid(p); break;
+            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: {
+                if (mTestingEmergencyCall.getAndSet(false)) {
+                    if (mEmergencyCallbackModeRegistrant != null) {
+                        riljLog("testing emergency call, notify ECM Registrants");
+                        mEmergencyCallbackModeRegistrant.notifyRegistrant();
+                    }
+                }
+                ret =  responseVoid(p);
+                break;
+            }
             case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret =  responseVoid(p); break;
             case RIL_REQUEST_CONFERENCE: ret =  responseVoid(p); break;
             case RIL_REQUEST_UDUB: ret =  responseVoid(p); break;
@@ -3014,6 +3027,11 @@
         num = p.readInt();
         response = new ArrayList<DriverCall>(num);
 
+        if (RILJ_LOGV) {
+            riljLog("responseCallList: num=" + num +
+                    " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
+                    " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
+        }
         for (int i = 0 ; i < num ; i++) {
             dc = new DriverCall();
 
@@ -3065,6 +3083,14 @@
 
         Collections.sort(response);
 
+        if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
+            if (mEmergencyCallbackModeRegistrant != null) {
+                riljLog("responseCallList: call ended, testing emergency call," +
+                            " notify ECM Registrants");
+                mEmergencyCallbackModeRegistrant.notifyRegistrant();
+            }
+        }
+
         return response;
     }
 
@@ -3791,4 +3817,13 @@
 
         send(rr);
     }
+
+    /* (non-Javadoc)
+     * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
+     */
+    @Override
+    public void testingEmergencyCall() {
+        if (RILJ_LOGD) riljLog("testingEmergencyCall");
+        mTestingEmergencyCall.set(true);
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index 83efc51..f918dce 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -210,7 +210,8 @@
             return dialThreeWay(dialString);
         }
 
-        pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall);
+        pendingMO = new CdmaConnection(phone.getContext(), checkForTestEmergencyNumber(dialString),
+                this, foregroundCall);
         hangupPendingMO = false;
 
         if (pendingMO.address == null || pendingMO.address.length() == 0
@@ -259,7 +260,7 @@
 
             // Attach the new connection to foregroundCall
             pendingMO = new CdmaConnection(phone.getContext(),
-                                dialString, this, foregroundCall);
+                                checkForTestEmergencyNumber(dialString), this, foregroundCall);
             cm.sendCDMAFeatureCode(pendingMO.address,
                 obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
             return pendingMO;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
index 06f310c..425afe6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
@@ -198,7 +198,8 @@
             throw new CallStateException("cannot dial in current state");
         }
 
-        pendingMO = new GsmConnection(phone.getContext(), dialString, this, foregroundCall);
+        pendingMO = new GsmConnection(phone.getContext(), checkForTestEmergencyNumber(dialString),
+                this, foregroundCall);
         hangupPendingMO = false;
 
         if (pendingMO.address == null || pendingMO.address.length() == 0
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 8f04dba..66e9487 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -131,7 +131,7 @@
 
     private static final String INTENT_RECONNECT_ALARM =
         "com.android.internal.telephony.gprs-reconnect";
-    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "type";
+    private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
 
     private static final String INTENT_DATA_STALL_ALARM =
         "com.android.internal.telephony.gprs-data-stall";
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 643cb8d..3904c21 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -40,6 +40,15 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
+        <activity
+                android:name="ClipRegionActivity"
+                android:label="_ClipRegion">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         
         <activity
                 android:name="DisplayListLayersActivity"
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java
new file mode 100644
index 0000000..b2a508b
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Region;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ClipRegionActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final RegionView view = new RegionView(this);
+        setContentView(view);
+    }
+
+    public static class RegionView extends View {
+        public RegionView(Context c) {
+            super(c);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+
+            canvas.save();
+            canvas.clipRect(100.0f, 100.0f, getWidth() - 100.0f, getHeight() - 100.0f,
+                    Region.Op.DIFFERENCE);
+            canvas.drawARGB(255, 255, 0, 0);
+            canvas.restore();
+        }
+    }
+}