diff --git a/NOTICE b/NOTICE
index c45f010..152be20 100644
--- a/NOTICE
+++ b/NOTICE
@@ -17,7 +17,7 @@
    =========================================================================
 
 Apache Commons
-Copyright 1999-2004 The Apache Software Foundation
+Copyright 1999-2006 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
@@ -56,6 +56,25 @@
    =========================================================================
    ==  NOTICE file corresponding to the section 4 d of                    ==
    ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the TagSoup code.                                 ==
+   =========================================================================
+
+This file is part of TagSoup and is Copyright 2002-2008 by John Cowan.
+
+TagSoup is licensed under the Apache License,
+Version 2.0.  You may obtain a copy of this license at
+http://www.apache.org/licenses/LICENSE-2.0 .  You may also have
+additional legal rights not granted by this license.
+
+TagSoup is distributed in the hope that it will be useful, but
+unless required by applicable law or agreed to in writing, TagSoup
+is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, either express or implied; not even the implied warranty
+of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
    ==  in this case for Additional Codecs code.                           ==
    =========================================================================
 
@@ -74,6 +93,7 @@
 Copyright (C) 2010 The Android Open Source Project, but released under
 the Apache2 License.
 
+
                                Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
diff --git a/include/binder/CursorWindow.h b/include/binder/CursorWindow.h
new file mode 100644
index 0000000..f0b2909
--- /dev/null
+++ b/include/binder/CursorWindow.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2006 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__DATABASE_WINDOW_H
+#define _ANDROID__DATABASE_WINDOW_H
+
+#include <cutils/log.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <binder/IMemory.h>
+#include <utils/RefBase.h>
+
+#define DEFAULT_WINDOW_SIZE 4096
+#define WINDOW_ALLOCATION_SIZE 4096
+
+#define ROW_SLOT_CHUNK_NUM_ROWS 16
+
+// Row slots are allocated in chunks of ROW_SLOT_CHUNK_NUM_ROWS,
+// with an offset after the rows that points to the next chunk
+#define ROW_SLOT_CHUNK_SIZE ((ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t)) + sizeof(uint32_t))
+
+
+#if LOG_NDEBUG
+
+#define IF_LOG_WINDOW() if (false)
+#define LOG_WINDOW(...)
+
+#else
+
+#define IF_LOG_WINDOW() IF_LOG(LOG_DEBUG, "CursorWindow")
+#define LOG_WINDOW(...) LOG(LOG_DEBUG, "CursorWindow", __VA_ARGS__)
+
+#endif
+
+
+// When defined to true strings are stored as UTF8, otherwise they're UTF16
+#define WINDOW_STORAGE_UTF8 1
+
+// When defined to true numberic values are stored inline in the field_slot_t, otherwise they're allocated in the window
+#define WINDOW_STORAGE_INLINE_NUMERICS 1
+
+namespace android {
+
+typedef struct
+{
+    uint32_t numRows;
+    uint32_t numColumns;
+} window_header_t;
+
+typedef struct
+{
+    uint32_t offset;
+} row_slot_t;
+
+typedef struct
+{
+    uint8_t type;
+    union {
+        double d;
+        int64_t l;
+        struct {
+            uint32_t offset;
+            uint32_t size;
+        } buffer;
+    } data;
+} __attribute__((packed)) field_slot_t;
+
+#define FIELD_TYPE_NULL 0
+#define FIELD_TYPE_INTEGER 1
+#define FIELD_TYPE_FLOAT 2
+#define FIELD_TYPE_STRING 3
+#define FIELD_TYPE_BLOB 4
+
+/**
+ * This class stores a set of rows from a database in a buffer. The begining of the
+ * window has first chunk of row_slot_ts, which are offsets to the row directory, followed by
+ * an offset to the next chunk in a linked-list of additional chunk of row_slot_ts in case
+ * the pre-allocated chunk isn't big enough to refer to all rows. Each row directory has a
+ * field_slot_t per column, which has the size, offset, and type of the data for that field.
+ * Note that the data types come from sqlite3.h.
+ */
+class CursorWindow
+{
+public:
+                        CursorWindow(size_t maxSize);
+                        CursorWindow(){}
+    bool                setMemory(const sp<IMemory>&);
+                        ~CursorWindow();
+
+    bool                initBuffer(bool localOnly);
+    sp<IMemory>         getMemory() {return mMemory;}
+
+    size_t              size() {return mSize;}
+    uint8_t *           data() {return mData;}
+    uint32_t            getNumRows() {return mHeader->numRows;}
+    uint32_t            getNumColumns() {return mHeader->numColumns;}
+    void                freeLastRow() {
+                            if (mHeader->numRows > 0) {
+                                mHeader->numRows--;
+                            }
+                        }
+    bool                setNumColumns(uint32_t numColumns)
+                            {
+                                uint32_t cur = mHeader->numColumns;
+                                if (cur > 0 && cur != numColumns) {
+                                    LOGE("Trying to go from %d columns to %d", cur, numColumns);
+                                    return false;
+                                }
+                                mHeader->numColumns = numColumns;
+                                return true;
+                            }
+
+    int32_t             freeSpace();
+
+    void                clear();
+
+                        /**
+                         * Allocate a row slot and its directory. The returned
+                         * pointer points to the begining of the row's directory
+                         * or NULL if there wasn't room. The directory is
+                         * initialied with NULL entries for each field.
+                         */
+    field_slot_t *      allocRow();
+
+                        /**
+                         * Allocate a portion of the window. Returns the offset
+                         * of the allocation, or 0 if there isn't enough space.
+                         * If aligned is true, the allocation gets 4 byte alignment.
+                         */
+    uint32_t            alloc(size_t size, bool aligned = false);
+
+    uint32_t            read_field_slot(int row, int column, field_slot_t * slot);
+
+                        /**
+                         * Copy data into the window at the given offset.
+                         */
+    void                copyIn(uint32_t offset, uint8_t const * data, size_t size);
+    void                copyIn(uint32_t offset, int64_t data);
+    void                copyIn(uint32_t offset, double data);
+
+    void                copyOut(uint32_t offset, uint8_t * data, size_t size);
+    int64_t             copyOutLong(uint32_t offset);
+    double              copyOutDouble(uint32_t offset);
+
+    bool                putLong(unsigned int row, unsigned int col, int64_t value);
+    bool                putDouble(unsigned int row, unsigned int col, double value);
+    bool                putNull(unsigned int row, unsigned int col);
+
+    bool                getLong(unsigned int row, unsigned int col, int64_t * valueOut);
+    bool                getDouble(unsigned int row, unsigned int col, double * valueOut);
+    bool                getNull(unsigned int row, unsigned int col, bool * valueOut);
+
+    uint8_t *           offsetToPtr(uint32_t offset) {return mData + offset;}
+
+    row_slot_t *        allocRowSlot();
+
+    row_slot_t *        getRowSlot(int row);
+
+                        /**
+                         * return NULL if Failed to find rowSlot or
+                         * Invalid rowSlot
+                         */
+    field_slot_t *      getFieldSlotWithCheck(int row, int column);
+    field_slot_t *      getFieldSlot(int row, int column)
+                            {
+                                int fieldDirOffset = getRowSlot(row)->offset;
+                                return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;
+                            }
+
+private:
+    uint8_t * mData;
+    size_t mSize;
+    size_t mMaxSize;
+    window_header_t * mHeader;
+    sp<IMemory> mMemory;
+
+    /**
+     * Offset of the lowest unused data byte in the array.
+     */
+    uint32_t mFreeOffset;
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 749a977..81b56c2 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -98,7 +98,7 @@
      * Register the @a recipient for a notification if this binder
      * goes away.  If this binder object unexpectedly goes away
      * (typically because its hosting process has been killed),
-     * then DeathRecipient::binderDied() will be called with a referene
+     * then DeathRecipient::binderDied() will be called with a reference
      * to this.
      *
      * The @a cookie is optional -- if non-NULL, it should be a
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index b54718f..3378d97 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -33,6 +33,7 @@
 {
 public:
     static  IPCThreadState*     self();
+    static  IPCThreadState*     selfOrNull();  // self(), but won't instantiate
     
             sp<ProcessState>    process();
             
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
new file mode 100644
index 0000000..168310c
--- /dev/null
+++ b/include/gui/ISurfaceTexture.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_GUI_ISURFACETEXTURE_H
+#define ANDROID_GUI_ISURFACETEXTURE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/Rect.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISurfaceTexture : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SurfaceTexture);
+
+    // requestBuffer requests a new buffer for the given index. The server (i.e.
+    // the ISurfaceTexture implementation) assigns the newly created buffer to
+    // the given slot index, and the client is expected to mirror the
+    // slot->buffer mapping so that it's not necessary to transfer a
+    // GraphicBuffer for every dequeue operation.
+    virtual sp<GraphicBuffer> requestBuffer(int slot, uint32_t w, uint32_t h,
+            uint32_t format, uint32_t usage) = 0;
+
+    // setBufferCount sets the number of buffer slots available. Calling this
+    // will also cause all buffer slots to be emptied. The caller should empty
+    // its mirrored copy of the buffer slots when calling this method.
+    virtual status_t setBufferCount(int bufferCount) = 0;
+
+    // dequeueBuffer requests a new buffer slot for the client to use. Ownership
+    // of the slot is transfered to the client, meaning that the server will not
+    // use the contents of the buffer associated with that slot. The slot index
+    // returned may or may not contain a buffer. If the slot is empty the client
+    // should call requestBuffer to assign a new buffer to that slot. The client
+    // is expected to either call cancelBuffer on the dequeued slot or to fill
+    // in the contents of its associated buffer contents and call queueBuffer.
+    virtual status_t dequeueBuffer(int *slot) = 0;
+
+    // queueBuffer indicates that the client has finished filling in the
+    // contents of the buffer associated with slot and transfers ownership of
+    // that slot back to the server. It is not valid to call queueBuffer on a
+    // slot that is not owned by the client or one for which a buffer associated
+    // via requestBuffer.
+    virtual status_t queueBuffer(int slot) = 0;
+
+    // cancelBuffer indicates that the client does not wish to fill in the
+    // buffer associated with slot and transfers ownership of the slot back to
+    // the server.
+    virtual void cancelBuffer(int slot) = 0;
+
+    virtual status_t setCrop(const Rect& reg) = 0;
+    virtual status_t setTransform(uint32_t transform) = 0;
+
+    // getAllocator retrieves the binder object that must be referenced as long
+    // as the GraphicBuffers dequeued from this ISurfaceTexture are referenced.
+    // Holding this binder reference prevents SurfaceFlinger from freeing the
+    // buffers before the client is done with them.
+    virtual sp<IBinder> getAllocator() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSurfaceTexture : public BnInterface<ISurfaceTexture>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_ISURFACETEXTURE_H
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 54ce789..9bf38f7 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -17,19 +17,211 @@
 #ifndef ANDROID_GUI_SURFACETEXTURE_H
 #define ANDROID_GUI_SURFACETEXTURE_H
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+
+#include <gui/ISurfaceTexture.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
+
 namespace android {
+// ----------------------------------------------------------------------------
 
-struct SurfaceTexture {
-    struct FrameAvailableListener : public virtual RefBase {};
+class IGraphicBufferAlloc;
 
-    SurfaceTexture(GLuint) {}
-    void updateTexImage() {}
-    void decStrong(android::sp<android::SurfaceTexture>* const) {}
-    void incStrong(android::sp<android::SurfaceTexture>* const) {}
-    void getTransformMatrix(float mtx[16]) {}
-    void setFrameAvailableListener(const sp<FrameAvailableListener>&) {}
+class SurfaceTexture : public BnSurfaceTexture {
+public:
+    enum { MIN_UNDEQUEUED_BUFFERS = 2 };
+    enum { MIN_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS + 1 };
+    enum { NUM_BUFFER_SLOTS = 32 };
+
+    struct FrameAvailableListener : public virtual RefBase {
+        virtual void onFrameAvailable() = 0;
+    };
+
+    // tex indicates the name OpenGL texture to which images are to be streamed.
+    // This texture name cannot be changed once the SurfaceTexture is created.
+    SurfaceTexture(GLuint tex);
+
+    virtual ~SurfaceTexture();
+
+    // setBufferCount updates the number of available buffer slots.  After
+    // calling this all buffer slots are both unallocated and owned by the
+    // SurfaceTexture object (i.e. they are not owned by the client).
+    virtual status_t setBufferCount(int bufferCount);
+
+    virtual sp<GraphicBuffer> requestBuffer(int buf, uint32_t w, uint32_t h,
+            uint32_t format, uint32_t usage);
+
+    // dequeueBuffer gets the next buffer slot index for the client to use. If a
+    // buffer slot is available then that slot index is written to the location
+    // pointed to by the buf argument and a status of OK is returned.  If no
+    // slot is available then a status of -EBUSY is returned and buf is
+    // unmodified.
+    virtual status_t dequeueBuffer(int *buf);
+
+    virtual status_t queueBuffer(int buf);
+    virtual void cancelBuffer(int buf);
+    virtual status_t setCrop(const Rect& reg);
+    virtual status_t setTransform(uint32_t transform);
+
+    // updateTexImage sets the image contents of the target texture to that of
+    // the most recently queued buffer.
+    //
+    // This call may only be made while the OpenGL ES context to which the
+    // target texture belongs is bound to the calling thread.
+    status_t updateTexImage();
+
+    // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix
+    // associated with the texture image set by the most recent call to
+    // updateTexImage.
+    //
+    // This transform matrix maps 2D homogeneous texture coordinates of the form
+    // (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture
+    // coordinate that should be used to sample that location from the texture.
+    // Sampling the texture outside of the range of this transform is undefined.
+    //
+    // This transform is necessary to compensate for transforms that the stream
+    // content producer may implicitly apply to the content. By forcing users of
+    // a SurfaceTexture to apply this transform we avoid performing an extra
+    // copy of the data that would be needed to hide the transform from the
+    // user.
+    //
+    // The matrix is stored in column-major order so that it may be passed
+    // directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv
+    // functions.
+    void getTransformMatrix(float mtx[16]);
+
+    // setFrameAvailableListener sets the listener object that will be notified
+    // when a new frame becomes available.
+    void setFrameAvailableListener(const sp<FrameAvailableListener>& l);
+
+    // getAllocator retrieves the binder object that must be referenced as long
+    // as the GraphicBuffers dequeued from this SurfaceTexture are referenced.
+    // Holding this binder reference prevents SurfaceFlinger from freeing the
+    // buffers before the client is done with them.
+    sp<IBinder> getAllocator();
+
+private:
+
+    // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for
+    // all slots.
+    void freeAllBuffers();
+
+    // createImage creates a new EGLImage from a GraphicBuffer.
+    EGLImageKHR createImage(EGLDisplay dpy,
+            const sp<GraphicBuffer>& graphicBuffer);
+
+    enum { INVALID_BUFFER_SLOT = -1 };
+
+    struct BufferSlot {
+        // mGraphicBuffer points to the buffer allocated for this slot or is NULL
+        // if no buffer has been allocated.
+        sp<GraphicBuffer> mGraphicBuffer;
+
+        // mEglImage is the EGLImage created from mGraphicBuffer.
+        EGLImageKHR mEglImage;
+
+        // mEglDisplay is the EGLDisplay used to create mEglImage.
+        EGLDisplay mEglDisplay;
+
+        // mOwnedByClient indicates whether the slot is currently accessible to a
+        // client and should not be used by the SurfaceTexture object. It gets
+        // set to true when dequeueBuffer returns the slot and is reset to false
+        // when the client calls either queueBuffer or cancelBuffer on the slot.
+        bool mOwnedByClient;
+    };
+
+    // mSlots is the array of buffer slots that must be mirrored on the client
+    // side. This allows buffer ownership to be transferred between the client
+    // and server without sending a GraphicBuffer over binder. The entire array
+    // is initialized to NULL at construction time, and buffers are allocated
+    // for a slot when requestBuffer is called with that slot's index.
+    BufferSlot mSlots[NUM_BUFFER_SLOTS];
+
+    // mBufferCount is the number of buffer slots that the client and server
+    // must maintain. It defaults to MIN_BUFFER_SLOTS and can be changed by
+    // calling setBufferCount.
+    int mBufferCount;
+
+    // mCurrentTexture is the buffer slot index of the buffer that is currently
+    // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
+    // indicating that no buffer slot is currently bound to the texture. Note,
+    // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+    // that no buffer is bound to the texture. A call to setBufferCount will
+    // reset mCurrentTexture to INVALID_BUFFER_SLOT.
+    int mCurrentTexture;
+
+    // mCurrentTextureBuf is the graphic buffer of the current texture. It's
+    // possible that this buffer is not associated with any buffer slot, so we
+    // must track it separately in order to properly use
+    // IGraphicBufferAlloc::freeAllGraphicBuffersExcept.
+    sp<GraphicBuffer> mCurrentTextureBuf;
+
+    // mCurrentCrop is the crop rectangle that applies to the current texture.
+    // It gets set to mLastQueuedCrop each time updateTexImage is called.
+    Rect mCurrentCrop;
+
+    // mCurrentTransform is the transform identifier for the current texture. It
+    // gets set to mLastQueuedTransform each time updateTexImage is called.
+    uint32_t mCurrentTransform;
+
+    // mLastQueued is the buffer slot index of the most recently enqueued buffer.
+    // At construction time it is initialized to INVALID_BUFFER_SLOT, and is
+    // updated each time queueBuffer is called.
+    int mLastQueued;
+
+    // mLastQueuedCrop is the crop rectangle for the buffer that was most
+    // recently queued. This gets set to mNextCrop each time queueBuffer gets
+    // called.
+    Rect mLastQueuedCrop;
+
+    // mLastQueuedTransform is the transform identifier for the buffer that was
+    // most recently queued. This gets set to mNextTransform each time
+    // queueBuffer gets called.
+    uint32_t mLastQueuedTransform;
+
+    // mNextCrop is the crop rectangle that will be used for the next buffer
+    // that gets queued. It is set by calling setCrop.
+    Rect mNextCrop;
+
+    // mNextTransform is the transform identifier that will be used for the next
+    // buffer that gets queued. It is set by calling setTransform.
+    uint32_t mNextTransform;
+
+    // mTexName is the name of the OpenGL texture to which streamed images will
+    // be bound when updateTexImage is called. It is set at construction time 
+    // changed with a call to setTexName.
+    const GLuint mTexName;
+
+    // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
+    // allocate new GraphicBuffer objects.
+    sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
+
+    // mAllocdBuffers is mirror of the list of buffers that SurfaceFlinger is
+    // referencing. This is kept so that gralloc implementations do not need to
+    // properly handle the case where SurfaceFlinger no longer holds a reference
+    // to a buffer, but other processes do.
+    Vector<sp<GraphicBuffer> > mAllocdBuffers;
+
+    // mFrameAvailableListener is the listener object that will be called when a
+    // new frame becomes available. If it is not NULL it will be called from
+    // queueBuffer.
+    sp<FrameAvailableListener> mFrameAvailableListener;
+
+    // mMutex is the mutex used to prevent concurrent access to the member
+    // variables of SurfaceTexture objects. It must be locked whenever the
+    // member variables are accessed.
+    Mutex mMutex;
 };
 
-}
+// ----------------------------------------------------------------------------
+}; // namespace android
 
-#endif
+#endif // ANDROID_GUI_SURFACETEXTURE_H
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index a83756e..7992105 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -17,14 +17,109 @@
 #ifndef ANDROID_GUI_SURFACETEXTURECLIENT_H
 #define ANDROID_GUI_SURFACETEXTURECLIENT_H
 
+#include <gui/ISurfaceTexture.h>
+#include <gui/SurfaceTexture.h>
+
 #include <ui/egl/android_natives.h>
 
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
 namespace android {
 
-struct SurfaceTextureClient : public ANativeWindow {
-    SurfaceTextureClient(const sp<SurfaceTexture>&){}
+class SurfaceTextureClient
+    : public EGLNativeBase<ANativeWindow, SurfaceTextureClient, RefBase>
+{
+public:
+    SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);
+
+    sp<ISurfaceTexture> getISurfaceTexture() const;
+
+private:
+
+    // can't be copied
+    SurfaceTextureClient& operator = (const SurfaceTextureClient& rhs);
+    SurfaceTextureClient(const SurfaceTextureClient& rhs);
+
+    // ANativeWindow hooks
+    static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
+    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int perform(ANativeWindow* window, int operation, ...);
+    static int query(ANativeWindow* window, int what, int* value);
+    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int setSwapInterval(ANativeWindow* window, int interval);
+
+    int cancelBuffer(android_native_buffer_t* buffer);
+    int dequeueBuffer(android_native_buffer_t** buffer);
+    int lockBuffer(android_native_buffer_t* buffer);
+    int perform(int operation, va_list args);
+    int query(int what, int* value);
+    int queueBuffer(android_native_buffer_t* buffer);
+    int setSwapInterval(int interval);
+
+    int dispatchConnect(va_list args);
+    int dispatchDisconnect(va_list args);
+    int dispatchSetBufferCount(va_list args);
+    int dispatchSetBuffersGeometry(va_list args);
+    int dispatchSetBuffersTransform(va_list args);
+    int dispatchSetCrop(va_list args);
+    int dispatchSetUsage(va_list args);
+
+    int connect(int api);
+    int disconnect(int api);
+    int setBufferCount(int bufferCount);
+    int setBuffersGeometry(int w, int h, int format);
+    int setBuffersTransform(int transform);
+    int setCrop(Rect const* rect);
+    int setUsage(uint32_t reqUsage);
+
+    void freeAllBuffers();
+
+    enum { MIN_UNDEQUEUED_BUFFERS = SurfaceTexture::MIN_UNDEQUEUED_BUFFERS };
+    enum { MIN_BUFFER_SLOTS = SurfaceTexture::MIN_BUFFER_SLOTS };
+    enum { NUM_BUFFER_SLOTS = SurfaceTexture::NUM_BUFFER_SLOTS };
+    enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
+
+    // mSurfaceTexture is the interface to the surface texture server. All
+    // operations on the surface texture client ultimately translate into
+    // interactions with the server using this interface.
+    sp<ISurfaceTexture> mSurfaceTexture;
+
+    // mAllocator is the binder object that is referenced to prevent the
+    // dequeued buffers from being freed prematurely.
+    sp<IBinder> mAllocator;
+
+    // mSlots stores the buffers that have been allocated for each buffer slot.
+    // It is initialized to null pointers, and gets filled in with the result of
+    // ISurfaceTexture::requestBuffer when the client dequeues a buffer from a
+    // slot that has not yet been used. The buffer allocated to a slot will also
+    // be replaced if the requested buffer usage or geometry differs from that
+    // of the buffer allocated to a slot.
+    sp<GraphicBuffer> mSlots[NUM_BUFFER_SLOTS];
+
+    // mReqWidth is the buffer width that will be requested at the next dequeue
+    // operation. It is initialized to 1.
+    uint32_t mReqWidth;
+
+    // mReqHeight is the buffer height that will be requested at the next deuque
+    // operation. It is initialized to 1.
+    uint32_t mReqHeight;
+
+    // mReqFormat is the buffer pixel format that will be requested at the next
+    // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888.
+    uint32_t mReqFormat;
+
+    // mReqUsage is the set of buffer usage flags that will be requested
+    // at the next deuque operation. It is initialized to 0.
+    uint32_t mReqUsage;
+
+    // mMutex is the mutex used to prevent concurrent access to the member
+    // variables of SurfaceTexture objects. It must be locked whenever the
+    // member variables are accessed.
+    Mutex mMutex;
 };
 
-}
+}; // namespace android
 
-#endif
+#endif  // ANDROID_GUI_SURFACETEXTURECLIENT_H
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 4ae3cdf..717f837 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -65,7 +65,7 @@
     // When changing these values, the COMPILE_TIME_ASSERT at the end of this
     // file need to be updated.
     static const unsigned int NUM_LAYERS_MAX  = 31;
-    static const unsigned int NUM_BUFFER_MAX  = 16;
+    static const unsigned int NUM_BUFFER_MAX  = 32;
     static const unsigned int NUM_BUFFER_MIN  = 2;
     static const unsigned int NUM_DISPLAY_MAX = 4;
 
@@ -123,7 +123,7 @@
 
 // ----------------------------------------------------------------------------
 
-// 32 KB max
+// 64 KB max
 class SharedClient
 {
 public:
@@ -284,6 +284,8 @@
     uint32_t getTransform(int buffer) const;
 
     status_t resize(int newNumBuffers);
+    status_t grow(int newNumBuffers);
+    status_t shrink(int newNumBuffers);
 
     SharedBufferStack::Statistics getStats() const;
     
@@ -345,6 +347,13 @@
     int mNumBuffers;
     BufferList mBufferList;
 
+    struct BuffersAvailableCondition : public ConditionBase {
+        int mNumBuffers;
+        inline BuffersAvailableCondition(SharedBufferServer* sbs,
+                int numBuffers);
+        inline bool operator()() const;
+        inline const char* name() const { return "BuffersAvailableCondition"; }
+    };
 
     struct RetireUpdate : public UpdateBase {
         const int numBuffers;
@@ -385,7 +394,7 @@
 
 // ---------------------------------------------------------------------------
 
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 65536)
 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
 // ---------------------------------------------------------------------------
diff --git a/include/private/ui/sw_gralloc_handle.h b/include/private/ui/sw_gralloc_handle.h
deleted file mode 100644
index b3d333e..0000000
--- a/include/private/ui/sw_gralloc_handle.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2008 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_UI_PRIVATE_SW_GRALLOC_HANDLE_H
-#define ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H
-
-#include <stdint.h>
-#include <limits.h>
-#include <sys/cdefs.h>
-#include <hardware/gralloc.h>
-#include <errno.h>
-
-#include <cutils/native_handle.h>
-
-namespace android {
-
-/*****************************************************************************/
-
-struct sw_gralloc_handle_t : public native_handle 
-{
-    // file-descriptors
-    int     fd;
-    // ints
-    int     magic;
-    int     size;
-    int     base;
-    int     prot;
-    int     pid;
-
-    static const int sNumInts = 5;
-    static const int sNumFds = 1;
-    static const int sMagic = '_sgh';
-
-    sw_gralloc_handle_t() :
-        fd(-1), magic(sMagic), size(0), base(0), prot(0), pid(getpid())
-    {
-        version = sizeof(native_handle);
-        numInts = sNumInts;
-        numFds = sNumFds;
-    }
-    ~sw_gralloc_handle_t() {
-        magic = 0;
-    }
-
-    static int validate(const native_handle* h) {
-        const sw_gralloc_handle_t* hnd = (const sw_gralloc_handle_t*)h;
-        if (!h || h->version != sizeof(native_handle) ||
-                h->numInts != sNumInts || h->numFds != sNumFds ||
-                hnd->magic != sMagic) 
-        {
-            return -EINVAL;
-        }
-        return 0;
-    }
-
-    static status_t alloc(uint32_t w, uint32_t h, int format,
-            int usage, buffer_handle_t* handle, int32_t* stride);
-    static status_t free(sw_gralloc_handle_t* hnd);
-    static status_t registerBuffer(sw_gralloc_handle_t* hnd);
-    static status_t unregisterBuffer(sw_gralloc_handle_t* hnd);
-    static status_t lock(sw_gralloc_handle_t* hnd, int usage,
-            int l, int t, int w, int h, void** vaddr);
-    static status_t unlock(sw_gralloc_handle_t* hnd);
-};
-
-/*****************************************************************************/
-
-}; // namespace android
-
-#endif /* ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H */
diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/surfaceflinger/IGraphicBufferAlloc.h
new file mode 100644
index 0000000..d996af7
--- /dev/null
+++ b/include/surfaceflinger/IGraphicBufferAlloc.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class IGraphicBufferAlloc : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(GraphicBufferAlloc);
+
+    /* Create a new GraphicBuffer for the client to use.  The server will
+     * maintain a reference to the newly created GraphicBuffer until
+     * freeAllGraphicBuffers is called.
+     */
+    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+            PixelFormat format, uint32_t usage) = 0;
+
+    /* Free all but one of the GraphicBuffer objects that the server is
+     * currently referencing. If bufIndex is not a valid index of the buffers
+     * the server is referencing, then all buffers are freed.
+     */
+    virtual void freeAllGraphicBuffersExcept(int bufIndex) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnGraphicBufferAlloc : public BnInterface<IGraphicBufferAlloc>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index ddbe03d..cd0ee40 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -34,18 +34,15 @@
 
 typedef int32_t    SurfaceID;
 
-class IMemoryHeap;
-class OverlayRef;
 class GraphicBuffer;
 
 class ISurface : public IInterface
 {
 protected:
     enum {
-        REGISTER_BUFFERS = IBinder::FIRST_CALL_TRANSACTION,
-        UNREGISTER_BUFFERS,
-        POST_BUFFER, // one-way transaction
-        CREATE_OVERLAY,
+        RESERVED0 = IBinder::FIRST_CALL_TRANSACTION,
+        RESERVED1,
+        RESERVED2,
         REQUEST_BUFFER,
         SET_BUFFER_COUNT,
     };
@@ -66,49 +63,6 @@
      * sets the number of buffers dequeuable for this surface.
      */
     virtual status_t setBufferCount(int bufferCount) = 0;
-    
-    // ------------------------------------------------------------------------
-    // Deprecated...
-    // ------------------------------------------------------------------------
-
-    class BufferHeap {
-    public:
-        enum {
-            /* rotate source image */
-            ROT_0     = 0,
-            ROT_90    = HAL_TRANSFORM_ROT_90,
-            ROT_180   = HAL_TRANSFORM_ROT_180,
-            ROT_270   = HAL_TRANSFORM_ROT_270,
-        };
-        BufferHeap();
-        
-        BufferHeap(uint32_t w, uint32_t h,
-                int32_t hor_stride, int32_t ver_stride, 
-                PixelFormat format, const sp<IMemoryHeap>& heap);
-        
-        BufferHeap(uint32_t w, uint32_t h,
-                int32_t hor_stride, int32_t ver_stride, 
-                PixelFormat format, uint32_t transform, uint32_t flags,
-                const sp<IMemoryHeap>& heap);
-        
-        ~BufferHeap(); 
-        
-        uint32_t w;
-        uint32_t h;
-        int32_t hor_stride;
-        int32_t ver_stride;
-        PixelFormat format;
-        uint32_t transform;
-        uint32_t flags;
-        sp<IMemoryHeap> heap;
-    };
-    
-    virtual status_t registerBuffers(const BufferHeap& buffers) = 0;
-    virtual void postBuffer(ssize_t offset) = 0; // one-way
-    virtual void unregisterBuffers() = 0;
-    
-    virtual sp<OverlayRef> createOverlay(
-            uint32_t w, uint32_t h, int32_t format, int32_t orientation) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index da4d56f..dea1b10 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -28,6 +28,7 @@
 #include <ui/PixelFormat.h>
 
 #include <surfaceflinger/ISurfaceComposerClient.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -42,7 +43,9 @@
         eDestroyBackbuffer  = 0x00000020,
         eSecure             = 0x00000080,
         eNonPremultiplied   = 0x00000100,
-        ePushBuffers        = 0x00000200,
+        eOpaque             = 0x00000400,
+        eProtectedByApp     = 0x00000800,
+        eProtectedByDRM     = 0x00001000,
 
         eFXSurfaceNormal    = 0x00000000,
         eFXSurfaceBlur      = 0x00010000,
@@ -96,6 +99,10 @@
      */
     virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
 
+    /* create a graphic buffer allocator
+     */
+    virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0;
+
     /* retrieve the control block */
     virtual sp<IMemoryHeap> getCblk() const = 0;
 
@@ -121,7 +128,8 @@
     virtual status_t captureScreen(DisplayID dpy,
             sp<IMemoryHeap>* heap,
             uint32_t* width, uint32_t* height, PixelFormat* format,
-            uint32_t reqWidth, uint32_t reqHeight) = 0;
+            uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
 
     virtual status_t turnElectronBeamOff(int32_t mode) = 0;
     virtual status_t turnElectronBeamOn(int32_t mode) = 0;
@@ -130,6 +138,10 @@
      * This is an ASYNCHRONOUS call.
      */
     virtual void signal() const = 0;
+
+    /* verify that an ISurface was created by SurfaceFlinger.
+     */
+    virtual bool authenticateSurface(const sp<ISurface>& surface) const = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -143,6 +155,7 @@
         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
         CREATE_CONNECTION,
         CREATE_CLIENT_CONNECTION,
+        CREATE_GRAPHIC_BUFFER_ALLOC,
         GET_CBLK,
         OPEN_GLOBAL_TRANSACTION,
         CLOSE_GLOBAL_TRANSACTION,
@@ -152,7 +165,8 @@
         SIGNAL,
         CAPTURE_SCREEN,
         TURN_ELECTRON_BEAM_OFF,
-        TURN_ELECTRON_BEAM_ON
+        TURN_ELECTRON_BEAM_ON,
+        AUTHENTICATE_SURFACE,
     };
 
     virtual status_t    onTransact( uint32_t code,
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 7b2a7f5..9e0b5bb 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -94,12 +94,15 @@
     friend class SurfaceComposerClient;
 
     // camera and camcorder need access to the ISurface binder interface for preview
-    friend class Camera;
+    friend class CameraService;
     friend class MediaRecorder;
     // mediaplayer needs access to ISurface for display
     friend class MediaPlayer;
     // for testing
     friend class Test;
+    // videoEditor preview classes
+    friend class VideoEditorPreviewController;
+
     const sp<ISurface>& getISurface() const { return mSurface; }
     
 
@@ -173,13 +176,17 @@
      * (eventually this should go away and be replaced by proper APIs)
      */
     // camera and camcorder need access to the ISurface binder interface for preview
-    friend class Camera;
+    friend class CameraService;
     friend class MediaRecorder;
     // MediaPlayer needs access to ISurface for display
     friend class MediaPlayer;
     friend class IOMX;
+    friend class SoftwareRenderer;
     // this is just to be able to write some unit tests
     friend class Test;
+    // videoEditor preview classes
+    friend class VideoEditorPreviewController;
+    friend class PreviewRenderer;
 
 private:
     friend class SurfaceComposerClient;
@@ -232,9 +239,13 @@
      *  private stuff...
      */
     void init();
-    status_t validate() const;
+    status_t validate(bool inCancelBuffer = false) const;
     sp<ISurface> getISurface() const;
 
+    // When the buffer pool is a fixed size we want to make sure SurfaceFlinger
+    // won't stall clients, so we require an extra buffer.
+    enum { MIN_UNDEQUEUED_BUFFERS = 2 };
+
     inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
     inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
 
@@ -314,4 +325,3 @@
 }; // namespace android
 
 #endif // ANDROID_SF_SURFACE_H
-
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index a80832d..25b2ebf 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -183,6 +183,8 @@
     // frees the previous screenshot and capture a new one
     status_t update();
     status_t update(uint32_t reqWidth, uint32_t reqHeight);
+    status_t update(uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ);
 
     // release memory occupied by the screenshot
     void release();
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
index c419efe..edd28a6 100644
--- a/include/ui/DisplayInfo.h
+++ b/include/ui/DisplayInfo.h
@@ -37,6 +37,15 @@
     float               ydpi;
 };
 
+/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
+enum {
+    DISPLAY_ORIENTATION_0 = 0,
+    DISPLAY_ORIENTATION_90 = 1,
+    DISPLAY_ORIENTATION_180 = 2,
+    DISPLAY_ORIENTATION_270 = 3
+};
+
+
 }; // namespace android
 
 #endif // ANDROID_COMPOSER_DISPLAY_INFO_H
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
deleted file mode 100644
index d78e35f..0000000
--- a/include/ui/EventHub.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2005 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 _RUNTIME_EVENT_HUB_H
-#define _RUNTIME_EVENT_HUB_H
-
-#include <android/input.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-
-#include <linux/input.h>
-
-/* These constants are not defined in linux/input.h but they are part of the multitouch
- * input protocol. */
-
-#define ABS_MT_TOUCH_MAJOR 0x30  /* Major axis of touching ellipse */
-#define ABS_MT_TOUCH_MINOR 0x31  /* Minor axis (omit if circular) */
-#define ABS_MT_WIDTH_MAJOR 0x32  /* Major axis of approaching ellipse */
-#define ABS_MT_WIDTH_MINOR 0x33  /* Minor axis (omit if circular) */
-#define ABS_MT_ORIENTATION 0x34  /* Ellipse orientation */
-#define ABS_MT_POSITION_X 0x35   /* Center X ellipse position */
-#define ABS_MT_POSITION_Y 0x36   /* Center Y ellipse position */
-#define ABS_MT_TOOL_TYPE 0x37    /* Type of touching device (finger, pen, ...) */
-#define ABS_MT_BLOB_ID 0x38      /* Group a set of packets as a blob */
-#define ABS_MT_TRACKING_ID 0x39  /* Unique ID of initiated contact */
-#define ABS_MT_PRESSURE 0x3a     /* Pressure on contact area */
-
-#define MT_TOOL_FINGER 0 /* Identifies a finger */
-#define MT_TOOL_PEN 1    /* Identifies a pen */
-
-#define SYN_MT_REPORT 2
-
-/* Convenience constants. */
-
-#define BTN_FIRST 0x100  // first button scancode
-#define BTN_LAST 0x15f   // last button scancode
-
-struct pollfd;
-
-namespace android {
-
-class KeyLayoutMap;
-
-/*
- * A raw event as retrieved from the EventHub.
- */
-struct RawEvent {
-    nsecs_t when;
-    int32_t deviceId;
-    int32_t type;
-    int32_t scanCode;
-    int32_t keyCode;
-    int32_t value;
-    uint32_t flags;
-};
-
-/* Describes an absolute axis. */
-struct RawAbsoluteAxisInfo {
-    bool valid; // true if the information is valid, false otherwise
-
-    int32_t minValue;  // minimum value
-    int32_t maxValue;  // maximum value
-    int32_t flat;      // center flat position, eg. flat == 8 means center is between -8 and 8
-    int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
-
-    inline int32_t getRange() { return maxValue - minValue; }
-
-    inline void clear() {
-        valid = false;
-        minValue = 0;
-        maxValue = 0;
-        flat = 0;
-        fuzz = 0;
-    }
-};
-
-/*
- * Input device classes.
- */
-enum {
-    /* The input device is a keyboard. */
-    INPUT_DEVICE_CLASS_KEYBOARD      = 0x00000001,
-
-    /* The input device is an alpha-numeric keyboard (not just a dial pad). */
-    INPUT_DEVICE_CLASS_ALPHAKEY      = 0x00000002,
-
-    /* The input device is a touchscreen (either single-touch or multi-touch). */
-    INPUT_DEVICE_CLASS_TOUCHSCREEN   = 0x00000004,
-
-    /* The input device is a trackball. */
-    INPUT_DEVICE_CLASS_TRACKBALL     = 0x00000008,
-
-    /* The input device is a multi-touch touchscreen. */
-    INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010,
-
-    /* The input device is a directional pad (implies keyboard, has DPAD keys). */
-    INPUT_DEVICE_CLASS_DPAD          = 0x00000020,
-
-    /* The input device is a gamepad (implies keyboard, has BUTTON keys). */
-    INPUT_DEVICE_CLASS_GAMEPAD       = 0x00000040,
-
-    /* The input device has switches. */
-    INPUT_DEVICE_CLASS_SWITCH        = 0x00000080,
-};
-
-/*
- * Grand Central Station for events.
- *
- * The event hub aggregates input events received across all known input
- * devices on the system, including devices that may be emulated by the simulator
- * environment.  In addition, the event hub generates fake input events to indicate
- * when devices are added or removed.
- *
- * The event hub provies a stream of input events (via the getEvent function).
- * It also supports querying the current actual state of input devices such as identifying
- * which keys are currently down.  Finally, the event hub keeps track of the capabilities of
- * individual input devices, such as their class and the set of key codes that they support.
- */
-class EventHubInterface : public virtual RefBase {
-protected:
-    EventHubInterface() { }
-    virtual ~EventHubInterface() { }
-
-public:
-    // Synthetic raw event type codes produced when devices are added or removed.
-    enum {
-        // Sent when a device is added.
-        DEVICE_ADDED = 0x10000000,
-        // Sent when a device is removed.
-        DEVICE_REMOVED = 0x20000000,
-        // Sent when all added/removed devices from the most recent scan have been reported.
-        // This event is always sent at least once.
-        FINISHED_DEVICE_SCAN = 0x30000000,
-    };
-
-    virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
-
-    virtual String8 getDeviceName(int32_t deviceId) const = 0;
-
-    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-            RawAbsoluteAxisInfo* outAxisInfo) const = 0;
-
-    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
-            int32_t* outKeycode, uint32_t* outFlags) const = 0;
-
-    // exclude a particular device from opening
-    // this can be used to ignore input devices for sensors
-    virtual void addExcludedDevice(const char* deviceName) = 0;
-
-    /*
-     * Wait for the next event to become available and return it.
-     * After returning, the EventHub holds onto a wake lock until the next call to getEvent.
-     * This ensures that the device will not go to sleep while the event is being processed.
-     * If the device needs to remain awake longer than that, then the caller is responsible
-     * for taking care of it (say, by poking the power manager user activity timer).
-     */
-    virtual bool getEvent(RawEvent* outEvent) = 0;
-
-    /*
-     * Query current input state.
-     */
-    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
-    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
-    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
-
-    /*
-     * Examine key input devices for specific framework keycode support
-     */
-    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
-            uint8_t* outFlags) const = 0;
-
-    virtual void dump(String8& dump) = 0;
-};
-
-class EventHub : public EventHubInterface
-{
-public:
-    EventHub();
-
-    status_t errorCheck() const;
-
-    virtual uint32_t getDeviceClasses(int32_t deviceId) const;
-    
-    virtual String8 getDeviceName(int32_t deviceId) const;
-    
-    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-            RawAbsoluteAxisInfo* outAxisInfo) const;
-
-    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
-            int32_t* outKeycode, uint32_t* outFlags) const;
-
-    virtual void addExcludedDevice(const char* deviceName);
-
-    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
-    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
-    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
-
-    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags) const;
-
-    virtual bool getEvent(RawEvent* outEvent);
-
-    virtual void dump(String8& dump);
-
-protected:
-    virtual ~EventHub();
-    
-private:
-    bool openPlatformInput(void);
-
-    int openDevice(const char *device);
-    int closeDevice(const char *device);
-    int scanDir(const char *dirname);
-    int readNotify(int nfd);
-
-    status_t mError;
-
-    struct device_t {
-        const int32_t   id;
-        const String8   path;
-        String8         name;
-        uint32_t        classes;
-        uint8_t*        keyBitmask;
-        KeyLayoutMap*   layoutMap;
-        String8         keylayoutFilename;
-        int             fd;
-        device_t*       next;
-        
-        device_t(int32_t _id, const char* _path, const char* name);
-        ~device_t();
-    };
-
-    device_t* getDeviceLocked(int32_t deviceId) const;
-    bool hasKeycodeLocked(device_t* device, int keycode) const;
-    
-    int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const;
-    int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const;
-    int32_t getSwitchStateLocked(device_t* device, int32_t sw) const;
-    bool markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags) const;
-
-    // Protect all internal state.
-    mutable Mutex   mLock;
-    
-    bool            mHaveFirstKeyboard;
-    int32_t         mFirstKeyboardId; // the API is that the built-in keyboard is id 0, so map it
-    
-    struct device_ent {
-        device_t* device;
-        uint32_t seq;
-    };
-    device_ent      *mDevicesById;
-    int             mNumDevicesById;
-    
-    device_t        *mOpeningDevices;
-    device_t        *mClosingDevices;
-    
-    device_t        **mDevices;
-    struct pollfd   *mFDs;
-    int             mFDCount;
-
-    bool            mOpened;
-    bool            mNeedToSendFinishedDeviceScan;
-    List<String8>   mExcludedDevices;
-
-    // device ids that report particular switches.
-#ifdef EV_SW
-    int32_t         mSwitches[SW_MAX + 1];
-#endif
-
-    static const int INPUT_BUFFER_SIZE = 64;
-    struct input_event mInputBufferData[INPUT_BUFFER_SIZE];
-    int32_t mInputBufferIndex;
-    int32_t mInputBufferCount;
-    int32_t mInputDeviceIndex;
-};
-
-}; // namespace android
-
-#endif // _RUNTIME_EVENT_HUB_H
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 2cd0911..16117ad 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -23,6 +23,7 @@
 #include <EGL/egl.h>
 
 #include <utils/threads.h>
+#include <utils/String8.h>
 #include <ui/Rect.h>
 
 #include <pixelflinger/pixelflinger.h>
@@ -56,7 +57,9 @@
     bool isUpdateOnDemand() const { return mUpdateOnDemand; }
     status_t setUpdateRectangle(const Rect& updateRect);
     status_t compositionComplete();
-    
+
+    void dump(String8& result);
+
     // for debugging only
     int getCurrentBufferIndex() const;
 
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 0be26a7..02d6f8f 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -26,8 +26,6 @@
 #include <utils/Flattenable.h>
 #include <pixelflinger/pixelflinger.h>
 
-#include <hardware/hardware.h>
-
 struct android_native_buffer_t;
 
 namespace android {
@@ -56,22 +54,17 @@
         USAGE_SW_WRITE_RARELY   = GRALLOC_USAGE_SW_WRITE_RARELY,
         USAGE_SW_WRITE_OFTEN    = GRALLOC_USAGE_SW_WRITE_OFTEN,
         USAGE_SW_WRITE_MASK     = GRALLOC_USAGE_SW_WRITE_MASK,
-        
+
         USAGE_SOFTWARE_MASK     = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK,
-        
+
+        USAGE_PROTECTED         = GRALLOC_USAGE_PROTECTED,
+
         USAGE_HW_TEXTURE        = GRALLOC_USAGE_HW_TEXTURE,
         USAGE_HW_RENDER         = GRALLOC_USAGE_HW_RENDER,
         USAGE_HW_2D             = GRALLOC_USAGE_HW_2D,
         USAGE_HW_MASK           = GRALLOC_USAGE_HW_MASK
     };
 
-    enum {
-        TRANSFORM_IDENTITY      = 0,
-        TRANSFORM_ROT_90        = HAL_TRANSFORM_ROT_90,
-        TRANSFORM_ROT_180       = HAL_TRANSFORM_ROT_180,
-        TRANSFORM_ROT_270       = HAL_TRANSFORM_ROT_270
-    };
-
     GraphicBuffer();
 
     // creates w * h buffer
@@ -81,6 +74,9 @@
     GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
             uint32_t stride, native_handle_t* handle, bool keepOwnership);
 
+    // create a buffer from an existing android_native_buffer_t
+    GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership);
+
     // return status
     status_t initCheck() const;
 
@@ -88,7 +84,6 @@
     uint32_t getHeight() const          { return height; }
     uint32_t getStride() const          { return stride; }
     uint32_t getUsage() const           { return usage; }
-    uint32_t getTransform() const       { return transform; }
     PixelFormat getPixelFormat() const  { return format; }
     Rect getBounds() const              { return Rect(width, height); }
     
@@ -128,6 +123,7 @@
     friend class Surface;
     friend class BpSurface;
     friend class BnSurface;
+    friend class SurfaceTextureClient;
     friend class LightRefBase<GraphicBuffer>;
     GraphicBuffer(const GraphicBuffer& rhs);
     GraphicBuffer& operator = (const GraphicBuffer& rhs);
@@ -150,6 +146,10 @@
     GraphicBufferMapper& mBufferMapper;
     ssize_t mInitCheck;
     int mIndex;
+
+    // If we're wrapping another buffer then this reference will make sure it
+    // doesn't get freed.
+    sp<android_native_buffer_t> mWrappedBuffer;
 };
 
 }; // namespace android
diff --git a/include/ui/IOverlay.h b/include/ui/IOverlay.h
deleted file mode 100644
index af3add1..0000000
--- a/include/ui/IOverlay.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007 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_IOVERLAY_H
-#define ANDROID_IOVERLAY_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <utils/RefBase.h>
-#include <ui/PixelFormat.h>
-
-namespace android {
-
-class IOverlay : public IInterface
-{
-public: 
-    DECLARE_META_INTERFACE(Overlay);
-
-    virtual void destroy() = 0; // one-way
-};
-
-// ----------------------------------------------------------------------------
-
-class BnOverlay : public BnInterface<IOverlay>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_IOVERLAY_H
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 4e809d6..d9d77c4 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -28,6 +28,10 @@
 #include <utils/RefBase.h>
 #include <utils/String8.h>
 
+#ifdef HAVE_ANDROID_OS
+class SkMatrix;
+#endif
+
 /*
  * Additional private constants not defined in ndk/ui/input.h.
  */
@@ -48,10 +52,20 @@
 };
 
 /*
+ * SystemUiVisibility constants from View.
+ */
+enum {
+    ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0,
+    ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001,
+};
+
+/*
  * Maximum number of pointers supported per motion event.
  * Smallest number of pointers is 1.
+ * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
+ * will occasionally emit 11.  There is not much harm making this constant bigger.)
  */
-#define MAX_POINTERS 10
+#define MAX_POINTERS 16
 
 /*
  * Maximum pointer id value supported in a motion event.
@@ -77,6 +91,10 @@
 
 namespace android {
 
+#ifdef HAVE_ANDROID_OS
+class Parcel;
+#endif
+
 /*
  * Flags that flow alongside events in the input dispatch system to help with certain
  * policy decisions such as waking from device sleep.
@@ -85,7 +103,7 @@
  */
 enum {
     /* These flags originate in RawEvents and are generally set in the key map.
-     * See also labels for policy flags in KeycodeLabels.h. */
+     * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */
 
     POLICY_FLAG_WAKE = 0x00000001,
     POLICY_FLAG_WAKE_DROPPED = 0x00000002,
@@ -96,6 +114,7 @@
     POLICY_FLAG_MENU = 0x00000040,
     POLICY_FLAG_LAUNCHER = 0x00000080,
     POLICY_FLAG_VIRTUAL = 0x00000100,
+    POLICY_FLAG_FUNCTION = 0x00000200,
 
     POLICY_FLAG_RAW_MASK = 0x0000ffff,
 
@@ -125,6 +144,14 @@
 };
 
 /*
+ * Button state.
+ */
+enum {
+    // Primary button pressed (left mouse button).
+    BUTTON_STATE_PRIMARY = 1 << 0,
+};
+
+/*
  * Describes the basic configuration of input devices that are present.
  */
 struct InputConfiguration {
@@ -159,15 +186,30 @@
  * Pointer coordinate data.
  */
 struct PointerCoords {
-    float x;
-    float y;
-    float pressure;
-    float size;
-    float touchMajor;
-    float touchMinor;
-    float toolMajor;
-    float toolMinor;
-    float orientation;
+    enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64
+
+    // Bitfield of axes that are present in this structure.
+    uint64_t bits;
+
+    // Values of axes that are stored in this structure packed in order by axis id
+    // for each axis that is present in the structure according to 'bits'.
+    float values[MAX_AXES];
+
+    inline void clear() {
+        bits = 0;
+    }
+
+    float getAxisValue(int32_t axis) const;
+    status_t setAxisValue(int32_t axis, float value);
+    float* editAxisValue(int32_t axis);
+
+#ifdef HAVE_ANDROID_OS
+    status_t readFromParcel(Parcel* parcel);
+    status_t writeToParcel(Parcel* parcel) const;
+#endif
+
+private:
+    void tooManyAxes(int axis);
 };
 
 /*
@@ -182,12 +224,13 @@
     inline int32_t getDeviceId() const { return mDeviceId; }
 
     inline int32_t getSource() const { return mSource; }
-    
+
+    inline void setSource(int32_t source) { mSource = source; }
+
 protected:
     void initialize(int32_t deviceId, int32_t source);
     void initialize(const InputEvent& from);
 
-private:
     int32_t mDeviceId;
     int32_t mSource;
 };
@@ -238,7 +281,7 @@
             nsecs_t eventTime);
     void initialize(const KeyEvent& from);
 
-private:
+protected:
     int32_t mAction;
     int32_t mFlags;
     int32_t mKeyCode;
@@ -260,12 +303,18 @@
 
     inline int32_t getAction() const { return mAction; }
 
+    inline void setAction(int32_t action) { mAction = action; }
+
     inline int32_t getFlags() const { return mFlags; }
 
     inline int32_t getEdgeFlags() const { return mEdgeFlags; }
 
+    inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
+
     inline int32_t getMetaState() const { return mMetaState; }
 
+    inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
+
     inline float getXOffset() const { return mXOffset; }
 
     inline float getYOffset() const { return mYOffset; }
@@ -282,48 +331,54 @@
 
     inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
 
+    const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
+
+    float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
+
     inline float getRawX(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).x;
+        return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
     }
 
     inline float getRawY(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).y;
+        return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
     }
 
+    float getAxisValue(int32_t axis, size_t pointerIndex) const;
+
     inline float getX(size_t pointerIndex) const {
-        return getRawX(pointerIndex) + mXOffset;
+        return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
     }
 
     inline float getY(size_t pointerIndex) const {
-        return getRawY(pointerIndex) + mYOffset;
+        return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
     }
 
     inline float getPressure(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).pressure;
+        return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
     }
 
     inline float getSize(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).size;
+        return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
     }
 
     inline float getTouchMajor(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).touchMajor;
+        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
     }
 
     inline float getTouchMinor(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).touchMinor;
+        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
     }
 
     inline float getToolMajor(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).toolMajor;
+        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
     }
 
     inline float getToolMinor(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).toolMinor;
+        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
     }
 
     inline float getOrientation(size_t pointerIndex) const {
-        return getCurrentPointerCoords(pointerIndex).orientation;
+        return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
     }
 
     inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
@@ -332,48 +387,67 @@
         return mSampleEventTimes[historicalIndex];
     }
 
+    const PointerCoords* getHistoricalRawPointerCoords(
+            size_t pointerIndex, size_t historicalIndex) const;
+
+    float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
+            size_t historicalIndex) const;
+
     inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).x;
+        return getHistoricalRawAxisValue(
+                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).y;
+        return getHistoricalRawAxisValue(
+                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
     }
 
+    float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
+
     inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalRawX(pointerIndex, historicalIndex) + mXOffset;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalRawY(pointerIndex, historicalIndex) + mYOffset;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).pressure;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).size;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMajor;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMinor;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMajor;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMinor;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
     }
 
     inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalPointerCoords(pointerIndex, historicalIndex).orientation;
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
     }
 
     void initialize(
@@ -393,12 +467,28 @@
             const int32_t* pointerIds,
             const PointerCoords* pointerCoords);
 
+    void copyFrom(const MotionEvent* other, bool keepHistory);
+
     void addSample(
             nsecs_t eventTime,
             const PointerCoords* pointerCoords);
 
     void offsetLocation(float xOffset, float yOffset);
 
+    void scale(float scaleFactor);
+
+#ifdef HAVE_ANDROID_OS
+    void transform(const SkMatrix* matrix);
+
+    status_t readFromParcel(Parcel* parcel);
+    status_t writeToParcel(Parcel* parcel) const;
+#endif
+
+    static bool isTouchEvent(int32_t source, int32_t action);
+    inline bool isTouchEvent() const {
+        return isTouchEvent(mSource, mAction);
+    }
+
     // Low-level accessors.
     inline const int32_t* getPointerIds() const { return mPointerIds.array(); }
     inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
@@ -406,7 +496,7 @@
             return mSamplePointerCoords.array();
     }
 
-private:
+protected:
     int32_t mAction;
     int32_t mFlags;
     int32_t mEdgeFlags;
@@ -419,15 +509,6 @@
     Vector<int32_t> mPointerIds;
     Vector<nsecs_t> mSampleEventTimes;
     Vector<PointerCoords> mSamplePointerCoords;
-
-    inline const PointerCoords& getCurrentPointerCoords(size_t pointerIndex) const {
-        return mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
-    }
-
-    inline const PointerCoords& getHistoricalPointerCoords(
-            size_t pointerIndex, size_t historicalIndex) const {
-        return mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
-    }
 };
 
 /*
@@ -471,6 +552,8 @@
     ~InputDeviceInfo();
 
     struct MotionRange {
+        int32_t axis;
+        uint32_t source;
         float min;
         float max;
         float flat;
@@ -483,16 +566,17 @@
     inline const String8 getName() const { return mName; }
     inline uint32_t getSources() const { return mSources; }
 
-    const MotionRange* getMotionRange(int32_t rangeType) const;
+    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
 
     void addSource(uint32_t source);
-    void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
-    void addMotionRange(int32_t rangeType, const MotionRange& range);
+    void addMotionRange(int32_t axis, uint32_t source,
+            float min, float max, float flat, float fuzz);
+    void addMotionRange(const MotionRange& range);
 
     inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
     inline int32_t getKeyboardType() const { return mKeyboardType; }
 
-    inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
+    inline const Vector<MotionRange>& getMotionRanges() const {
         return mMotionRanges;
     }
 
@@ -502,9 +586,57 @@
     uint32_t mSources;
     int32_t mKeyboardType;
 
-    KeyedVector<int32_t, MotionRange> mMotionRanges;
+    Vector<MotionRange> mMotionRanges;
 };
 
+/*
+ * Identifies a device.
+ */
+struct InputDeviceIdentifier {
+    inline InputDeviceIdentifier() :
+            bus(0), vendor(0), product(0), version(0) {
+    }
+
+    String8 name;
+    String8 location;
+    String8 uniqueId;
+    uint16_t bus;
+    uint16_t vendor;
+    uint16_t product;
+    uint16_t version;
+};
+
+/* Types of input device configuration files. */
+enum InputDeviceConfigurationFileType {
+    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0,     /* .idc file */
+    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1,        /* .kl file */
+    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */
+};
+
+/*
+ * Gets the path of an input device configuration file, if one is available.
+ * Considers both system provided and user installed configuration files.
+ *
+ * The device identifier is used to construct several default configuration file
+ * names to try based on the device name, vendor, product, and version.
+ *
+ * Returns an empty string if not found.
+ */
+extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
+        const InputDeviceIdentifier& deviceIdentifier,
+        InputDeviceConfigurationFileType type);
+
+/*
+ * Gets the path of an input device configuration file, if one is available.
+ * Considers both system provided and user installed configuration files.
+ *
+ * The name is case-sensitive and is used to construct the filename to resolve.
+ * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.
+ *
+ * Returns an empty string if not found.
+ */
+extern String8 getInputDeviceConfigurationFilePathByName(
+        const String8& name, InputDeviceConfigurationFileType type);
 
 } // namespace android
 
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
deleted file mode 100644
index 5f77cba..0000000
--- a/include/ui/InputDispatcher.h
+++ /dev/null
@@ -1,1083 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _UI_INPUT_DISPATCHER_H
-#define _UI_INPUT_DISPATCHER_H
-
-#include <ui/Input.h>
-#include <ui/InputTransport.h>
-#include <utils/KeyedVector.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Looper.h>
-#include <utils/Pool.h>
-#include <utils/BitSet.h>
-
-#include <stddef.h>
-#include <unistd.h>
-#include <limits.h>
-
-
-namespace android {
-
-/*
- * Constants used to report the outcome of input event injection.
- */
-enum {
-    /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
-    INPUT_EVENT_INJECTION_PENDING = -1,
-
-    /* Injection succeeded. */
-    INPUT_EVENT_INJECTION_SUCCEEDED = 0,
-
-    /* Injection failed because the injector did not have permission to inject
-     * into the application with input focus. */
-    INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1,
-
-    /* Injection failed because there were no available input targets. */
-    INPUT_EVENT_INJECTION_FAILED = 2,
-
-    /* Injection failed due to a timeout. */
-    INPUT_EVENT_INJECTION_TIMED_OUT = 3
-};
-
-/*
- * Constants used to determine the input event injection synchronization mode.
- */
-enum {
-    /* Injection is asynchronous and is assumed always to be successful. */
-    INPUT_EVENT_INJECTION_SYNC_NONE = 0,
-
-    /* Waits for previous events to be dispatched so that the input dispatcher can determine
-     * whether input event injection willbe permitted based on the current input focus.
-     * Does not wait for the input event to finish processing. */
-    INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1,
-
-    /* Waits for the input event to be completely processed. */
-    INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2,
-};
-
-
-/*
- * An input target specifies how an input event is to be dispatched to a particular window
- * including the window's input channel, control flags, a timeout, and an X / Y offset to
- * be added to input event coordinates to compensate for the absolute position of the
- * window area.
- */
-struct InputTarget {
-    enum {
-        /* This flag indicates that the event is being delivered to a foreground application. */
-        FLAG_FOREGROUND = 0x01,
-
-        /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside
-         * of the area of this target and so should instead be delivered as an
-         * AMOTION_EVENT_ACTION_OUTSIDE to this target. */
-        FLAG_OUTSIDE = 0x02,
-
-        /* This flag indicates that the target of a MotionEvent is partly or wholly
-         * obscured by another visible window above it.  The motion event should be
-         * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
-        FLAG_WINDOW_IS_OBSCURED = 0x04,
-
-        /* This flag indicates that a motion event is being split across multiple windows. */
-        FLAG_SPLIT = 0x08,
-    };
-
-    // The input channel to be targeted.
-    sp<InputChannel> inputChannel;
-
-    // Flags for the input target.
-    int32_t flags;
-
-    // The x and y offset to add to a MotionEvent as it is delivered.
-    // (ignored for KeyEvents)
-    float xOffset, yOffset;
-
-    // The subset of pointer ids to include in motion events dispatched to this input target
-    // if FLAG_SPLIT is set.
-    BitSet32 pointerIds;
-};
-
-
-/*
- * An input window describes the bounds of a window that can receive input.
- */
-struct InputWindow {
-    // Window flags from WindowManager.LayoutParams
-    enum {
-        FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001,
-        FLAG_DIM_BEHIND        = 0x00000002,
-        FLAG_BLUR_BEHIND        = 0x00000004,
-        FLAG_NOT_FOCUSABLE      = 0x00000008,
-        FLAG_NOT_TOUCHABLE      = 0x00000010,
-        FLAG_NOT_TOUCH_MODAL    = 0x00000020,
-        FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040,
-        FLAG_KEEP_SCREEN_ON     = 0x00000080,
-        FLAG_LAYOUT_IN_SCREEN   = 0x00000100,
-        FLAG_LAYOUT_NO_LIMITS   = 0x00000200,
-        FLAG_FULLSCREEN      = 0x00000400,
-        FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800,
-        FLAG_DITHER             = 0x00001000,
-        FLAG_SECURE             = 0x00002000,
-        FLAG_SCALED             = 0x00004000,
-        FLAG_IGNORE_CHEEK_PRESSES    = 0x00008000,
-        FLAG_LAYOUT_INSET_DECOR = 0x00010000,
-        FLAG_ALT_FOCUSABLE_IM = 0x00020000,
-        FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000,
-        FLAG_SHOW_WHEN_LOCKED = 0x00080000,
-        FLAG_SHOW_WALLPAPER = 0x00100000,
-        FLAG_TURN_SCREEN_ON = 0x00200000,
-        FLAG_DISMISS_KEYGUARD = 0x00400000,
-        FLAG_SPLIT_TOUCH = 0x00800000,
-        FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000,
-        FLAG_COMPATIBLE_WINDOW = 0x20000000,
-        FLAG_SYSTEM_ERROR = 0x40000000,
-    };
-
-    // Window types from WindowManager.LayoutParams
-    enum {
-        FIRST_APPLICATION_WINDOW = 1,
-        TYPE_BASE_APPLICATION   = 1,
-        TYPE_APPLICATION        = 2,
-        TYPE_APPLICATION_STARTING = 3,
-        LAST_APPLICATION_WINDOW = 99,
-        FIRST_SUB_WINDOW        = 1000,
-        TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW,
-        TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1,
-        TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2,
-        TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3,
-        TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW+4,
-        LAST_SUB_WINDOW         = 1999,
-        FIRST_SYSTEM_WINDOW     = 2000,
-        TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW,
-        TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1,
-        TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2,
-        TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3,
-        TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4,
-        TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5,
-        TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6,
-        TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7,
-        TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8,
-        TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9,
-        TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10,
-        TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11,
-        TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
-        TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13,
-        TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14,
-        TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15,
-        LAST_SYSTEM_WINDOW      = 2999,
-    };
-
-    sp<InputChannel> inputChannel;
-    String8 name;
-    int32_t layoutParamsFlags;
-    int32_t layoutParamsType;
-    nsecs_t dispatchingTimeout;
-    int32_t frameLeft;
-    int32_t frameTop;
-    int32_t frameRight;
-    int32_t frameBottom;
-    int32_t visibleFrameLeft;
-    int32_t visibleFrameTop;
-    int32_t visibleFrameRight;
-    int32_t visibleFrameBottom;
-    int32_t touchableAreaLeft;
-    int32_t touchableAreaTop;
-    int32_t touchableAreaRight;
-    int32_t touchableAreaBottom;
-    bool visible;
-    bool canReceiveKeys;
-    bool hasFocus;
-    bool hasWallpaper;
-    bool paused;
-    int32_t layer;
-    int32_t ownerPid;
-    int32_t ownerUid;
-
-    bool touchableAreaContainsPoint(int32_t x, int32_t y) const;
-    bool frameContainsPoint(int32_t x, int32_t y) const;
-
-    /* Returns true if the window is of a trusted type that is allowed to silently
-     * overlay other windows for the purpose of implementing the secure views feature.
-     * Trusted overlays, such as IME windows, can partly obscure other windows without causing
-     * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
-     */
-    bool isTrustedOverlay() const;
-};
-
-
-/*
- * A private handle type used by the input manager to track the window.
- */
-class InputApplicationHandle : public RefBase {
-protected:
-    InputApplicationHandle() { }
-    virtual ~InputApplicationHandle() { }
-};
-
-
-/*
- * An input application describes properties of an application that can receive input.
- */
-struct InputApplication {
-    String8 name;
-    nsecs_t dispatchingTimeout;
-    sp<InputApplicationHandle> handle;
-};
-
-
-/*
- * Input dispatcher policy interface.
- *
- * The input reader policy is used by the input reader to interact with the Window Manager
- * and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI.  This interface is also mocked in the unit tests.
- */
-class InputDispatcherPolicyInterface : public virtual RefBase {
-protected:
-    InputDispatcherPolicyInterface() { }
-    virtual ~InputDispatcherPolicyInterface() { }
-
-public:
-    /* Notifies the system that a configuration change has occurred. */
-    virtual void notifyConfigurationChanged(nsecs_t when) = 0;
-
-    /* Notifies the system that an application is not responding.
-     * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
-    virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputChannel>& inputChannel) = 0;
-
-    /* Notifies the system that an input channel is unrecoverably broken. */
-    virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0;
-
-    /* Gets the key repeat initial timeout or -1 if automatic key repeating is disabled. */
-    virtual nsecs_t getKeyRepeatTimeout() = 0;
-
-    /* Gets the key repeat inter-key delay. */
-    virtual nsecs_t getKeyRepeatDelay() = 0;
-
-    /* Gets the maximum suggested event delivery rate per second.
-     * This value is used to throttle motion event movement actions on a per-device
-     * basis.  It is not intended to be a hard limit.
-     */
-    virtual int32_t getMaxEventsPerSecond() = 0;
-
-    /* Intercepts a key event immediately before queueing it.
-     * The policy can use this method as an opportunity to perform power management functions
-     * and early event preprocessing such as updating policy flags.
-     *
-     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
-     * should be dispatched to applications.
-     */
-    virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
-            int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
-            uint32_t& policyFlags) = 0;
-
-    /* Intercepts a generic touch, trackball or other event before queueing it.
-     * The policy can use this method as an opportunity to perform power management functions
-     * and early event preprocessing such as updating policy flags.
-     *
-     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
-     * should be dispatched to applications.
-     */
-    virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
-
-    /* Allows the policy a chance to intercept a key before dispatching. */
-    virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
-            const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
-
-    /* Notifies the policy about switch events.
-     */
-    virtual void notifySwitch(nsecs_t when,
-            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;
-
-    /* Poke user activity for an event dispatched to a window. */
-    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;
-
-    /* Checks whether a given application pid/uid has permission to inject input events
-     * into other applications.
-     *
-     * This method is special in that its implementation promises to be non-reentrant and
-     * is safe to call while holding other locks.  (Most other methods make no such guarantees!)
-     */
-    virtual bool checkInjectEventsPermissionNonReentrant(
-            int32_t injectorPid, int32_t injectorUid) = 0;
-};
-
-
-/* Notifies the system about input events generated by the input reader.
- * The dispatcher is expected to be mostly asynchronous. */
-class InputDispatcherInterface : public virtual RefBase {
-protected:
-    InputDispatcherInterface() { }
-    virtual ~InputDispatcherInterface() { }
-
-public:
-    /* Dumps the state of the input dispatcher.
-     *
-     * This method may be called on any thread (usually by the input manager). */
-    virtual void dump(String8& dump) = 0;
-
-    /* Runs a single iteration of the dispatch loop.
-     * Nominally processes one queued event, a timeout, or a response from an input consumer.
-     *
-     * This method should only be called on the input dispatcher thread.
-     */
-    virtual void dispatchOnce() = 0;
-
-    /* Notifies the dispatcher about new events.
-     *
-     * These methods should only be called on the input reader thread.
-     */
-    virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
-    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
-            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
-            int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
-    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
-            uint32_t policyFlags, int32_t action, int32_t flags,
-            int32_t metaState, int32_t edgeFlags,
-            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
-            float xPrecision, float yPrecision, nsecs_t downTime) = 0;
-    virtual void notifySwitch(nsecs_t when,
-            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;
-
-    /* Injects an input event and optionally waits for sync.
-     * The synchronization mode determines whether the method blocks while waiting for
-     * input injection to proceed.
-     * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual int32_t injectInputEvent(const InputEvent* event,
-            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
-
-    /* Sets the list of input windows.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void setInputWindows(const Vector<InputWindow>& inputWindows) = 0;
-
-    /* Sets the focused application.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void setFocusedApplication(const InputApplication* inputApplication) = 0;
-
-    /* Sets the input dispatching mode.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void setInputDispatchMode(bool enabled, bool frozen) = 0;
-
-    /* Registers or unregister input channels that may be used as targets for input events.
-     * If monitor is true, the channel will receive a copy of all input events.
-     *
-     * These methods may be called on any thread (usually by the input manager).
-     */
-    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) = 0;
-    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
-};
-
-/* Dispatches events to input targets.  Some functions of the input dispatcher, such as
- * identifying input targets, are controlled by a separate policy object.
- *
- * IMPORTANT INVARIANT:
- *     Because the policy can potentially block or cause re-entrance into the input dispatcher,
- *     the input dispatcher never calls into the policy while holding its internal locks.
- *     The implementation is also carefully designed to recover from scenarios such as an
- *     input channel becoming unregistered while identifying input targets or processing timeouts.
- *
- *     Methods marked 'Locked' must be called with the lock acquired.
- *
- *     Methods marked 'LockedInterruptible' must be called with the lock acquired but
- *     may during the course of their execution release the lock, call into the policy, and
- *     then reacquire the lock.  The caller is responsible for recovering gracefully.
- *
- *     A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
- */
-class InputDispatcher : public InputDispatcherInterface {
-protected:
-    virtual ~InputDispatcher();
-
-public:
-    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
-
-    virtual void dump(String8& dump);
-
-    virtual void dispatchOnce();
-
-    virtual void notifyConfigurationChanged(nsecs_t eventTime);
-    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
-            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
-            int32_t scanCode, int32_t metaState, nsecs_t downTime);
-    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
-            uint32_t policyFlags, int32_t action, int32_t flags,
-            int32_t metaState, int32_t edgeFlags,
-            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
-            float xPrecision, float yPrecision, nsecs_t downTime);
-    virtual void notifySwitch(nsecs_t when,
-            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ;
-
-    virtual int32_t injectInputEvent(const InputEvent* event,
-            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
-
-    virtual void setInputWindows(const Vector<InputWindow>& inputWindows);
-    virtual void setFocusedApplication(const InputApplication* inputApplication);
-    virtual void setInputDispatchMode(bool enabled, bool frozen);
-
-    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor);
-    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
-
-private:
-    template <typename T>
-    struct Link {
-        T* next;
-        T* prev;
-    };
-
-    struct InjectionState {
-        mutable int32_t refCount;
-
-        int32_t injectorPid;
-        int32_t injectorUid;
-        int32_t injectionResult;  // initially INPUT_EVENT_INJECTION_PENDING
-        bool injectionIsAsync; // set to true if injection is not waiting for the result
-        int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
-    };
-
-    struct EventEntry : Link<EventEntry> {
-        enum {
-            TYPE_SENTINEL,
-            TYPE_CONFIGURATION_CHANGED,
-            TYPE_KEY,
-            TYPE_MOTION
-        };
-
-        mutable int32_t refCount;
-        int32_t type;
-        nsecs_t eventTime;
-        uint32_t policyFlags;
-        InjectionState* injectionState;
-
-        bool dispatchInProgress; // initially false, set to true while dispatching
-
-        inline bool isInjected() { return injectionState != NULL; }
-    };
-
-    struct ConfigurationChangedEntry : EventEntry {
-    };
-
-    struct KeyEntry : EventEntry {
-        int32_t deviceId;
-        int32_t source;
-        int32_t action;
-        int32_t flags;
-        int32_t keyCode;
-        int32_t scanCode;
-        int32_t metaState;
-        int32_t repeatCount;
-        nsecs_t downTime;
-
-        bool syntheticRepeat; // set to true for synthetic key repeats
-
-        enum InterceptKeyResult {
-            INTERCEPT_KEY_RESULT_UNKNOWN,
-            INTERCEPT_KEY_RESULT_SKIP,
-            INTERCEPT_KEY_RESULT_CONTINUE,
-        };
-        InterceptKeyResult interceptKeyResult; // set based on the interception result
-    };
-
-    struct MotionSample {
-        MotionSample* next;
-
-        nsecs_t eventTime;
-        PointerCoords pointerCoords[MAX_POINTERS];
-    };
-
-    struct MotionEntry : EventEntry {
-        int32_t deviceId;
-        int32_t source;
-        int32_t action;
-        int32_t flags;
-        int32_t metaState;
-        int32_t edgeFlags;
-        float xPrecision;
-        float yPrecision;
-        nsecs_t downTime;
-        uint32_t pointerCount;
-        int32_t pointerIds[MAX_POINTERS];
-
-        // Linked list of motion samples associated with this motion event.
-        MotionSample firstSample;
-        MotionSample* lastSample;
-
-        uint32_t countSamples() const;
-    };
-
-    // Tracks the progress of dispatching a particular event to a particular connection.
-    struct DispatchEntry : Link<DispatchEntry> {
-        EventEntry* eventEntry; // the event to dispatch
-        int32_t targetFlags;
-        float xOffset;
-        float yOffset;
-
-        // True if dispatch has started.
-        bool inProgress;
-
-        // For motion events:
-        //   Pointer to the first motion sample to dispatch in this cycle.
-        //   Usually NULL to indicate that the list of motion samples begins at
-        //   MotionEntry::firstSample.  Otherwise, some samples were dispatched in a previous
-        //   cycle and this pointer indicates the location of the first remainining sample
-        //   to dispatch during the current cycle.
-        MotionSample* headMotionSample;
-        //   Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
-        //   unable to send all motion samples during this cycle.  On the next cycle,
-        //   headMotionSample will be initialized to tailMotionSample and tailMotionSample
-        //   will be set to NULL.
-        MotionSample* tailMotionSample;
-
-        inline bool hasForegroundTarget() const {
-            return targetFlags & InputTarget::FLAG_FOREGROUND;
-        }
-
-        inline bool isSplit() const {
-            return targetFlags & InputTarget::FLAG_SPLIT;
-        }
-    };
-
-    // A command entry captures state and behavior for an action to be performed in the
-    // dispatch loop after the initial processing has taken place.  It is essentially
-    // a kind of continuation used to postpone sensitive policy interactions to a point
-    // in the dispatch loop where it is safe to release the lock (generally after finishing
-    // the critical parts of the dispatch cycle).
-    //
-    // The special thing about commands is that they can voluntarily release and reacquire
-    // the dispatcher lock at will.  Initially when the command starts running, the
-    // dispatcher lock is held.  However, if the command needs to call into the policy to
-    // do some work, it can release the lock, do the work, then reacquire the lock again
-    // before returning.
-    //
-    // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
-    // never calls into the policy while holding its lock.
-    //
-    // Commands are implicitly 'LockedInterruptible'.
-    struct CommandEntry;
-    typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
-
-    class Connection;
-    struct CommandEntry : Link<CommandEntry> {
-        CommandEntry();
-        ~CommandEntry();
-
-        Command command;
-
-        // parameters for the command (usage varies by command)
-        sp<Connection> connection;
-        nsecs_t eventTime;
-        KeyEntry* keyEntry;
-        sp<InputChannel> inputChannel;
-        sp<InputApplicationHandle> inputApplicationHandle;
-        int32_t userActivityEventType;
-    };
-
-    // Generic queue implementation.
-    template <typename T>
-    struct Queue {
-        T headSentinel;
-        T tailSentinel;
-
-        inline Queue() {
-            headSentinel.prev = NULL;
-            headSentinel.next = & tailSentinel;
-            tailSentinel.prev = & headSentinel;
-            tailSentinel.next = NULL;
-        }
-
-        inline bool isEmpty() const {
-            return headSentinel.next == & tailSentinel;
-        }
-
-        inline void enqueueAtTail(T* entry) {
-            T* last = tailSentinel.prev;
-            last->next = entry;
-            entry->prev = last;
-            entry->next = & tailSentinel;
-            tailSentinel.prev = entry;
-        }
-
-        inline void enqueueAtHead(T* entry) {
-            T* first = headSentinel.next;
-            headSentinel.next = entry;
-            entry->prev = & headSentinel;
-            entry->next = first;
-            first->prev = entry;
-        }
-
-        inline void dequeue(T* entry) {
-            entry->prev->next = entry->next;
-            entry->next->prev = entry->prev;
-        }
-
-        inline T* dequeueAtHead() {
-            T* first = headSentinel.next;
-            dequeue(first);
-            return first;
-        }
-
-        uint32_t count() const;
-    };
-
-    /* Allocates queue entries and performs reference counting as needed. */
-    class Allocator {
-    public:
-        Allocator();
-
-        InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid);
-        ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
-        KeyEntry* obtainKeyEntry(nsecs_t eventTime,
-                int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
-                int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
-                int32_t repeatCount, nsecs_t downTime);
-        MotionEntry* obtainMotionEntry(nsecs_t eventTime,
-                int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
-                int32_t flags, int32_t metaState, int32_t edgeFlags,
-                float xPrecision, float yPrecision,
-                nsecs_t downTime, uint32_t pointerCount,
-                const int32_t* pointerIds, const PointerCoords* pointerCoords);
-        DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry,
-                int32_t targetFlags, float xOffset, float yOffset);
-        CommandEntry* obtainCommandEntry(Command command);
-
-        void releaseInjectionState(InjectionState* injectionState);
-        void releaseEventEntry(EventEntry* entry);
-        void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
-        void releaseKeyEntry(KeyEntry* entry);
-        void releaseMotionEntry(MotionEntry* entry);
-        void releaseDispatchEntry(DispatchEntry* entry);
-        void releaseCommandEntry(CommandEntry* entry);
-
-        void recycleKeyEntry(KeyEntry* entry);
-
-        void appendMotionSample(MotionEntry* motionEntry,
-                nsecs_t eventTime, const PointerCoords* pointerCoords);
-
-    private:
-        Pool<InjectionState> mInjectionStatePool;
-        Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
-        Pool<KeyEntry> mKeyEntryPool;
-        Pool<MotionEntry> mMotionEntryPool;
-        Pool<MotionSample> mMotionSamplePool;
-        Pool<DispatchEntry> mDispatchEntryPool;
-        Pool<CommandEntry> mCommandEntryPool;
-
-        void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime,
-                uint32_t policyFlags);
-        void releaseEventEntryInjectionState(EventEntry* entry);
-    };
-
-    /* Tracks dispatched key and motion event state so that cancelation events can be
-     * synthesized when events are dropped. */
-    class InputState {
-    public:
-        // Specifies whether a given event will violate input state consistency.
-        enum Consistency {
-            // The event is consistent with the current input state.
-            CONSISTENT,
-            // The event is inconsistent with the current input state but applications
-            // will tolerate it.  eg. Down followed by another down.
-            TOLERABLE,
-            // The event is inconsistent with the current input state and will probably
-            // cause applications to crash.  eg. Up without prior down, move with
-            // unexpected number of pointers.
-            BROKEN
-        };
-
-        // Specifies the sources to cancel.
-        enum CancelationOptions {
-            CANCEL_ALL_EVENTS = 0,
-            CANCEL_POINTER_EVENTS = 1,
-            CANCEL_NON_POINTER_EVENTS = 2,
-        };
-
-        InputState();
-        ~InputState();
-
-        // Returns true if there is no state to be canceled.
-        bool isNeutral() const;
-
-        // Records tracking information for an event that has just been published.
-        // Returns whether the event is consistent with the current input state.
-        Consistency trackEvent(const EventEntry* entry);
-
-        // Records tracking information for a key event that has just been published.
-        // Returns whether the event is consistent with the current input state.
-        Consistency trackKey(const KeyEntry* entry);
-
-        // Records tracking information for a motion event that has just been published.
-        // Returns whether the event is consistent with the current input state.
-        Consistency trackMotion(const MotionEntry* entry);
-
-        // Synthesizes cancelation events for the current state and resets the tracked state.
-        void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
-                Vector<EventEntry*>& outEvents, CancelationOptions options);
-
-        // Clears the current state.
-        void clear();
-
-    private:
-        struct KeyMemento {
-            int32_t deviceId;
-            int32_t source;
-            int32_t keyCode;
-            int32_t scanCode;
-            nsecs_t downTime;
-        };
-
-        struct MotionMemento {
-            int32_t deviceId;
-            int32_t source;
-            float xPrecision;
-            float yPrecision;
-            nsecs_t downTime;
-            uint32_t pointerCount;
-            int32_t pointerIds[MAX_POINTERS];
-            PointerCoords pointerCoords[MAX_POINTERS];
-
-            void setPointers(const MotionEntry* entry);
-        };
-
-        Vector<KeyMemento> mKeyMementos;
-        Vector<MotionMemento> mMotionMementos;
-
-        static bool shouldCancelEvent(int32_t eventSource, CancelationOptions options);
-    };
-
-    /* Manages the dispatch state associated with a single input channel. */
-    class Connection : public RefBase {
-    protected:
-        virtual ~Connection();
-
-    public:
-        enum Status {
-            // Everything is peachy.
-            STATUS_NORMAL,
-            // An unrecoverable communication error has occurred.
-            STATUS_BROKEN,
-            // The input channel has been unregistered.
-            STATUS_ZOMBIE
-        };
-
-        Status status;
-        sp<InputChannel> inputChannel;
-        InputPublisher inputPublisher;
-        InputState inputState;
-        Queue<DispatchEntry> outboundQueue;
-
-        nsecs_t lastEventTime; // the time when the event was originally captured
-        nsecs_t lastDispatchTime; // the time when the last event was dispatched
-
-        explicit Connection(const sp<InputChannel>& inputChannel);
-
-        inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
-
-        const char* getStatusLabel() const;
-
-        // Finds a DispatchEntry in the outbound queue associated with the specified event.
-        // Returns NULL if not found.
-        DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
-
-        // Gets the time since the current event was originally obtained from the input driver.
-        inline double getEventLatencyMillis(nsecs_t currentTime) const {
-            return (currentTime - lastEventTime) / 1000000.0;
-        }
-
-        // Gets the time since the current event entered the outbound dispatch queue.
-        inline double getDispatchLatencyMillis(nsecs_t currentTime) const {
-            return (currentTime - lastDispatchTime) / 1000000.0;
-        }
-
-        status_t initialize();
-    };
-
-    enum DropReason {
-        DROP_REASON_NOT_DROPPED = 0,
-        DROP_REASON_POLICY = 1,
-        DROP_REASON_APP_SWITCH = 2,
-        DROP_REASON_DISABLED = 3,
-    };
-
-    sp<InputDispatcherPolicyInterface> mPolicy;
-
-    Mutex mLock;
-
-    Allocator mAllocator;
-    sp<Looper> mLooper;
-
-    EventEntry* mPendingEvent;
-    Queue<EventEntry> mInboundQueue;
-    Queue<CommandEntry> mCommandQueue;
-
-    Vector<EventEntry*> mTempCancelationEvents;
-
-    void dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout, nsecs_t keyRepeatDelay,
-            nsecs_t* nextWakeupTime);
-
-    // Enqueues an inbound event.  Returns true if mLooper->wake() should be called.
-    bool enqueueInboundEventLocked(EventEntry* entry);
-
-    // Cleans up input state when dropping an inbound event.
-    void dropInboundEventLocked(EventEntry* entry, DropReason dropReason);
-
-    // App switch latency optimization.
-    bool mAppSwitchSawKeyDown;
-    nsecs_t mAppSwitchDueTime;
-
-    static bool isAppSwitchKeyCode(int32_t keyCode);
-    bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry);
-    bool isAppSwitchPendingLocked();
-    void resetPendingAppSwitchLocked(bool handled);
-
-    // All registered connections mapped by receive pipe file descriptor.
-    KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
-
-    ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel);
-
-    // Active connections are connections that have a non-empty outbound queue.
-    // We don't use a ref-counted pointer here because we explicitly abort connections
-    // during unregistration which causes the connection's outbound queue to be cleared
-    // and the connection itself to be deactivated.
-    Vector<Connection*> mActiveConnections;
-
-    // Input channels that will receive a copy of all input events.
-    Vector<sp<InputChannel> > mMonitoringChannels;
-
-    // Preallocated key event object used for policy inquiries.
-    KeyEvent mReusableKeyEvent;
-
-    // Event injection and synchronization.
-    Condition mInjectionResultAvailableCondition;
-    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
-    void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
-
-    Condition mInjectionSyncFinishedCondition;
-    void incrementPendingForegroundDispatchesLocked(EventEntry* entry);
-    void decrementPendingForegroundDispatchesLocked(EventEntry* entry);
-
-    // Throttling state.
-    struct ThrottleState {
-        nsecs_t minTimeBetweenEvents;
-
-        nsecs_t lastEventTime;
-        int32_t lastDeviceId;
-        uint32_t lastSource;
-
-        uint32_t originalSampleCount; // only collected during debugging
-    } mThrottleState;
-
-    // Key repeat tracking.
-    struct KeyRepeatState {
-        KeyEntry* lastKeyEntry; // or null if no repeat
-        nsecs_t nextRepeatTime;
-    } mKeyRepeatState;
-
-    void resetKeyRepeatLocked();
-    KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime, nsecs_t keyRepeatTimeout);
-
-    // Deferred command processing.
-    bool runCommandsLockedInterruptible();
-    CommandEntry* postCommandLocked(Command command);
-
-    // Inbound event processing.
-    void drainInboundQueueLocked();
-    void releasePendingEventLocked();
-    void releaseInboundEventLocked(EventEntry* entry);
-
-    // Dispatch state.
-    bool mDispatchEnabled;
-    bool mDispatchFrozen;
-
-    Vector<InputWindow> mWindows;
-
-    const InputWindow* getWindowLocked(const sp<InputChannel>& inputChannel);
-
-    // Focus tracking for keys, trackball, etc.
-    const InputWindow* mFocusedWindow;
-
-    // Focus tracking for touch.
-    struct TouchedWindow {
-        const InputWindow* window;
-        int32_t targetFlags;
-        BitSet32 pointerIds;
-        sp<InputChannel> channel;
-    };
-    struct TouchState {
-        bool down;
-        bool split;
-        Vector<TouchedWindow> windows;
-
-        TouchState();
-        ~TouchState();
-        void reset();
-        void copyFrom(const TouchState& other);
-        void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds);
-        void removeOutsideTouchWindows();
-        const InputWindow* getFirstForegroundWindow();
-    };
-
-    TouchState mTouchState;
-    TouchState mTempTouchState;
-
-    // Focused application.
-    InputApplication* mFocusedApplication;
-    InputApplication mFocusedApplicationStorage; // preallocated storage for mFocusedApplication
-    void releaseFocusedApplicationLocked();
-
-    // Dispatch inbound events.
-    bool dispatchConfigurationChangedLocked(
-            nsecs_t currentTime, ConfigurationChangedEntry* entry);
-    bool dispatchKeyLocked(
-            nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
-            DropReason* dropReason, nsecs_t* nextWakeupTime);
-    bool dispatchMotionLocked(
-            nsecs_t currentTime, MotionEntry* entry,
-            DropReason* dropReason, nsecs_t* nextWakeupTime);
-    void dispatchEventToCurrentInputTargetsLocked(
-            nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
-
-    void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
-    void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
-
-    // The input targets that were most recently identified for dispatch.
-    bool mCurrentInputTargetsValid; // false while targets are being recomputed
-    Vector<InputTarget> mCurrentInputTargets;
-
-    enum InputTargetWaitCause {
-        INPUT_TARGET_WAIT_CAUSE_NONE,
-        INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
-        INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY,
-    };
-
-    InputTargetWaitCause mInputTargetWaitCause;
-    nsecs_t mInputTargetWaitStartTime;
-    nsecs_t mInputTargetWaitTimeoutTime;
-    bool mInputTargetWaitTimeoutExpired;
-
-    // Finding targets for input events.
-    void resetTargetsLocked();
-    void commitTargetsLocked();
-    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
-            const InputApplication* application, const InputWindow* window,
-            nsecs_t* nextWakeupTime);
-    void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
-            const sp<InputChannel>& inputChannel);
-    nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
-    void resetANRTimeoutsLocked();
-
-    int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
-            nsecs_t* nextWakeupTime);
-    int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
-            nsecs_t* nextWakeupTime);
-
-    void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
-            BitSet32 pointerIds);
-    void addMonitoringTargetsLocked();
-    void pokeUserActivityLocked(const EventEntry* eventEntry);
-    bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState);
-    bool isWindowObscuredAtPointLocked(const InputWindow* window, int32_t x, int32_t y) const;
-    bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
-    String8 getApplicationWindowLabelLocked(const InputApplication* application,
-            const InputWindow* window);
-
-    // Manage the dispatch cycle for a single connection.
-    // These methods are deliberately not Interruptible because doing all of the work
-    // with the mutex held makes it easier to ensure that connection invariants are maintained.
-    // If needed, the methods post commands to run later once the critical bits are done.
-    void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
-            EventEntry* eventEntry, const InputTarget* inputTarget,
-            bool resumeWithAppendedMotionSample);
-    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
-    void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
-    void startNextDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
-    void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
-    void drainOutboundQueueLocked(Connection* connection);
-    static int handleReceiveCallback(int receiveFd, int events, void* data);
-
-    void synthesizeCancelationEventsForAllConnectionsLocked(
-            InputState::CancelationOptions options, const char* reason);
-    void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
-            InputState::CancelationOptions options, const char* reason);
-    void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
-            InputState::CancelationOptions options, const char* reason);
-
-    // Splitting motion events across windows.
-    MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
-
-    // Reset and drop everything the dispatcher is doing.
-    void resetAndDropEverythingLocked(const char* reason);
-
-    // Dump state.
-    void dumpDispatchStateLocked(String8& dump);
-    void logDispatchStateLocked();
-
-    // Add or remove a connection to the mActiveConnections vector.
-    void activateConnectionLocked(Connection* connection);
-    void deactivateConnectionLocked(Connection* connection);
-
-    // Interesting events that we might like to log or tell the framework about.
-    void onDispatchCycleStartedLocked(
-            nsecs_t currentTime, const sp<Connection>& connection);
-    void onDispatchCycleFinishedLocked(
-            nsecs_t currentTime, const sp<Connection>& connection);
-    void onDispatchCycleBrokenLocked(
-            nsecs_t currentTime, const sp<Connection>& connection);
-    void onANRLocked(
-            nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
-            nsecs_t eventTime, nsecs_t waitStartTime);
-
-    // Outbound policy interactions.
-    void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
-    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
-    void doNotifyANRLockedInterruptible(CommandEntry* commandEntry);
-    void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry);
-    void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry);
-
-    // Statistics gathering.
-    void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
-            int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
-};
-
-/* Enqueues and dispatches input events, endlessly. */
-class InputDispatcherThread : public Thread {
-public:
-    explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
-    ~InputDispatcherThread();
-
-private:
-    virtual bool threadLoop();
-
-    sp<InputDispatcherInterface> mDispatcher;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_DISPATCHER_H
diff --git a/include/ui/InputManager.h b/include/ui/InputManager.h
deleted file mode 100644
index 568568b..0000000
--- a/include/ui/InputManager.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _UI_INPUT_MANAGER_H
-#define _UI_INPUT_MANAGER_H
-
-/**
- * Native input manager.
- */
-
-#include <ui/EventHub.h>
-#include <ui/Input.h>
-#include <utils/Errors.h>
-#include <utils/Vector.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-namespace android {
-
-class InputChannel;
-
-class InputReaderInterface;
-class InputReaderPolicyInterface;
-class InputReaderThread;
-
-class InputDispatcherInterface;
-class InputDispatcherPolicyInterface;
-class InputDispatcherThread;
-
-/*
- * The input manager is the core of the system event processing.
- *
- * The input manager uses two threads.
- *
- * 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
- *    applies policy, and posts messages to a queue managed by the DispatcherThread.
- * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
- *    queue and asynchronously dispatches them to applications.
- *
- * By design, the InputReaderThread class and InputDispatcherThread class do not share any
- * internal state.  Moreover, all communication is done one way from the InputReaderThread
- * into the InputDispatcherThread and never the reverse.  Both classes may interact with the
- * InputDispatchPolicy, however.
- *
- * The InputManager class never makes any calls into Java itself.  Instead, the
- * InputDispatchPolicy is responsible for performing all external interactions with the
- * system, including calling DVM services.
- */
-class InputManagerInterface : public virtual RefBase {
-protected:
-    InputManagerInterface() { }
-    virtual ~InputManagerInterface() { }
-
-public:
-    /* Starts the input manager threads. */
-    virtual status_t start() = 0;
-
-    /* Stops the input manager threads and waits for them to exit. */
-    virtual status_t stop() = 0;
-
-    /* Gets the input reader. */
-    virtual sp<InputReaderInterface> getReader() = 0;
-
-    /* Gets the input dispatcher. */
-    virtual sp<InputDispatcherInterface> getDispatcher() = 0;
-};
-
-class InputManager : public InputManagerInterface {
-protected:
-    virtual ~InputManager();
-
-public:
-    InputManager(
-            const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& readerPolicy,
-            const sp<InputDispatcherPolicyInterface>& dispatcherPolicy);
-
-    // (used for testing purposes)
-    InputManager(
-            const sp<InputReaderInterface>& reader,
-            const sp<InputDispatcherInterface>& dispatcher);
-
-    virtual status_t start();
-    virtual status_t stop();
-
-    virtual sp<InputReaderInterface> getReader();
-    virtual sp<InputDispatcherInterface> getDispatcher();
-
-private:
-    sp<InputReaderInterface> mReader;
-    sp<InputReaderThread> mReaderThread;
-
-    sp<InputDispatcherInterface> mDispatcher;
-    sp<InputDispatcherThread> mDispatcherThread;
-
-    void initialize();
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_MANAGER_H
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
deleted file mode 100644
index 7568ba7..0000000
--- a/include/ui/InputReader.h
+++ /dev/null
@@ -1,944 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _UI_INPUT_READER_H
-#define _UI_INPUT_READER_H
-
-#include <ui/EventHub.h>
-#include <ui/Input.h>
-#include <ui/InputDispatcher.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/BitSet.h>
-
-#include <stddef.h>
-#include <unistd.h>
-
-namespace android {
-
-class InputDevice;
-class InputMapper;
-
-/* Describes a virtual key. */
-struct VirtualKeyDefinition {
-    int32_t scanCode;
-
-    // configured position data, specified in display coords
-    int32_t centerX;
-    int32_t centerY;
-    int32_t width;
-    int32_t height;
-};
-
-
-/* Specifies input device calibration settings. */
-class InputDeviceCalibration {
-public:
-    InputDeviceCalibration();
-
-    void clear();
-    void addProperty(const String8& key, const String8& value);
-
-    bool tryGetProperty(const String8& key, String8& outValue) const;
-    bool tryGetProperty(const String8& key, int32_t& outValue) const;
-    bool tryGetProperty(const String8& key, float& outValue) const;
-
-private:
-    KeyedVector<String8, String8> mProperties;
-};
-
-
-/*
- * Input reader policy interface.
- *
- * The input reader policy is used by the input reader to interact with the Window Manager
- * and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI.  This interface is also mocked in the unit tests.
- */
-class InputReaderPolicyInterface : public virtual RefBase {
-protected:
-    InputReaderPolicyInterface() { }
-    virtual ~InputReaderPolicyInterface() { }
-
-public:
-    /* Display orientations. */
-    enum {
-        ROTATION_0 = 0,
-        ROTATION_90 = 1,
-        ROTATION_180 = 2,
-        ROTATION_270 = 3
-    };
-
-    /* Gets information about the display with the specified id.
-     * Returns true if the display info is available, false otherwise.
-     */
-    virtual bool getDisplayInfo(int32_t displayId,
-            int32_t* width, int32_t* height, int32_t* orientation) = 0;
-
-    /* Determines whether to turn on some hacks we have to improve the touch interaction with a
-     * certain device whose screen currently is not all that good.
-     */
-    virtual bool filterTouchEvents() = 0;
-
-    /* Determines whether to turn on some hacks to improve touch interaction with another device
-     * where touch coordinate data can get corrupted.
-     */
-    virtual bool filterJumpyTouchEvents() = 0;
-
-    /* Gets the amount of time to disable virtual keys after the screen is touched
-     * in order to filter out accidental virtual key presses due to swiping gestures
-     * or taps near the edge of the display.  May be 0 to disable the feature.
-     */
-    virtual nsecs_t getVirtualKeyQuietTime() = 0;
-
-    /* Gets the configured virtual key definitions for an input device. */
-    virtual void getVirtualKeyDefinitions(const String8& deviceName,
-            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
-
-    /* Gets the calibration for an input device. */
-    virtual void getInputDeviceCalibration(const String8& deviceName,
-            InputDeviceCalibration& outCalibration) = 0;
-
-    /* Gets the excluded device names for the platform. */
-    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
-};
-
-
-/* Processes raw input events and sends cooked event data to an input dispatcher. */
-class InputReaderInterface : public virtual RefBase {
-protected:
-    InputReaderInterface() { }
-    virtual ~InputReaderInterface() { }
-
-public:
-    /* Dumps the state of the input reader.
-     *
-     * This method may be called on any thread (usually by the input manager). */
-    virtual void dump(String8& dump) = 0;
-
-    /* Runs a single iteration of the processing loop.
-     * Nominally reads and processes one incoming message from the EventHub.
-     *
-     * This method should be called on the input reader thread.
-     */
-    virtual void loopOnce() = 0;
-
-    /* Gets the current input device configuration.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;
-
-    /* Gets information about the specified input device.
-     * Returns OK if the device information was obtained or NAME_NOT_FOUND if there
-     * was no such device.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;
-
-    /* Gets the list of all registered device ids. */
-    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;
-
-    /* Query current input state. */
-    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t scanCode) = 0;
-    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t keyCode) = 0;
-    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
-            int32_t sw) = 0;
-
-    /* Determine whether physical keys exist for the given framework-domain key codes. */
-    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
-            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
-};
-
-
-/* Internal interface used by individual input devices to access global input device state
- * and parameters maintained by the input reader.
- */
-class InputReaderContext {
-public:
-    InputReaderContext() { }
-    virtual ~InputReaderContext() { }
-
-    virtual void updateGlobalMetaState() = 0;
-    virtual int32_t getGlobalMetaState() = 0;
-
-    virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
-    virtual bool shouldDropVirtualKey(nsecs_t now,
-            InputDevice* device, int32_t keyCode, int32_t scanCode) = 0;
-
-    virtual InputReaderPolicyInterface* getPolicy() = 0;
-    virtual InputDispatcherInterface* getDispatcher() = 0;
-    virtual EventHubInterface* getEventHub() = 0;
-};
-
-
-/* The input reader reads raw event data from the event hub and processes it into input events
- * that it sends to the input dispatcher.  Some functions of the input reader, such as early
- * event filtering in low power states, are controlled by a separate policy object.
- *
- * IMPORTANT INVARIANT:
- *     Because the policy and dispatcher can potentially block or cause re-entrance into
- *     the input reader, the input reader never calls into other components while holding
- *     an exclusive internal lock whenever re-entrance can happen.
- */
-class InputReader : public InputReaderInterface, protected InputReaderContext {
-public:
-    InputReader(const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& policy,
-            const sp<InputDispatcherInterface>& dispatcher);
-    virtual ~InputReader();
-
-    virtual void dump(String8& dump);
-
-    virtual void loopOnce();
-
-    virtual void getInputConfiguration(InputConfiguration* outConfiguration);
-
-    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
-    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
-
-    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t scanCode);
-    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t keyCode);
-    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
-            int32_t sw);
-
-    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
-            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
-
-protected:
-    // These methods are protected virtual so they can be overridden and instrumented
-    // by test cases.
-    virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
-
-private:
-    sp<EventHubInterface> mEventHub;
-    sp<InputReaderPolicyInterface> mPolicy;
-    sp<InputDispatcherInterface> mDispatcher;
-
-    virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
-    virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
-    virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
-
-    // This reader/writer lock guards the list of input devices.
-    // The writer lock must be held whenever the list of input devices is modified
-    //   and then promptly released.
-    // The reader lock must be held whenever the list of input devices is traversed or an
-    //   input device in the list is accessed.
-    // This lock only protects the registry and prevents inadvertent deletion of device objects
-    // that are in use.  Individual devices are responsible for guarding their own internal state
-    // as needed for concurrent operation.
-    RWLock mDeviceRegistryLock;
-    KeyedVector<int32_t, InputDevice*> mDevices;
-
-    // low-level input event decoding and device management
-    void process(const RawEvent* rawEvent);
-
-    void addDevice(int32_t deviceId);
-    void removeDevice(int32_t deviceId);
-    void configureExcludedDevices();
-
-    void consumeEvent(const RawEvent* rawEvent);
-
-    void handleConfigurationChanged(nsecs_t when);
-
-    // state management for all devices
-    Mutex mStateLock;
-
-    int32_t mGlobalMetaState;
-    virtual void updateGlobalMetaState();
-    virtual int32_t getGlobalMetaState();
-
-    InputConfiguration mInputConfiguration;
-    void updateInputConfiguration();
-
-    nsecs_t mDisableVirtualKeysTimeout;
-    virtual void disableVirtualKeysUntil(nsecs_t time);
-    virtual bool shouldDropVirtualKey(nsecs_t now,
-            InputDevice* device, int32_t keyCode, int32_t scanCode);
-
-    // state queries
-    typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
-    int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
-            GetStateFunc getStateFunc);
-    bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-};
-
-
-/* Reads raw events from the event hub and processes them, endlessly. */
-class InputReaderThread : public Thread {
-public:
-    InputReaderThread(const sp<InputReaderInterface>& reader);
-    virtual ~InputReaderThread();
-
-private:
-    sp<InputReaderInterface> mReader;
-
-    virtual bool threadLoop();
-};
-
-
-/* Represents the state of a single input device. */
-class InputDevice {
-public:
-    InputDevice(InputReaderContext* context, int32_t id, const String8& name);
-    ~InputDevice();
-
-    inline InputReaderContext* getContext() { return mContext; }
-    inline int32_t getId() { return mId; }
-    inline const String8& getName() { return mName; }
-    inline uint32_t getSources() { return mSources; }
-
-    inline bool isIgnored() { return mMappers.isEmpty(); }
-
-    void dump(String8& dump);
-    void addMapper(InputMapper* mapper);
-    void configure();
-    void reset();
-    void process(const RawEvent* rawEvent);
-
-    void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
-    int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
-    bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-
-    int32_t getMetaState();
-
-    inline const InputDeviceCalibration& getCalibration() {
-        return mCalibration;
-    }
-
-private:
-    InputReaderContext* mContext;
-    int32_t mId;
-
-    Vector<InputMapper*> mMappers;
-
-    String8 mName;
-    uint32_t mSources;
-
-    typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
-    int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
-
-    InputDeviceCalibration mCalibration;
-};
-
-
-/* An input mapper transforms raw input events into cooked event data.
- * A single input device can have multiple associated input mappers in order to interpret
- * different classes of events.
- */
-class InputMapper {
-public:
-    InputMapper(InputDevice* device);
-    virtual ~InputMapper();
-
-    inline InputDevice* getDevice() { return mDevice; }
-    inline int32_t getDeviceId() { return mDevice->getId(); }
-    inline const String8 getDeviceName() { return mDevice->getName(); }
-    inline InputReaderContext* getContext() { return mContext; }
-    inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
-    inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); }
-    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
-
-    virtual uint32_t getSources() = 0;
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void configure();
-    virtual void reset();
-    virtual void process(const RawEvent* rawEvent) = 0;
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-
-    virtual int32_t getMetaState();
-
-protected:
-    InputDevice* mDevice;
-    InputReaderContext* mContext;
-};
-
-
-class SwitchInputMapper : public InputMapper {
-public:
-    SwitchInputMapper(InputDevice* device);
-    virtual ~SwitchInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
-
-private:
-    void processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue);
-};
-
-
-class KeyboardInputMapper : public InputMapper {
-public:
-    KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, uint32_t sources,
-            int32_t keyboardType);
-    virtual ~KeyboardInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void reset();
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-
-    virtual int32_t getMetaState();
-
-private:
-    Mutex mLock;
-
-    struct KeyDown {
-        int32_t keyCode;
-        int32_t scanCode;
-    };
-
-    int32_t mAssociatedDisplayId;
-    uint32_t mSources;
-    int32_t mKeyboardType;
-
-    struct LockedState {
-        Vector<KeyDown> keyDowns; // keys that are down
-        int32_t metaState;
-        nsecs_t downTime; // time of most recent key down
-    } mLocked;
-
-    void initializeLocked();
-
-    bool isKeyboardOrGamepadKey(int32_t scanCode);
-
-    void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
-            uint32_t policyFlags);
-
-    ssize_t findKeyDownLocked(int32_t scanCode);
-};
-
-
-class TrackballInputMapper : public InputMapper {
-public:
-    TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId);
-    virtual ~TrackballInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void reset();
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-
-private:
-    // Amount that trackball needs to move in order to generate a key event.
-    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
-
-    Mutex mLock;
-
-    int32_t mAssociatedDisplayId;
-
-    struct Accumulator {
-        enum {
-            FIELD_BTN_MOUSE = 1,
-            FIELD_REL_X = 2,
-            FIELD_REL_Y = 4
-        };
-
-        uint32_t fields;
-
-        bool btnMouse;
-        int32_t relX;
-        int32_t relY;
-
-        inline void clear() {
-            fields = 0;
-        }
-    } mAccumulator;
-
-    float mXScale;
-    float mYScale;
-    float mXPrecision;
-    float mYPrecision;
-
-    struct LockedState {
-        bool down;
-        nsecs_t downTime;
-    } mLocked;
-
-    void initializeLocked();
-
-    void sync(nsecs_t when);
-};
-
-
-class TouchInputMapper : public InputMapper {
-public:
-    TouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
-    virtual ~TouchInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void configure();
-    virtual void reset();
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-
-protected:
-    Mutex mLock;
-
-    struct VirtualKey {
-        int32_t keyCode;
-        int32_t scanCode;
-        uint32_t flags;
-
-        // computed hit box, specified in touch screen coords based on known display size
-        int32_t hitLeft;
-        int32_t hitTop;
-        int32_t hitRight;
-        int32_t hitBottom;
-
-        inline bool isHit(int32_t x, int32_t y) const {
-            return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
-        }
-    };
-
-    // Raw data for a single pointer.
-    struct PointerData {
-        uint32_t id;
-        int32_t x;
-        int32_t y;
-        int32_t pressure;
-        int32_t touchMajor;
-        int32_t touchMinor;
-        int32_t toolMajor;
-        int32_t toolMinor;
-        int32_t orientation;
-
-        inline bool operator== (const PointerData& other) const {
-            return id == other.id
-                    && x == other.x
-                    && y == other.y
-                    && pressure == other.pressure
-                    && touchMajor == other.touchMajor
-                    && touchMinor == other.touchMinor
-                    && toolMajor == other.toolMajor
-                    && toolMinor == other.toolMinor
-                    && orientation == other.orientation;
-        }
-        inline bool operator!= (const PointerData& other) const {
-            return !(*this == other);
-        }
-    };
-
-    // Raw data for a collection of pointers including a pointer id mapping table.
-    struct TouchData {
-        uint32_t pointerCount;
-        PointerData pointers[MAX_POINTERS];
-        BitSet32 idBits;
-        uint32_t idToIndex[MAX_POINTER_ID + 1];
-
-        void copyFrom(const TouchData& other) {
-            pointerCount = other.pointerCount;
-            idBits = other.idBits;
-
-            for (uint32_t i = 0; i < pointerCount; i++) {
-                pointers[i] = other.pointers[i];
-
-                int id = pointers[i].id;
-                idToIndex[id] = other.idToIndex[id];
-            }
-        }
-
-        inline void clear() {
-            pointerCount = 0;
-            idBits.clear();
-        }
-    };
-
-    int32_t mAssociatedDisplayId;
-
-    // Immutable configuration parameters.
-    struct Parameters {
-        bool useBadTouchFilter;
-        bool useJumpyTouchFilter;
-        bool useAveragingTouchFilter;
-        nsecs_t virtualKeyQuietTime;
-    } mParameters;
-
-    // Immutable calibration parameters in parsed form.
-    struct Calibration {
-        // Touch Size
-        enum TouchSizeCalibration {
-            TOUCH_SIZE_CALIBRATION_DEFAULT,
-            TOUCH_SIZE_CALIBRATION_NONE,
-            TOUCH_SIZE_CALIBRATION_GEOMETRIC,
-            TOUCH_SIZE_CALIBRATION_PRESSURE,
-        };
-
-        TouchSizeCalibration touchSizeCalibration;
-
-        // Tool Size
-        enum ToolSizeCalibration {
-            TOOL_SIZE_CALIBRATION_DEFAULT,
-            TOOL_SIZE_CALIBRATION_NONE,
-            TOOL_SIZE_CALIBRATION_GEOMETRIC,
-            TOOL_SIZE_CALIBRATION_LINEAR,
-            TOOL_SIZE_CALIBRATION_AREA,
-        };
-
-        ToolSizeCalibration toolSizeCalibration;
-        bool haveToolSizeLinearScale;
-        float toolSizeLinearScale;
-        bool haveToolSizeLinearBias;
-        float toolSizeLinearBias;
-        bool haveToolSizeAreaScale;
-        float toolSizeAreaScale;
-        bool haveToolSizeAreaBias;
-        float toolSizeAreaBias;
-        bool haveToolSizeIsSummed;
-        int32_t toolSizeIsSummed;
-
-        // Pressure
-        enum PressureCalibration {
-            PRESSURE_CALIBRATION_DEFAULT,
-            PRESSURE_CALIBRATION_NONE,
-            PRESSURE_CALIBRATION_PHYSICAL,
-            PRESSURE_CALIBRATION_AMPLITUDE,
-        };
-        enum PressureSource {
-            PRESSURE_SOURCE_DEFAULT,
-            PRESSURE_SOURCE_PRESSURE,
-            PRESSURE_SOURCE_TOUCH,
-        };
-
-        PressureCalibration pressureCalibration;
-        PressureSource pressureSource;
-        bool havePressureScale;
-        float pressureScale;
-
-        // Size
-        enum SizeCalibration {
-            SIZE_CALIBRATION_DEFAULT,
-            SIZE_CALIBRATION_NONE,
-            SIZE_CALIBRATION_NORMALIZED,
-        };
-
-        SizeCalibration sizeCalibration;
-
-        // Orientation
-        enum OrientationCalibration {
-            ORIENTATION_CALIBRATION_DEFAULT,
-            ORIENTATION_CALIBRATION_NONE,
-            ORIENTATION_CALIBRATION_INTERPOLATED,
-        };
-
-        OrientationCalibration orientationCalibration;
-    } mCalibration;
-
-    // Raw axis information from the driver.
-    struct RawAxes {
-        RawAbsoluteAxisInfo x;
-        RawAbsoluteAxisInfo y;
-        RawAbsoluteAxisInfo pressure;
-        RawAbsoluteAxisInfo touchMajor;
-        RawAbsoluteAxisInfo touchMinor;
-        RawAbsoluteAxisInfo toolMajor;
-        RawAbsoluteAxisInfo toolMinor;
-        RawAbsoluteAxisInfo orientation;
-    } mRawAxes;
-
-    // Current and previous touch sample data.
-    TouchData mCurrentTouch;
-    TouchData mLastTouch;
-
-    // The time the primary pointer last went down.
-    nsecs_t mDownTime;
-
-    struct LockedState {
-        Vector<VirtualKey> virtualKeys;
-
-        // The surface orientation and width and height set by configureSurfaceLocked().
-        int32_t surfaceOrientation;
-        int32_t surfaceWidth, surfaceHeight;
-
-        // Translation and scaling factors, orientation-independent.
-        int32_t xOrigin;
-        float xScale;
-        float xPrecision;
-
-        int32_t yOrigin;
-        float yScale;
-        float yPrecision;
-
-        float geometricScale;
-
-        float toolSizeLinearScale;
-        float toolSizeLinearBias;
-        float toolSizeAreaScale;
-        float toolSizeAreaBias;
-
-        float pressureScale;
-
-        float sizeScale;
-
-        float orientationScale;
-
-        // Oriented motion ranges for input device info.
-        struct OrientedRanges {
-            InputDeviceInfo::MotionRange x;
-            InputDeviceInfo::MotionRange y;
-
-            bool havePressure;
-            InputDeviceInfo::MotionRange pressure;
-
-            bool haveSize;
-            InputDeviceInfo::MotionRange size;
-
-            bool haveTouchSize;
-            InputDeviceInfo::MotionRange touchMajor;
-            InputDeviceInfo::MotionRange touchMinor;
-
-            bool haveToolSize;
-            InputDeviceInfo::MotionRange toolMajor;
-            InputDeviceInfo::MotionRange toolMinor;
-
-            bool haveOrientation;
-            InputDeviceInfo::MotionRange orientation;
-        } orientedRanges;
-
-        // Oriented dimensions and precision.
-        float orientedSurfaceWidth, orientedSurfaceHeight;
-        float orientedXPrecision, orientedYPrecision;
-
-        struct CurrentVirtualKeyState {
-            bool down;
-            nsecs_t downTime;
-            int32_t keyCode;
-            int32_t scanCode;
-        } currentVirtualKey;
-    } mLocked;
-
-    virtual void configureParameters();
-    virtual void dumpParameters(String8& dump);
-    virtual void configureRawAxes();
-    virtual void dumpRawAxes(String8& dump);
-    virtual bool configureSurfaceLocked();
-    virtual void dumpSurfaceLocked(String8& dump);
-    virtual void configureVirtualKeysLocked();
-    virtual void dumpVirtualKeysLocked(String8& dump);
-    virtual void parseCalibration();
-    virtual void resolveCalibration();
-    virtual void dumpCalibration(String8& dump);
-
-    enum TouchResult {
-        // Dispatch the touch normally.
-        DISPATCH_TOUCH,
-        // Do not dispatch the touch, but keep tracking the current stroke.
-        SKIP_TOUCH,
-        // Do not dispatch the touch, and drop all information associated with the current stoke
-        // so the next movement will appear as a new down.
-        DROP_STROKE
-    };
-
-    void syncTouch(nsecs_t when, bool havePointerIds);
-
-private:
-    /* Maximum number of historical samples to average. */
-    static const uint32_t AVERAGING_HISTORY_SIZE = 5;
-
-    /* Slop distance for jumpy pointer detection.
-     * The vertical range of the screen divided by this is our epsilon value. */
-    static const uint32_t JUMPY_EPSILON_DIVISOR = 212;
-
-    /* Number of jumpy points to drop for touchscreens that need it. */
-    static const uint32_t JUMPY_TRANSITION_DROPS = 3;
-    static const uint32_t JUMPY_DROP_LIMIT = 3;
-
-    /* Maximum squared distance for averaging.
-     * If moving farther than this, turn of averaging to avoid lag in response. */
-    static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75;
-
-    struct AveragingTouchFilterState {
-        // Individual history tracks are stored by pointer id
-        uint32_t historyStart[MAX_POINTERS];
-        uint32_t historyEnd[MAX_POINTERS];
-        struct {
-            struct {
-                int32_t x;
-                int32_t y;
-                int32_t pressure;
-            } pointers[MAX_POINTERS];
-        } historyData[AVERAGING_HISTORY_SIZE];
-    } mAveragingTouchFilter;
-
-    struct JumpyTouchFilterState {
-        uint32_t jumpyPointsDropped;
-    } mJumpyTouchFilter;
-
-    struct PointerDistanceHeapElement {
-        uint32_t currentPointerIndex : 8;
-        uint32_t lastPointerIndex : 8;
-        uint64_t distance : 48; // squared distance
-    };
-
-    void initializeLocked();
-
-    TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
-    void dispatchTouches(nsecs_t when, uint32_t policyFlags);
-    void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
-            BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
-            int32_t motionEventAction);
-    void detectGestures(nsecs_t when);
-
-    bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
-    const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
-
-    bool applyBadTouchFilter();
-    bool applyJumpyTouchFilter();
-    void applyAveragingTouchFilter();
-    void calculatePointerIds();
-};
-
-
-class SingleTouchInputMapper : public TouchInputMapper {
-public:
-    SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
-    virtual ~SingleTouchInputMapper();
-
-    virtual void reset();
-    virtual void process(const RawEvent* rawEvent);
-
-protected:
-    virtual void configureRawAxes();
-
-private:
-    struct Accumulator {
-        enum {
-            FIELD_BTN_TOUCH = 1,
-            FIELD_ABS_X = 2,
-            FIELD_ABS_Y = 4,
-            FIELD_ABS_PRESSURE = 8,
-            FIELD_ABS_TOOL_WIDTH = 16
-        };
-
-        uint32_t fields;
-
-        bool btnTouch;
-        int32_t absX;
-        int32_t absY;
-        int32_t absPressure;
-        int32_t absToolWidth;
-
-        inline void clear() {
-            fields = 0;
-        }
-    } mAccumulator;
-
-    bool mDown;
-    int32_t mX;
-    int32_t mY;
-    int32_t mPressure;
-    int32_t mToolWidth;
-
-    void initialize();
-
-    void sync(nsecs_t when);
-};
-
-
-class MultiTouchInputMapper : public TouchInputMapper {
-public:
-    MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
-    virtual ~MultiTouchInputMapper();
-
-    virtual void reset();
-    virtual void process(const RawEvent* rawEvent);
-
-protected:
-    virtual void configureRawAxes();
-
-private:
-    struct Accumulator {
-        enum {
-            FIELD_ABS_MT_POSITION_X = 1,
-            FIELD_ABS_MT_POSITION_Y = 2,
-            FIELD_ABS_MT_TOUCH_MAJOR = 4,
-            FIELD_ABS_MT_TOUCH_MINOR = 8,
-            FIELD_ABS_MT_WIDTH_MAJOR = 16,
-            FIELD_ABS_MT_WIDTH_MINOR = 32,
-            FIELD_ABS_MT_ORIENTATION = 64,
-            FIELD_ABS_MT_TRACKING_ID = 128,
-            FIELD_ABS_MT_PRESSURE = 256,
-        };
-
-        uint32_t pointerCount;
-        struct Pointer {
-            uint32_t fields;
-
-            int32_t absMTPositionX;
-            int32_t absMTPositionY;
-            int32_t absMTTouchMajor;
-            int32_t absMTTouchMinor;
-            int32_t absMTWidthMajor;
-            int32_t absMTWidthMinor;
-            int32_t absMTOrientation;
-            int32_t absMTTrackingId;
-            int32_t absMTPressure;
-
-            inline void clear() {
-                fields = 0;
-            }
-        } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
-
-        inline void clear() {
-            pointerCount = 0;
-            pointers[0].clear();
-        }
-    } mAccumulator;
-
-    void initialize();
-
-    void sync(nsecs_t when);
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_READER_H
diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h
index dc9e27a..119db81 100644
--- a/include/ui/InputTransport.h
+++ b/include/ui/InputTransport.h
@@ -250,12 +250,13 @@
     status_t sendDispatchSignal();
 
     /* Receives the finished signal from the consumer in reply to the original dispatch signal.
+     * Returns whether the consumer handled the message.
      *
      * Returns OK on success.
      * Returns WOULD_BLOCK if there is no signal present.
      * Other errors probably indicate that the channel is broken.
      */
-    status_t receiveFinishedSignal();
+    status_t receiveFinishedSignal(bool* outHandled);
 
 private:
     sp<InputChannel> mChannel;
@@ -305,12 +306,12 @@
     status_t consume(InputEventFactoryInterface* factory, InputEvent** outEvent);
 
     /* Sends a finished signal to the publisher to inform it that the current message is
-     * finished processing.
+     * finished processing and specifies whether the message was handled by the consumer.
      *
      * Returns OK on success.
      * Errors probably indicate that the channel is broken.
      */
-    status_t sendFinishedSignal();
+    status_t sendFinishedSignal(bool handled);
 
     /* Receives the dispatched signal from the publisher.
      *
diff --git a/include/ui/KeyCharacterMap.h b/include/ui/KeyCharacterMap.h
index bad2cf8..10a3810 100644
--- a/include/ui/KeyCharacterMap.h
+++ b/include/ui/KeyCharacterMap.h
@@ -18,55 +18,183 @@
 #define _UI_KEY_CHARACTER_MAP_H
 
 #include <stdint.h>
-#include <utils/Vector.h>
 
-using namespace android;
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/Tokenizer.h>
+#include <utils/String8.h>
+#include <utils/Unicode.h>
 
-class KeyCharacterMap
-{
+namespace android {
+
+/**
+ * Describes a mapping from Android key codes to characters.
+ * Also specifies other functions of the keyboard such as the keyboard type
+ * and key modifier semantics.
+ */
+class KeyCharacterMap {
 public:
+    enum KeyboardType {
+        KEYBOARD_TYPE_UNKNOWN = 0,
+        KEYBOARD_TYPE_NUMERIC = 1,
+        KEYBOARD_TYPE_PREDICTIVE = 2,
+        KEYBOARD_TYPE_ALPHA = 3,
+        KEYBOARD_TYPE_FULL = 4,
+        KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
+    };
+
+    // Substitute key code and meta state for fallback action.
+    struct FallbackAction {
+        int32_t keyCode;
+        int32_t metaState;
+    };
+
     ~KeyCharacterMap();
 
-    // see the javadoc for android.text.method.KeyCharacterMap for what
-    // these do
-    unsigned short get(int keycode, int meta);
-    unsigned short getNumber(int keycode);
-    unsigned short getMatch(int keycode, const unsigned short* chars,
-                            int charsize, uint32_t modifiers);
-    unsigned short getDisplayLabel(int keycode);
-    bool getKeyData(int keycode, unsigned short *displayLabel,
-                    unsigned short *number, unsigned short* results);
-    inline unsigned int getKeyboardType() { return m_type; }
-    bool getEvents(uint16_t* chars, size_t len,
-                   Vector<int32_t>* keys, Vector<uint32_t>* modifiers);
+    static status_t load(const String8& filename, KeyCharacterMap** outMap);
+    static status_t loadByDeviceId(int32_t deviceId, KeyCharacterMap** outMap);
 
-    static KeyCharacterMap* load(int id);
+    /* Gets the keyboard type. */
+    int32_t getKeyboardType() const;
 
-    enum {
-        NUMERIC = 1,
-        Q14 = 2,
-        QWERTY = 3 // or AZERTY or whatever
-    };
+    /* Gets the primary character for this key as in the label physically printed on it.
+     * Returns 0 if none (eg. for non-printing keys). */
+    char16_t getDisplayLabel(int32_t keyCode) const;
 
-#define META_MASK 3
+    /* Gets the Unicode character for the number or symbol generated by the key
+     * when the keyboard is used as a dialing pad.
+     * Returns 0 if no number or symbol is generated.
+     */
+    char16_t getNumber(int32_t keyCode) const;
+
+    /* Gets the Unicode character generated by the key and meta key modifiers.
+     * Returns 0 if no character is generated.
+     */
+    char16_t getCharacter(int32_t keyCode, int32_t metaState) const;
+
+    /* Gets the fallback action to use by default if the application does not
+     * handle the specified key.
+     * Returns true if an action was available, false if none.
+     */
+    bool getFallbackAction(int32_t keyCode, int32_t metaState,
+            FallbackAction* outFallbackAction) const;
+
+    /* Gets the first matching Unicode character that can be generated by the key,
+     * preferring the one with the specified meta key modifiers.
+     * Returns 0 if no matching character is generated.
+     */
+    char16_t getMatch(int32_t keyCode, const char16_t* chars,
+            size_t numChars, int32_t metaState) const;
+
+    /* Gets a sequence of key events that could plausibly generate the specified
+     * character sequence.  Returns false if some of the characters cannot be generated.
+     */
+    bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
+            Vector<KeyEvent>& outEvents) const;
 
 private:
-    struct Key
-    {
-        int32_t keycode;
-        uint16_t display_label;
-        uint16_t number;
-        uint16_t data[META_MASK + 1];
+    struct Behavior {
+        Behavior();
+
+        /* The next behavior in the list, or NULL if none. */
+        Behavior* next;
+
+        /* The meta key modifiers for this behavior. */
+        int32_t metaState;
+
+        /* The character to insert. */
+        char16_t character;
+
+        /* The fallback keycode if the key is not handled. */
+        int32_t fallbackKeyCode;
     };
 
-    KeyCharacterMap();
-    static KeyCharacterMap* try_file(const char* filename);
-    Key* find_key(int keycode);
-    bool find_char(uint16_t c, uint32_t* key, uint32_t* mods);
+    struct Key {
+        Key();
+        ~Key();
 
-    unsigned int m_type;
-    unsigned int m_keyCount;
-    Key* m_keys;
+        /* The single character label printed on the key, or 0 if none. */
+        char16_t label;
+
+        /* The number or symbol character generated by the key, or 0 if none. */
+        char16_t number;
+
+        /* The list of key behaviors sorted from most specific to least specific
+         * meta key binding. */
+        Behavior* firstBehavior;
+    };
+
+    class Parser {
+        enum State {
+            STATE_TOP = 0,
+            STATE_KEY = 1,
+        };
+
+        enum {
+            PROPERTY_LABEL = 1,
+            PROPERTY_NUMBER = 2,
+            PROPERTY_META = 3,
+        };
+
+        struct Property {
+            inline Property(int32_t property = 0, int32_t metaState = 0) :
+                    property(property), metaState(metaState) { }
+
+            int32_t property;
+            int32_t metaState;
+        };
+
+        KeyCharacterMap* mMap;
+        Tokenizer* mTokenizer;
+        State mState;
+        int32_t mKeyCode;
+
+    public:
+        Parser(KeyCharacterMap* map, Tokenizer* tokenizer);
+        ~Parser();
+        status_t parse();
+
+    private:
+        status_t parseType();
+        status_t parseKey();
+        status_t parseKeyProperty();
+        status_t parseModifier(const String8& token, int32_t* outMetaState);
+        status_t parseCharacterLiteral(char16_t* outCharacter);
+    };
+
+    KeyedVector<int32_t, Key*> mKeys;
+    int mType;
+
+    KeyCharacterMap();
+
+    bool getKey(int32_t keyCode, const Key** outKey) const;
+    bool getKeyBehavior(int32_t keyCode, int32_t metaState,
+            const Key** outKey, const Behavior** outBehavior) const;
+
+    bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
+
+    static void addKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
+    static void addMetaKeys(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+            int32_t* currentMetaState);
+    static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+            int32_t keyCode, int32_t keyMetaState,
+            int32_t* currentMetaState);
+    static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+            int32_t leftKeyCode, int32_t leftKeyMetaState,
+            int32_t rightKeyCode, int32_t rightKeyMetaState,
+            int32_t eitherKeyMetaState,
+            int32_t* currentMetaState);
+    static void addLockedMetaKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, nsecs_t time,
+            int32_t keyCode, int32_t keyMetaState,
+            int32_t* currentMetaState);
 };
 
+} // namespace android
+
 #endif // _UI_KEY_CHARACTER_MAP_H
diff --git a/include/ui/KeyLayoutMap.h b/include/ui/KeyLayoutMap.h
new file mode 100644
index 0000000..d82d0c8
--- /dev/null
+++ b/include/ui/KeyLayoutMap.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 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 _UI_KEY_LAYOUT_MAP_H
+#define _UI_KEY_LAYOUT_MAP_H
+
+#include <stdint.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/Tokenizer.h>
+
+namespace android {
+
+struct AxisInfo {
+    enum Mode {
+        // Axis value is reported directly.
+        MODE_NORMAL = 0,
+        // Axis value should be inverted before reporting.
+        MODE_INVERT = 1,
+        // Axis value should be split into two axes
+        MODE_SPLIT = 2,
+    };
+
+    // Axis mode.
+    Mode mode;
+
+    // Axis id.
+    // When split, this is the axis used for values smaller than the split position.
+    int32_t axis;
+
+    // When split, this is the axis used for values after higher than the split position.
+    int32_t highAxis;
+
+    // The split value, or 0 if not split.
+    int32_t splitValue;
+
+    // The flat value, or -1 if none.
+    int32_t flatOverride;
+
+    AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
+    }
+};
+
+/**
+ * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
+ */
+class KeyLayoutMap {
+public:
+    ~KeyLayoutMap();
+
+    static status_t load(const String8& filename, KeyLayoutMap** outMap);
+
+    status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
+    status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
+
+    status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
+
+private:
+    struct Key {
+        int32_t keyCode;
+        uint32_t flags;
+    };
+
+    KeyedVector<int32_t, Key> mKeys;
+    KeyedVector<int32_t, AxisInfo> mAxes;
+
+    KeyLayoutMap();
+
+    class Parser {
+        KeyLayoutMap* mMap;
+        Tokenizer* mTokenizer;
+
+    public:
+        Parser(KeyLayoutMap* map, Tokenizer* tokenizer);
+        ~Parser();
+        status_t parse();
+
+    private:
+        status_t parseKey();
+        status_t parseAxis();
+    };
+};
+
+} // namespace android
+
+#endif // _UI_KEY_LAYOUT_MAP_H
diff --git a/include/ui/Keyboard.h b/include/ui/Keyboard.h
new file mode 100644
index 0000000..609f319
--- /dev/null
+++ b/include/ui/Keyboard.h
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#ifndef _UI_KEYBOARD_H
+#define _UI_KEYBOARD_H
+
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/PropertyMap.h>
+
+namespace android {
+
+enum {
+    /* Device id of the built in keyboard. */
+    DEVICE_ID_BUILT_IN_KEYBOARD = 0,
+
+    /* Device id of a generic virtual keyboard with a full layout that can be used
+     * to synthesize key events. */
+    DEVICE_ID_VIRTUAL_KEYBOARD = -1,
+};
+
+class KeyLayoutMap;
+class KeyCharacterMap;
+
+/**
+ * Loads the key layout map and key character map for a keyboard device.
+ */
+class KeyMap {
+public:
+    String8 keyLayoutFile;
+    KeyLayoutMap* keyLayoutMap;
+
+    String8 keyCharacterMapFile;
+    KeyCharacterMap* keyCharacterMap;
+
+    KeyMap();
+    ~KeyMap();
+
+    status_t load(const InputDeviceIdentifier& deviceIdenfier,
+            const PropertyMap* deviceConfiguration);
+
+    inline bool haveKeyLayout() const {
+        return !keyLayoutFile.isEmpty();
+    }
+
+    inline bool haveKeyCharacterMap() const {
+        return !keyCharacterMapFile.isEmpty();
+    }
+
+    inline bool isComplete() const {
+        return haveKeyLayout() && haveKeyCharacterMap();
+    }
+
+private:
+    bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
+    status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
+    status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
+            const String8& name);
+    String8 getPath(const InputDeviceIdentifier& deviceIdentifier,
+            const String8& name, InputDeviceConfigurationFileType type);
+};
+
+/**
+ * Returns true if the keyboard is eligible for use as a built-in keyboard.
+ */
+extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
+        const PropertyMap* deviceConfiguration, const KeyMap* keyMap);
+
+/**
+ * Sets keyboard system properties.
+ */
+extern void setKeyboardProperties(int32_t deviceId, const InputDeviceIdentifier& deviceIdentifier,
+        const String8& keyLayoutFile, const String8& keyCharacterMapFile);
+
+/**
+ * Clears keyboard system properties.
+ */
+extern void clearKeyboardProperties(int32_t deviceId);
+
+/**
+ * Gets the key character map filename for a device using inspecting system properties
+ * and then falling back on a default key character map if necessary.
+ * Returns a NAME_NOT_FOUND if none found.
+ */
+extern status_t getKeyCharacterMapFile(int32_t deviceId, String8& outKeyCharacterMapFile);
+
+/**
+ * Gets a key code by its short form label, eg. "HOME".
+ * Returns 0 if unknown.
+ */
+extern int32_t getKeyCodeByLabel(const char* label);
+
+/**
+ * Gets a key flag by its short form label, eg. "WAKE".
+ * Returns 0 if unknown.
+ */
+extern uint32_t getKeyFlagByLabel(const char* label);
+
+/**
+ * Gets a axis by its short form label, eg. "X".
+ * Returns -1 if unknown.
+ */
+extern int32_t getAxisByLabel(const char* label);
+
+/**
+ * Gets a axis label by its id.
+ * Returns NULL if unknown.
+ */
+extern const char* getAxisLabel(int32_t axisId);
+
+/**
+ * Updates a meta state field when a key is pressed or released.
+ */
+extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
+
+/**
+ * Returns true if a key is a meta key like ALT or CAPS_LOCK.
+ */
+extern bool isMetaKey(int32_t keyCode);
+
+} // namespace android
+
+#endif // _UI_KEYBOARD_H
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index f71d9cd..b912e9b 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -135,6 +135,99 @@
     { "BUTTON_START", 108 },
     { "BUTTON_SELECT", 109 },
     { "BUTTON_MODE", 110 },
+    { "ESCAPE", 111 },
+    { "FORWARD_DEL", 112 },
+    { "CTRL_LEFT", 113 },
+    { "CTRL_RIGHT", 114 },
+    { "CAPS_LOCK", 115 },
+    { "SCROLL_LOCK", 116 },
+    { "META_LEFT", 117 },
+    { "META_RIGHT", 118 },
+    { "FUNCTION", 119 },
+    { "SYSRQ", 120 },
+    { "BREAK", 121 },
+    { "MOVE_HOME", 122 },
+    { "MOVE_END", 123 },
+    { "INSERT", 124 },
+    { "FORWARD", 125 },
+    { "MEDIA_PLAY", 126 },
+    { "MEDIA_PAUSE", 127 },
+    { "MEDIA_CLOSE", 128 },
+    { "MEDIA_EJECT", 129 },
+    { "MEDIA_RECORD", 130 },
+    { "F1", 131 },
+    { "F2", 132 },
+    { "F3", 133 },
+    { "F4", 134 },
+    { "F5", 135 },
+    { "F6", 136 },
+    { "F7", 137 },
+    { "F8", 138 },
+    { "F9", 139 },
+    { "F10", 140 },
+    { "F11", 141 },
+    { "F12", 142 },
+    { "NUM_LOCK", 143 },
+    { "NUMPAD_0", 144 },
+    { "NUMPAD_1", 145 },
+    { "NUMPAD_2", 146 },
+    { "NUMPAD_3", 147 },
+    { "NUMPAD_4", 148 },
+    { "NUMPAD_5", 149 },
+    { "NUMPAD_6", 150 },
+    { "NUMPAD_7", 151 },
+    { "NUMPAD_8", 152 },
+    { "NUMPAD_9", 153 },
+    { "NUMPAD_DIVIDE", 154 },
+    { "NUMPAD_MULTIPLY", 155 },
+    { "NUMPAD_SUBTRACT", 156 },
+    { "NUMPAD_ADD", 157 },
+    { "NUMPAD_DOT", 158 },
+    { "NUMPAD_COMMA", 159 },
+    { "NUMPAD_ENTER", 160 },
+    { "NUMPAD_EQUALS", 161 },
+    { "NUMPAD_LEFT_PAREN", 162 },
+    { "NUMPAD_RIGHT_PAREN", 163 },
+    { "VOLUME_MUTE", 164 },
+    { "INFO", 165 },
+    { "CHANNEL_UP", 166 },
+    { "CHANNEL_DOWN", 167 },
+    { "ZOOM_IN", 168 },
+    { "ZOOM_OUT", 169 },
+    { "TV", 170 },
+    { "WINDOW", 171 },
+    { "GUIDE", 172 },
+    { "DVR", 173 },
+    { "BOOKMARK", 174 },
+    { "CAPTIONS", 175 },
+    { "SETTINGS", 176 },
+    { "TV_POWER", 177 },
+    { "TV_INPUT", 178 },
+    { "STB_POWER", 179 },
+    { "STB_INPUT", 180 },
+    { "AVR_POWER", 181 },
+    { "AVR_INPUT", 182 },
+    { "PROG_RED", 183 },
+    { "PROG_GREEN", 184 },
+    { "PROG_YELLOW", 185 },
+    { "PROG_BLUE", 186 },
+    { "APP_SWITCH", 187 },
+    { "BUTTON_1", 188 },
+    { "BUTTON_2", 189 },
+    { "BUTTON_3", 190 },
+    { "BUTTON_4", 191 },
+    { "BUTTON_5", 192 },
+    { "BUTTON_6", 193 },
+    { "BUTTON_7", 194 },
+    { "BUTTON_8", 195 },
+    { "BUTTON_9", 196 },
+    { "BUTTON_10", 197 },
+    { "BUTTON_11", 198 },
+    { "BUTTON_12", 199 },
+    { "BUTTON_13", 200 },
+    { "BUTTON_14", 201 },
+    { "BUTTON_15", 202 },
+    { "BUTTON_16", 203 },
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
@@ -142,7 +235,7 @@
     { NULL, 0 }
 };
 
-// See also policy flags in Input.h.
+// NOTE: If you edit these flags, also edit policy flags in Input.h.
 static const KeycodeLabel FLAGS[] = {
     { "WAKE", 0x00000001 },
     { "WAKE_DROPPED", 0x00000002 },
@@ -153,7 +246,56 @@
     { "MENU", 0x00000040 },
     { "LAUNCHER", 0x00000080 },
     { "VIRTUAL", 0x00000100 },
+    { "FUNCTION", 0x00000200 },
     { NULL, 0 }
 };
 
+static const KeycodeLabel AXES[] = {
+    { "X", 0 },
+    { "Y", 1 },
+    { "PRESSURE", 2 },
+    { "SIZE", 3 },
+    { "TOUCH_MAJOR", 4 },
+    { "TOUCH_MINOR", 5 },
+    { "TOOL_MAJOR", 6 },
+    { "TOOL_MINOR", 7 },
+    { "ORIENTATION", 8 },
+    { "VSCROLL", 9 },
+    { "HSCROLL", 10 },
+    { "Z", 11 },
+    { "RX", 12 },
+    { "RY", 13 },
+    { "RZ", 14 },
+    { "HAT_X", 15 },
+    { "HAT_Y", 16 },
+    { "LTRIGGER", 17 },
+    { "RTRIGGER", 18 },
+    { "THROTTLE", 19 },
+    { "RUDDER", 20 },
+    { "WHEEL", 21 },
+    { "GAS", 22 },
+    { "BRAKE", 23 },
+    { "GENERIC_1", 32 },
+    { "GENERIC_2", 33 },
+    { "GENERIC_3", 34 },
+    { "GENERIC_4", 35 },
+    { "GENERIC_5", 36 },
+    { "GENERIC_6", 37 },
+    { "GENERIC_7", 38 },
+    { "GENERIC_8", 39 },
+    { "GENERIC_9", 40 },
+    { "GENERIC_10", 41 },
+    { "GENERIC_11", 42 },
+    { "GENERIC_12", 43 },
+    { "GENERIC_13", 44 },
+    { "GENERIC_14", 45 },
+    { "GENERIC_15", 46 },
+    { "GENERIC_16", 47 },
+
+    // NOTE: If you add a new axis here you must also add it to several other files.
+    //       Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
+
+    { NULL, -1 }
+};
+
 #endif // _UI_KEYCODE_LABELS_H
diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h
deleted file mode 100644
index a9ae1c4..0000000
--- a/include/ui/Overlay.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2007 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_OVERLAY_H
-#define ANDROID_OVERLAY_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/IOverlay.h>
-
-#include <hardware/overlay.h>
-
-namespace android {
-
-class IMemory;
-class IMemoryHeap;
-
-// ----------------------------------------------------------------------------
-
-class OverlayRef : public LightRefBase<OverlayRef>
-{
-public:
-    OverlayRef(overlay_handle_t, const sp<IOverlay>&,
-            uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs);
-
-    static sp<OverlayRef> readFromParcel(const Parcel& data);
-    static status_t writeToParcel(Parcel* reply, const sp<OverlayRef>& o);    
-
-private:
-    friend class LightRefBase<OverlayRef>;
-    friend class Overlay;
-
-    OverlayRef();
-    virtual ~OverlayRef();
-
-    overlay_handle_t mOverlayHandle;
-    sp<IOverlay> mOverlayChannel;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    int32_t  mFormat;
-    int32_t  mWidthStride;
-    int32_t  mHeightStride;
-    bool mOwnHandle;
-};
-
-// ----------------------------------------------------------------------------
-
-class Overlay : public virtual RefBase
-{
-public:
-    Overlay(const sp<OverlayRef>& overlayRef);
-
-    /* destroys this overlay */
-    void destroy();
-    
-    /* get the HAL handle for this overlay */
-    overlay_handle_t getHandleRef() const;
-
-    /* blocks until an overlay buffer is available and return that buffer. */
-    status_t dequeueBuffer(overlay_buffer_t* buffer);
-
-    /* release the overlay buffer and post it */
-    status_t queueBuffer(overlay_buffer_t buffer);
-
-    /* change the width and height of the overlay */
-    status_t resizeInput(uint32_t width, uint32_t height);
-
-    status_t setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) ;
-
-    status_t getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) ;
-
-    /* set the buffer attributes */
-    status_t setParameter(int param, int value);
-
-    /* returns the address of a given buffer if supported, NULL otherwise. */
-    void* getBufferAddress(overlay_buffer_t buffer);
-
-    /* get physical informations about the overlay */
-    uint32_t getWidth() const;
-    uint32_t getHeight() const;
-    int32_t getFormat() const;
-    int32_t getWidthStride() const;
-    int32_t getHeightStride() const;
-    int32_t getBufferCount() const;
-    status_t getStatus() const;
-    
-private:
-    virtual ~Overlay();
-
-    sp<OverlayRef> mOverlayRef;
-    overlay_data_device_t *mOverlayData;
-    status_t mStatus;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_OVERLAY_H
diff --git a/include/ui/PowerManager.h b/include/ui/PowerManager.h
index 5434b4f..dd80318 100644
--- a/include/ui/PowerManager.h
+++ b/include/ui/PowerManager.h
@@ -22,14 +22,10 @@
 
 enum {
     POWER_MANAGER_OTHER_EVENT = 0,
-    POWER_MANAGER_CHEEK_EVENT = 1,
-    POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either
-                                   // up events or LONG_TOUCH events.
-    POWER_MANAGER_LONG_TOUCH_EVENT = 3,
-    POWER_MANAGER_TOUCH_UP_EVENT = 4,
-    POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events.
+    POWER_MANAGER_BUTTON_EVENT = 1,
+    POWER_MANAGER_TOUCH_EVENT = 2,
 
-    POWER_MANAGER_LAST_EVENT = POWER_MANAGER_BUTTON_EVENT, // Last valid event code.
+    POWER_MANAGER_LAST_EVENT = POWER_MANAGER_TOUCH_EVENT, // Last valid event code.
 };
 
 } // namespace android
diff --git a/include/ui/VirtualKeyMap.h b/include/ui/VirtualKeyMap.h
new file mode 100644
index 0000000..7813d9d
--- /dev/null
+++ b/include/ui/VirtualKeyMap.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#ifndef _UI_VIRTUAL_KEY_MAP_H
+#define _UI_VIRTUAL_KEY_MAP_H
+
+#include <stdint.h>
+
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/Tokenizer.h>
+#include <utils/String8.h>
+#include <utils/Unicode.h>
+
+namespace android {
+
+/* Describes a virtual key. */
+struct VirtualKeyDefinition {
+    int32_t scanCode;
+
+    // configured position data, specified in display coords
+    int32_t centerX;
+    int32_t centerY;
+    int32_t width;
+    int32_t height;
+};
+
+
+/**
+ * Describes a collection of virtual keys on a touch screen in terms of
+ * virtual scan codes and hit rectangles.
+ */
+class VirtualKeyMap {
+public:
+    ~VirtualKeyMap();
+
+    static status_t load(const String8& filename, VirtualKeyMap** outMap);
+
+    inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {
+        return mVirtualKeys;
+    }
+
+private:
+    class Parser {
+        VirtualKeyMap* mMap;
+        Tokenizer* mTokenizer;
+
+    public:
+        Parser(VirtualKeyMap* map, Tokenizer* tokenizer);
+        ~Parser();
+        status_t parse();
+
+    private:
+        bool consumeFieldDelimiterAndSkipWhitespace();
+        bool parseNextIntField(int32_t* outValue);
+    };
+
+    Vector<VirtualKeyDefinition> mVirtualKeys;
+
+    VirtualKeyMap();
+};
+
+} // namespace android
+
+#endif // _UI_KEY_CHARACTER_MAP_H
diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h
index a472824..402843e 100644
--- a/include/ui/android_native_buffer.h
+++ b/include/ui/android_native_buffer.h
@@ -51,12 +51,8 @@
     int stride;
     int format;
     int usage;
-
-    /* transformation as defined in hardware.h */
-    uint8_t transform;
-
-    uint8_t reserved_bytes[3];
-    void* reserved[1];
+    
+    void* reserved[2];
 
     buffer_handle_t handle;
 
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 654d0f3..0fc1ddf 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -75,6 +75,49 @@
     NATIVE_WINDOW_WIDTH     = 0,
     NATIVE_WINDOW_HEIGHT,
     NATIVE_WINDOW_FORMAT,
+
+    /* The minimum number of buffers that must remain un-dequeued after a buffer
+     * has been queued.  This value applies only if set_buffer_count was used to
+     * override the number of buffers and if a buffer has since been queued.
+     * Users of the set_buffer_count ANativeWindow method should query this
+     * value before calling set_buffer_count.  If it is necessary to have N
+     * buffers simultaneously dequeued as part of the steady-state operation,
+     * and this query returns M then N+M buffers should be requested via
+     * native_window_set_buffer_count.
+     *
+     * Note that this value does NOT apply until a single buffer has been
+     * queued.  In particular this means that it is possible to:
+     *
+     * 1. Query M = min undequeued buffers
+     * 2. Set the buffer count to N + M
+     * 3. Dequeue all N + M buffers
+     * 4. Cancel M buffers
+     * 5. Queue, dequeue, queue, dequeue, ad infinitum
+     */
+    NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+
+    /* Check whether queueBuffer operations on the ANativeWindow send the buffer
+     * to the window compositor.  The query sets the returned 'value' argument
+     * to 1 if the ANativeWindow DOES send queued buffers directly to the window
+     * compositor and 0 if the buffers do not go directly to the window
+     * compositor.
+     *
+     * This can be used to determine whether protected buffer content should be
+     * sent to the ANativeWindow.  Note, however, that a result of 1 does NOT
+     * indicate that queued buffers will be protected from applications or users
+     * capturing their contents.  If that behavior is desired then some other
+     * mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in
+     * conjunction with this query.
+     */
+    NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+
+    /* Get the concrete type of a ANativeWindow.  See below for the list of
+     * possible return values.
+     *
+     * This query should not be used outside the Android framework and will
+     * likely be removed in the near future.
+     */
+    NATIVE_WINDOW_CONCRETE_TYPE,
 };
 
 /* valid operations for the (*perform)() hook */
@@ -107,6 +150,13 @@
     NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
 };
 
+/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */
+enum {
+    NATIVE_WINDOW_FRAMEBUFFER,                  // FramebufferNativeWindow
+    NATIVE_WINDOW_SURFACE,                      // Surface
+    NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT,       // SurfaceTextureClient
+};
+
 struct ANativeWindow 
 {
 #ifdef __cplusplus
@@ -315,6 +365,8 @@
  * If all parameters are 0, the normal behavior is restored. That is,
  * dequeued buffers following this call will be sized to the window's size.
  *
+ * Calling this function will reset the window crop to a NULL value, which
+ * disables cropping of the buffers.
  */
 static inline int native_window_set_buffers_geometry(
         ANativeWindow* window,
diff --git a/include/utils/Asset.h b/include/utils/Asset.h
index 2a09095..1fe0e06 100644
--- a/include/utils/Asset.h
+++ b/include/utils/Asset.h
@@ -23,9 +23,11 @@
 
 #include <stdio.h>
 #include <sys/types.h>
-#include "FileMap.h"
-#include "String8.h"
-#include "Errors.h"
+
+#include <utils/Compat.h>
+#include <utils/Errors.h>
+#include <utils/FileMap.h>
+#include <utils/String8.h>
 
 namespace android {
 
@@ -69,10 +71,10 @@
 
     /*
      * Seek to the specified offset.  "whence" uses the same values as
-     * lseek/fseek.  Returns the new position on success, or (off_t) -1
+     * lseek/fseek.  Returns the new position on success, or (off64_t) -1
      * on failure.
      */
-    virtual off_t seek(off_t offset, int whence) = 0;
+    virtual off64_t seek(off64_t offset, int whence) = 0;
 
     /*
      * Close the asset, freeing all associated resources.
@@ -87,26 +89,26 @@
     /*
      * Get the total amount of data that can be read.
      */
-    virtual off_t getLength(void) const = 0;
+    virtual off64_t getLength(void) const = 0;
 
     /*
      * Get the total amount of data that can be read from the current position.
      */
-    virtual off_t getRemainingLength(void) const = 0;
+    virtual off64_t getRemainingLength(void) const = 0;
 
     /*
      * Open a new file descriptor that can be used to read this asset.
      * Returns -1 if you can not use the file descriptor (for example if the
      * asset is compressed).
      */
-    virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0;
-    
+    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const = 0;
+
     /*
      * Return whether this asset's buffer is allocated in RAM (not mmapped).
      * Note: not virtual so it is safe to call even when being destroyed.
      */
     virtual bool isAllocated(void) const { return false; }
-    
+
     /*
      * Get a string identifying the asset's source.  This might be a full
      * path, it might be a colon-separated list of identifiers.
@@ -120,7 +122,7 @@
     Asset(void);        // constructor; only invoked indirectly
 
     /* handle common seek() housekeeping */
-    off_t handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn);
+    off64_t handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn);
 
     /* set the asset source string */
     void setAssetSource(const String8& path) { mAssetSource = path; }
@@ -153,7 +155,7 @@
      *
      * The asset takes ownership of the file descriptor.
      */
-    static Asset* createFromFileSegment(int fd, off_t offset, size_t length,
+    static Asset* createFromFileSegment(int fd, off64_t offset, size_t length,
         AccessMode mode);
 
     /*
@@ -166,7 +168,7 @@
      * This may not verify the validity of the compressed data until first
      * use.
      */
-    static Asset* createFromCompressedData(int fd, off_t offset,
+    static Asset* createFromCompressedData(int fd, off64_t offset,
         int compressionMethod, size_t compressedLength,
         size_t uncompressedLength, AccessMode mode);
 #endif
@@ -221,7 +223,7 @@
      *
      * On success, the object takes ownership of "fd".
      */
-    status_t openChunk(const char* fileName, int fd, off_t offset, size_t length);
+    status_t openChunk(const char* fileName, int fd, off64_t offset, size_t length);
 
     /*
      * Use a memory-mapped region.
@@ -234,18 +236,18 @@
      * Standard Asset interfaces.
      */
     virtual ssize_t read(void* buf, size_t count);
-    virtual off_t seek(off_t offset, int whence);
+    virtual off64_t seek(off64_t offset, int whence);
     virtual void close(void);
     virtual const void* getBuffer(bool wordAligned);
-    virtual off_t getLength(void) const { return mLength; }
-    virtual off_t getRemainingLength(void) const { return mLength-mOffset; }
-    virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const;
+    virtual off64_t getLength(void) const { return mLength; }
+    virtual off64_t getRemainingLength(void) const { return mLength-mOffset; }
+    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const;
     virtual bool isAllocated(void) const { return mBuf != NULL; }
 
 private:
-    off_t       mStart;         // absolute file offset of start of chunk
-    off_t       mLength;        // length of the chunk
-    off_t       mOffset;        // current local offset, 0 == mStart
+    off64_t     mStart;         // absolute file offset of start of chunk
+    off64_t     mLength;        // length of the chunk
+    off64_t     mOffset;        // current local offset, 0 == mStart
     FILE*       mFp;            // for read/seek
     char*       mFileName;      // for opening
 
@@ -276,7 +278,7 @@
      *
      * On success, the object takes ownership of "fd".
      */
-    status_t openChunk(int fd, off_t offset, int compressionMethod,
+    status_t openChunk(int fd, off64_t offset, int compressionMethod,
         size_t uncompressedLen, size_t compressedLen);
 
     /*
@@ -291,19 +293,19 @@
      * Standard Asset interfaces.
      */
     virtual ssize_t read(void* buf, size_t count);
-    virtual off_t seek(off_t offset, int whence);
+    virtual off64_t seek(off64_t offset, int whence);
     virtual void close(void);
     virtual const void* getBuffer(bool wordAligned);
-    virtual off_t getLength(void) const { return mUncompressedLen; }
-    virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
-    virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; }
+    virtual off64_t getLength(void) const { return mUncompressedLen; }
+    virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
+    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; }
     virtual bool isAllocated(void) const { return mBuf != NULL; }
 
 private:
-    off_t       mStart;         // offset to start of compressed data
-    off_t       mCompressedLen; // length of the compressed data
-    off_t       mUncompressedLen; // length of the uncompressed data
-    off_t       mOffset;        // current offset, 0 == start of uncomp data
+    off64_t     mStart;         // offset to start of compressed data
+    off64_t     mCompressedLen; // length of the compressed data
+    off64_t     mUncompressedLen; // length of the uncompressed data
+    off64_t     mOffset;        // current offset, 0 == start of uncomp data
 
     FileMap*    mMap;           // for memory-mapped input
     int         mFd;            // for file input
diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h
index c2c8ce5..8817120 100644
--- a/include/utils/CallStack.h
+++ b/include/utils/CallStack.h
@@ -50,7 +50,7 @@
     
     void clear();
 
-    void update(int32_t ignoreDepth=0, int32_t maxDepth=MAX_DEPTH);
+    void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH);
 
     // Dump a stack trace to the log
     void dump(const char* prefix = 0) const;
diff --git a/include/utils/Compat.h b/include/utils/Compat.h
new file mode 100644
index 0000000..1819266
--- /dev/null
+++ b/include/utils/Compat.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef __LIB_UTILS_COMPAT_H
+#define __LIB_UTILS_COMPAT_H
+
+#include <unistd.h>
+
+/* Compatibility definitions for non-Linux (i.e., BSD-based) hosts. */
+#ifndef HAVE_OFF64_T
+#if _FILE_OFFSET_BITS < 64
+#error "_FILE_OFFSET_BITS < 64; large files are not supported on this platform"
+#endif /* _FILE_OFFSET_BITS < 64 */
+
+typedef off_t off64_t;
+
+static inline off64_t lseek64(int fd, off64_t offset, int whence) {
+    return lseek(fd, offset, whence);
+}
+
+#ifdef HAVE_PREAD
+static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) {
+    return pread(fd, buf, nbytes, offset);
+}
+#endif
+
+#endif /* !HAVE_OFF64_T */
+
+#endif /* __LIB_UTILS_COMPAT_H */
diff --git a/include/utils/FileMap.h b/include/utils/FileMap.h
index 8dfd3be..dfe6d51 100644
--- a/include/utils/FileMap.h
+++ b/include/utils/FileMap.h
@@ -22,6 +22,8 @@
 
 #include <sys/types.h>
 
+#include <utils/Compat.h>
+
 #ifdef HAVE_WIN32_FILEMAP
 #include <windows.h>
 #endif
@@ -55,7 +57,7 @@
      * Returns "false" on failure.
      */
     bool create(const char* origFileName, int fd,
-                off_t offset, size_t length, bool readOnly);
+                off64_t offset, size_t length, bool readOnly);
 
     /*
      * Return the name of the file this map came from, if known.
@@ -75,7 +77,7 @@
     /*
      * Get the data offset used to create this map.
      */
-    off_t getDataOffset(void) const { return mDataOffset; }
+    off64_t getDataOffset(void) const { return mDataOffset; }
 
     /*
      * Get a "copy" of the object.
@@ -118,7 +120,7 @@
     char*       mFileName;      // original file name, if known
     void*       mBasePtr;       // base of mmap area; page aligned
     size_t      mBaseLength;    // length, measured from "mBasePtr"
-    off_t       mDataOffset;    // offset used when map was created
+    off64_t     mDataOffset;    // offset used when map was created
     void*       mDataPtr;       // start of requested data, offset from base
     size_t      mDataLength;    // length, measured from "mDataPtr"
 #ifdef HAVE_WIN32_FILEMAP
diff --git a/include/utils/Functor.h b/include/utils/Functor.h
index 56a7557..e24ded4 100644
--- a/include/utils/Functor.h
+++ b/include/utils/Functor.h
@@ -17,11 +17,17 @@
 #ifndef ANDROID_FUNCTOR_H
 #define ANDROID_FUNCTOR_H
 
+#include <utils/Errors.h>
+
 namespace  android {
 
-struct Functor{};
+class Functor {
+public:
+    Functor() {}
+    virtual ~Functor() {}
+    virtual status_t operator ()(int what, void* data) { return NO_ERROR; }
+};
 
-}
+}; // namespace android
 
-#endif
-
+#endif // ANDROID_FUNCTOR_H
diff --git a/include/utils/Looper.h b/include/utils/Looper.h
index eefff31..3c2905d 100644
--- a/include/utils/Looper.h
+++ b/include/utils/Looper.h
@@ -45,6 +45,51 @@
 namespace android {
 
 /**
+ * A message that can be posted to a Looper.
+ */
+struct Message {
+    Message() : what(0) { }
+    Message(int what) : what(what) { }
+
+    /* The message type. (interpretation is left up to the handler) */
+    int what;
+};
+
+
+/**
+ * Interface for a Looper message handler.
+ *
+ * The Looper holds a strong reference to the message handler whenever it has
+ * a message to deliver to it.  Make sure to call Looper::removeMessages
+ * to remove any pending messages destined for the handler so that the handler
+ * can be destroyed.
+ */
+class MessageHandler : public virtual RefBase {
+protected:
+    virtual ~MessageHandler() { }
+
+public:
+    /**
+     * Handles a message.
+     */
+    virtual void handleMessage(const Message& message) = 0;
+};
+
+
+/**
+ * A simple proxy that holds a weak reference to a message handler.
+ */
+class WeakMessageHandler : public MessageHandler {
+public:
+    WeakMessageHandler(const wp<MessageHandler>& handler);
+    virtual void handleMessage(const Message& message);
+
+private:
+    wp<MessageHandler> mHandler;
+};
+
+
+/**
  * A polling loop that supports monitoring file descriptor events, optionally
  * using callbacks.  The implementation uses epoll() internally.
  *
@@ -166,6 +211,52 @@
     int removeFd(int fd);
 
     /**
+     * Enqueues a message to be processed by the specified handler.
+     *
+     * The handler must not be null.
+     * This method can be called on any thread.
+     */
+    void sendMessage(const sp<MessageHandler>& handler, const Message& message);
+
+    /**
+     * Enqueues a message to be processed by the specified handler after all pending messages
+     * after the specified delay.
+     *
+     * The time delay is specified in uptime nanoseconds.
+     * The handler must not be null.
+     * This method can be called on any thread.
+     */
+    void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
+            const Message& message);
+
+    /**
+     * Enqueues a message to be processed by the specified handler after all pending messages
+     * at the specified time.
+     *
+     * The time is specified in uptime nanoseconds.
+     * The handler must not be null.
+     * This method can be called on any thread.
+     */
+    void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
+            const Message& message);
+
+    /**
+     * Removes all messages for the specified handler from the queue.
+     *
+     * The handler must not be null.
+     * This method can be called on any thread.
+     */
+    void removeMessages(const sp<MessageHandler>& handler);
+
+    /**
+     * Removes all messages of a particular type for the specified handler from the queue.
+     *
+     * The handler must not be null.
+     * This method can be called on any thread.
+     */
+    void removeMessages(const sp<MessageHandler>& handler, int what);
+
+    /**
      * Prepares a looper associated with the calling thread, and returns it.
      * If the thread already has a looper, it is returned.  Otherwise, a new
      * one is created, associated with the thread, and returned.
@@ -201,12 +292,27 @@
         Request request;
     };
 
+    struct MessageEnvelope {
+        MessageEnvelope() : uptime(0) { }
+
+        MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,
+                const Message& message) : uptime(uptime), handler(handler), message(message) {
+        }
+
+        nsecs_t uptime;
+        sp<MessageHandler> handler;
+        Message message;
+    };
+
     const bool mAllowNonCallbacks; // immutable
 
     int mWakeReadPipeFd;  // immutable
     int mWakeWritePipeFd; // immutable
     Mutex mLock;
 
+    Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
+    bool mSendingMessage; // guarded by mLock
+
 #ifdef LOOPER_USES_EPOLL
     int mEpollFd; // immutable
 
@@ -256,6 +362,7 @@
     // it runs on a single thread.
     Vector<Response> mResponses;
     size_t mResponseIndex;
+    nsecs_t mNextMessageUptime; // set to LLONG_MAX when none
 
     int pollInner(int timeoutMillis);
     void awoken();
diff --git a/include/utils/PropertyMap.h b/include/utils/PropertyMap.h
new file mode 100644
index 0000000..a9e674f
--- /dev/null
+++ b/include/utils/PropertyMap.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#ifndef _UTILS_PROPERTY_MAP_H
+#define _UTILS_PROPERTY_MAP_H
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/Errors.h>
+#include <utils/Tokenizer.h>
+
+namespace android {
+
+/*
+ * Provides a mechanism for passing around string-based property key / value pairs
+ * and loading them from property files.
+ *
+ * The property files have the following simple structure:
+ *
+ * # Comment
+ * key = value
+ *
+ * Keys and values are any sequence of printable ASCII characters.
+ * The '=' separates the key from the value.
+ * The key and value may not contain whitespace.
+ *
+ * The '\' character is reserved for escape sequences and is not currently supported.
+ * The '"" character is reserved for quoting and is not currently supported.
+ * Files that contain the '\' or '"' character will fail to parse.
+ *
+ * The file must not contain duplicate keys.
+ *
+ * TODO Support escape sequences and quoted values when needed.
+ */
+class PropertyMap {
+public:
+    /* Creates an empty property map. */
+    PropertyMap();
+    ~PropertyMap();
+
+    /* Clears the property map. */
+    void clear();
+
+    /* Adds a property.
+     * Replaces the property with the same key if it is already present.
+     */
+    void addProperty(const String8& key, const String8& value);
+
+    /* Returns true if the property map contains the specified key. */
+    bool hasProperty(const String8& key) const;
+
+    /* Gets the value of a property and parses it.
+     * Returns true and sets outValue if the key was found and its value was parsed successfully.
+     * Otherwise returns false and does not modify outValue.  (Also logs a warning.)
+     */
+    bool tryGetProperty(const String8& key, String8& outValue) const;
+    bool tryGetProperty(const String8& key, bool& outValue) const;
+    bool tryGetProperty(const String8& key, int32_t& outValue) const;
+    bool tryGetProperty(const String8& key, float& outValue) const;
+
+    /* Adds all values from the specified property map. */
+    void addAll(const PropertyMap* map);
+
+    /* Gets the underlying property map. */
+    inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; }
+
+    /* Loads a property map from a file. */
+    static status_t load(const String8& filename, PropertyMap** outMap);
+
+private:
+    class Parser {
+        PropertyMap* mMap;
+        Tokenizer* mTokenizer;
+
+    public:
+        Parser(PropertyMap* map, Tokenizer* tokenizer);
+        ~Parser();
+        status_t parse();
+
+    private:
+        status_t parseType();
+        status_t parseKey();
+        status_t parseKeyProperty();
+        status_t parseModifier(const String8& token, int32_t* outMetaState);
+        status_t parseCharacterLiteral(char16_t* outCharacter);
+    };
+
+    KeyedVector<String8, String8> mProperties;
+};
+
+} // namespace android
+
+#endif // _UTILS_PROPERTY_MAP_H
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index c24c0db..f355087 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -18,16 +18,19 @@
 #define ANDROID_REF_BASE_H
 
 #include <cutils/atomic.h>
-#include <utils/TextOutput.h>
 
 #include <stdint.h>
 #include <sys/types.h>
 #include <stdlib.h>
+#include <string.h>
+
+#include <utils/StrongPointer.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
 
-template<typename T> class wp;
+class TextOutput;
+TextOutput& printWeakPointer(TextOutput& to, const void* val);
 
 // ---------------------------------------------------------------------------
 
@@ -47,15 +50,15 @@
     return m_ptr _op_ o;                                        \
 }
 
-#define COMPARE(_op_)                                           \
-COMPARE_WEAK(_op_)                                              \
-inline bool operator _op_ (const wp<T>& o) const {              \
-    return m_ptr _op_ o.m_ptr;                                  \
-}                                                               \
-template<typename U>                                            \
-inline bool operator _op_ (const wp<U>& o) const {              \
-    return m_ptr _op_ o.m_ptr;                                  \
-}
+// ---------------------------------------------------------------------------
+
+class ReferenceMover;
+class ReferenceConverterBase {
+public:
+    virtual size_t getReferenceTypeSize() const = 0;
+    virtual void* getReferenceBase(void const*) const = 0;
+    inline virtual ~ReferenceConverterBase() { }
+};
 
 // ---------------------------------------------------------------------------
 
@@ -112,6 +115,8 @@
         getWeakRefs()->trackMe(enable, retain); 
     }
 
+    typedef RefBase basetype;
+
 protected:
                             RefBase();
     virtual                 ~RefBase();
@@ -135,6 +140,11 @@
     virtual void            onLastWeakRef(const void* id);
 
 private:
+    friend class ReferenceMover;
+    static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster);
+
+private:
     friend class weakref_type;
     class weakref_impl;
     
@@ -163,10 +173,17 @@
     inline int32_t getStrongCount() const {
         return mCount;
     }
-    
+
+    typedef LightRefBase<T> basetype;
+
 protected:
     inline ~LightRefBase() { }
-    
+
+private:
+    friend class ReferenceMover;
+    inline static void moveReferences(void* d, void const* s, size_t n,
+            const ReferenceConverterBase& caster) { }
+
 private:
     mutable volatile int32_t mCount;
 };
@@ -174,66 +191,6 @@
 // ---------------------------------------------------------------------------
 
 template <typename T>
-class sp
-{
-public:
-    typedef typename RefBase::weakref_type weakref_type;
-    
-    inline sp() : m_ptr(0) { }
-
-    sp(T* other);
-    sp(const sp<T>& other);
-    template<typename U> sp(U* other);
-    template<typename U> sp(const sp<U>& other);
-
-    ~sp();
-    
-    // Assignment
-
-    sp& operator = (T* other);
-    sp& operator = (const sp<T>& other);
-    
-    template<typename U> sp& operator = (const sp<U>& other);
-    template<typename U> sp& operator = (U* other);
-    
-    //! Special optimization for use by ProcessState (and nobody else).
-    void force_set(T* other);
-    
-    // Reset
-    
-    void clear();
-    
-    // Accessors
-
-    inline  T&      operator* () const  { return *m_ptr; }
-    inline  T*      operator-> () const { return m_ptr;  }
-    inline  T*      get() const         { return m_ptr; }
-
-    // Operators
-        
-    COMPARE(==)
-    COMPARE(!=)
-    COMPARE(>)
-    COMPARE(<)
-    COMPARE(<=)
-    COMPARE(>=)
-
-private:    
-    template<typename Y> friend class sp;
-    template<typename Y> friend class wp;
-
-    // Optimization for wp::promote().
-    sp(T* p, weakref_type* refs);
-    
-    T*              m_ptr;
-};
-
-template <typename T>
-TextOutput& operator<<(TextOutput& to, const sp<T>& val);
-
-// ---------------------------------------------------------------------------
-
-template <typename T>
 class wp
 {
 public:
@@ -326,114 +283,12 @@
 template <typename T>
 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
 
-#undef COMPARE
 #undef COMPARE_WEAK
 
 // ---------------------------------------------------------------------------
 // No user serviceable parts below here.
 
 template<typename T>
-sp<T>::sp(T* other)
-    : m_ptr(other)
-{
-    if (other) other->incStrong(this);
-}
-
-template<typename T>
-sp<T>::sp(const sp<T>& other)
-    : m_ptr(other.m_ptr)
-{
-    if (m_ptr) m_ptr->incStrong(this);
-}
-
-template<typename T> template<typename U>
-sp<T>::sp(U* other) : m_ptr(other)
-{
-    if (other) other->incStrong(this);
-}
-
-template<typename T> template<typename U>
-sp<T>::sp(const sp<U>& other)
-    : m_ptr(other.m_ptr)
-{
-    if (m_ptr) m_ptr->incStrong(this);
-}
-
-template<typename T>
-sp<T>::~sp()
-{
-    if (m_ptr) m_ptr->decStrong(this);
-}
-
-template<typename T>
-sp<T>& sp<T>::operator = (const sp<T>& other) {
-    T* otherPtr(other.m_ptr);
-    if (otherPtr) otherPtr->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = otherPtr;
-    return *this;
-}
-
-template<typename T>
-sp<T>& sp<T>::operator = (T* other)
-{
-    if (other) other->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other;
-    return *this;
-}
-
-template<typename T> template<typename U>
-sp<T>& sp<T>::operator = (const sp<U>& other)
-{
-    U* otherPtr(other.m_ptr);
-    if (otherPtr) otherPtr->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = otherPtr;
-    return *this;
-}
-
-template<typename T> template<typename U>
-sp<T>& sp<T>::operator = (U* other)
-{
-    if (other) other->incStrong(this);
-    if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other;
-    return *this;
-}
-
-template<typename T>    
-void sp<T>::force_set(T* other)
-{
-    other->forceIncStrong(this);
-    m_ptr = other;
-}
-
-template<typename T>
-void sp<T>::clear()
-{
-    if (m_ptr) {
-        m_ptr->decStrong(this);
-        m_ptr = 0;
-    }
-}
-
-template<typename T>
-sp<T>::sp(T* p, weakref_type* refs)
-    : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
-{
-}
-
-template <typename T>
-inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
-{
-    to << "sp<>(" << val.get() << ")";
-    return to;
-}
-
-// ---------------------------------------------------------------------------
-
-template<typename T>
 wp<T>::wp(T* other)
     : m_ptr(other)
 {
@@ -570,7 +425,11 @@
 template<typename T>
 sp<T> wp<T>::promote() const
 {
-    return sp<T>(m_ptr, m_refs);
+    sp<T> result;
+    if (m_ptr && m_refs->attemptIncStrong(&result)) {
+        result.set_pointer(m_ptr);
+    }
+    return result;
 }
 
 template<typename T>
@@ -585,10 +444,80 @@
 template <typename T>
 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
 {
-    to << "wp<>(" << val.unsafe_get() << ")";
-    return to;
+    return printWeakPointer(to, val.unsafe_get());
 }
 
+// ---------------------------------------------------------------------------
+
+// this class just serves as a namespace so TYPE::moveReferences can stay
+// private.
+
+class ReferenceMover {
+    // StrongReferenceCast and WeakReferenceCast do the impedance matching
+    // between the generic (void*) implementation in Refbase and the strongly typed
+    // template specializations below.
+
+    template <typename TYPE>
+    struct StrongReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->get());
+        }
+    };
+
+    template <typename TYPE>
+    struct WeakReferenceCast : public ReferenceConverterBase {
+        virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
+        virtual void* getReferenceBase(void const* p) const {
+            wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
+            return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
+        }
+    };
+
+public:
+    template<typename TYPE> static inline
+    void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(sp<TYPE>));
+        StrongReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+    template<typename TYPE> static inline
+    void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+        memmove(d, s, n*sizeof(wp<TYPE>));
+        WeakReferenceCast<TYPE> caster;
+        TYPE::moveReferences(d, s, n, caster);
+    }
+};
+
+// specialization for moving sp<> and wp<> types.
+// these are used by the [Sorted|Keyed]Vector<> implementations
+// sp<> and wp<> need to be handled specially, because they do not
+// have trivial copy operation in the general case (see RefBase.cpp
+// when DEBUG ops are enabled), but can be implemented very
+// efficiently in most cases.
+
+template<typename TYPE> inline
+void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+template<typename TYPE> inline
+void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+    ReferenceMover::move_references(d, s, n);
+}
+
+
 }; // namespace android
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index ab7b973..6227f3e 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -1771,12 +1771,14 @@
      *
      * @return ssize_t Either a >= 0 table index or a negative error code.
      */
-    ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false,
-            uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const;
+    ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag = false,
+                    uint16_t density = 0,
+                    uint32_t* outSpecFlags = NULL,
+                    ResTable_config* outConfig = NULL) const;
 
     inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
             uint32_t* outSpecFlags=NULL) const {
-        return getResource(res.ident, outValue, false, outSpecFlags, NULL);
+        return getResource(res.ident, outValue, false, 0, outSpecFlags, NULL);
     }
 
     ssize_t resolveReference(Res_value* inOutValue,
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index 3b975b4..e1ee8eb 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -37,6 +37,11 @@
         }
         return *instance;
     }
+
+    static bool hasInstance() {
+        Mutex::Autolock _l(sLock);
+        return sInstance != 0;
+    }
     
 protected:
     ~Singleton() { };
diff --git a/include/utils/StreamingZipInflater.h b/include/utils/StreamingZipInflater.h
index 16867d8..3ace5d5 100644
--- a/include/utils/StreamingZipInflater.h
+++ b/include/utils/StreamingZipInflater.h
@@ -21,6 +21,8 @@
 #include <inttypes.h>
 #include <zlib.h>
 
+#include <utils/Compat.h>
+
 namespace android {
 
 class StreamingZipInflater {
@@ -29,7 +31,7 @@
     static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;
 
     // Flavor that pages in the compressed data from a fd
-    StreamingZipInflater(int fd, off_t compDataStart, size_t uncompSize, size_t compSize);
+    StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize);
 
     // Flavor that gets the compressed data from an in-memory buffer
     StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
@@ -43,7 +45,7 @@
     // seeking backwards requires uncompressing fom the beginning, so is very
     // expensive.  seeking forwards only requires uncompressing from the current
     // position to the destination.
-    off_t seekAbsolute(off_t absoluteInputPosition);
+    off64_t seekAbsolute(off64_t absoluteInputPosition);
 
 private:
     void initInflateState();
@@ -51,7 +53,7 @@
 
     // where to find the uncompressed data
     int mFd;
-    off_t mInFileStart;         // where the compressed data lives in the file
+    off64_t mInFileStart;         // where the compressed data lives in the file
     class FileMap* mDataMap;
 
     z_stream mInflateState;
@@ -63,7 +65,7 @@
     size_t mOutTotalSize;       // total uncompressed size of the blob
 
     // current output state bookkeeping
-    off_t mOutCurPosition;      // current position in total offset
+    off64_t mOutCurPosition;      // current position in total offset
     size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf
     size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf
 
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 07a0c11..584f53f 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -19,39 +19,12 @@
 
 #include <utils/Errors.h>
 #include <utils/SharedBuffer.h>
-
-#include <stdint.h>
-#include <sys/types.h>
+#include <utils/Unicode.h>
 
 // ---------------------------------------------------------------------------
 
 extern "C" {
 
-typedef uint16_t char16_t;
-
-// Standard string functions on char16 strings.
-int strcmp16(const char16_t *, const char16_t *);
-int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
-size_t strlen16(const char16_t *);
-size_t strnlen16(const char16_t *, size_t);
-char16_t *strcpy16(char16_t *, const char16_t *);
-char16_t *strncpy16(char16_t *, const char16_t *, size_t);
-
-// Version of comparison that supports embedded nulls.
-// This is different than strncmp() because we don't stop
-// at a nul character and consider the strings to be different
-// if the lengths are different (thus we need to supply the
-// lengths of both strings).  This can also be used when
-// your string is not nul-terminated as it will have the
-// equivalent result as strcmp16 (unlike strncmp16).
-int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
-
-// Version of strzcmp16 for comparing strings in different endianness.
-int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
-
-// Convert UTF-8 to UTF-16 including surrogate pairs
-void utf8_to_utf16(const uint8_t *src, size_t srcLen, char16_t* dst, const size_t dstLen);
-
 }
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/String8.h b/include/utils/String8.h
index ef0b51a..4163697 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -18,122 +18,17 @@
 #define ANDROID_STRING8_H
 
 #include <utils/Errors.h>
+#include <utils/SharedBuffer.h>
+#include <utils/Unicode.h>
 
-// Need this for the char16_t type; String8.h should not
-// be depedent on the String16 class.
-#include <utils/String16.h>
-
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-
-// ---------------------------------------------------------------------------
-
-extern "C" {
-
-typedef uint32_t char32_t;
-
-size_t strlen32(const char32_t *);
-size_t strnlen32(const char32_t *, size_t);
-
-/*
- * Returns the length of "src" when "src" is valid UTF-8 string.
- * Returns 0 if src is NULL, 0-length string or non UTF-8 string.
- * This function should be used to determine whether "src" is valid UTF-8
- * characters with valid unicode codepoints. "src" must be null-terminated.
- *
- * If you are going to use other GetUtf... functions defined in this header
- * with string which may not be valid UTF-8 with valid codepoint (form 0 to
- * 0x10FFFF), you should use this function before calling others, since the
- * other functions do not check whether the string is valid UTF-8 or not.
- *
- * If you do not care whether "src" is valid UTF-8 or not, you should use
- * strlen() as usual, which should be much faster.
- */
-size_t utf8_length(const char *src);
-
-/*
- * Returns the UTF-32 length of "src".
- */
-size_t utf32_length(const char *src, size_t src_len);
-
-/*
- * Returns the UTF-8 length of "src".
- */
-size_t utf8_length_from_utf16(const char16_t *src, size_t src_len);
-
-/*
- * Returns the UTF-8 length of "src".
- */
-size_t utf8_length_from_utf32(const char32_t *src, size_t src_len);
-
-/*
- * Returns the unicode value at "index".
- * Returns -1 when the index is invalid (equals to or more than "src_len").
- * If returned value is positive, it is able to be converted to char32_t, which
- * is unsigned. Then, if "next_index" is not NULL, the next index to be used is
- * stored in "next_index". "next_index" can be NULL.
- */
-int32_t utf32_at(const char *src, size_t src_len,
-                 size_t index, size_t *next_index);
-
-/*
- * Stores a UTF-32 string converted from "src" in "dst", if "dst_length" is not
- * large enough to store the string, the part of the "src" string is stored
- * into "dst".
- * Returns the size actually used for storing the string.
- * "dst" is not null-terminated when dst_len is fully used (like strncpy).
- */
-size_t utf8_to_utf32(const char* src, size_t src_len,
-                     char32_t* dst, size_t dst_len);
-
-/*
- * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not
- * large enough to store the string, the part of the "src" string is stored
- * into "dst" as much as possible. See the examples for more detail.
- * Returns the size actually used for storing the string.
- * dst" is not null-terminated when dst_len is fully used (like strncpy).
- *
- * Example 1
- * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
- * "src_len" == 2
- * "dst_len" >= 7
- * ->
- * Returned value == 6
- * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0
- * (note that "dst" is null-terminated)
- *
- * Example 2
- * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
- * "src_len" == 2
- * "dst_len" == 5
- * ->
- * Returned value == 3
- * "dst" becomes \xE3\x81\x82\0
- * (note that "dst" is null-terminated, but \u3044 is not stored in "dst"
- * since "dst" does not have enough size to store the character)
- *
- * Example 3
- * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
- * "src_len" == 2
- * "dst_len" == 6
- * ->
- * Returned value == 6
- * "dst" becomes \xE3\x81\x82\xE3\x81\x84
- * (note that "dst" is NOT null-terminated, like strncpy)
- */
-size_t utf32_to_utf8(const char32_t* src, size_t src_len,
-                     char* dst, size_t dst_len);
-
-size_t utf16_to_utf8(const char16_t* src, size_t src_len,
-                     char* dst, size_t dst_len);
-
-}
+#include <string.h> // for strcmp
+#include <stdarg.h>
 
 // ---------------------------------------------------------------------------
 
 namespace android {
 
+class String16;
 class TextOutput;
 
 //! This is a string holding UTF-8 characters. Does not allow the value more
@@ -152,14 +47,22 @@
     explicit                    String8(const char32_t* o);
     explicit                    String8(const char32_t* o, size_t numChars);
                                 ~String8();
-    
+
+    static inline const String8 empty();
+
+    static String8              format(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
+    static String8              formatV(const char* fmt, va_list args);
+
     inline  const char*         string() const;
     inline  size_t              size() const;
     inline  size_t              length() const;
     inline  size_t              bytes() const;
+    inline  bool                isEmpty() const;
     
     inline  const SharedBuffer* sharedBuffer() const;
     
+            void                clear();
+
             void                setTo(const String8& other);
             status_t            setTo(const char* other);
             status_t            setTo(const char* other, size_t numChars);
@@ -173,13 +76,14 @@
 
             status_t            appendFormat(const char* fmt, ...)
                     __attribute__((format (printf, 2, 3)));
+            status_t            appendFormatV(const char* fmt, va_list args);
 
             // Note that this function takes O(N) time to calculate the value.
             // No cache value is stored.
             size_t              getUtf32Length() const;
             int32_t             getUtf32At(size_t index,
                                            size_t *next_index) const;
-            size_t              getUtf32(char32_t* dst, size_t dst_len) const;
+            void                getUtf32(char32_t* dst) const;
 
     inline  String8&            operator=(const String8& other);
     inline  String8&            operator=(const char* other);
@@ -261,8 +165,8 @@
     String8 walkPath(String8* outRemains = NULL) const;
 
     /*
-     * Return the filename extension.  This is the last '.' and up to
-     * four characters that follow it.  The '.' is included in case we
+     * Return the filename extension.  This is the last '.' and any number
+     * of characters that follow it.  The '.' is included in case we
      * decide to expand our definition of what constitutes an extension.
      *
      * "/tmp/foo/bar.c" --> ".c"
@@ -330,6 +234,10 @@
     return compare_type(lhs, rhs) < 0;
 }
 
+inline const String8 String8::empty() {
+    return String8();
+}
+
 inline const char* String8::string() const
 {
     return mString;
@@ -345,6 +253,11 @@
     return length();
 }
 
+inline bool String8::isEmpty() const
+{
+    return length() == 0;
+}
+
 inline size_t String8::bytes() const
 {
     return SharedBuffer::sizeFromData(mString)-1;
diff --git a/include/utils/StrongPointer.h b/include/utils/StrongPointer.h
new file mode 100644
index 0000000..49fa3a8
--- /dev/null
+++ b/include/utils/StrongPointer.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2005 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_STRONG_POINTER_H
+#define ANDROID_STRONG_POINTER_H
+
+#include <cutils/atomic.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class TextOutput;
+TextOutput& printStrongPointer(TextOutput& to, const void* val);
+
+template<typename T> class wp;
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE(_op_)                                           \
+inline bool operator _op_ (const sp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+inline bool operator _op_ (const T* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const sp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const U* o) const {                  \
+    return m_ptr _op_ o;                                        \
+}                                                               \
+inline bool operator _op_ (const wp<T>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}                                                               \
+template<typename U>                                            \
+inline bool operator _op_ (const wp<U>& o) const {              \
+    return m_ptr _op_ o.m_ptr;                                  \
+}
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class sp
+{
+public:
+    inline sp() : m_ptr(0) { }
+
+    sp(T* other);
+    sp(const sp<T>& other);
+    template<typename U> sp(U* other);
+    template<typename U> sp(const sp<U>& other);
+
+    ~sp();
+
+    // Assignment
+
+    sp& operator = (T* other);
+    sp& operator = (const sp<T>& other);
+
+    template<typename U> sp& operator = (const sp<U>& other);
+    template<typename U> sp& operator = (U* other);
+
+    //! Special optimization for use by ProcessState (and nobody else).
+    void force_set(T* other);
+
+    // Reset
+
+    void clear();
+
+    // Accessors
+
+    inline  T&      operator* () const  { return *m_ptr; }
+    inline  T*      operator-> () const { return m_ptr;  }
+    inline  T*      get() const         { return m_ptr; }
+
+    // Operators
+
+    COMPARE(==)
+    COMPARE(!=)
+    COMPARE(>)
+    COMPARE(<)
+    COMPARE(<=)
+    COMPARE(>=)
+
+private:    
+    template<typename Y> friend class sp;
+    template<typename Y> friend class wp;
+    void set_pointer(T* ptr);
+    T* m_ptr;
+};
+
+#undef COMPARE
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const sp<T>& val);
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+sp<T>::sp(T* other)
+: m_ptr(other)
+  {
+    if (other) other->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::sp(const sp<T>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T> template<typename U>
+sp<T>::sp(U* other) : m_ptr(other)
+{
+    if (other) ((T*)other)->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(const sp<U>& other)
+: m_ptr(other.m_ptr)
+  {
+    if (m_ptr) m_ptr->incStrong(this);
+  }
+
+template<typename T>
+sp<T>::~sp()
+{
+    if (m_ptr) m_ptr->decStrong(this);
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (const sp<T>& other) {
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (T* other)
+{
+    if (other) other->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (const sp<U>& other)
+{
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = otherPtr;
+    return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (U* other)
+{
+    if (other) ((T*)other)->incStrong(this);
+    if (m_ptr) m_ptr->decStrong(this);
+    m_ptr = other;
+    return *this;
+}
+
+template<typename T>    
+void sp<T>::force_set(T* other)
+{
+    other->forceIncStrong(this);
+    m_ptr = other;
+}
+
+template<typename T>
+void sp<T>::clear()
+{
+    if (m_ptr) {
+        m_ptr->decStrong(this);
+        m_ptr = 0;
+    }
+}
+
+template<typename T>
+void sp<T>::set_pointer(T* ptr) {
+    m_ptr = ptr;
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
+{
+    return printStrongPointer(to, val.get());
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STRONG_POINTER_H
diff --git a/include/utils/Tokenizer.h b/include/utils/Tokenizer.h
new file mode 100644
index 0000000..c7db5fb
--- /dev/null
+++ b/include/utils/Tokenizer.h
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+#ifndef _UTILS_TOKENIZER_H
+#define _UTILS_TOKENIZER_H
+
+#include <assert.h>
+#include <utils/Errors.h>
+#include <utils/FileMap.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/**
+ * A simple tokenizer for loading and parsing ASCII text files line by line.
+ */
+class Tokenizer {
+    Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length);
+
+public:
+    ~Tokenizer();
+
+    /**
+     * Opens a file and maps it into memory.
+     *
+     * Returns NO_ERROR and a tokenizer for the file, if successful.
+     * Otherwise returns an error and sets outTokenizer to NULL.
+     */
+    static status_t open(const String8& filename, Tokenizer** outTokenizer);
+
+    /**
+     * Returns true if at the end of the file.
+     */
+    inline bool isEof() const { return mCurrent == getEnd(); }
+
+    /**
+     * Returns true if at the end of the line or end of the file.
+     */
+    inline bool isEol() const { return isEof() || *mCurrent == '\n'; }
+
+    /**
+     * Gets the name of the file.
+     */
+    inline String8 getFilename() const { return mFilename; }
+
+    /**
+     * Gets a 1-based line number index for the current position.
+     */
+    inline int32_t getLineNumber() const { return mLineNumber; }
+
+    /**
+     * Formats a location string consisting of the filename and current line number.
+     * Returns a string like "MyFile.txt:33".
+     */
+    String8 getLocation() const;
+
+    /**
+     * Gets the character at the current position.
+     * Returns null at end of file.
+     */
+    inline char peekChar() const { return isEof() ? '\0' : *mCurrent; }
+
+    /**
+     * Gets the remainder of the current line as a string, excluding the newline character.
+     */
+    String8 peekRemainderOfLine() const;
+
+    /**
+     * Gets the character at the current position and advances past it.
+     * Returns null at end of file.
+     */
+    inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); }
+
+    /**
+     * Gets the next token on this line stopping at the specified delimiters
+     * or the end of the line whichever comes first and advances past it.
+     * Also stops at embedded nulls.
+     * Returns the token or an empty string if the current character is a delimiter
+     * or is at the end of the line.
+     */
+    String8 nextToken(const char* delimiters);
+
+    /**
+     * Advances to the next line.
+     * Does nothing if already at the end of the file.
+     */
+    void nextLine();
+
+    /**
+     * Skips over the specified delimiters in the line.
+     * Also skips embedded nulls.
+     */
+    void skipDelimiters(const char* delimiters);
+
+private:
+    Tokenizer(const Tokenizer& other); // not copyable
+
+    String8 mFilename;
+    FileMap* mFileMap;
+    char* mBuffer;
+    size_t mLength;
+
+    const char* mCurrent;
+    int32_t mLineNumber;
+
+    inline const char* getEnd() const { return mBuffer + mLength; }
+
+};
+
+} // namespace android
+
+#endif // _UTILS_TOKENIZER_H
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
index 2ff2749..a1663f3 100644
--- a/include/utils/TypeHelpers.h
+++ b/include/utils/TypeHelpers.h
@@ -37,18 +37,6 @@
 template <typename T> struct trait_pointer      { enum { value = false }; };    
 template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
 
-// sp<> can be trivially moved
-template <typename T> class sp;
-template <typename T> struct trait_trivial_move< sp<T> >{
-    enum { value = true }; 
-};
-
-// wp<> can be trivially moved
-template <typename T> class wp;
-template <typename T> struct trait_trivial_move< wp<T> >{ 
-    enum { value = true }; 
-};
-
 template <typename TYPE>
 struct traits {
     enum {
@@ -217,7 +205,6 @@
     }
 }
 
-
 // ---------------------------------------------------------------------------
 
 /*
diff --git a/include/utils/Unicode.h b/include/utils/Unicode.h
new file mode 100644
index 0000000..6afb291
--- /dev/null
+++ b/include/utils/Unicode.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2005 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_UNICODE_H
+#define ANDROID_UNICODE_H
+
+#include <sys/types.h>
+#include <stdint.h>
+
+extern "C" {
+
+typedef uint32_t char32_t;
+typedef uint16_t char16_t;
+
+// Standard string functions on char16_t strings.
+int strcmp16(const char16_t *, const char16_t *);
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
+size_t strlen16(const char16_t *);
+size_t strnlen16(const char16_t *, size_t);
+char16_t *strcpy16(char16_t *, const char16_t *);
+char16_t *strncpy16(char16_t *, const char16_t *, size_t);
+
+// Version of comparison that supports embedded nulls.
+// This is different than strncmp() because we don't stop
+// at a nul character and consider the strings to be different
+// if the lengths are different (thus we need to supply the
+// lengths of both strings).  This can also be used when
+// your string is not nul-terminated as it will have the
+// equivalent result as strcmp16 (unlike strncmp16).
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
+
+// Version of strzcmp16 for comparing strings in different endianness.
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
+
+// Standard string functions on char32_t strings.
+size_t strlen32(const char32_t *);
+size_t strnlen32(const char32_t *, size_t);
+
+/**
+ * Measure the length of a UTF-32 string in UTF-8. If the string is invalid
+ * such as containing a surrogate character, -1 will be returned.
+ */
+ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len);
+
+/**
+ * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not
+ * large enough to store the string, the part of the "src" string is stored
+ * into "dst" as much as possible. See the examples for more detail.
+ * Returns the size actually used for storing the string.
+ * dst" is not null-terminated when dst_len is fully used (like strncpy).
+ *
+ * Example 1
+ * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
+ * "src_len" == 2
+ * "dst_len" >= 7
+ * ->
+ * Returned value == 6
+ * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0
+ * (note that "dst" is null-terminated)
+ *
+ * Example 2
+ * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
+ * "src_len" == 2
+ * "dst_len" == 5
+ * ->
+ * Returned value == 3
+ * "dst" becomes \xE3\x81\x82\0
+ * (note that "dst" is null-terminated, but \u3044 is not stored in "dst"
+ * since "dst" does not have enough size to store the character)
+ *
+ * Example 3
+ * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84)
+ * "src_len" == 2
+ * "dst_len" == 6
+ * ->
+ * Returned value == 6
+ * "dst" becomes \xE3\x81\x82\xE3\x81\x84
+ * (note that "dst" is NOT null-terminated, like strncpy)
+ */
+void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst);
+
+/**
+ * Returns the unicode value at "index".
+ * Returns -1 when the index is invalid (equals to or more than "src_len").
+ * If returned value is positive, it is able to be converted to char32_t, which
+ * is unsigned. Then, if "next_index" is not NULL, the next index to be used is
+ * stored in "next_index". "next_index" can be NULL.
+ */
+int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index);
+
+
+/**
+ * Returns the UTF-8 length of UTF-16 string "src".
+ */
+ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len);
+
+/**
+ * Converts a UTF-16 string to UTF-8. The destination buffer must be large
+ * enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added
+ * NULL terminator.
+ */
+void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst);
+
+/**
+ * Returns the length of "src" when "src" is valid UTF-8 string.
+ * Returns 0 if src is NULL or 0-length string. Returns -1 when the source
+ * is an invalid string.
+ *
+ * This function should be used to determine whether "src" is valid UTF-8
+ * characters with valid unicode codepoints. "src" must be null-terminated.
+ *
+ * If you are going to use other utf8_to_... functions defined in this header
+ * with string which may not be valid UTF-8 with valid codepoint (form 0 to
+ * 0x10FFFF), you should use this function before calling others, since the
+ * other functions do not check whether the string is valid UTF-8 or not.
+ *
+ * If you do not care whether "src" is valid UTF-8 or not, you should use
+ * strlen() as usual, which should be much faster.
+ */
+ssize_t utf8_length(const char *src);
+
+/**
+ * Measure the length of a UTF-32 string.
+ */
+size_t utf8_to_utf32_length(const char *src, size_t src_len);
+
+/**
+ * Stores a UTF-32 string converted from "src" in "dst". "dst" must be large
+ * enough to store the entire converted string as measured by
+ * utf8_to_utf32_length plus space for a NULL terminator.
+ */
+void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst);
+
+/**
+ * Returns the UTF-16 length of UTF-8 string "src".
+ */
+ssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen);
+
+/**
+ * Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer
+ * must be large enough to hold the result as measured by utf8_to_utf16_length
+ * plus an added NULL terminator.
+ */
+void utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst);
+
+}
+
+#endif
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index ec851bd..6fd307f 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -162,6 +162,9 @@
      inline status_t        sort(compar_t cmp);
      inline status_t        sort(compar_r_t cmp, void* state);
 
+     // for debugging only
+     inline size_t getItemSize() const { return itemSize(); }
+
 protected:
     virtual void    do_construct(void* storage, size_t num) const;
     virtual void    do_destroy(void* storage, size_t num) const;
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
index e38bf66..3e42a95 100644
--- a/include/utils/ZipFileCRO.h
+++ b/include/utils/ZipFileCRO.h
@@ -24,6 +24,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <utils/Compat.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -48,7 +50,7 @@
 
 extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
         int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32);
 
 extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
 
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
index 3c1f3ca..3a99979 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -30,6 +30,7 @@
 #ifndef __LIBS_ZIPFILERO_H
 #define __LIBS_ZIPFILERO_H
 
+#include <utils/Compat.h>
 #include <utils/Errors.h>
 #include <utils/FileMap.h>
 #include <utils/threads.h>
@@ -128,7 +129,7 @@
      * appears to be bad.
      */
     bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
+        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
 
     /*
      * Create a new FileMap object that maps a subset of the archive.  For
@@ -231,7 +232,7 @@
     int         mNumEntries;
 
     /* CD directory offset in the Zip archive */
-    off_t       mDirectoryOffset;
+    off64_t     mDirectoryOffset;
 
     /*
      * We know how many entries are in the Zip archive, so we have a
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 1bcfaed..41e5766 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -527,9 +527,10 @@
     static  int             _threadLoop(void* user);
     const   bool            mCanCallJava;
             thread_id_t     mThread;
-            Mutex           mLock;
+    mutable Mutex           mLock;
             Condition       mThreadExitedCondition;
             status_t        mStatus;
+    // note that all accesses of mExitPending and mRunning need to hold mLock
     volatile bool           mExitPending;
     volatile bool           mRunning;
             sp<Thread>      mHoldSelf;
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index 13dc500..f9d9f25 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -16,6 +16,7 @@
 sources := \
     Binder.cpp \
     BpBinder.cpp \
+    CursorWindow.cpp \
     IInterface.cpp \
     IMemory.cpp \
     IPCThreadState.cpp \
diff --git a/libs/binder/CursorWindow.cpp b/libs/binder/CursorWindow.cpp
new file mode 100644
index 0000000..47bbd04
--- /dev/null
+++ b/libs/binder/CursorWindow.cpp
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2006-2007 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "CursorWindow"
+
+#include <utils/Log.h>
+#include <binder/CursorWindow.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/MemoryBase.h>
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+namespace android {
+
+CursorWindow::CursorWindow(size_t maxSize) :
+    mMaxSize(maxSize)
+{
+}
+
+bool CursorWindow::setMemory(const sp<IMemory>& memory)
+{
+    mMemory = memory;
+    mData = (uint8_t *) memory->pointer();
+    if (mData == NULL) {
+        return false;
+    }
+    mHeader = (window_header_t *) mData;
+
+    // Make the window read-only
+    ssize_t size = memory->size();
+    mSize = size;
+    mMaxSize = size;
+    mFreeOffset = size;
+LOG_WINDOW("Created CursorWindow from existing IMemory: mFreeOffset = %d, numRows = %d, numColumns = %d, mSize = %d, mMaxSize = %d, mData = %p", mFreeOffset, mHeader->numRows, mHeader->numColumns, mSize, mMaxSize, mData);
+    return true;
+}
+
+bool CursorWindow::initBuffer(bool localOnly)
+{
+    //TODO Use a non-memory dealer mmap region for localOnly
+
+    sp<MemoryHeapBase> heap;
+    heap = new MemoryHeapBase(mMaxSize, 0, "CursorWindow");
+    if (heap != NULL) {
+        mMemory = new MemoryBase(heap, 0, mMaxSize);
+        if (mMemory != NULL) {
+            mData = (uint8_t *) mMemory->pointer();
+            if (mData) {
+                mHeader = (window_header_t *) mData;
+                mSize = mMaxSize;
+
+                // Put the window into a clean state
+                clear();
+            LOG_WINDOW("Created CursorWindow with new MemoryDealer: mFreeOffset = %d, mSize = %d, mMaxSize = %d, mData = %p", mFreeOffset, mSize, mMaxSize, mData);
+                return true;                
+            }
+        } 
+        LOGE("CursorWindow heap allocation failed");
+        return false;
+    } else {
+        LOGE("failed to create the CursorWindow heap");
+        return false;
+    }
+}
+
+CursorWindow::~CursorWindow()
+{
+    // Everything that matters is a smart pointer
+}
+
+void CursorWindow::clear()
+{
+    mHeader->numRows = 0;
+    mHeader->numColumns = 0;
+    mFreeOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE;
+    // Mark the first chunk's next 'pointer' as null
+    *((uint32_t *)(mData + mFreeOffset - sizeof(uint32_t))) = 0;
+}
+
+int32_t CursorWindow::freeSpace()
+{
+    int32_t freeSpace = mSize - mFreeOffset;
+    if (freeSpace < 0) {
+        freeSpace = 0;
+    }
+    return freeSpace;
+}
+
+field_slot_t * CursorWindow::allocRow()
+{
+    // Fill in the row slot
+    row_slot_t * rowSlot = allocRowSlot();
+    if (rowSlot == NULL) {
+        return NULL;
+    }
+
+    // Allocate the slots for the field directory
+    size_t fieldDirSize = mHeader->numColumns * sizeof(field_slot_t);
+    uint32_t fieldDirOffset = alloc(fieldDirSize);
+    if (!fieldDirOffset) {
+        mHeader->numRows--;
+        LOG_WINDOW("The row failed, so back out the new row accounting from allocRowSlot %d", mHeader->numRows);
+        return NULL;
+    }
+    field_slot_t * fieldDir = (field_slot_t *)offsetToPtr(fieldDirOffset);
+    memset(fieldDir, 0x0, fieldDirSize);
+
+LOG_WINDOW("Allocated row %u, rowSlot is at offset %u, fieldDir is %d bytes at offset %u\n", (mHeader->numRows - 1), ((uint8_t *)rowSlot) - mData, fieldDirSize, fieldDirOffset);
+    rowSlot->offset = fieldDirOffset;
+
+    return fieldDir;
+}
+
+uint32_t CursorWindow::alloc(size_t requestedSize, bool aligned)
+{
+    int32_t size;
+    uint32_t padding;
+    if (aligned) {
+        // 4 byte alignment
+        padding = 4 - (mFreeOffset & 0x3);
+    } else {
+        padding = 0;
+    }
+
+    size = requestedSize + padding;
+
+    if (size > freeSpace()) {
+        LOGV("need to grow: mSize = %d, size = %d, freeSpace() = %d, numRows = %d", mSize, size,
+                freeSpace(), mHeader->numRows);
+        // Only grow the window if the first row doesn't fit
+        if (mHeader->numRows > 1) {
+            LOGV("not growing since there are already %d row(s), max size %d", mHeader->numRows,
+                    mMaxSize);
+            return 0;
+        }
+
+        // Find a new size that will fit the allocation
+        int allocated = mSize - freeSpace();
+        int newSize = mSize + WINDOW_ALLOCATION_SIZE;
+        while (size > (newSize - allocated)) {
+            newSize += WINDOW_ALLOCATION_SIZE;
+            if (newSize > mMaxSize) {
+                LOGE("Attempting to grow window beyond max size (%d)", mMaxSize);
+                return 0;
+            }
+        }
+LOG_WINDOW("found size %d", newSize);
+        mSize = newSize;
+    }
+
+    uint32_t offset = mFreeOffset + padding;
+    mFreeOffset += size;
+    return offset;
+}
+
+row_slot_t * CursorWindow::getRowSlot(int row)
+{
+    LOG_WINDOW("enter getRowSlot current row num %d, this row %d", mHeader->numRows, row);
+    int chunkNum = row / ROW_SLOT_CHUNK_NUM_ROWS;
+    int chunkPos = row % ROW_SLOT_CHUNK_NUM_ROWS;
+    int chunkPtrOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t);
+    uint8_t * rowChunk = mData + sizeof(window_header_t);
+    for (int i = 0; i < chunkNum; i++) {
+        rowChunk = offsetToPtr(*((uint32_t *)(mData + chunkPtrOffset)));
+        chunkPtrOffset = rowChunk - mData + (ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t));
+    }
+    return (row_slot_t *)(rowChunk + (chunkPos * sizeof(row_slot_t)));
+    LOG_WINDOW("exit getRowSlot current row num %d, this row %d", mHeader->numRows, row);    
+}
+
+row_slot_t * CursorWindow::allocRowSlot()
+{
+    int chunkNum = mHeader->numRows / ROW_SLOT_CHUNK_NUM_ROWS;
+    int chunkPos = mHeader->numRows % ROW_SLOT_CHUNK_NUM_ROWS;
+    int chunkPtrOffset = sizeof(window_header_t) + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t);
+    uint8_t * rowChunk = mData + sizeof(window_header_t);
+LOG_WINDOW("Allocating row slot, mHeader->numRows is %d, chunkNum is %d, chunkPos is %d", mHeader->numRows, chunkNum, chunkPos);
+    for (int i = 0; i < chunkNum; i++) {
+        uint32_t nextChunkOffset = *((uint32_t *)(mData + chunkPtrOffset));
+LOG_WINDOW("nextChunkOffset is %d", nextChunkOffset);
+        if (nextChunkOffset == 0) {
+            // Allocate a new row chunk
+            nextChunkOffset = alloc(ROW_SLOT_CHUNK_SIZE, true);
+            if (nextChunkOffset == 0) {
+                return NULL;
+            }
+            rowChunk = offsetToPtr(nextChunkOffset);
+LOG_WINDOW("allocated new chunk at %d, rowChunk = %p", nextChunkOffset, rowChunk);
+            *((uint32_t *)(mData + chunkPtrOffset)) = rowChunk - mData;
+            // Mark the new chunk's next 'pointer' as null
+            *((uint32_t *)(rowChunk + ROW_SLOT_CHUNK_SIZE - sizeof(uint32_t))) = 0;
+        } else {
+LOG_WINDOW("follwing 'pointer' to next chunk, offset of next pointer is %d", chunkPtrOffset);
+            rowChunk = offsetToPtr(nextChunkOffset);
+            chunkPtrOffset = rowChunk - mData + (ROW_SLOT_CHUNK_NUM_ROWS * sizeof(row_slot_t));
+        }
+    }
+    mHeader->numRows++;
+
+    return (row_slot_t *)(rowChunk + (chunkPos * sizeof(row_slot_t)));
+}
+
+field_slot_t * CursorWindow::getFieldSlotWithCheck(int row, int column)
+{
+  if (row < 0 || row >= mHeader->numRows || column < 0 || column >= mHeader->numColumns) {
+      LOGE("Failed to read row# %d, column# from a CursorWindow which has %d rows, %d columns.",
+              row, column, mHeader->numRows, mHeader->numColumns);
+      return NULL;
+  }        
+  row_slot_t * rowSlot = getRowSlot(row);
+  if (!rowSlot) {
+      LOGE("Failed to find rowSlot for row %d", row);
+      return NULL;
+  }
+  if (rowSlot->offset == 0 || rowSlot->offset >= mSize) {
+      LOGE("Invalid rowSlot, offset = %d", rowSlot->offset);
+      return NULL;
+  }  
+  int fieldDirOffset = rowSlot->offset;
+  return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;  
+}
+
+uint32_t CursorWindow::read_field_slot(int row, int column, field_slot_t * slotOut)
+{
+    if (row < 0 || row >= mHeader->numRows || column < 0 || column >= mHeader->numColumns) {
+        LOGE("Can't read row# %d, col# %d from CursorWindow. Make sure your Cursor is initialized correctly.",
+                row, column);
+        return -1;
+    }        
+    row_slot_t * rowSlot = getRowSlot(row);
+    if (!rowSlot) {
+        LOGE("Failed to find rowSlot for row %d", row);
+        return -1;
+    }
+    if (rowSlot->offset == 0 || rowSlot->offset >= mSize) {
+        LOGE("Invalid rowSlot, offset = %d", rowSlot->offset);
+        return -1;
+    }
+LOG_WINDOW("Found field directory for %d,%d at rowSlot %d, offset %d", row, column, (uint8_t *)rowSlot - mData, rowSlot->offset);
+    field_slot_t * fieldDir = (field_slot_t *)offsetToPtr(rowSlot->offset);
+LOG_WINDOW("Read field_slot_t %d,%d: offset = %d, size = %d, type = %d", row, column, fieldDir[column].data.buffer.offset, fieldDir[column].data.buffer.size, fieldDir[column].type);
+
+    // Copy the data to the out param
+    slotOut->data.buffer.offset = fieldDir[column].data.buffer.offset;
+    slotOut->data.buffer.size = fieldDir[column].data.buffer.size;
+    slotOut->type = fieldDir[column].type;
+    return 0;
+}
+
+void CursorWindow::copyIn(uint32_t offset, uint8_t const * data, size_t size)
+{
+    assert(offset + size <= mSize);    
+    memcpy(mData + offset, data, size);
+}
+
+void CursorWindow::copyIn(uint32_t offset, int64_t data)
+{
+    assert(offset + sizeof(int64_t) <= mSize);
+    memcpy(mData + offset, (uint8_t *)&data, sizeof(int64_t));
+}
+
+void CursorWindow::copyIn(uint32_t offset, double data)
+{
+    assert(offset + sizeof(double) <= mSize);
+    memcpy(mData + offset, (uint8_t *)&data, sizeof(double));
+}
+
+void CursorWindow::copyOut(uint32_t offset, uint8_t * data, size_t size)
+{
+    assert(offset + size <= mSize);
+    memcpy(data, mData + offset, size);
+}
+
+int64_t CursorWindow::copyOutLong(uint32_t offset)
+{
+    int64_t value;
+    assert(offset + sizeof(int64_t) <= mSize);
+    memcpy(&value, mData + offset, sizeof(int64_t));
+    return value;
+}
+
+double CursorWindow::copyOutDouble(uint32_t offset)
+{
+    double value;
+    assert(offset + sizeof(double) <= mSize);
+    memcpy(&value, mData + offset, sizeof(double));
+    return value;
+}
+
+bool CursorWindow::putLong(unsigned int row, unsigned int col, int64_t value)
+{
+    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+    if (!fieldSlot) {
+        return false;
+    }
+
+#if WINDOW_STORAGE_INLINE_NUMERICS
+    fieldSlot->data.l = value;
+#else
+    int offset = alloc(sizeof(int64_t));
+    if (!offset) {
+        return false;
+    }
+
+    copyIn(offset, value);
+
+    fieldSlot->data.buffer.offset = offset;
+    fieldSlot->data.buffer.size = sizeof(int64_t);
+#endif
+    fieldSlot->type = FIELD_TYPE_INTEGER;
+    return true;
+}
+
+bool CursorWindow::putDouble(unsigned int row, unsigned int col, double value)
+{
+    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+    if (!fieldSlot) {
+        return false;
+    }
+
+#if WINDOW_STORAGE_INLINE_NUMERICS
+    fieldSlot->data.d = value;
+#else
+    int offset = alloc(sizeof(int64_t));
+    if (!offset) {
+        return false;
+    }
+
+    copyIn(offset, value);
+
+    fieldSlot->data.buffer.offset = offset;
+    fieldSlot->data.buffer.size = sizeof(double);
+#endif
+    fieldSlot->type = FIELD_TYPE_FLOAT;
+    return true;
+}
+
+bool CursorWindow::putNull(unsigned int row, unsigned int col)
+{
+    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+    if (!fieldSlot) {
+        return false;
+    }
+
+    fieldSlot->type = FIELD_TYPE_NULL;
+    fieldSlot->data.buffer.offset = 0;
+    fieldSlot->data.buffer.size = 0;
+    return true;
+}
+
+bool CursorWindow::getLong(unsigned int row, unsigned int col, int64_t * valueOut)
+{
+    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+    if (!fieldSlot || fieldSlot->type != FIELD_TYPE_INTEGER) {
+        return false;
+    }
+    
+#if WINDOW_STORAGE_INLINE_NUMERICS
+    *valueOut = fieldSlot->data.l;
+#else
+    *valueOut = copyOutLong(fieldSlot->data.buffer.offset);
+#endif
+    return true;
+}
+
+bool CursorWindow::getDouble(unsigned int row, unsigned int col, double * valueOut)
+{
+    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+    if (!fieldSlot || fieldSlot->type != FIELD_TYPE_FLOAT) {
+        return false;
+    }
+
+#if WINDOW_STORAGE_INLINE_NUMERICS
+    *valueOut = fieldSlot->data.d;
+#else
+    *valueOut = copyOutDouble(fieldSlot->data.buffer.offset);
+#endif
+    return true;
+}
+
+bool CursorWindow::getNull(unsigned int row, unsigned int col, bool * valueOut)
+{
+    field_slot_t * fieldSlot = getFieldSlotWithCheck(row, col);
+    if (!fieldSlot) {
+        return false;
+    }
+    
+    if (fieldSlot->type != FIELD_TYPE_NULL) {
+        *valueOut = false;
+    } else {
+        *valueOut = true;
+    }
+    return true;
+}
+
+}; // namespace android
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 13c58f0..95cfddf 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -318,6 +318,16 @@
     goto restart;
 }
 
+IPCThreadState* IPCThreadState::selfOrNull()
+{
+    if (gHaveTLS) {
+        const pthread_key_t k = gTLS;
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
+        return st;
+    }
+    return NULL;
+}
+
 void IPCThreadState::shutdown()
 {
     gShutdown = true;
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 624f7eb..9f501e2 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -31,7 +31,7 @@
 
 #include <binder/MemoryHeapBase.h>
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
 #include <linux/android_pmem.h>
 #endif
 
@@ -108,7 +108,7 @@
 {
     if (size == 0) {
         // try to figure out the size automatically
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
         // first try the PMEM ioctl
         pmem_region reg;
         int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, &reg);
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
index 16e92f9..03322ea 100644
--- a/libs/binder/MemoryHeapPmem.cpp
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -30,7 +30,7 @@
 #include <binder/MemoryHeapPmem.h>
 #include <binder/MemoryHeapBase.h>
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
 #include <linux/android_pmem.h>
 #endif
 
@@ -72,7 +72,7 @@
     memset(start_ptr, 0xda, size);
 #endif
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     if (size > 0) {
         const size_t pagesize = getpagesize();
         size = (size + pagesize-1) & ~(pagesize-1);
@@ -107,7 +107,7 @@
     // which means MemoryHeapPmem::revoke() wouldn't have been able to 
     // promote() it.
     
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     if (mSize != 0) {
         const sp<MemoryHeapPmem>& heap(getHeap());
         int our_fd = heap->heapID();
@@ -130,7 +130,7 @@
     : MemoryHeapBase()
 {
     char const * const device = pmemHeap->getDevice();
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     if (device) {
         int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
         LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
@@ -187,7 +187,7 @@
 
 status_t MemoryHeapPmem::slap()
 {
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     size_t size = getSize();
     const size_t pagesize = getpagesize();
     size = (size + pagesize-1) & ~(pagesize-1);
@@ -205,7 +205,7 @@
 
 status_t MemoryHeapPmem::unslap()
 {
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     size_t size = getSize();
     const size_t pagesize = getpagesize();
     size = (size + pagesize-1) & ~(pagesize-1);
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 249558a..d1a6af1 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -4,17 +4,25 @@
 LOCAL_SRC_FILES:= \
 	ISensorEventConnection.cpp \
 	ISensorServer.cpp \
+	ISurfaceTexture.cpp \
 	Sensor.cpp \
 	SensorChannel.cpp \
 	SensorEventQueue.cpp \
-	SensorManager.cpp
+	SensorManager.cpp \
+	SurfaceTexture.cpp \
+	SurfaceTextureClient.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libutils \
 	libbinder \
 	libhardware \
-	libhardware_legacy
+	libhardware_legacy \
+	libui \
+	libEGL \
+	libGLESv2 \
+	libsurfaceflinger_client
+
 
 LOCAL_MODULE:= libgui
 
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
new file mode 100644
index 0000000..d661fd5
--- /dev/null
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <gui/ISurfaceTexture.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
+    SET_BUFFER_COUNT,
+    DEQUEUE_BUFFER,
+    QUEUE_BUFFER,
+    CANCEL_BUFFER,
+    SET_CROP,
+    SET_TRANSFORM,
+    GET_ALLOCATOR,
+};
+
+
+class BpSurfaceTexture : public BpInterface<ISurfaceTexture>
+{
+public:
+    BpSurfaceTexture(const sp<IBinder>& impl)
+        : BpInterface<ISurfaceTexture>(impl)
+    {
+    }
+
+    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        data.writeInt32(bufferIdx);
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
+        data.writeInt32(usage);
+        remote()->transact(REQUEST_BUFFER, data, &reply);
+        sp<GraphicBuffer> buffer;
+        bool nonNull = reply.readInt32();
+        if (nonNull) {
+            buffer = new GraphicBuffer();
+            reply.read(*buffer);
+        }
+        return buffer;
+    }
+
+    virtual status_t setBufferCount(int bufferCount)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        data.writeInt32(bufferCount);
+        remote()->transact(SET_BUFFER_COUNT, data, &reply);
+        status_t err = reply.readInt32();
+        return err;
+    }
+
+    virtual status_t dequeueBuffer(int *buf) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        remote()->transact(DEQUEUE_BUFFER, data, &reply);
+        *buf = reply.readInt32();
+        int result = reply.readInt32();
+        return result;
+    }
+
+    virtual status_t queueBuffer(int buf) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        data.writeInt32(buf);
+        remote()->transact(QUEUE_BUFFER, data, &reply);
+        status_t result = reply.readInt32();
+        return result;
+    }
+
+    virtual void cancelBuffer(int buf) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        data.writeInt32(buf);
+        remote()->transact(CANCEL_BUFFER, data, &reply);
+    }
+
+    virtual status_t setCrop(const Rect& reg) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        data.writeFloat(reg.left);
+        data.writeFloat(reg.top);
+        data.writeFloat(reg.right);
+        data.writeFloat(reg.bottom);
+        remote()->transact(SET_CROP, data, &reply);
+        status_t result = reply.readInt32();
+        return result;
+    }
+
+    virtual status_t setTransform(uint32_t transform) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        data.writeInt32(transform);
+        remote()->transact(SET_TRANSFORM, data, &reply);
+        status_t result = reply.readInt32();
+        return result;
+    }
+
+    virtual sp<IBinder> getAllocator() {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+        remote()->transact(GET_ALLOCATOR, data, &reply);
+        return reply.readStrongBinder();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture");
+
+// ----------------------------------------------------------------------
+
+status_t BnSurfaceTexture::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case REQUEST_BUFFER: {
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            int bufferIdx   = data.readInt32();
+            uint32_t w      = data.readInt32();
+            uint32_t h      = data.readInt32();
+            uint32_t format = data.readInt32();
+            uint32_t usage  = data.readInt32();
+            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, w, h, format,
+                    usage));
+            reply->writeInt32(buffer != 0);
+            if (buffer != 0) {
+                reply->write(*buffer);
+            }
+            return NO_ERROR;
+        } break;
+        case SET_BUFFER_COUNT: {
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            int bufferCount = data.readInt32();
+            int result = setBufferCount(bufferCount);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+        case DEQUEUE_BUFFER: {
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            int buf;
+            int result = dequeueBuffer(&buf);
+            reply->writeInt32(buf);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+        case QUEUE_BUFFER: {
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            int buf = data.readInt32();
+            status_t result = queueBuffer(buf);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+        case CANCEL_BUFFER: {
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            int buf = data.readInt32();
+            cancelBuffer(buf);
+            return NO_ERROR;
+        } break;
+        case SET_CROP: {
+            Rect reg;
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            reg.left = data.readFloat();
+            reg.top = data.readFloat();
+            reg.right = data.readFloat();
+            reg.bottom = data.readFloat();
+            status_t result = setCrop(reg);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+        case SET_TRANSFORM: {
+            Rect reg;
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            uint32_t transform = data.readInt32();
+            status_t result = setTransform(transform);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+        case GET_ALLOCATOR: {
+            CHECK_INTERFACE(ISurfaceTexture, data, reply);
+            sp<IBinder> result = getAllocator();
+            reply->writeStrongBinder(result);
+            return NO_ERROR;
+        } break;
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
new file mode 100644
index 0000000..5c6d71b
--- /dev/null
+++ b/libs/gui/SurfaceTexture.cpp
@@ -0,0 +1,423 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceTexture"
+//#define LOG_NDEBUG 0
+
+#define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <gui/SurfaceTexture.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
+
+#include <utils/Log.h>
+
+namespace android {
+
+// Transform matrices
+static float mtxIdentity[16] = {
+    1, 0, 0, 0,
+    0, 1, 0, 0,
+    0, 0, 1, 0,
+    0, 0, 0, 1,
+};
+static float mtxFlipH[16] = {
+    -1, 0, 0, 0,
+    0, 1, 0, 0,
+    0, 0, 1, 0,
+    1, 0, 0, 1,
+};
+static float mtxFlipV[16] = {
+    1, 0, 0, 0,
+    0, -1, 0, 0,
+    0, 0, 1, 0,
+    0, 1, 0, 1,
+};
+static float mtxRot90[16] = {
+    0, 1, 0, 0,
+    -1, 0, 0, 0,
+    0, 0, 1, 0,
+    1, 0, 0, 1,
+};
+static float mtxRot180[16] = {
+    -1, 0, 0, 0,
+    0, -1, 0, 0,
+    0, 0, 1, 0,
+    1, 1, 0, 1,
+};
+static float mtxRot270[16] = {
+    0, -1, 0, 0,
+    1, 0, 0, 0,
+    0, 0, 1, 0,
+    0, 1, 0, 1,
+};
+
+static void mtxMul(float out[16], const float a[16], const float b[16]);
+
+SurfaceTexture::SurfaceTexture(GLuint tex) :
+    mBufferCount(MIN_BUFFER_SLOTS), mCurrentTexture(INVALID_BUFFER_SLOT),
+    mCurrentTransform(0), mLastQueued(INVALID_BUFFER_SLOT),
+    mLastQueuedTransform(0), mNextTransform(0), mTexName(tex) {
+    LOGV("SurfaceTexture::SurfaceTexture");
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
+        mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+        mSlots[i].mOwnedByClient = false;
+    }
+    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
+}
+
+SurfaceTexture::~SurfaceTexture() {
+    LOGV("SurfaceTexture::~SurfaceTexture");
+    freeAllBuffers();
+}
+
+status_t SurfaceTexture::setBufferCount(int bufferCount) {
+    LOGV("SurfaceTexture::setBufferCount");
+
+    if (bufferCount < MIN_BUFFER_SLOTS) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mMutex);
+    freeAllBuffers();
+    mBufferCount = bufferCount;
+    mCurrentTexture = INVALID_BUFFER_SLOT;
+    mLastQueued = INVALID_BUFFER_SLOT;
+    return OK;
+}
+
+sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf,
+        uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+    LOGV("SurfaceTexture::requestBuffer");
+    Mutex::Autolock lock(mMutex);
+    if (buf < 0 || mBufferCount <= buf) {
+        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
+                mBufferCount, buf);
+        return 0;
+    }
+    usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+    sp<GraphicBuffer> graphicBuffer(
+            mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage));
+    if (graphicBuffer == 0) {
+        LOGE("requestBuffer: SurfaceComposer::createGraphicBuffer failed");
+    } else {
+        mSlots[buf].mGraphicBuffer = graphicBuffer;
+        if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mSlots[buf].mEglDisplay, mSlots[buf].mEglImage);
+            mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
+            mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+        }
+        mAllocdBuffers.add(graphicBuffer);
+    }
+    return graphicBuffer;
+}
+
+status_t SurfaceTexture::dequeueBuffer(int *buf) {
+    LOGV("SurfaceTexture::dequeueBuffer");
+    Mutex::Autolock lock(mMutex);
+    int found = INVALID_BUFFER_SLOT;
+    for (int i = 0; i < mBufferCount; i++) {
+        if (!mSlots[i].mOwnedByClient && i != mCurrentTexture && i != mLastQueued) {
+            mSlots[i].mOwnedByClient = true;
+            found = i;
+            break;
+        }
+    }
+    if (found == INVALID_BUFFER_SLOT) {
+        return -EBUSY;
+    }
+    *buf = found;
+    return OK;
+}
+
+status_t SurfaceTexture::queueBuffer(int buf) {
+    LOGV("SurfaceTexture::queueBuffer");
+    Mutex::Autolock lock(mMutex);
+    if (buf < 0 || mBufferCount <= buf) {
+        LOGE("queueBuffer: slot index out of range [0, %d]: %d",
+                mBufferCount, buf);
+        return -EINVAL;
+    } else if (!mSlots[buf].mOwnedByClient) {
+        LOGE("queueBuffer: slot %d is not owned by the client", buf);
+        return -EINVAL;
+    } else if (mSlots[buf].mGraphicBuffer == 0) {
+        LOGE("queueBuffer: slot %d was enqueued without requesting a buffer",
+                buf);
+        return -EINVAL;
+    }
+    mSlots[buf].mOwnedByClient = false;
+    mLastQueued = buf;
+    mLastQueuedCrop = mNextCrop;
+    mLastQueuedTransform = mNextTransform;
+    if (mFrameAvailableListener != 0) {
+        mFrameAvailableListener->onFrameAvailable();
+    }
+    return OK;
+}
+
+void SurfaceTexture::cancelBuffer(int buf) {
+    LOGV("SurfaceTexture::cancelBuffer");
+    Mutex::Autolock lock(mMutex);
+    if (buf < 0 || mBufferCount <= buf) {
+        LOGE("cancelBuffer: slot index out of range [0, %d]: %d", mBufferCount,
+                buf);
+        return;
+    } else if (!mSlots[buf].mOwnedByClient) {
+        LOGE("cancelBuffer: slot %d is not owned by the client", buf);
+        return;
+    }
+    mSlots[buf].mOwnedByClient = false;
+}
+
+status_t SurfaceTexture::setCrop(const Rect& crop) {
+    LOGV("SurfaceTexture::setCrop");
+    Mutex::Autolock lock(mMutex);
+    mNextCrop = crop;
+    return OK;
+}
+
+status_t SurfaceTexture::setTransform(uint32_t transform) {
+    LOGV("SurfaceTexture::setTransform");
+    Mutex::Autolock lock(mMutex);
+    mNextTransform = transform;
+    return OK;
+}
+
+status_t SurfaceTexture::updateTexImage() {
+    LOGV("SurfaceTexture::updateTexImage");
+    Mutex::Autolock lock(mMutex);
+
+    // We always bind the texture even if we don't update its contents.
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
+
+    // Initially both mCurrentTexture and mLastQueued are INVALID_BUFFER_SLOT,
+    // so this check will fail until a buffer gets queued.
+    if (mCurrentTexture != mLastQueued) {
+        // Update the GL texture object.
+        EGLImageKHR image = mSlots[mLastQueued].mEglImage;
+        if (image == EGL_NO_IMAGE_KHR) {
+            EGLDisplay dpy = eglGetCurrentDisplay();
+            sp<GraphicBuffer> graphicBuffer = mSlots[mLastQueued].mGraphicBuffer;
+            image = createImage(dpy, graphicBuffer);
+            mSlots[mLastQueued].mEglImage = image;
+            mSlots[mLastQueued].mEglDisplay = dpy;
+        }
+
+        GLint error;
+        while ((error = glGetError()) != GL_NO_ERROR) {
+            LOGE("GL error cleared before updating SurfaceTexture: %#04x", error);
+        }
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image);
+        bool failed = false;
+        while ((error = glGetError()) != GL_NO_ERROR) {
+            LOGE("error binding external texture image %p (slot %d): %#04x",
+                    image, mLastQueued, error);
+            failed = true;
+        }
+        if (failed) {
+            return -EINVAL;
+        }
+
+        // Update the SurfaceTexture state.
+        mCurrentTexture = mLastQueued;
+        mCurrentTextureBuf = mSlots[mCurrentTexture].mGraphicBuffer;
+        mCurrentCrop = mLastQueuedCrop;
+        mCurrentTransform = mLastQueuedTransform;
+    }
+    return OK;
+}
+
+void SurfaceTexture::getTransformMatrix(float mtx[16]) {
+    LOGV("SurfaceTexture::updateTexImage");
+    Mutex::Autolock lock(mMutex);
+
+    float xform[16];
+    for (int i = 0; i < 16; i++) {
+        xform[i] = mtxIdentity[i];
+    }
+    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
+        float result[16];
+        mtxMul(result, xform, mtxFlipH);
+        for (int i = 0; i < 16; i++) {
+            xform[i] = result[i];
+        }
+    }
+    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
+        float result[16];
+        mtxMul(result, xform, mtxFlipV);
+        for (int i = 0; i < 16; i++) {
+            xform[i] = result[i];
+        }
+    }
+    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+        float result[16];
+        mtxMul(result, xform, mtxRot90);
+        for (int i = 0; i < 16; i++) {
+            xform[i] = result[i];
+        }
+    }
+
+    sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
+    float tx, ty, sx, sy;
+    if (!mCurrentCrop.isEmpty()) {
+        // In order to prevent bilinear sampling at the of the crop rectangle we
+        // may need to shrink it by 2 texels in each direction.  Normally this
+        // would just need to take 1/2 a texel off each end, but because the
+        // chroma channels will likely be subsampled we need to chop off a whole
+        // texel.  This will cause artifacts if someone does nearest sampling
+        // with 1:1 pixel:texel ratio, but it's impossible to simultaneously
+        // accomodate the bilinear and nearest sampling uses.
+        //
+        // If nearest sampling turns out to be a desirable usage of these
+        // textures then we could add the ability to switch a SurfaceTexture to
+        // nearest-mode.  Preferably, however, the image producers (video
+        // decoder, camera, etc.) would simply not use a crop rectangle (or at
+        // least not tell the framework about it) so that the GPU can do the
+        // correct edge behavior.
+        int xshrink = 0, yshrink = 0;
+        if (mCurrentCrop.left > 0) {
+            tx = float(mCurrentCrop.left + 1) / float(buf->getWidth());
+            xshrink++;
+        } else {
+            tx = 0.0f;
+        }
+        if (mCurrentCrop.right < buf->getWidth()) {
+            xshrink++;
+        }
+        if (mCurrentCrop.bottom < buf->getHeight()) {
+            ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) /
+                    float(buf->getHeight());
+            yshrink++;
+        } else {
+            ty = 0.0f;
+        }
+        if (mCurrentCrop.top > 0) {
+            yshrink++;
+        }
+        sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth());
+        sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight());
+    } else {
+        tx = 0.0f;
+        ty = 0.0f;
+        sx = 1.0f;
+        sy = 1.0f;
+    }
+    float crop[16] = {
+        sx, 0, 0, 0,
+        0, sy, 0, 0,
+        0, 0, 1, 0,
+        tx, ty, 0, 1,
+    };
+
+    float mtxBeforeFlipV[16];
+    mtxMul(mtxBeforeFlipV, crop, xform);
+
+    // SurfaceFlinger expects the top of its window textures to be at a Y
+    // coordinate of 0, so SurfaceTexture must behave the same way.  We don't
+    // want to expose this to applications, however, so we must add an
+    // additional vertical flip to the transform after all the other transforms.
+    mtxMul(mtx, mtxFlipV, mtxBeforeFlipV);
+}
+
+void SurfaceTexture::setFrameAvailableListener(
+        const sp<FrameAvailableListener>& l) {
+    LOGV("SurfaceTexture::setFrameAvailableListener");
+    Mutex::Autolock lock(mMutex);
+    mFrameAvailableListener = l;
+}
+
+sp<IBinder> SurfaceTexture::getAllocator() {
+    LOGV("SurfaceTexture::getAllocator");
+    return mGraphicBufferAlloc->asBinder();
+}
+
+void SurfaceTexture::freeAllBuffers() {
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        mSlots[i].mGraphicBuffer = 0;
+        mSlots[i].mOwnedByClient = false;
+        if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
+            mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
+            mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+        }
+    }
+
+    int exceptBuf = -1;
+    for (size_t i = 0; i < mAllocdBuffers.size(); i++) {
+        if (mAllocdBuffers[i] == mCurrentTextureBuf) {
+            exceptBuf = i;
+            break;
+        }
+    }
+    mAllocdBuffers.clear();
+    if (exceptBuf >= 0) {
+        mAllocdBuffers.add(mCurrentTextureBuf);
+    }
+    mGraphicBufferAlloc->freeAllGraphicBuffersExcept(exceptBuf);
+}
+
+EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
+        const sp<GraphicBuffer>& graphicBuffer) {
+    EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
+    EGLint attrs[] = {
+        EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
+        EGL_NONE,
+    };
+    EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
+            EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
+    EGLint error = eglGetError();
+    if (error != EGL_SUCCESS) {
+        LOGE("error creating EGLImage: %#x", error);
+    } else if (image == EGL_NO_IMAGE_KHR) {
+        LOGE("no error reported, but no image was returned by "
+                "eglCreateImageKHR");
+    }
+    return image;
+}
+
+static void mtxMul(float out[16], const float a[16], const float b[16]) {
+    out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
+    out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
+    out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
+    out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];
+
+    out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
+    out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
+    out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
+    out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];
+
+    out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
+    out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
+    out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
+    out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];
+
+    out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
+    out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
+    out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
+    out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
+}
+
+}; // namespace android
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
new file mode 100644
index 0000000..7f1d9cb
--- /dev/null
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -0,0 +1,332 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceTextureClient"
+//#define LOG_NDEBUG 0
+
+#include <gui/SurfaceTextureClient.h>
+
+#include <utils/Log.h>
+
+namespace android {
+
+SurfaceTextureClient::SurfaceTextureClient(
+        const sp<ISurfaceTexture>& surfaceTexture):
+        mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(1),
+        mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0), mMutex() {
+    // Initialize the ANativeWindow function pointers.
+    ANativeWindow::setSwapInterval  = setSwapInterval;
+    ANativeWindow::dequeueBuffer    = dequeueBuffer;
+    ANativeWindow::cancelBuffer     = cancelBuffer;
+    ANativeWindow::lockBuffer       = lockBuffer;
+    ANativeWindow::queueBuffer      = queueBuffer;
+    ANativeWindow::query            = query;
+    ANativeWindow::perform          = perform;
+
+    // Get a reference to the allocator.
+    mAllocator = mSurfaceTexture->getAllocator();
+}
+
+sp<ISurfaceTexture> SurfaceTextureClient::getISurfaceTexture() const {
+    return mSurfaceTexture;
+}
+
+int SurfaceTextureClient::setSwapInterval(ANativeWindow* window, int interval) {
+    SurfaceTextureClient* c = getSelf(window);
+    return c->setSwapInterval(interval);
+}
+
+int SurfaceTextureClient::dequeueBuffer(ANativeWindow* window,
+        android_native_buffer_t** buffer) {
+    SurfaceTextureClient* c = getSelf(window);
+    return c->dequeueBuffer(buffer);
+}
+
+int SurfaceTextureClient::cancelBuffer(ANativeWindow* window,
+        android_native_buffer_t* buffer) {
+    SurfaceTextureClient* c = getSelf(window);
+    return c->cancelBuffer(buffer);
+}
+
+int SurfaceTextureClient::lockBuffer(ANativeWindow* window,
+        android_native_buffer_t* buffer) {
+    SurfaceTextureClient* c = getSelf(window);
+    return c->lockBuffer(buffer);
+}
+
+int SurfaceTextureClient::queueBuffer(ANativeWindow* window,
+        android_native_buffer_t* buffer) {
+    SurfaceTextureClient* c = getSelf(window);
+    return c->queueBuffer(buffer);
+}
+
+int SurfaceTextureClient::query(ANativeWindow* window, int what, int* value) {
+    SurfaceTextureClient* c = getSelf(window);
+    return c->query(what, value);
+}
+
+int SurfaceTextureClient::perform(ANativeWindow* window, int operation, ...) {
+    va_list args;
+    va_start(args, operation);
+    SurfaceTextureClient* c = getSelf(window);
+    return c->perform(operation, args);
+}
+
+int SurfaceTextureClient::setSwapInterval(int interval) {
+    return INVALID_OPERATION;
+}
+
+int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
+    LOGV("SurfaceTextureClient::dequeueBuffer");
+    Mutex::Autolock lock(mMutex);
+    int buf = -1;
+    status_t err = mSurfaceTexture->dequeueBuffer(&buf);
+    if (err < 0) {
+        LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer failed: %d", err);
+        return err;
+    }
+    sp<GraphicBuffer>& gbuf(mSlots[buf]);
+    if (gbuf == 0 || gbuf->getWidth() != mReqWidth ||
+        gbuf->getHeight() != mReqHeight ||
+        uint32_t(gbuf->getPixelFormat()) != mReqFormat ||
+        (gbuf->getUsage() & mReqUsage) != mReqUsage) {
+        gbuf = mSurfaceTexture->requestBuffer(buf, mReqWidth, mReqHeight,
+                mReqFormat, mReqUsage);
+        if (gbuf == 0) {
+            LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed");
+            return NO_MEMORY;
+        }
+    }
+    *buffer = gbuf.get();
+    return OK;
+}
+
+int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) {
+    LOGV("SurfaceTextureClient::cancelBuffer");
+    Mutex::Autolock lock(mMutex);
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        if (mSlots[i]->handle == buffer->handle) {
+            mSurfaceTexture->cancelBuffer(i);
+            return OK;
+        }
+    }
+    return BAD_VALUE;
+}
+
+int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
+    LOGV("SurfaceTextureClient::lockBuffer");
+    Mutex::Autolock lock(mMutex);
+    return OK;
+}
+
+int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
+    LOGV("SurfaceTextureClient::queueBuffer");
+    Mutex::Autolock lock(mMutex);
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        if (mSlots[i]->handle == buffer->handle) {
+            return mSurfaceTexture->queueBuffer(i);
+        }
+    }
+    LOGE("queueBuffer: unknown buffer queued");
+    return BAD_VALUE;
+}
+
+int SurfaceTextureClient::query(int what, int* value) {
+    LOGV("SurfaceTextureClient::query");
+    Mutex::Autolock lock(mMutex);
+    switch (what) {
+    case NATIVE_WINDOW_WIDTH:
+    case NATIVE_WINDOW_HEIGHT:
+        // XXX: How should SurfaceTexture behave if setBuffersGeometry didn't
+        // override the size?
+        *value = 0;
+        return NO_ERROR;
+    case NATIVE_WINDOW_FORMAT:
+        *value = DEFAULT_FORMAT;
+        return NO_ERROR;
+    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+        *value = MIN_UNDEQUEUED_BUFFERS;
+        return NO_ERROR;
+    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+        // SurfaceTextureClient currently never queues frames to SurfaceFlinger.
+        *value = 0;
+        return NO_ERROR;
+    case NATIVE_WINDOW_CONCRETE_TYPE:
+        *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
+        return NO_ERROR;
+    }
+    return BAD_VALUE;
+}
+
+int SurfaceTextureClient::perform(int operation, va_list args)
+{
+    int res = NO_ERROR;
+    switch (operation) {
+    case NATIVE_WINDOW_CONNECT:
+        res = dispatchConnect(args);
+        break;
+    case NATIVE_WINDOW_DISCONNECT:
+        res = dispatchDisconnect(args);
+        break;
+    case NATIVE_WINDOW_SET_USAGE:
+        res = dispatchSetUsage(args);
+        break;
+    case NATIVE_WINDOW_SET_CROP:
+        res = dispatchSetCrop(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFER_COUNT:
+        res = dispatchSetBufferCount(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
+        res = dispatchSetBuffersGeometry(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+        res = dispatchSetBuffersTransform(args);
+        break;
+    default:
+        res = NAME_NOT_FOUND;
+        break;
+    }
+    return res;
+}
+
+int SurfaceTextureClient::dispatchConnect(va_list args) {
+    int api = va_arg(args, int);
+    return connect(api);
+}
+
+int SurfaceTextureClient::dispatchDisconnect(va_list args) {
+    int api = va_arg(args, int);
+    return disconnect(api);
+}
+
+int SurfaceTextureClient::dispatchSetUsage(va_list args) {
+    int usage = va_arg(args, int);
+    return setUsage(usage);
+}
+
+int SurfaceTextureClient::dispatchSetCrop(va_list args) {
+    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
+    return setCrop(reinterpret_cast<Rect const*>(rect));
+}
+
+int SurfaceTextureClient::dispatchSetBufferCount(va_list args) {
+    size_t bufferCount = va_arg(args, size_t);
+    return setBufferCount(bufferCount);
+}
+
+int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) {
+    int w = va_arg(args, int);
+    int h = va_arg(args, int);
+    int f = va_arg(args, int);
+    return setBuffersGeometry(w, h, f);
+}
+
+int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) {
+    int transform = va_arg(args, int);
+    return setBuffersTransform(transform);
+}
+
+int SurfaceTextureClient::connect(int api) {
+    LOGV("SurfaceTextureClient::connect");
+    // XXX: Implement this!
+    return INVALID_OPERATION;
+}
+
+int SurfaceTextureClient::disconnect(int api) {
+    LOGV("SurfaceTextureClient::disconnect");
+    // XXX: Implement this!
+    return INVALID_OPERATION;
+}
+
+int SurfaceTextureClient::setUsage(uint32_t reqUsage)
+{
+    LOGV("SurfaceTextureClient::setUsage");
+    Mutex::Autolock lock(mMutex);
+    mReqUsage = reqUsage;
+    return OK;
+}
+
+int SurfaceTextureClient::setCrop(Rect const* rect)
+{
+    LOGV("SurfaceTextureClient::setCrop");
+    Mutex::Autolock lock(mMutex);
+
+    Rect realRect;
+    if (rect == NULL || rect->isEmpty()) {
+        realRect = Rect(0, 0);
+    } else {
+        realRect = *rect;
+    }
+
+    status_t err = mSurfaceTexture->setCrop(*rect);
+    LOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err));
+
+    return err;
+}
+
+int SurfaceTextureClient::setBufferCount(int bufferCount)
+{
+    LOGV("SurfaceTextureClient::setBufferCount");
+    Mutex::Autolock lock(mMutex);
+
+    status_t err = mSurfaceTexture->setBufferCount(bufferCount);
+    LOGE_IF(err, "ISurfaceTexture::setBufferCount(%d) returned %s",
+            bufferCount, strerror(-err));
+
+    if (err == NO_ERROR) {
+        freeAllBuffers();
+    }
+
+    return err;
+}
+
+int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format)
+{
+    LOGV("SurfaceTextureClient::setBuffersGeometry");
+    Mutex::Autolock lock(mMutex);
+
+    if (w<0 || h<0 || format<0)
+        return BAD_VALUE;
+
+    if ((w && !h) || (!w && h))
+        return BAD_VALUE;
+
+    mReqWidth = w;
+    mReqHeight = h;
+    mReqFormat = format;
+
+    status_t err = mSurfaceTexture->setCrop(Rect(0, 0));
+    LOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err));
+
+    return err;
+}
+
+int SurfaceTextureClient::setBuffersTransform(int transform)
+{
+    LOGV("SurfaceTextureClient::setBuffersTransform");
+    Mutex::Autolock lock(mMutex);
+    status_t err = mSurfaceTexture->setTransform(transform);
+    return err;
+}
+
+void SurfaceTextureClient::freeAllBuffers() {
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        mSlots[i] = 0;
+    }
+}
+
+}; // namespace android
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
new file mode 100644
index 0000000..7516299
--- /dev/null
+++ b/libs/gui/tests/Android.mk
@@ -0,0 +1,51 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_MODULE := SurfaceTexture_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+    SurfaceTextureClient_test.cpp \
+    SurfaceTexture_test.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+	libEGL \
+	libGLESv2 \
+	libandroid \
+	libbinder \
+	libcutils \
+	libgui \
+	libstlport \
+	libsurfaceflinger_client \
+	libui \
+	libutils \
+
+LOCAL_STATIC_LIBRARIES := \
+	libgtest \
+	libgtest_main \
+
+LOCAL_C_INCLUDES := \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport \
+
+include $(BUILD_EXECUTABLE)
+
+# Build the manual test programs.
+include $(call all-subdir-makefiles)
+
+endif
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
new file mode 100644
index 0000000..94b05bc
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 <EGL/egl.h>
+#include <gtest/gtest.h>
+#include <gui/SurfaceTextureClient.h>
+
+namespace android {
+
+class SurfaceTextureClientTest : public ::testing::Test {
+protected:
+    virtual void SetUp() {
+        mST = new SurfaceTexture(123);
+        mSTC = new SurfaceTextureClient(mST);
+    }
+
+    virtual void TearDown() {
+        mST.clear();
+        mSTC.clear();
+    }
+
+    sp<SurfaceTexture> mST;
+    sp<SurfaceTextureClient> mSTC;
+};
+
+TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) {
+    sp<ISurfaceTexture> ist(mSTC->getISurfaceTexture());
+    ASSERT_TRUE(ist != NULL);
+}
+
+TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) {
+    sp<ANativeWindow> anw(mSTC);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+            &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(0, result);
+}
+
+TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
+    sp<ANativeWindow> anw(mSTC);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
+}
+
+TEST_F(SurfaceTextureClientTest, ANativeWindowLockFails) {
+    sp<ANativeWindow> anw(mSTC);
+    ANativeWindow_Buffer buf;
+    ASSERT_EQ(BAD_VALUE, ANativeWindow_lock(anw.get(), &buf, NULL));
+}
+
+TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceFails) {
+    sp<ANativeWindow> anw(mSTC);
+
+    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_DISPLAY, dpy);
+
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EXPECT_TRUE(eglInitialize(dpy, &majorVersion, &minorVersion));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EGLConfig myConfig = {0};
+    EGLint numConfigs = 0;
+    EGLint configAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_RED_SIZE, 8,
+        EGL_GREEN_SIZE, 8,
+        EGL_BLUE_SIZE, 8,
+        EGL_ALPHA_SIZE, 8,
+        EGL_DEPTH_SIZE, 16,
+        EGL_STENCIL_SIZE, 8,
+        EGL_NONE };
+    EXPECT_TRUE(eglChooseConfig(dpy, configAttribs, &myConfig, 1,
+            &numConfigs));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, anw.get(),
+            NULL);
+    ASSERT_EQ(EGL_NO_SURFACE, eglSurface);
+    ASSERT_EQ(EGL_BAD_NATIVE_WINDOW, eglGetError());
+
+    eglTerminate(dpy);
+}
+
+}
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
new file mode 100644
index 0000000..4184463
--- /dev/null
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -0,0 +1,621 @@
+/*
+ * 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 <gtest/gtest.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/String8.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+
+namespace android {
+
+class GLTest : public ::testing::Test {
+protected:
+
+    GLTest():
+            mEglDisplay(EGL_NO_DISPLAY),
+            mEglSurface(EGL_NO_SURFACE),
+            mEglContext(EGL_NO_CONTEXT) {
+    }
+
+    virtual void SetUp() {
+        EGLBoolean returnValue;
+
+        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
+
+        EGLint majorVersion;
+        EGLint minorVersion;
+        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        RecordProperty("EglVersionMajor", majorVersion);
+        RecordProperty("EglVersionMajor", minorVersion);
+
+        EGLConfig myConfig = {0};
+        EGLint numConfigs = 0;
+        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
+                1, &numConfigs));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
+        if (displaySecsEnv != NULL) {
+            mDisplaySecs = atoi(displaySecsEnv);
+            if (mDisplaySecs < 0) {
+                mDisplaySecs = 0;
+            }
+        } else {
+            mDisplaySecs = 0;
+        }
+
+        if (mDisplaySecs > 0) {
+            mComposerClient = new SurfaceComposerClient;
+            ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+            mSurfaceControl = mComposerClient->createSurface(getpid(),
+                    String8("Test Surface"), 0,
+                    getSurfaceWidth(), getSurfaceHeight(),
+                    PIXEL_FORMAT_RGB_888, 0);
+
+            ASSERT_TRUE(mSurfaceControl != NULL);
+            ASSERT_TRUE(mSurfaceControl->isValid());
+
+            ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
+            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
+            ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+            ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
+
+            sp<ANativeWindow> window = mSurfaceControl->getSurface();
+            mEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
+                    window.get(), NULL);
+        } else {
+            EGLint pbufferAttribs[] = {
+                EGL_WIDTH, getSurfaceWidth(),
+                EGL_HEIGHT, getSurfaceHeight(),
+                EGL_NONE };
+
+            mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig,
+                    pbufferAttribs);
+        }
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
+
+        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
+                getContextAttribs());
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
+
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        EGLint w, h;
+        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        RecordProperty("EglSurfaceWidth", w);
+        RecordProperty("EglSurfaceHeight", h);
+
+        glViewport(0, 0, w, h);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    }
+
+    virtual void TearDown() {
+        // Display the result 
+        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
+            eglSwapBuffers(mEglDisplay, mEglSurface);
+            sleep(mDisplaySecs);
+        }
+
+        if (mComposerClient != NULL) {
+            mComposerClient->dispose();
+        }
+        if (mEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mEglContext);
+        }
+        if (mEglSurface != EGL_NO_SURFACE) {
+            eglDestroySurface(mEglDisplay, mEglSurface);
+        }
+        if (mEglDisplay != EGL_NO_DISPLAY) {
+            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                    EGL_NO_CONTEXT);
+            eglTerminate(mEglDisplay);
+        }
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    }
+
+    virtual EGLint const* getConfigAttribs() {
+        static EGLint sDefaultConfigAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+            EGL_DEPTH_SIZE, 16,
+            EGL_STENCIL_SIZE, 8,
+            EGL_NONE };
+
+        return sDefaultConfigAttribs;
+    }
+
+    virtual EGLint const* getContextAttribs() {
+        static EGLint sDefaultContextAttribs[] = {
+            EGL_CONTEXT_CLIENT_VERSION, 2,
+            EGL_NONE };
+
+        return sDefaultContextAttribs;
+    }
+
+    virtual EGLint getSurfaceWidth() {
+        return 64;
+    }
+
+    virtual EGLint getSurfaceHeight() {
+        return 64;
+    }
+
+    void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) {
+        GLuint shader = glCreateShader(shaderType);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        if (shader) {
+            glShaderSource(shader, 1, &pSource, NULL);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            glCompileShader(shader);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            GLint compiled = 0;
+            glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            if (!compiled) {
+                GLint infoLen = 0;
+                glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+                ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+                if (infoLen) {
+                    char* buf = (char*) malloc(infoLen);
+                    if (buf) {
+                        glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                        printf("Shader compile log:\n%s\n", buf);
+                        free(buf);
+                        FAIL();
+                    }
+                } else {
+                    char* buf = (char*) malloc(0x1000);
+                    if (buf) {
+                        glGetShaderInfoLog(shader, 0x1000, NULL, buf);
+                        printf("Shader compile log:\n%s\n", buf);
+                        free(buf);
+                        FAIL();
+                    }
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+        ASSERT_TRUE(shader != 0);
+        *outShader = shader;
+    }
+
+    void createProgram(const char* pVertexSource, const char* pFragmentSource,
+            GLuint* outPgm) {
+        GLuint vertexShader, fragmentShader;
+        {
+            SCOPED_TRACE("compiling vertex shader");
+            loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader);
+            if (HasFatalFailure()) {
+                return;
+            }
+        }
+        {
+            SCOPED_TRACE("compiling fragment shader");
+            loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader);
+            if (HasFatalFailure()) {
+                return;
+            }
+        }
+
+        GLuint program = glCreateProgram();
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        if (program) {
+            glAttachShader(program, vertexShader);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            glAttachShader(program, fragmentShader);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            glLinkProgram(program);
+            GLint linkStatus = GL_FALSE;
+            glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+            if (linkStatus != GL_TRUE) {
+                GLint bufLength = 0;
+                glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+                if (bufLength) {
+                    char* buf = (char*) malloc(bufLength);
+                    if (buf) {
+                        glGetProgramInfoLog(program, bufLength, NULL, buf);
+                        printf("Program link log:\n%s\n", buf);
+                        free(buf);
+                        FAIL();
+                    }
+                }
+                glDeleteProgram(program);
+                program = 0;
+            }
+        }
+        glDeleteShader(vertexShader);
+        glDeleteShader(fragmentShader);
+        ASSERT_TRUE(program != 0);
+        *outPgm = program;
+    }
+
+    ::testing::AssertionResult checkPixel(int x, int y, int r,
+            int g, int b, int a) {
+        GLubyte pixel[4];
+        String8 msg;
+        glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+        GLenum err = glGetError();
+        if (err != GL_NO_ERROR) {
+            msg += String8::format("error reading pixel: %#x", err);
+            while ((err = glGetError()) != GL_NO_ERROR) {
+                msg += String8::format(", %#x", err);
+            }
+            fprintf(stderr, "pixel check failure: %s\n", msg.string());
+            return ::testing::AssertionFailure(
+                    ::testing::Message(msg.string()));
+        }
+        if (r >= 0 && GLubyte(r) != pixel[0]) {
+            msg += String8::format("r(%d isn't %d)", pixel[0], r);
+        }
+        if (g >= 0 && GLubyte(g) != pixel[1]) {
+            if (!msg.isEmpty()) {
+                msg += " ";
+            }
+            msg += String8::format("g(%d isn't %d)", pixel[1], g);
+        }
+        if (b >= 0 && GLubyte(b) != pixel[2]) {
+            if (!msg.isEmpty()) {
+                msg += " ";
+            }
+            msg += String8::format("b(%d isn't %d)", pixel[2], b);
+        }
+        if (a >= 0 && GLubyte(a) != pixel[3]) {
+            if (!msg.isEmpty()) {
+                msg += " ";
+            }
+            msg += String8::format("a(%d isn't %d)", pixel[3], a);
+        }
+        if (!msg.isEmpty()) {
+            fprintf(stderr, "pixel check failure: %s\n", msg.string());
+            return ::testing::AssertionFailure(
+                    ::testing::Message(msg.string()));
+        } else {
+            return ::testing::AssertionSuccess();
+        }
+    }
+
+    int mDisplaySecs;
+    sp<SurfaceComposerClient> mComposerClient;
+    sp<SurfaceControl> mSurfaceControl;
+
+    EGLDisplay mEglDisplay;
+    EGLSurface mEglSurface;
+    EGLContext mEglContext;
+};
+
+// XXX: Code above this point should live elsewhere
+
+class SurfaceTextureGLTest : public GLTest {
+protected:
+    static const GLint TEX_ID = 123;
+
+    virtual void SetUp() {
+        GLTest::SetUp();
+        mST = new SurfaceTexture(TEX_ID);
+        mSTC = new SurfaceTextureClient(mST);
+        mANW = mSTC;
+
+        const char vsrc[] =
+            "attribute vec4 vPosition;\n"
+            "varying vec2 texCoords;\n"
+            "uniform mat4 texMatrix;\n"
+            "void main() {\n"
+            "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
+            "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
+            "  gl_Position = vPosition;\n"
+            "}\n";
+
+        const char fsrc[] =
+            "#extension GL_OES_EGL_image_external : require\n"
+            "precision mediump float;\n"
+            "uniform samplerExternalOES texSampler;\n"
+            "varying vec2 texCoords;\n"
+            "void main() {\n"
+            "  gl_FragColor = texture2D(texSampler, texCoords);\n"
+            "}\n";
+
+        {
+            SCOPED_TRACE("creating shader program");
+            createProgram(vsrc, fsrc, &mPgm);
+            if (HasFatalFailure()) {
+                return;
+            }
+        }
+
+        mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        ASSERT_NE(-1, mPositionHandle);
+        mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        ASSERT_NE(-1, mTexSamplerHandle);
+        mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        ASSERT_NE(-1, mTexMatrixHandle);
+    }
+
+    // drawTexture draws the SurfaceTexture over the entire GL viewport.
+    void drawTexture() {
+        const GLfloat triangleVertices[] = {
+            -1.0f, 1.0f,
+            -1.0f, -1.0f,
+            1.0f, -1.0f,
+            1.0f, 1.0f,
+        };
+
+        glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glEnableVertexAttribArray(mPositionHandle);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        glUseProgram(mPgm);
+        glUniform1i(mTexSamplerHandle, 0);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        GLfloat texMatrix[16];
+        mST->getTransformMatrix(texMatrix);
+        glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
+
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    }
+
+    sp<SurfaceTexture> mST;
+    sp<SurfaceTextureClient> mSTC;
+    sp<ANativeWindow> mANW;
+
+    GLuint mPgm;
+    GLint mPositionHandle;
+    GLint mTexSamplerHandle;
+    GLint mTexMatrixHandle;
+};
+
+// Fill a YV12 buffer with a multi-colored checkerboard pattern
+void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
+    const int blockWidth = w > 16 ? w / 16 : 1;
+    const int blockHeight = h > 16 ? h / 16 : 1;
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            int parityX = (x / blockWidth) & 1;
+            int parityY = (y / blockHeight) & 1;
+            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+            if (x < w / 2 && y < h / 2) {
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+                if (x * 2 < w / 2 && y * 2 < h / 2) {
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
+                        intensity;
+                }
+            }
+        }
+    }
+}
+
+// Fill a YV12 buffer with red outside a given rectangle and green inside it.
+void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
+        const android_native_rect_t& rect) {
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            bool inside = rect.left <= x && x < rect.right &&
+                    rect.top <= y && y < rect.bottom;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
+            if (x < w / 2 && y < h / 2) {
+                bool inside = rect.left <= 2*x && 2*x < rect.right &&
+                        rect.top <= 2*y && 2*y < rect.bottom;
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
+                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
+                        inside ? 16 : 255;
+            }
+        }
+    }
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
+    const int yuvTexWidth = 64;
+    const int yuvTexHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillYV12Buffer(img, yuvTexWidth, yuvTexHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
+
+    EXPECT_TRUE(checkPixel(22, 44, 247,  70, 255, 255));
+    EXPECT_TRUE(checkPixel(45, 52, 209,  32, 235, 255));
+    EXPECT_TRUE(checkPixel(52, 51, 100, 255,  73, 255));
+    EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255));
+    EXPECT_TRUE(checkPixel(31,  9, 148,  71, 110, 255));
+    EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255));
+}
+
+// XXX: This test is disabled because it it currently broken on all devices to
+// which I have access.  Some of the checkPixel calls are not correct because
+// I just copied them from the npot test above and haven't bothered to figure
+// out the correct values.
+TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) {
+    const int yuvTexWidth = 64;
+    const int yuvTexHeight = 64;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillYV12Buffer(img, yuvTexWidth, yuvTexHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    mST->updateTexImage();
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
+
+    EXPECT_TRUE(checkPixel(22, 19, 247,  70, 255, 255));
+    EXPECT_TRUE(checkPixel(45, 11, 209,  32, 235, 255));
+    EXPECT_TRUE(checkPixel(52, 12, 100, 255,  73, 255));
+    EXPECT_TRUE(checkPixel( 7, 32, 155,   0, 118, 255));
+    EXPECT_TRUE(checkPixel(31, 54, 148,  71, 110, 255));
+    EXPECT_TRUE(checkPixel(29, 28, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(36, 41, 155,  29,   0, 255));
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
+    const int yuvTexWidth = 64;
+    const int yuvTexHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            yuvTexWidth, yuvTexHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_rect_t crops[] = {
+        {4, 6, 22, 36},
+        {0, 6, 22, 36},
+        {4, 0, 22, 36},
+        {4, 6, yuvTexWidth, 36},
+        {4, 6, 22, yuvTexHeight},
+    };
+
+    for (int i = 0; i < 5; i++) {
+        const android_native_rect_t& crop(crops[i]);
+        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", crop.left,
+                crop.top, crop.right, crop.bottom).string());
+
+        ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
+
+        android_native_buffer_t* anb;
+        ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+        ASSERT_TRUE(anb != NULL);
+
+        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+        uint8_t* img = NULL;
+        buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+        fillYV12BufferRect(img, yuvTexWidth, yuvTexHeight, buf->getStride(), crop);
+        buf->unlock();
+        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+        mST->updateTexImage();
+
+        glClearColor(0.2, 0.2, 0.2, 0.2);
+        glClear(GL_COLOR_BUFFER_BIT);
+
+        drawTexture();
+
+        EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
+
+        EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
+    }
+}
+
+}
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
index ce3c71a..4a0faf0 100644
--- a/libs/surfaceflinger_client/Android.mk
+++ b/libs/surfaceflinger_client/Android.mk
@@ -5,6 +5,7 @@
 	ISurfaceComposer.cpp \
 	ISurface.cpp \
 	ISurfaceComposerClient.cpp \
+	IGraphicBufferAlloc.cpp \
 	LayerState.cpp \
 	SharedBufferStack.cpp \
 	Surface.cpp \
diff --git a/libs/surfaceflinger_client/IGraphicBufferAlloc.cpp b/libs/surfaceflinger_client/IGraphicBufferAlloc.cpp
new file mode 100644
index 0000000..e05da72
--- /dev/null
+++ b/libs/surfaceflinger_client/IGraphicBufferAlloc.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+// tag as surfaceflinger
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include <surfaceflinger/IGraphicBufferAlloc.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+enum {
+    CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
+    FREE_ALL_GRAPHIC_BUFFERS_EXCEPT,
+};
+
+class BpGraphicBufferAlloc : public BpInterface<IGraphicBufferAlloc>
+{
+public:
+    BpGraphicBufferAlloc(const sp<IBinder>& impl)
+        : BpInterface<IGraphicBufferAlloc>(impl)
+    {
+    }
+
+    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+            PixelFormat format, uint32_t usage) {
+        Parcel data, reply;
+        data.writeInterfaceToken(
+                IGraphicBufferAlloc::getInterfaceDescriptor());
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
+        data.writeInt32(usage);
+        remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
+        sp<GraphicBuffer> graphicBuffer;
+        bool nonNull = (bool)reply.readInt32();
+        if (nonNull) {
+            graphicBuffer = new GraphicBuffer();
+            reply.read(*graphicBuffer);
+        }
+        return graphicBuffer;
+    }
+
+    virtual void freeAllGraphicBuffersExcept(int bufIdx) {
+        Parcel data, reply;
+        data.writeInterfaceToken(
+                IGraphicBufferAlloc::getInterfaceDescriptor());
+        data.writeInt32(bufIdx);
+        remote()->transact(FREE_ALL_GRAPHIC_BUFFERS_EXCEPT, data, &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc");
+
+// ----------------------------------------------------------------------
+
+status_t BnGraphicBufferAlloc::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // codes that don't require permission check
+
+    switch(code) {
+        case CREATE_GRAPHIC_BUFFER: {
+            CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
+            uint32_t w = data.readInt32();
+            uint32_t h = data.readInt32();
+            PixelFormat format = data.readInt32();
+            uint32_t usage = data.readInt32();
+            sp<GraphicBuffer> result(createGraphicBuffer(w, h, format, usage));
+            reply->writeInt32(result != 0);
+            if (result != 0) {
+                reply->write(*result);
+            }
+            return NO_ERROR;
+        } break;
+        case FREE_ALL_GRAPHIC_BUFFERS_EXCEPT: {
+            CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
+            int bufIdx = data.readInt32();
+            freeAllGraphicBuffersExcept(bufIdx);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger_client/ISurface.cpp b/libs/surfaceflinger_client/ISurface.cpp
index 7049d9e..23b90af 100644
--- a/libs/surfaceflinger_client/ISurface.cpp
+++ b/libs/surfaceflinger_client/ISurface.cpp
@@ -21,9 +21,7 @@
 #include <sys/types.h>
 
 #include <binder/Parcel.h>
-#include <binder/IMemory.h>
 
-#include <ui/Overlay.h>
 #include <ui/GraphicBuffer.h>
 
 #include <surfaceflinger/Surface.h>
@@ -33,36 +31,6 @@
 
 // ----------------------------------------------------------------------
 
-ISurface::BufferHeap::BufferHeap() 
-    : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
-    transform(0), flags(0) 
-{     
-}
-
-ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
-        int32_t hor_stride, int32_t ver_stride,
-        PixelFormat format, const sp<IMemoryHeap>& heap)
-    : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
-      format(format), transform(0), flags(0), heap(heap) 
-{
-}
-
-ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
-        int32_t hor_stride, int32_t ver_stride,
-        PixelFormat format, uint32_t transform, uint32_t flags,
-        const sp<IMemoryHeap>& heap)
-        : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
-          format(format), transform(transform), flags(flags), heap(heap) 
-{
-}
-
-
-ISurface::BufferHeap::~BufferHeap() 
-{     
-}
-
-// ----------------------------------------------------------------------
-
 class BpSurface : public BpInterface<ISurface>
 {
 public:
@@ -96,51 +64,6 @@
         status_t err = reply.readInt32();
         return err;
     }
-
-    virtual status_t registerBuffers(const BufferHeap& buffers)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(buffers.w);
-        data.writeInt32(buffers.h);
-        data.writeInt32(buffers.hor_stride);
-        data.writeInt32(buffers.ver_stride);
-        data.writeInt32(buffers.format);
-        data.writeInt32(buffers.transform);
-        data.writeInt32(buffers.flags);
-        data.writeStrongBinder(buffers.heap->asBinder());
-        remote()->transact(REGISTER_BUFFERS, data, &reply);
-        status_t result = reply.readInt32();
-        return result;
-    }
-
-    virtual void postBuffer(ssize_t offset)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(offset);
-        remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    virtual void unregisterBuffers()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        remote()->transact(UNREGISTER_BUFFERS, data, &reply);
-    }
-
-    virtual sp<OverlayRef> createOverlay(
-             uint32_t w, uint32_t h, int32_t format, int32_t orientation)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(w);
-        data.writeInt32(h);
-        data.writeInt32(format);
-        data.writeInt32(orientation);
-        remote()->transact(CREATE_OVERLAY, data, &reply);
-        return OverlayRef::readFromParcel(reply);
-    }
 };
 
 IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
@@ -170,41 +93,6 @@
             reply->writeInt32(err);
             return NO_ERROR;
         }
-        case REGISTER_BUFFERS: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            BufferHeap buffer;
-            buffer.w = data.readInt32();
-            buffer.h = data.readInt32();
-            buffer.hor_stride = data.readInt32();
-            buffer.ver_stride= data.readInt32();
-            buffer.format = data.readInt32();
-            buffer.transform = data.readInt32();
-            buffer.flags = data.readInt32();
-            buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
-            status_t err = registerBuffers(buffer);
-            reply->writeInt32(err);
-            return NO_ERROR;
-        } break;
-        case UNREGISTER_BUFFERS: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            unregisterBuffers();
-            return NO_ERROR;
-        } break;
-        case POST_BUFFER: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            ssize_t offset = data.readInt32();
-            postBuffer(offset);
-            return NO_ERROR;
-        } break;
-        case CREATE_OVERLAY: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            int w = data.readInt32();
-            int h = data.readInt32();
-            int f = data.readInt32();
-            int orientation = data.readInt32();
-            sp<OverlayRef> o = createOverlay(w, h, f, orientation);
-            return OverlayRef::writeToParcel(reply, o);
-        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index a2a5455..8951c3f 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -25,9 +25,11 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
+#include <surfaceflinger/ISurfaceComposer.h>
+
 #include <ui/DisplayInfo.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
+#include <utils/Log.h>
 
 // ---------------------------------------------------------------------------
 
@@ -64,6 +66,15 @@
         return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
     }
 
+    virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc()
+    {
+        uint32_t n;
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply);
+        return interface_cast<IGraphicBufferAlloc>(reply.readStrongBinder());
+    }
+
     virtual sp<IMemoryHeap> getCblk() const
     {
         Parcel data, reply;
@@ -127,13 +138,16 @@
     virtual status_t captureScreen(DisplayID dpy,
             sp<IMemoryHeap>* heap,
             uint32_t* width, uint32_t* height, PixelFormat* format,
-            uint32_t reqWidth, uint32_t reqHeight)
+            uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeInt32(dpy);
         data.writeInt32(reqWidth);
         data.writeInt32(reqHeight);
+        data.writeInt32(minLayerZ);
+        data.writeInt32(maxLayerZ);
         remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
         *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
         *width = reply.readInt32();
@@ -166,6 +180,40 @@
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
     }
+
+    virtual bool authenticateSurface(const sp<ISurface>& surface) const
+    {
+        Parcel data, reply;
+        int err = NO_ERROR;
+        err = data.writeInterfaceToken(
+                ISurfaceComposer::getInterfaceDescriptor());
+        if (err != NO_ERROR) {
+            LOGE("ISurfaceComposer::authenticateSurface: error writing "
+                    "interface descriptor: %s (%d)", strerror(-err), -err);
+            return false;
+        }
+        err = data.writeStrongBinder(surface->asBinder());
+        if (err != NO_ERROR) {
+            LOGE("ISurfaceComposer::authenticateSurface: error writing strong "
+                    "binder to parcel: %s (%d)", strerror(-err), -err);
+            return false;
+        }
+        err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
+                &reply);
+        if (err != NO_ERROR) {
+            LOGE("ISurfaceComposer::authenticateSurface: error performing "
+                    "transaction: %s (%d)", strerror(-err), -err);
+            return false;
+        }
+        int32_t result = 0;
+        err = reply.readInt32(&result);
+        if (err != NO_ERROR) {
+            LOGE("ISurfaceComposer::authenticateSurface: error retrieving "
+                    "result: %s (%d)", strerror(-err), -err);
+            return false;
+        }
+        return result != 0;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -186,6 +234,11 @@
             sp<IBinder> b = createClientConnection()->asBinder();
             reply->writeStrongBinder(b);
         } break;
+        case CREATE_GRAPHIC_BUFFER_ALLOC: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
+            reply->writeStrongBinder(b);
+        } break;
         case OPEN_GLOBAL_TRANSACTION: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             openGlobalTransaction();
@@ -231,11 +284,13 @@
             DisplayID dpy = data.readInt32();
             uint32_t reqWidth = data.readInt32();
             uint32_t reqHeight = data.readInt32();
+            uint32_t minLayerZ = data.readInt32();
+            uint32_t maxLayerZ = data.readInt32();
             sp<IMemoryHeap> heap;
             uint32_t w, h;
             PixelFormat f;
             status_t res = captureScreen(dpy, &heap, &w, &h, &f,
-                    reqWidth, reqHeight);
+                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
             reply->writeStrongBinder(heap->asBinder());
             reply->writeInt32(w);
             reply->writeInt32(h);
@@ -254,6 +309,12 @@
             status_t res = turnElectronBeamOn(mode);
             reply->writeInt32(res);
         } break;
+        case AUTHENTICATE_SURFACE: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
+            int32_t result = authenticateSurface(surface) ? 1 : 0;
+            reply->writeInt32(result);
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
index 2cc1f8e..7730eb1 100644
--- a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
@@ -157,7 +157,7 @@
      const int pid = ipc->getCallingPid();
      const int uid = ipc->getCallingUid();
      const int self_pid = getpid();
-     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
+     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
          // we're called from a different process, do the real check
          if (!checkCallingPermission(
                  String16("android.permission.ACCESS_SURFACE_FLINGER")))
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index b45e43f..7505d53 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -263,6 +263,14 @@
     return (buf != stack.index[stack.head]);
 }
 
+SharedBufferServer::BuffersAvailableCondition::BuffersAvailableCondition(
+        SharedBufferServer* sbs, int numBuffers) : ConditionBase(sbs),
+        mNumBuffers(numBuffers) {
+}
+bool SharedBufferServer::BuffersAvailableCondition::operator()() const {
+    return stack.available == mNumBuffers;
+}
+
 // ----------------------------------------------------------------------------
 
 SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb)
@@ -358,11 +366,6 @@
 {
     SharedBufferStack& stack( *mSharedStack );
 
-    if (stack.head == tail && stack.available == mNumBuffers) {
-        LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
-                tail, stack.head, stack.available, stack.queued);
-    }
-
     RWLock::AutoRLock _rd(mLock);
 
     const nsecs_t dequeueTime = systemTime(SYSTEM_TIME_THREAD);
@@ -431,6 +434,7 @@
 
     const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
     stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
+
     return err;
 }
 
@@ -475,6 +479,7 @@
     if (err == NO_ERROR) {
         mNumBuffers = bufferCount;
         queued_head = (stack.head + stack.queued) % mNumBuffers;
+        tail = computeTail();
     }
     return err;
 }
@@ -582,17 +587,24 @@
  */
 status_t SharedBufferServer::resize(int newNumBuffers)
 {
-    if (uint32_t(newNumBuffers) >= SharedBufferStack::NUM_BUFFER_MAX)
+    if ((unsigned int)(newNumBuffers) < SharedBufferStack::NUM_BUFFER_MIN ||
+        (unsigned int)(newNumBuffers) > SharedBufferStack::NUM_BUFFER_MAX) {
         return BAD_VALUE;
+    }
 
     RWLock::AutoWLock _l(mLock);
 
-    // for now we're not supporting shrinking
-    const int numBuffers = mNumBuffers;
-    if (newNumBuffers < numBuffers)
-        return BAD_VALUE;
+    if (newNumBuffers < mNumBuffers) {
+        return shrink(newNumBuffers);
+    } else {
+        return grow(newNumBuffers);
+    }
+}
 
+status_t SharedBufferServer::grow(int newNumBuffers)
+{
     SharedBufferStack& stack( *mSharedStack );
+    const int numBuffers = mNumBuffers;
     const int extra = newNumBuffers - numBuffers;
 
     // read the head, make sure it's valid
@@ -626,6 +638,48 @@
     return NO_ERROR;
 }
 
+status_t SharedBufferServer::shrink(int newNumBuffers)
+{
+    SharedBufferStack& stack( *mSharedStack );
+
+    // Shrinking is only supported if there are no buffers currently dequeued.
+    int32_t avail = stack.available;
+    int32_t queued = stack.queued;
+    if (avail + queued != mNumBuffers) {
+        return INVALID_OPERATION;
+    }
+
+    // Wait for any queued buffers to be displayed.
+    BuffersAvailableCondition condition(this, mNumBuffers);
+    status_t err = waitForCondition(condition);
+    if (err < 0) {
+        return err;
+    }
+
+    // Reset head to index 0 and make it refer to buffer 0.  The same renaming
+    // (head -> 0) is done in the BufferManager.
+    int32_t head = stack.head;
+    int8_t* index = const_cast<int8_t*>(stack.index);
+    for (int8_t i = 0; i < newNumBuffers; i++) {
+        index[i] = i;
+    }
+    stack.head = 0;
+    stack.headBuf = 0;
+
+    // Free the buffers from the end of the list that are no longer needed.
+    for (int i = newNumBuffers; i < mNumBuffers; i++) {
+        mBufferList.remove(i);
+    }
+
+    // Tell the client to reallocate all the buffers.
+    reallocateAll();
+
+    mNumBuffers = newNumBuffers;
+    stack.available = newNumBuffers;
+
+    return NO_ERROR;
+}
+
 SharedBufferStack::Statistics SharedBufferServer::getStats() const
 {
     SharedBufferStack& stack( *mSharedStack );
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 017e94c..21d509a 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -364,6 +364,13 @@
         height   = surface->mHeight;
         format   = surface->mFormat;
         flags    = surface->mFlags;
+    } else if (surface != 0 && surface->mSurface != 0) {
+        LOGW("Parceling invalid surface with non-NULL ISurface as NULL: "
+             "mSurface = %p, mIdentity = %d, mWidth = %d, mHeight = %d, "
+             "mFormat = %d, mFlags = 0x%08x, mInitCheck = %d",
+             surface->mSurface.get(), surface->mIdentity, surface->mWidth,
+             surface->mHeight, surface->mFormat, surface->mFlags,
+             surface->mInitCheck);
     }
     parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
     parcel->writeInt32(identity);
@@ -438,21 +445,15 @@
             mSharedBufferClient = new SharedBufferClient(
                     mClient.getSharedClient(), token, 2, mIdentity);
             mInitCheck = mClient.getSharedClient()->validate(token);
+        } else {
+            LOGW("Not initializing the shared buffer client because token = %d",
+                    token);
         }
     }
 }
 
 Surface::~Surface()
 {
-    // this is a client-side operation, the surface is destroyed, unmap
-    // its buffers in this process.
-    size_t size = mBuffers.size();
-    for (size_t i=0 ; i<size ; i++) {
-        if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
-            getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
-        }
-    }
-
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
     mBuffers.clear();
@@ -465,7 +466,7 @@
     return mInitCheck == NO_ERROR;
 }
 
-status_t Surface::validate() const
+status_t Surface::validate(bool inCancelBuffer) const
 {
     // check that we initialized ourself properly
     if (mInitCheck != NO_ERROR) {
@@ -475,27 +476,26 @@
 
     // verify the identity of this surface
     uint32_t identity = mSharedBufferClient->getIdentity();
-
-    // this is a bit of a (temporary) special case, identity==0 means that
-    // no operation are allowed from the client (eg: dequeue/queue), this
-    // is used with PUSH_BUFFER surfaces for instance
-    if (identity == 0) {
-        LOGE("[Surface] invalid operation (identity=%u)", mIdentity);
-        return INVALID_OPERATION;
-    }
-
     if (mIdentity != identity) {
         LOGE("[Surface] using an invalid surface, "
                 "identity=%u should be %d",
                 mIdentity, identity);
-        return NO_INIT;
+        CallStack stack;
+        stack.update();
+        stack.dump("Surface");
+        return BAD_INDEX;
     }
 
     // check the surface didn't become invalid
     status_t err = mSharedBufferClient->getStatus();
     if (err != NO_ERROR) {
-        LOGE("surface (identity=%u) is invalid, err=%d (%s)",
-                mIdentity, err, strerror(-err));
+        if (!inCancelBuffer) {
+            LOGE("surface (identity=%u) is invalid, err=%d (%s)",
+                    mIdentity, err, strerror(-err));
+            CallStack stack;
+            stack.update();
+            stack.dump("Surface");
+        }
         return err;
     }
 
@@ -626,12 +626,12 @@
 
 int Surface::cancelBuffer(android_native_buffer_t* buffer)
 {
-    status_t err = validate();
+    status_t err = validate(true);
     switch (err) {
     case NO_ERROR:
         // no error, common case
         break;
-    case INVALID_OPERATION:
+    case BAD_INDEX:
         // legitimate errors here
         return err;
     default:
@@ -709,6 +709,17 @@
     case NATIVE_WINDOW_FORMAT:
         *value = int(mFormat);
         return NO_ERROR;
+    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+        *value = MIN_UNDEQUEUED_BUFFERS;
+        return NO_ERROR;
+    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
+        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+        *value = sf->authenticateSurface(mSurface) ? 1 : 0;
+        return NO_ERROR;
+    }
+    case NATIVE_WINDOW_CONCRETE_TYPE:
+        *value = NATIVE_WINDOW_SURFACE;
+        return NO_ERROR;
     }
     return BAD_VALUE;
 }
@@ -827,13 +838,15 @@
 
 int Surface::crop(Rect const* rect)
 {
-    // empty/invalid rects are not allowed
-    if (rect->isEmpty())
-        return BAD_VALUE;
-
     Mutex::Autolock _l(mSurfaceLock);
     // TODO: validate rect size
-    mNextBufferCrop = *rect;
+
+    if (rect == NULL || rect->isEmpty()) {
+        mNextBufferCrop = Rect(0,0);
+    } else {
+        mNextBufferCrop = *rect;
+    }
+
     return NO_ERROR;
 }
 
@@ -854,6 +867,12 @@
     status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
     LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
             bufferCount, strerror(-err));
+
+    if (err == NO_ERROR) {
+        // Clear out any references to the old buffers.
+        mBuffers.clear();
+    }
+
     return err;
 }
 
@@ -878,6 +897,9 @@
         // EGLConfig validation.
         mFormat = format;
     }
+
+    mNextBufferCrop = Rect(0,0);
+
     return NO_ERROR;
 }
 
@@ -1022,7 +1044,20 @@
 
 int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
 {
-    return buffer->getIndex();
+    int idx = buffer->getIndex();
+    if (idx < 0) {
+        // The buffer doesn't have an index set.  See if the handle the same as
+        // one of the buffers for which we do know the index.  This can happen
+        // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that
+        // was dequeued from an ANativeWindow.
+        for (size_t i = 0; i < mBuffers.size(); i++) {
+            if (mBuffers[i] != 0 && buffer->handle == mBuffers[i]->handle) {
+                idx = mBuffers[i]->getIndex();
+                break;
+            }
+        }
+    }
+    return idx;
 }
 
 status_t Surface::getBufferLocked(int index,
@@ -1036,7 +1071,6 @@
     // free the current buffer
     sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
     if (currentBuffer != 0) {
-        getBufferMapper().unregisterBuffer(currentBuffer->handle);
         currentBuffer.clear();
     }
 
@@ -1044,7 +1078,7 @@
     LOGE_IF(buffer==0,
             "ISurface::getBuffer(%d, %08x) returned NULL",
             index, usage);
-    if (buffer != 0) { // this should never happen by construction
+    if (buffer != 0) { // this should always happen by construction
         LOGE_IF(buffer->handle == NULL, 
                 "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
                 "returned a buffer with a null handle",
@@ -1052,13 +1086,8 @@
         err = mSharedBufferClient->getStatus();
         LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
         if (!err && buffer->handle != NULL) {
-            err = getBufferMapper().registerBuffer(buffer->handle);
-            LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
-                    err, strerror(-err));
-            if (err == NO_ERROR) {
-                currentBuffer = buffer;
-                currentBuffer->setIndex(index);
-            }
+            currentBuffer = buffer;
+            currentBuffer->setIndex(index);
         } else {
             err = err<0 ? err : status_t(NO_MEMORY);
         }
diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
index f270461..d336724 100644
--- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
@@ -555,7 +555,8 @@
     if (s == NULL) return NO_INIT;
     mHeap = 0;
     return s->captureScreen(0, &mHeap,
-            &mWidth, &mHeight, &mFormat, 0, 0);
+            &mWidth, &mHeight, &mFormat, 0, 0,
+            0, -1UL);
 }
 
 status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
@@ -563,7 +564,18 @@
     if (s == NULL) return NO_INIT;
     mHeap = 0;
     return s->captureScreen(0, &mHeap,
-            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight);
+            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
+            0, -1UL);
+}
+
+status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight,
+        uint32_t minLayerZ, uint32_t maxLayerZ) {
+    sp<ISurfaceComposer> s(ComposerService::getComposerService());
+    if (s == NULL) return NO_INIT;
+    mHeap = 0;
+    return s->captureScreen(0, &mHeap,
+            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
+            minLayerZ, maxLayerZ);
 }
 
 void ScreenshotClient::release() {
diff --git a/libs/surfaceflinger_client/tests/Android.mk b/libs/surfaceflinger_client/tests/Android.mk
index 5053e7d..212b8e7 100644
--- a/libs/surfaceflinger_client/tests/Android.mk
+++ b/libs/surfaceflinger_client/tests/Android.mk
@@ -1 +1,53 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+# Build the unit tests.
+test_src_files := \
+    Surface_test.cpp \
+
+shared_libraries := \
+	libcutils \
+	libutils \
+	libbinder \
+	libsurfaceflinger_client \
+	libstlport \
+
+static_libraries := \
+	libgtest \
+	libgtest_main \
+
+c_includes := \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport \
+
+module_tags := tests
+
+$(foreach file,$(test_src_files), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+    $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+# Build the manual test programs.
 include $(call all-subdir-makefiles)
+
+endif
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
index f409f48..7ef5926 100644
--- a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
+++ b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
@@ -32,7 +32,8 @@
 int main(int argc, char** argv)
 {
     SharedClient client;
-    SharedBufferServer s(&client, 0, 4, 0);
+    sp<SharedBufferServer> ps(new SharedBufferServer(&client, 0, 4, 0));
+    SharedBufferServer& s(*ps);
     SharedBufferClient c(&client, 0, 4, 0);
 
     printf("basic test 0\n");
@@ -67,6 +68,10 @@
     int list3[6] = {3, 2, 1, 4, 5, 0};
     test0(s, c, 6, list3);
 
+    c.setBufferCount(4, resize);
+    int list4[4] = {1, 2, 3, 0};
+    test0(s, c, 4, list4);
+
     return 0;
 }
 
diff --git a/libs/surfaceflinger_client/tests/Surface_test.cpp b/libs/surfaceflinger_client/tests/Surface_test.cpp
new file mode 100644
index 0000000..fd07479
--- /dev/null
+++ b/libs/surfaceflinger_client/tests/Surface_test.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include <binder/IMemory.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class SurfaceTest : public ::testing::Test {
+protected:
+    virtual void SetUp() {
+        mComposerClient = new SurfaceComposerClient;
+        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+        mSurfaceControl = mComposerClient->createSurface(getpid(),
+                String8("Test Surface"), 0, 32, 32, PIXEL_FORMAT_RGB_888, 0);
+
+        ASSERT_TRUE(mSurfaceControl != NULL);
+        ASSERT_TRUE(mSurfaceControl->isValid());
+
+        ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+        ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
+
+        mSurface = mSurfaceControl->getSurface();
+        ASSERT_TRUE(mSurface != NULL);
+    }
+
+    virtual void TearDown() {
+        mComposerClient->dispose();
+    }
+
+    sp<Surface> mSurface;
+    sp<SurfaceComposerClient> mComposerClient;
+    sp<SurfaceControl> mSurfaceControl;
+};
+
+TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenVisible) {
+    sp<ANativeWindow> anw(mSurface);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+            &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(1, result);
+}
+
+TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) {
+    mSurfaceControl.clear();
+
+    sp<ANativeWindow> anw(mSurface);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
+            &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(1, result);
+}
+
+// This test probably doesn't belong here.
+TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersFail) {
+    sp<ANativeWindow> anw(mSurface);
+
+    // Verify the screenshot works with no protected buffers.
+    sp<IMemoryHeap> heap;
+    uint32_t w=0, h=0;
+    PixelFormat fmt=0;
+    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
+            40000));
+    ASSERT_TRUE(heap != NULL);
+
+    // Set the PROTECTED usage bit and verify that the screenshot fails.  Note
+    // that we need to dequeue a buffer in order for it to actually get
+    // allocated in SurfaceFlinger.
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(),
+            GRALLOC_USAGE_PROTECTED));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
+    android_native_buffer_t* buf = 0;
+    for (int i = 0; i < 4; i++) {
+        // Loop to make sure SurfaceFlinger has retired a protected buffer.
+        ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+        ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
+        ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
+    }
+    heap = 0;
+    w = h = fmt = 0;
+    ASSERT_EQ(INVALID_OPERATION, sf->captureScreen(0, &heap, &w, &h, &fmt,
+            64, 64, 0, 40000));
+    ASSERT_TRUE(heap == NULL);
+
+    // XXX: This should not be needed, but it seems that the new buffers don't
+    // correctly show up after the upcoming dequeue/lock/queue loop without it.
+    // We should look into this at some point.
+    ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
+
+    // Un-set the PROTECTED usage bit and verify that the screenshot works
+    // again.  Note that we have to change the buffers geometry to ensure that
+    // the buffers get reallocated, as the new usage bits are a subset of the
+    // old.
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), 0));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(anw.get(), 32, 32, 0));
+    for (int i = 0; i < 4; i++) {
+        // Loop to make sure SurfaceFlinger has retired a protected buffer.
+        ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
+        ASSERT_EQ(NO_ERROR, anw->lockBuffer(anw.get(), buf));
+        ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf));
+    }
+    heap = 0;
+    w = h = fmt = 0;
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(0, &heap, &w, &h, &fmt, 64, 64, 0,
+            40000));
+    ASSERT_TRUE(heap != NULL);
+}
+
+TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
+    sp<ANativeWindow> anw(mSurface);
+    int result = -123;
+    int err = anw->query(anw.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
+    EXPECT_EQ(NO_ERROR, err);
+    EXPECT_EQ(NATIVE_WINDOW_SURFACE, result);
+}
+
+}
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index c4a09d6..f9990bb 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -1,24 +1,55 @@
+# 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.
+
 LOCAL_PATH:= $(call my-dir)
+
+# libui is partially built for the host (used by build time keymap validation tool)
+# These files are common to host and target builds.
+commonSources:= \
+	Input.cpp \
+	Keyboard.cpp \
+	KeyLayoutMap.cpp \
+	KeyCharacterMap.cpp \
+	VirtualKeyMap.cpp
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(commonSources)
+
+LOCAL_MODULE:= libui
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# For the device
+# =====================================================
+
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
+	$(commonSources) \
 	EGLUtils.cpp \
-	EventHub.cpp \
 	EventRecurrence.cpp \
 	FramebufferNativeWindow.cpp \
 	GraphicBuffer.cpp \
 	GraphicBufferAllocator.cpp \
 	GraphicBufferMapper.cpp \
 	GraphicLog.cpp \
-	KeyLayoutMap.cpp \
-	KeyCharacterMap.cpp \
-	Input.cpp \
-	InputDispatcher.cpp \
-	InputManager.cpp \
-	InputReader.cpp \
 	InputTransport.cpp \
-	IOverlay.cpp \
-	Overlay.cpp \
 	PixelFormat.cpp \
 	Rect.cpp \
 	Region.cpp
@@ -27,10 +58,14 @@
 	libcutils \
 	libutils \
 	libEGL \
-	libbinder \
 	libpixelflinger \
 	libhardware \
-	libhardware_legacy
+	libhardware_legacy \
+	libskia \
+	libbinder
+
+LOCAL_C_INCLUDES := \
+    external/skia/include/core
 
 LOCAL_MODULE:= libui
 
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
deleted file mode 100644
index 41daa9c..0000000
--- a/libs/ui/EventHub.cpp
+++ /dev/null
@@ -1,1026 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-// Handle events, like key input and vsync.
-//
-// The goal is to provide an optimized solution for Linux, not an
-// implementation that works well across all platforms.  We expect
-// events to arrive on file descriptors, so that we can use a select()
-// select() call to sleep.
-//
-// We can't select() on anything but network sockets in Windows, so we
-// provide an alternative implementation of waitEvent for that platform.
-//
-#define LOG_TAG "EventHub"
-
-//#define LOG_NDEBUG 0
-
-#include <ui/EventHub.h>
-#include <ui/KeycodeLabels.h>
-#include <hardware_legacy/power.h>
-
-#include <cutils/properties.h>
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <utils/threads.h>
-#include <utils/Errors.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "KeyLayoutMap.h"
-
-#include <string.h>
-#include <stdint.h>
-#include <dirent.h>
-#ifdef HAVE_INOTIFY
-# include <sys/inotify.h>
-#endif
-#ifdef HAVE_ANDROID_OS
-# include <sys/limits.h>        /* not part of Linux */
-#endif
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-
-/* this macro is used to tell if "bit" is set in "array"
- * it selects a byte from the array, and does a boolean AND
- * operation with a byte that only has the relevant bit set.
- * eg. to check for the 12th bit, we do (array[1] & 1<<4)
- */
-#define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
-
-/* this macro computes the number of bytes needed to represent a bit array of the specified size */
-#define sizeof_bit_array(bits)  ((bits + 7) / 8)
-
-#define ID_MASK  0x0000ffff
-#define SEQ_MASK 0x7fff0000
-#define SEQ_SHIFT 16
-
-#ifndef ABS_MT_TOUCH_MAJOR
-#define ABS_MT_TOUCH_MAJOR      0x30    /* Major axis of touching ellipse */
-#endif
-
-#ifndef ABS_MT_POSITION_X
-#define ABS_MT_POSITION_X       0x35    /* Center X ellipse position */
-#endif
-
-#ifndef ABS_MT_POSITION_Y
-#define ABS_MT_POSITION_Y       0x36    /* Center Y ellipse position */
-#endif
-
-#define INDENT "  "
-#define INDENT2 "    "
-#define INDENT3 "      "
-
-namespace android {
-
-static const char *WAKE_LOCK_ID = "KeyEvents";
-static const char *device_path = "/dev/input";
-
-/* return the larger integer */
-static inline int max(int v1, int v2)
-{
-    return (v1 > v2) ? v1 : v2;
-}
-
-static inline const char* toString(bool value) {
-    return value ? "true" : "false";
-}
-
-EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name)
-    : id(_id), path(_path), name(name), classes(0)
-    , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), fd(-1), next(NULL) {
-}
-
-EventHub::device_t::~device_t() {
-    delete [] keyBitmask;
-    delete layoutMap;
-}
-
-EventHub::EventHub(void)
-    : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(0)
-    , mDevicesById(0), mNumDevicesById(0)
-    , mOpeningDevices(0), mClosingDevices(0)
-    , mDevices(0), mFDs(0), mFDCount(0), mOpened(false), mNeedToSendFinishedDeviceScan(false)
-    , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0)
-{
-    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-#ifdef EV_SW
-    memset(mSwitches, 0, sizeof(mSwitches));
-#endif
-}
-
-/*
- * Clean up.
- */
-EventHub::~EventHub(void)
-{
-    release_wake_lock(WAKE_LOCK_ID);
-    // we should free stuff here...
-}
-
-status_t EventHub::errorCheck() const
-{
-    return mError;
-}
-
-String8 EventHub::getDeviceName(int32_t deviceId) const
-{
-    AutoMutex _l(mLock);
-    device_t* device = getDeviceLocked(deviceId);
-    if (device == NULL) return String8();
-    return device->name;
-}
-
-uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
-{
-    AutoMutex _l(mLock);
-    device_t* device = getDeviceLocked(deviceId);
-    if (device == NULL) return 0;
-    return device->classes;
-}
-
-status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
-        RawAbsoluteAxisInfo* outAxisInfo) const {
-    outAxisInfo->clear();
-
-    AutoMutex _l(mLock);
-    device_t* device = getDeviceLocked(deviceId);
-    if (device == NULL) return -1;
-
-    struct input_absinfo info;
-
-    if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
-        LOGW("Error reading absolute controller %d for device %s fd %d\n",
-             axis, device->name.string(), device->fd);
-        return -errno;
-    }
-
-    if (info.minimum != info.maximum) {
-        outAxisInfo->valid = true;
-        outAxisInfo->minValue = info.minimum;
-        outAxisInfo->maxValue = info.maximum;
-        outAxisInfo->flat = info.flat;
-        outAxisInfo->fuzz = info.fuzz;
-    }
-    return OK;
-}
-
-int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
-    if (scanCode >= 0 && scanCode <= KEY_MAX) {
-        AutoMutex _l(mLock);
-
-        device_t* device = getDeviceLocked(deviceId);
-        if (device != NULL) {
-            return getScanCodeStateLocked(device, scanCode);
-        }
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) const {
-    uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
-    memset(key_bitmask, 0, sizeof(key_bitmask));
-    if (ioctl(device->fd,
-               EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
-        return test_bit(scanCode, key_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
-    AutoMutex _l(mLock);
-
-    device_t* device = getDeviceLocked(deviceId);
-    if (device != NULL) {
-        return getKeyCodeStateLocked(device, keyCode);
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getKeyCodeStateLocked(device_t* device, int32_t keyCode) const {
-    Vector<int32_t> scanCodes;
-    device->layoutMap->findScancodes(keyCode, &scanCodes);
-
-    uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
-    memset(key_bitmask, 0, sizeof(key_bitmask));
-    if (ioctl(device->fd, EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
-        #if 0
-        for (size_t i=0; i<=KEY_MAX; i++) {
-            LOGI("(Scan code %d: down=%d)", i, test_bit(i, key_bitmask));
-        }
-        #endif
-        const size_t N = scanCodes.size();
-        for (size_t i=0; i<N && i<=KEY_MAX; i++) {
-            int32_t sc = scanCodes.itemAt(i);
-            //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask));
-            if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) {
-                return AKEY_STATE_DOWN;
-            }
-        }
-        return AKEY_STATE_UP;
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
-#ifdef EV_SW
-    if (sw >= 0 && sw <= SW_MAX) {
-        AutoMutex _l(mLock);
-
-        device_t* device = getDeviceLocked(deviceId);
-        if (device != NULL) {
-            return getSwitchStateLocked(device, sw);
-        }
-    }
-#endif
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const {
-    uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
-    memset(sw_bitmask, 0, sizeof(sw_bitmask));
-    if (ioctl(device->fd,
-               EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
-        return test_bit(sw, sw_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) const {
-    AutoMutex _l(mLock);
-
-    device_t* device = getDeviceLocked(deviceId);
-    if (device != NULL) {
-        return markSupportedKeyCodesLocked(device, numCodes, keyCodes, outFlags);
-    }
-    return false;
-}
-
-bool EventHub::markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) const {
-    if (device->layoutMap == NULL || device->keyBitmask == NULL) {
-        return false;
-    }
-
-    Vector<int32_t> scanCodes;
-    for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
-        scanCodes.clear();
-
-        status_t err = device->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
-        if (! err) {
-            // check the possible scan codes identified by the layout map against the
-            // map of codes actually emitted by the driver
-            for (size_t sc = 0; sc < scanCodes.size(); sc++) {
-                if (test_bit(scanCodes[sc], device->keyBitmask)) {
-                    outFlags[codeIndex] = 1;
-                    break;
-                }
-            }
-        }
-    }
-    return true;
-}
-
-status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
-        int32_t* outKeycode, uint32_t* outFlags) const
-{
-    AutoMutex _l(mLock);
-    device_t* device = getDeviceLocked(deviceId);
-    
-    if (device != NULL && device->layoutMap != NULL) {
-        status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
-        if (err == NO_ERROR) {
-            return NO_ERROR;
-        }
-    }
-    
-    if (mHaveFirstKeyboard) {
-        device = getDeviceLocked(mFirstKeyboardId);
-        
-        if (device != NULL && device->layoutMap != NULL) {
-            status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
-            if (err == NO_ERROR) {
-                return NO_ERROR;
-            }
-        }
-    }
-    
-    *outKeycode = 0;
-    *outFlags = 0;
-    return NAME_NOT_FOUND;
-}
-
-void EventHub::addExcludedDevice(const char* deviceName)
-{
-    AutoMutex _l(mLock);
-
-    String8 name(deviceName);
-    mExcludedDevices.push_back(name);
-}
-
-EventHub::device_t* EventHub::getDeviceLocked(int32_t deviceId) const
-{
-    if (deviceId == 0) deviceId = mFirstKeyboardId;
-    int32_t id = deviceId & ID_MASK;
-    if (id >= mNumDevicesById || id < 0) return NULL;
-    device_t* dev = mDevicesById[id].device;
-    if (dev == NULL) return NULL;
-    if (dev->id == deviceId) {
-        return dev;
-    }
-    return NULL;
-}
-
-bool EventHub::getEvent(RawEvent* outEvent)
-{
-    outEvent->deviceId = 0;
-    outEvent->type = 0;
-    outEvent->scanCode = 0;
-    outEvent->keyCode = 0;
-    outEvent->flags = 0;
-    outEvent->value = 0;
-    outEvent->when = 0;
-
-    // Note that we only allow one caller to getEvent(), so don't need
-    // to do locking here...  only when adding/removing devices.
-
-    if (!mOpened) {
-        mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
-        mOpened = true;
-        mNeedToSendFinishedDeviceScan = true;
-    }
-
-    for (;;) {
-        // Report any devices that had last been added/removed.
-        if (mClosingDevices != NULL) {
-            device_t* device = mClosingDevices;
-            LOGV("Reporting device closed: id=0x%x, name=%s\n",
-                 device->id, device->path.string());
-            mClosingDevices = device->next;
-            if (device->id == mFirstKeyboardId) {
-                outEvent->deviceId = 0;
-            } else {
-                outEvent->deviceId = device->id;
-            }
-            outEvent->type = DEVICE_REMOVED;
-            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
-            delete device;
-            mNeedToSendFinishedDeviceScan = true;
-            return true;
-        }
-
-        if (mOpeningDevices != NULL) {
-            device_t* device = mOpeningDevices;
-            LOGV("Reporting device opened: id=0x%x, name=%s\n",
-                 device->id, device->path.string());
-            mOpeningDevices = device->next;
-            if (device->id == mFirstKeyboardId) {
-                outEvent->deviceId = 0;
-            } else {
-                outEvent->deviceId = device->id;
-            }
-            outEvent->type = DEVICE_ADDED;
-            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
-            mNeedToSendFinishedDeviceScan = true;
-            return true;
-        }
-
-        if (mNeedToSendFinishedDeviceScan) {
-            mNeedToSendFinishedDeviceScan = false;
-            outEvent->type = FINISHED_DEVICE_SCAN;
-            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
-            return true;
-        }
-
-        // Grab the next input event.
-        for (;;) {
-            // Consume buffered input events, if any.
-            if (mInputBufferIndex < mInputBufferCount) {
-                const struct input_event& iev = mInputBufferData[mInputBufferIndex++];
-                const device_t* device = mDevices[mInputDeviceIndex];
-
-                LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
-                     (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);
-                if (device->id == mFirstKeyboardId) {
-                    outEvent->deviceId = 0;
-                } else {
-                    outEvent->deviceId = device->id;
-                }
-                outEvent->type = iev.type;
-                outEvent->scanCode = iev.code;
-                if (iev.type == EV_KEY) {
-                    status_t err = device->layoutMap->map(iev.code,
-                            & outEvent->keyCode, & outEvent->flags);
-                    LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
-                        iev.code, outEvent->keyCode, outEvent->flags, err);
-                    if (err != 0) {
-                        outEvent->keyCode = AKEYCODE_UNKNOWN;
-                        outEvent->flags = 0;
-                    }
-                } else {
-                    outEvent->keyCode = iev.code;
-                }
-                outEvent->value = iev.value;
-
-                // Use an event timestamp in the same timebase as
-                // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
-                // as expected by the rest of the system.
-                outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
-                return true;
-            }
-
-            // Finish reading all events from devices identified in previous poll().
-            // This code assumes that mInputDeviceIndex is initially 0 and that the
-            // revents member of pollfd is initialized to 0 when the device is first added.
-            // Since mFDs[0] is used for inotify, we process regular events starting at index 1.
-            mInputDeviceIndex += 1;
-            if (mInputDeviceIndex >= mFDCount) {
-                break;
-            }
-
-            const struct pollfd& pfd = mFDs[mInputDeviceIndex];
-            if (pfd.revents & POLLIN) {
-                int32_t readSize = read(pfd.fd, mInputBufferData,
-                        sizeof(struct input_event) * INPUT_BUFFER_SIZE);
-                if (readSize < 0) {
-                    if (errno != EAGAIN && errno != EINTR) {
-                        LOGW("could not get event (errno=%d)", errno);
-                    }
-                } else if ((readSize % sizeof(struct input_event)) != 0) {
-                    LOGE("could not get event (wrong size: %d)", readSize);
-                } else {
-                    mInputBufferCount = readSize / sizeof(struct input_event);
-                    mInputBufferIndex = 0;
-                }
-            }
-        }
-
-#if HAVE_INOTIFY
-        // readNotify() will modify mFDs and mFDCount, so this must be done after
-        // processing all other events.
-        if(mFDs[0].revents & POLLIN) {
-            readNotify(mFDs[0].fd);
-            mFDs[0].revents = 0;
-            continue; // report added or removed devices immediately
-        }
-#endif
-
-        mInputDeviceIndex = 0;
-
-        // Poll for events.  Mind the wake lock dance!
-        // We hold a wake lock at all times except during poll().  This works due to some
-        // subtle choreography.  When a device driver has pending (unread) events, it acquires
-        // a kernel wake lock.  However, once the last pending event has been read, the device
-        // driver will release the kernel wake lock.  To prevent the system from going to sleep
-        // when this happens, the EventHub holds onto its own user wake lock while the client
-        // is processing events.  Thus the system can only sleep if there are no events
-        // pending or currently being processed.
-        release_wake_lock(WAKE_LOCK_ID);
-
-        int pollResult = poll(mFDs, mFDCount, -1);
-
-        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-
-        if (pollResult <= 0) {
-            if (errno != EINTR) {
-                LOGW("poll failed (errno=%d)\n", errno);
-                usleep(100000);
-            }
-        }
-    }
-}
-
-/*
- * Open the platform-specific input device.
- */
-bool EventHub::openPlatformInput(void)
-{
-    /*
-     * Open platform-specific input device(s).
-     */
-    int res;
-
-    mFDCount = 1;
-    mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
-    mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
-    mFDs[0].events = POLLIN;
-    mFDs[0].revents = 0;
-    mDevices[0] = NULL;
-#ifdef HAVE_INOTIFY
-    mFDs[0].fd = inotify_init();
-    res = inotify_add_watch(mFDs[0].fd, device_path, IN_DELETE | IN_CREATE);
-    if(res < 0) {
-        LOGE("could not add watch for %s, %s\n", device_path, strerror(errno));
-    }
-#else
-    /*
-     * The code in EventHub::getEvent assumes that mFDs[0] is an inotify fd.
-     * We allocate space for it and set it to something invalid.
-     */
-    mFDs[0].fd = -1;
-#endif
-
-    res = scanDir(device_path);
-    if(res < 0) {
-        LOGE("scan dir failed for %s\n", device_path);
-    }
-
-    return true;
-}
-
-// ----------------------------------------------------------------------------
-
-static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) {
-    const uint8_t* end = array + endIndex;
-    array += startIndex;
-    while (array != end) {
-        if (*(array++) != 0) {
-            return true;
-        }
-    }
-    return false;
-}
-
-static const int32_t GAMEPAD_KEYCODES[] = {
-        AKEYCODE_BUTTON_A, AKEYCODE_BUTTON_B, AKEYCODE_BUTTON_C,
-        AKEYCODE_BUTTON_X, AKEYCODE_BUTTON_Y, AKEYCODE_BUTTON_Z,
-        AKEYCODE_BUTTON_L1, AKEYCODE_BUTTON_R1,
-        AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2,
-        AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR,
-        AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE
-};
-
-int EventHub::openDevice(const char *deviceName) {
-    int version;
-    int fd;
-    struct pollfd *new_mFDs;
-    device_t **new_devices;
-    char **new_device_names;
-    char name[80];
-    char location[80];
-    char idstr[80];
-    struct input_id id;
-
-    LOGV("Opening device: %s", deviceName);
-
-    AutoMutex _l(mLock);
-
-    fd = open(deviceName, O_RDWR);
-    if(fd < 0) {
-        LOGE("could not open %s, %s\n", deviceName, strerror(errno));
-        return -1;
-    }
-
-    if(ioctl(fd, EVIOCGVERSION, &version)) {
-        LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno));
-        return -1;
-    }
-    if(ioctl(fd, EVIOCGID, &id)) {
-        LOGE("could not get driver id for %s, %s\n", deviceName, strerror(errno));
-        return -1;
-    }
-    name[sizeof(name) - 1] = '\0';
-    location[sizeof(location) - 1] = '\0';
-    idstr[sizeof(idstr) - 1] = '\0';
-    if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
-        //fprintf(stderr, "could not get device name for %s, %s\n", deviceName, strerror(errno));
-        name[0] = '\0';
-    }
-
-    // check to see if the device is on our excluded list
-    List<String8>::iterator iter = mExcludedDevices.begin();
-    List<String8>::iterator end = mExcludedDevices.end();
-    for ( ; iter != end; iter++) {
-        const char* test = *iter;
-        if (strcmp(name, test) == 0) {
-            LOGI("ignoring event id %s driver %s\n", deviceName, test);
-            close(fd);
-            return -1;
-        }
-    }
-
-    if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) {
-        //fprintf(stderr, "could not get location for %s, %s\n", deviceName, strerror(errno));
-        location[0] = '\0';
-    }
-    if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) {
-        //fprintf(stderr, "could not get idstring for %s, %s\n", deviceName, strerror(errno));
-        idstr[0] = '\0';
-    }
-
-    if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
-        LOGE("Error %d making device file descriptor non-blocking.", errno);
-        close(fd);
-        return -1;
-    }
-
-    int devid = 0;
-    while (devid < mNumDevicesById) {
-        if (mDevicesById[devid].device == NULL) {
-            break;
-        }
-        devid++;
-    }
-    if (devid >= mNumDevicesById) {
-        device_ent* new_devids = (device_ent*)realloc(mDevicesById,
-                sizeof(mDevicesById[0]) * (devid + 1));
-        if (new_devids == NULL) {
-            LOGE("out of memory");
-            return -1;
-        }
-        mDevicesById = new_devids;
-        mNumDevicesById = devid+1;
-        mDevicesById[devid].device = NULL;
-        mDevicesById[devid].seq = 0;
-    }
-
-    mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
-    if (mDevicesById[devid].seq == 0) {
-        mDevicesById[devid].seq = 1<<SEQ_SHIFT;
-    }
-
-    new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1));
-    new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1));
-    if (new_mFDs == NULL || new_devices == NULL) {
-        LOGE("out of memory");
-        return -1;
-    }
-    mFDs = new_mFDs;
-    mDevices = new_devices;
-
-#if 0
-    LOGI("add device %d: %s\n", mFDCount, deviceName);
-    LOGI("  bus:      %04x\n"
-         "  vendor    %04x\n"
-         "  product   %04x\n"
-         "  version   %04x\n",
-        id.bustype, id.vendor, id.product, id.version);
-    LOGI("  name:     \"%s\"\n", name);
-    LOGI("  location: \"%s\"\n"
-         "  id:       \"%s\"\n", location, idstr);
-    LOGI("  version:  %d.%d.%d\n",
-        version >> 16, (version >> 8) & 0xff, version & 0xff);
-#endif
-
-    device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName, name);
-    if (device == NULL) {
-        LOGE("out of memory");
-        return -1;
-    }
-
-    device->fd = fd;
-    mFDs[mFDCount].fd = fd;
-    mFDs[mFDCount].events = POLLIN;
-    mFDs[mFDCount].revents = 0;
-
-    // Figure out the kinds of events the device reports.
-    
-    uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
-    memset(key_bitmask, 0, sizeof(key_bitmask));
-
-    LOGV("Getting keys...");
-    if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
-        //LOGI("MAP\n");
-        //for (int i = 0; i < sizeof(key_bitmask); i++) {
-        //    LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
-        //}
-
-        // See if this is a keyboard.  Ignore everything in the button range except for
-        // gamepads which are also considered keyboards.
-        if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))
-                || containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_GAMEPAD),
-                        sizeof_bit_array(BTN_DIGI))
-                || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),
-                        sizeof_bit_array(KEY_MAX + 1))) {
-            device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
-
-            device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
-            if (device->keyBitmask != NULL) {
-                memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
-            } else {
-                delete device;
-                LOGE("out of memory allocating key bitmask");
-                return -1;
-            }
-        }
-    }
-    
-    // See if this is a trackball (or mouse).
-    if (test_bit(BTN_MOUSE, key_bitmask)) {
-        uint8_t rel_bitmask[sizeof_bit_array(REL_MAX + 1)];
-        memset(rel_bitmask, 0, sizeof(rel_bitmask));
-        LOGV("Getting relative controllers...");
-        if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0) {
-            if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
-                device->classes |= INPUT_DEVICE_CLASS_TRACKBALL;
-            }
-        }
-    }
-
-    // See if this is a touch pad.
-    uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];
-    memset(abs_bitmask, 0, sizeof(abs_bitmask));
-    LOGV("Getting absolute controllers...");
-    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
-        // Is this a new modern multi-touch driver?
-        if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
-                && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
-            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
-
-        // Is this an old style single-touch driver?
-        } else if (test_bit(BTN_TOUCH, key_bitmask)
-                && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
-            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN;
-        }
-    }
-
-#ifdef EV_SW
-    // figure out the switches this device reports
-    uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
-    memset(sw_bitmask, 0, sizeof(sw_bitmask));
-    bool hasSwitches = false;
-    if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
-        for (int i=0; i<EV_SW; i++) {
-            //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
-            if (test_bit(i, sw_bitmask)) {
-                hasSwitches = true;
-                if (mSwitches[i] == 0) {
-                    mSwitches[i] = device->id;
-                }
-            }
-        }
-    }
-    if (hasSwitches) {
-        device->classes |= INPUT_DEVICE_CLASS_SWITCH;
-    }
-#endif
-
-    if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
-        char tmpfn[sizeof(name)];
-        char keylayoutFilename[300];
-
-        // a more descriptive name
-        device->name = name;
-
-        // replace all the spaces with underscores
-        strcpy(tmpfn, name);
-        for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
-            *p = '_';
-
-        // find the .kl file we need for this device
-        const char* root = getenv("ANDROID_ROOT");
-        snprintf(keylayoutFilename, sizeof(keylayoutFilename),
-                 "%s/usr/keylayout/%s.kl", root, tmpfn);
-        bool defaultKeymap = false;
-        if (access(keylayoutFilename, R_OK)) {
-            snprintf(keylayoutFilename, sizeof(keylayoutFilename),
-                     "%s/usr/keylayout/%s", root, "qwerty.kl");
-            defaultKeymap = true;
-        }
-        status_t status = device->layoutMap->load(keylayoutFilename);
-        if (status) {
-            LOGE("Error %d loading key layout.", status);
-        }
-
-        // tell the world about the devname (the descriptive name)
-        if (!mHaveFirstKeyboard && !defaultKeymap && strstr(name, "-keypad")) {
-            // the built-in keyboard has a well-known device ID of 0,
-            // this device better not go away.
-            mHaveFirstKeyboard = true;
-            mFirstKeyboardId = device->id;
-            property_set("hw.keyboards.0.devname", name);
-        } else {
-            // ensure mFirstKeyboardId is set to -something-.
-            if (mFirstKeyboardId == 0) {
-                mFirstKeyboardId = device->id;
-            }
-        }
-        char propName[100];
-        sprintf(propName, "hw.keyboards.%u.devname", device->id);
-        property_set(propName, name);
-
-        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
-        if (hasKeycodeLocked(device, AKEYCODE_Q)) {
-            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
-        }
-        
-        // See if this device has a DPAD.
-        if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) {
-            device->classes |= INPUT_DEVICE_CLASS_DPAD;
-        }
-        
-        // See if this device has a gamepad.
-        for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) {
-            if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) {
-                device->classes |= INPUT_DEVICE_CLASS_GAMEPAD;
-                break;
-            }
-        }
-
-        LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
-                device->id, name, propName, keylayoutFilename);
-    }
-
-    // If the device isn't recognized as something we handle, don't monitor it.
-    if (device->classes == 0) {
-        LOGV("Dropping device %s %p, id = %d\n", deviceName, device, devid);
-        close(fd);
-        delete device;
-        return -1;
-    }
-
-    LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
-         deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
-         
-    LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
-         deviceName, device, mFDCount, devid, device->classes);
-
-    mDevicesById[devid].device = device;
-    device->next = mOpeningDevices;
-    mOpeningDevices = device;
-    mDevices[mFDCount] = device;
-
-    mFDCount++;
-    return 0;
-}
-
-bool EventHub::hasKeycodeLocked(device_t* device, int keycode) const
-{
-    if (device->keyBitmask == NULL || device->layoutMap == NULL) {
-        return false;
-    }
-    
-    Vector<int32_t> scanCodes;
-    device->layoutMap->findScancodes(keycode, &scanCodes);
-    const size_t N = scanCodes.size();
-    for (size_t i=0; i<N && i<=KEY_MAX; i++) {
-        int32_t sc = scanCodes.itemAt(i);
-        if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) {
-            return true;
-        }
-    }
-    
-    return false;
-}
-
-int EventHub::closeDevice(const char *deviceName) {
-    AutoMutex _l(mLock);
-
-    int i;
-    for(i = 1; i < mFDCount; i++) {
-        if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
-            //LOGD("remove device %d: %s\n", i, deviceName);
-            device_t* device = mDevices[i];
-            
-            LOGI("Removed device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
-                 device->path.string(), device->name.string(), device->id,
-                 mNumDevicesById, mFDCount, mFDs[i].fd, device->classes);
-         
-            // Clear this device's entry.
-            int index = (device->id&ID_MASK);
-            mDevicesById[index].device = NULL;
-            
-            // Close the file descriptor and compact the fd array.
-            close(mFDs[i].fd);
-            int count = mFDCount - i - 1;
-            memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count);
-            memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count);
-            mFDCount--;
-
-#ifdef EV_SW
-            for (int j=0; j<EV_SW; j++) {
-                if (mSwitches[j] == device->id) {
-                    mSwitches[j] = 0;
-                }
-            }
-#endif
-            
-            device->next = mClosingDevices;
-            mClosingDevices = device;
-
-            if (device->id == mFirstKeyboardId) {
-                LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
-                        device->path.string(), mFirstKeyboardId);
-                mFirstKeyboardId = 0;
-                property_set("hw.keyboards.0.devname", NULL);
-            }
-            // clear the property
-            char propName[100];
-            sprintf(propName, "hw.keyboards.%u.devname", device->id);
-            property_set(propName, NULL);
-            return 0;
-        }
-    }
-    LOGE("remove device: %s not found\n", deviceName);
-    return -1;
-}
-
-int EventHub::readNotify(int nfd) {
-#ifdef HAVE_INOTIFY
-    int res;
-    char devname[PATH_MAX];
-    char *filename;
-    char event_buf[512];
-    int event_size;
-    int event_pos = 0;
-    struct inotify_event *event;
-
-    LOGV("EventHub::readNotify nfd: %d\n", nfd);
-    res = read(nfd, event_buf, sizeof(event_buf));
-    if(res < (int)sizeof(*event)) {
-        if(errno == EINTR)
-            return 0;
-        LOGW("could not get event, %s\n", strerror(errno));
-        return 1;
-    }
-    //printf("got %d bytes of event information\n", res);
-
-    strcpy(devname, device_path);
-    filename = devname + strlen(devname);
-    *filename++ = '/';
-
-    while(res >= (int)sizeof(*event)) {
-        event = (struct inotify_event *)(event_buf + event_pos);
-        //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
-        if(event->len) {
-            strcpy(filename, event->name);
-            if(event->mask & IN_CREATE) {
-                openDevice(devname);
-            }
-            else {
-                closeDevice(devname);
-            }
-        }
-        event_size = sizeof(*event) + event->len;
-        res -= event_size;
-        event_pos += event_size;
-    }
-#endif
-    return 0;
-}
-
-
-int EventHub::scanDir(const char *dirname)
-{
-    char devname[PATH_MAX];
-    char *filename;
-    DIR *dir;
-    struct dirent *de;
-    dir = opendir(dirname);
-    if(dir == NULL)
-        return -1;
-    strcpy(devname, dirname);
-    filename = devname + strlen(devname);
-    *filename++ = '/';
-    while((de = readdir(dir))) {
-        if(de->d_name[0] == '.' &&
-           (de->d_name[1] == '\0' ||
-            (de->d_name[1] == '.' && de->d_name[2] == '\0')))
-            continue;
-        strcpy(filename, de->d_name);
-        openDevice(devname);
-    }
-    closedir(dir);
-    return 0;
-}
-
-void EventHub::dump(String8& dump) {
-    dump.append("Event Hub State:\n");
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        dump.appendFormat(INDENT "HaveFirstKeyboard: %s\n", toString(mHaveFirstKeyboard));
-        dump.appendFormat(INDENT "FirstKeyboardId: 0x%x\n", mFirstKeyboardId);
-
-        dump.append(INDENT "Devices:\n");
-
-        for (int i = 0; i < mNumDevicesById; i++) {
-            const device_t* device = mDevicesById[i].device;
-            if (device) {
-                if (mFirstKeyboardId == device->id) {
-                    dump.appendFormat(INDENT2 "0x%x: %s (aka device 0 - first keyboard)\n",
-                            device->id, device->name.string());
-                } else {
-                    dump.appendFormat(INDENT2 "0x%x: %s\n", device->id, device->name.string());
-                }
-                dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
-                dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
-                dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n", device->keylayoutFilename.string());
-            }
-        }
-    } // release lock
-}
-
-}; // namespace android
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 04a0195..dc223f9 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -182,6 +182,16 @@
     return fb->setSwapInterval(fb, interval);
 }
 
+void FramebufferNativeWindow::dump(String8& result) {
+    if (fbDev->common.version >= 1 && fbDev->dump) {
+        const size_t SIZE = 4096;
+        char buffer[SIZE];
+
+        fbDev->dump(fbDev, buffer, SIZE);
+        result.append(buffer);
+    }
+}
+
 // only for debugging / logging
 int FramebufferNativeWindow::getCurrentBufferIndex() const
 {
@@ -276,6 +286,9 @@
         case NATIVE_WINDOW_FORMAT:
             *value = fb->format;
             return NO_ERROR;
+        case NATIVE_WINDOW_CONCRETE_TYPE:
+            *value = NATIVE_WINDOW_FRAMEBUFFER;
+            return NO_ERROR;
     }
     *value = 0;
     return BAD_VALUE;
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 3671954..97312a6 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -45,7 +45,6 @@
     stride = 
     format = 
     usage  = 0;
-    transform = 0;
     handle = NULL;
 }
 
@@ -58,8 +57,7 @@
     height = 
     stride = 
     format = 
-    usage  =
-    transform = 0;
+    usage  = 0;
     handle = NULL;
     mInitCheck = initSize(w, h, reqFormat, reqUsage);
 }
@@ -76,10 +74,22 @@
     stride = inStride;
     format = inFormat;
     usage  = inUsage;
-    transform = 0;
     handle = inHandle;
 }
 
+GraphicBuffer::GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership)
+    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
+      mBufferMapper(GraphicBufferMapper::get()),
+      mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer)
+{
+    width  = buffer->width;
+    height = buffer->height;
+    stride = buffer->stride;
+    format = buffer->format;
+    usage  = buffer->usage;
+    handle = buffer->handle;
+}
+
 GraphicBuffer::~GraphicBuffer()
 {
     if (handle) {
@@ -90,12 +100,14 @@
 void GraphicBuffer::free_handle()
 {
     if (mOwner == ownHandle) {
+        mBufferMapper.unregisterBuffer(handle);
         native_handle_close(handle);
         native_handle_delete(const_cast<native_handle*>(handle));
     } else if (mOwner == ownData) {
         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
         allocator.free(handle);
     }
+    mWrappedBuffer = 0;
 }
 
 status_t GraphicBuffer::initCheck() const {
@@ -185,10 +197,8 @@
     return res;
 }
 
-const int kFlattenFdsOffset = 9;
-
 size_t GraphicBuffer::getFlattenedSize() const {
-    return (kFlattenFdsOffset + (handle ? handle->numInts : 0))*sizeof(int);
+    return (8 + (handle ? handle->numInts : 0))*sizeof(int);
 }
 
 size_t GraphicBuffer::getFdCount() const {
@@ -213,14 +223,13 @@
     buf[5] = usage;
     buf[6] = 0;
     buf[7] = 0;
-    buf[8] = transform;
 
     if (handle) {
         buf[6] = handle->numFds;
         buf[7] = handle->numInts;
         native_handle_t const* const h = handle;
         memcpy(fds,     h->data,             h->numFds*sizeof(int));
-        memcpy(&buf[kFlattenFdsOffset], h->data + h->numFds, h->numInts*sizeof(int));
+        memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
     }
 
     return NO_ERROR;
@@ -229,7 +238,7 @@
 status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
         int fds[], size_t count)
 {
-    if (size < kFlattenFdsOffset*sizeof(int)) return NO_MEMORY;
+    if (size < 8*sizeof(int)) return NO_MEMORY;
 
     int const* buf = static_cast<int const*>(buffer);
     if (buf[0] != 'GBFR') return BAD_TYPE;
@@ -237,7 +246,7 @@
     const size_t numFds  = buf[6];
     const size_t numInts = buf[7];
 
-    const size_t sizeNeeded = (kFlattenFdsOffset + numInts) * sizeof(int);
+    const size_t sizeNeeded = (8 + numInts) * sizeof(int);
     if (size < sizeNeeded) return NO_MEMORY;
 
     size_t fdCountNeeded = 0;
@@ -254,10 +263,9 @@
         stride = buf[3];
         format = buf[4];
         usage  = buf[5];
-        transform = buf[8];
         native_handle* h = native_handle_create(numFds, numInts);
         memcpy(h->data,          fds,     numFds*sizeof(int));
-        memcpy(h->data + numFds, &buf[kFlattenFdsOffset], numInts*sizeof(int));
+        memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
         handle = h;
     } else {
         width = height = stride = format = usage = 0;
@@ -265,6 +273,11 @@
     }
 
     mOwner = ownHandle;
+
+    if (handle != 0) {
+        mBufferMapper.registerBuffer(handle);
+    }
+
     return NO_ERROR;
 }
 
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index fa46ab7..33ef1fc 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -24,8 +24,6 @@
 
 #include <ui/GraphicBufferAllocator.h>
 
-#include <private/ui/sw_gralloc_handle.h>
-
 namespace android {
 // ---------------------------------------------------------------------------
 
@@ -56,14 +54,14 @@
     Mutex::Autolock _l(sLock);
     KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
     size_t total = 0;
-    const size_t SIZE = 512;
+    const size_t SIZE = 4096;
     char buffer[SIZE];
     snprintf(buffer, SIZE, "Allocated buffers:\n");
     result.append(buffer);
     const size_t c = list.size();
     for (size_t i=0 ; i<c ; i++) {
         const alloc_rec_t& rec(list.valueAt(i));
-        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
+        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
             list.keyAt(i), rec.size/1024.0f, 
             rec.w, rec.s, rec.h, rec.format, rec.usage);
         result.append(buffer);
@@ -71,6 +69,10 @@
     }
     snprintf(buffer, SIZE, "Total allocated: %.2f KB\n", total/1024.0f);
     result.append(buffer);
+    if (mAllocDev->common.version >= 1 && mAllocDev->dump) {
+        mAllocDev->dump(mAllocDev, buffer, SIZE);
+        result.append(buffer);
+    }
 }
 
 void GraphicBufferAllocator::dumpToSystemLog()
@@ -91,11 +93,7 @@
     // we have a h/w allocator and h/w buffer is requested
     status_t err; 
     
-    if (usage & GRALLOC_USAGE_HW_MASK) {
-        err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
-    } else {
-        err = sw_gralloc_handle_t::alloc(w, h, format, usage, handle, stride);
-    }
+    err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
 
     LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
             w, h, format, usage, err, strerror(-err));
@@ -119,11 +117,8 @@
 status_t GraphicBufferAllocator::free(buffer_handle_t handle)
 {
     status_t err;
-    if (sw_gralloc_handle_t::validate(handle) < 0) {
-        err = mAllocDev->free(mAllocDev, handle);
-    } else {
-        err = sw_gralloc_handle_t::free((sw_gralloc_handle_t*)handle);
-    }
+
+    err = mAllocDev->free(mAllocDev, handle);
 
     LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
     if (err == NO_ERROR) {
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index ce2acd0..07c0674 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -17,15 +17,7 @@
 #define LOG_TAG "GraphicBufferMapper"
 
 #include <stdint.h>
-#ifdef HAVE_ANDROID_OS      // just want PAGE_SIZE define
-# include <asm/page.h>
-#else
-# include <sys/user.h>
-#endif
 #include <errno.h>
-#include <sys/mman.h>
-
-#include <cutils/ashmem.h>
 
 #include <utils/Errors.h>
 #include <utils/Log.h>
@@ -35,8 +27,6 @@
 
 #include <hardware/gralloc.h>
 
-#include <private/ui/sw_gralloc_handle.h>
-
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -57,11 +47,9 @@
 status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
 {
     status_t err;
-    if (sw_gralloc_handle_t::validate(handle) < 0) {
-        err = mAllocMod->registerBuffer(mAllocMod, handle);
-    } else {
-        err = sw_gralloc_handle_t::registerBuffer((sw_gralloc_handle_t*)handle);
-    }
+
+    err = mAllocMod->registerBuffer(mAllocMod, handle);
+
     LOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
             handle, err, strerror(-err));
     return err;
@@ -70,11 +58,9 @@
 status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
 {
     status_t err;
-    if (sw_gralloc_handle_t::validate(handle) < 0) {
-        err = mAllocMod->unregisterBuffer(mAllocMod, handle);
-    } else {
-        err = sw_gralloc_handle_t::unregisterBuffer((sw_gralloc_handle_t*)handle);
-    }
+
+    err = mAllocMod->unregisterBuffer(mAllocMod, handle);
+
     LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)",
             handle, err, strerror(-err));
     return err;
@@ -84,15 +70,11 @@
         int usage, const Rect& bounds, void** vaddr)
 {
     status_t err;
-    if (sw_gralloc_handle_t::validate(handle) < 0) {
-        err = mAllocMod->lock(mAllocMod, handle, usage,
-                bounds.left, bounds.top, bounds.width(), bounds.height(),
-                vaddr);
-    } else {
-        err = sw_gralloc_handle_t::lock((sw_gralloc_handle_t*)handle, usage,
-                bounds.left, bounds.top, bounds.width(), bounds.height(),
-                vaddr);
-    }
+
+    err = mAllocMod->lock(mAllocMod, handle, usage,
+            bounds.left, bounds.top, bounds.width(), bounds.height(),
+            vaddr);
+
     LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
     return err;
 }
@@ -100,129 +82,12 @@
 status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
 {
     status_t err;
-    if (sw_gralloc_handle_t::validate(handle) < 0) {
-        err = mAllocMod->unlock(mAllocMod, handle);
-    } else {
-        err = sw_gralloc_handle_t::unlock((sw_gralloc_handle_t*)handle);
-    }
+
+    err = mAllocMod->unlock(mAllocMod, handle);
+
     LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
     return err;
 }
 
 // ---------------------------------------------------------------------------
-
-status_t sw_gralloc_handle_t::alloc(uint32_t w, uint32_t h, int format,
-        int usage, buffer_handle_t* pHandle, int32_t* pStride)
-{
-    int align = 4;
-    int bpp = 0;
-    switch (format) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-            bpp = 4;
-            break;
-        case HAL_PIXEL_FORMAT_RGB_888:
-            bpp = 3;
-            break;
-        case HAL_PIXEL_FORMAT_RGB_565:
-        case HAL_PIXEL_FORMAT_RGBA_5551:
-        case HAL_PIXEL_FORMAT_RGBA_4444:
-            bpp = 2;
-            break;
-        default:
-            return -EINVAL;
-    }
-    size_t bpr = (w*bpp + (align-1)) & ~(align-1);
-    size_t size = bpr * h;
-    size_t stride = bpr / bpp;
-    size = (size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
-    
-    int fd = ashmem_create_region("sw-gralloc-buffer", size);
-    if (fd < 0) {
-        LOGE("ashmem_create_region(size=%d) failed (%s)",
-                size, strerror(-errno));
-        return -errno;
-    }
-    
-    int prot = PROT_READ;
-    if (usage & GRALLOC_USAGE_SW_WRITE_MASK)
-        prot |= PROT_WRITE;
-    
-    if (ashmem_set_prot_region(fd, prot) < 0) {
-        LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
-                fd, prot, strerror(-errno));
-        close(fd);
-        return -errno;
-    }
-
-    void* base = mmap(0, size, prot, MAP_SHARED, fd, 0);
-    if (base == MAP_FAILED) {
-        LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
-                fd, size, prot, strerror(-errno));
-        close(fd);
-        return -errno;
-    }
-
-    sw_gralloc_handle_t* hnd = new sw_gralloc_handle_t();
-    hnd->fd = fd;
-    hnd->size = size;
-    hnd->base = intptr_t(base);
-    hnd->prot = prot;
-    *pStride = stride;
-    *pHandle = hnd; 
-    
-    return NO_ERROR;
-}
-
-status_t sw_gralloc_handle_t::free(sw_gralloc_handle_t* hnd)
-{
-    if (hnd->base) {
-        munmap((void*)hnd->base, hnd->size);
-    }
-    if (hnd->fd >= 0) {
-        close(hnd->fd);
-    }
-    delete hnd;    
-    return NO_ERROR;
-}
-
-status_t sw_gralloc_handle_t::registerBuffer(sw_gralloc_handle_t* hnd)
-{
-    if (hnd->pid != getpid()) {
-        void* base = mmap(0, hnd->size, hnd->prot, MAP_SHARED, hnd->fd, 0);
-        if (base == MAP_FAILED) {
-            LOGE("registerBuffer mmap(fd=%d, size=%d, prot=%x) failed (%s)",
-                    hnd->fd, hnd->size, hnd->prot, strerror(-errno));
-            return -errno;
-        }
-        hnd->base = intptr_t(base);
-    }
-    return NO_ERROR;
-}
-
-status_t sw_gralloc_handle_t::unregisterBuffer(sw_gralloc_handle_t* hnd)
-{
-    if (hnd->pid != getpid()) {
-        if (hnd->base) {
-            munmap((void*)hnd->base, hnd->size);
-        }
-        hnd->base = 0;
-    }
-    return NO_ERROR;
-}
-
-status_t sw_gralloc_handle_t::lock(sw_gralloc_handle_t* hnd, int usage,
-        int l, int t, int w, int h, void** vaddr)
-{
-    *vaddr = (void*)hnd->base;
-    return NO_ERROR;
-}
-
-status_t sw_gralloc_handle_t::unlock(sw_gralloc_handle_t* hnd)
-{
-    return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/ui/IOverlay.cpp b/libs/ui/IOverlay.cpp
deleted file mode 100644
index 65e6b4f..0000000
--- a/libs/ui/IOverlay.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IInterface.h>
-
-#include <ui/IOverlay.h>
-
-namespace android {
-
-enum {
-    DESTROY = IBinder::FIRST_CALL_TRANSACTION, // one-way transaction
-};
-
-class BpOverlay : public BpInterface<IOverlay>
-{
-public:
-    BpOverlay(const sp<IBinder>& impl)
-        : BpInterface<IOverlay>(impl)
-    {
-    }
-
-    virtual void destroy()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IOverlay::getInterfaceDescriptor());
-        remote()->transact(DESTROY, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(Overlay, "android.ui.IOverlay");
-
-// ----------------------------------------------------------------------
-
-status_t BnOverlay::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case DESTROY: {
-            CHECK_INTERFACE(IOverlay, data, reply);
-            destroy();
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-}; // namespace android
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 811edaf..e2e698e 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -7,11 +7,127 @@
 
 //#define LOG_NDEBUG 0
 
+#define DEBUG_PROBE 0
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+
 #include <ui/Input.h>
 
+#include <math.h>
+
+#ifdef HAVE_ANDROID_OS
+#include <binder/Parcel.h>
+
+#include "SkPoint.h"
+#include "SkMatrix.h"
+#include "SkScalar.h"
+#endif
+
 namespace android {
 
-// class InputEvent
+static const char* CONFIGURATION_FILE_DIR[] = {
+        "idc/",
+        "keylayout/",
+        "keychars/",
+};
+
+static const char* CONFIGURATION_FILE_EXTENSION[] = {
+        ".idc",
+        ".kl",
+        ".kcm",
+};
+
+static bool isValidNameChar(char ch) {
+    return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
+}
+
+static void appendInputDeviceConfigurationFileRelativePath(String8& path,
+        const String8& name, InputDeviceConfigurationFileType type) {
+    path.append(CONFIGURATION_FILE_DIR[type]);
+    for (size_t i = 0; i < name.length(); i++) {
+        char ch = name[i];
+        if (!isValidNameChar(ch)) {
+            ch = '_';
+        }
+        path.append(&ch, 1);
+    }
+    path.append(CONFIGURATION_FILE_EXTENSION[type]);
+}
+
+String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
+        const InputDeviceIdentifier& deviceIdentifier,
+        InputDeviceConfigurationFileType type) {
+    if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
+        if (deviceIdentifier.version != 0) {
+            // Try vendor product version.
+            String8 versionPath(getInputDeviceConfigurationFilePathByName(
+                    String8::format("Vendor_%04x_Product_%04x_Version_%04x",
+                            deviceIdentifier.vendor, deviceIdentifier.product,
+                            deviceIdentifier.version),
+                    type));
+            if (!versionPath.isEmpty()) {
+                return versionPath;
+            }
+        }
+
+        // Try vendor product.
+        String8 productPath(getInputDeviceConfigurationFilePathByName(
+                String8::format("Vendor_%04x_Product_%04x",
+                        deviceIdentifier.vendor, deviceIdentifier.product),
+                type));
+        if (!productPath.isEmpty()) {
+            return productPath;
+        }
+    }
+
+    // Try device name.
+    return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
+}
+
+String8 getInputDeviceConfigurationFilePathByName(
+        const String8& name, InputDeviceConfigurationFileType type) {
+    // Search system repository.
+    String8 path;
+    path.setTo(getenv("ANDROID_ROOT"));
+    path.append("/usr/");
+    appendInputDeviceConfigurationFileRelativePath(path, name, type);
+#if DEBUG_PROBE
+    LOGD("Probing for system provided input device configuration file: path='%s'", path.string());
+#endif
+    if (!access(path.string(), R_OK)) {
+#if DEBUG_PROBE
+        LOGD("Found");
+#endif
+        return path;
+    }
+
+    // Search user repository.
+    // TODO Should only look here if not in safe mode.
+    path.setTo(getenv("ANDROID_DATA"));
+    path.append("/system/devices/");
+    appendInputDeviceConfigurationFileRelativePath(path, name, type);
+#if DEBUG_PROBE
+    LOGD("Probing for system user input device configuration file: path='%s'", path.string());
+#endif
+    if (!access(path.string(), R_OK)) {
+#if DEBUG_PROBE
+        LOGD("Found");
+#endif
+        return path;
+    }
+
+    // Not found.
+#if DEBUG_PROBE
+    LOGD("Probe failed to find input device configuration file: name='%s', type=%d",
+            name.string(), type);
+#endif
+    return String8();
+}
+
+
+// --- InputEvent ---
 
 void InputEvent::initialize(int32_t deviceId, int32_t source) {
     mDeviceId = deviceId;
@@ -23,7 +139,7 @@
     mSource = from.mSource;
 }
 
-// class KeyEvent
+// --- KeyEvent ---
 
 bool KeyEvent::hasDefaultAction(int32_t keyCode) {
     switch (keyCode) {
@@ -33,6 +149,7 @@
         case AKEYCODE_ENDCALL:
         case AKEYCODE_VOLUME_UP:
         case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_VOLUME_MUTE:
         case AKEYCODE_POWER:
         case AKEYCODE_CAMERA:
         case AKEYCODE_HEADSETHOOK:
@@ -40,11 +157,14 @@
         case AKEYCODE_NOTIFICATION:
         case AKEYCODE_FOCUS:
         case AKEYCODE_SEARCH:
+        case AKEYCODE_MEDIA_PLAY:
+        case AKEYCODE_MEDIA_PAUSE:
         case AKEYCODE_MEDIA_PLAY_PAUSE:
         case AKEYCODE_MEDIA_STOP:
         case AKEYCODE_MEDIA_NEXT:
         case AKEYCODE_MEDIA_PREVIOUS:
         case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_RECORD:
         case AKEYCODE_MEDIA_FAST_FORWARD:
         case AKEYCODE_MUTE:
             return true;
@@ -67,14 +187,18 @@
         case AKEYCODE_ENDCALL:
         case AKEYCODE_VOLUME_UP:
         case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_VOLUME_MUTE:
         case AKEYCODE_MUTE:
         case AKEYCODE_POWER:
         case AKEYCODE_HEADSETHOOK:
+        case AKEYCODE_MEDIA_PLAY:
+        case AKEYCODE_MEDIA_PAUSE:
         case AKEYCODE_MEDIA_PLAY_PAUSE:
         case AKEYCODE_MEDIA_STOP:
         case AKEYCODE_MEDIA_NEXT:
         case AKEYCODE_MEDIA_PREVIOUS:
         case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_RECORD:
         case AKEYCODE_MEDIA_FAST_FORWARD:
         case AKEYCODE_CAMERA:
         case AKEYCODE_FOCUS:
@@ -123,7 +247,90 @@
     mEventTime = from.mEventTime;
 }
 
-// class MotionEvent
+
+// --- PointerCoords ---
+
+float PointerCoords::getAxisValue(int32_t axis) const {
+    if (axis < 0 || axis > 63) {
+        return 0;
+    }
+
+    uint64_t axisBit = 1LL << axis;
+    if (!(bits & axisBit)) {
+        return 0;
+    }
+    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+    return values[index];
+}
+
+status_t PointerCoords::setAxisValue(int32_t axis, float value) {
+    if (axis < 0 || axis > 63) {
+        return NAME_NOT_FOUND;
+    }
+
+    uint64_t axisBit = 1LL << axis;
+    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+    if (!(bits & axisBit)) {
+        uint32_t count = __builtin_popcountll(bits);
+        if (count >= MAX_AXES) {
+            tooManyAxes(axis);
+            return NO_MEMORY;
+        }
+        bits |= axisBit;
+        for (uint32_t i = count; i > index; i--) {
+            values[i] = values[i - 1];
+        }
+    }
+    values[index] = value;
+    return OK;
+}
+
+float* PointerCoords::editAxisValue(int32_t axis) {
+    if (axis < 0 || axis > 63) {
+        return NULL;
+    }
+
+    uint64_t axisBit = 1LL << axis;
+    if (!(bits & axisBit)) {
+        return NULL;
+    }
+    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+    return &values[index];
+}
+
+#ifdef HAVE_ANDROID_OS
+status_t PointerCoords::readFromParcel(Parcel* parcel) {
+    bits = parcel->readInt64();
+
+    uint32_t count = __builtin_popcountll(bits);
+    if (count > MAX_AXES) {
+        return BAD_VALUE;
+    }
+
+    for (uint32_t i = 0; i < count; i++) {
+        values[i] = parcel->readInt32();
+    }
+    return OK;
+}
+
+status_t PointerCoords::writeToParcel(Parcel* parcel) const {
+    parcel->writeInt64(bits);
+
+    uint32_t count = __builtin_popcountll(bits);
+    for (uint32_t i = 0; i < count; i++) {
+        parcel->writeInt32(values[i]);
+    }
+    return OK;
+}
+#endif
+
+void PointerCoords::tooManyAxes(int axis) {
+    LOGW("Could not set value for axis %d because the PointerCoords structure is full and "
+            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
+}
+
+
+// --- MotionEvent ---
 
 void MotionEvent::initialize(
         int32_t deviceId,
@@ -158,6 +365,33 @@
     addSample(eventTime, pointerCoords);
 }
 
+void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
+    InputEvent::initialize(other->mDeviceId, other->mSource);
+    mAction = other->mAction;
+    mFlags = other->mFlags;
+    mEdgeFlags = other->mEdgeFlags;
+    mMetaState = other->mMetaState;
+    mXOffset = other->mXOffset;
+    mYOffset = other->mYOffset;
+    mXPrecision = other->mXPrecision;
+    mYPrecision = other->mYPrecision;
+    mDownTime = other->mDownTime;
+    mPointerIds = other->mPointerIds;
+
+    if (keepHistory) {
+        mSampleEventTimes = other->mSampleEventTimes;
+        mSamplePointerCoords = other->mSamplePointerCoords;
+    } else {
+        mSampleEventTimes.clear();
+        mSampleEventTimes.push(other->getEventTime());
+        mSamplePointerCoords.clear();
+        size_t pointerCount = other->getPointerCount();
+        size_t historySize = other->getHistorySize();
+        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
+                + (historySize * pointerCount), pointerCount);
+    }
+}
+
 void MotionEvent::addSample(
         int64_t eventTime,
         const PointerCoords* pointerCoords) {
@@ -165,12 +399,242 @@
     mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
 }
 
+const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
+    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+}
+
+float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
+    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
+}
+
+float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
+    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
+    switch (axis) {
+    case AMOTION_EVENT_AXIS_X:
+        value += mXOffset;
+        break;
+    case AMOTION_EVENT_AXIS_Y:
+        value += mYOffset;
+        break;
+    }
+    return value;
+}
+
+const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
+        size_t pointerIndex, size_t historicalIndex) const {
+    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+}
+
+float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
+        size_t historicalIndex) const {
+    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
+}
+
+float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
+        size_t historicalIndex) const {
+    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
+    switch (axis) {
+    case AMOTION_EVENT_AXIS_X:
+        value += mXOffset;
+        break;
+    case AMOTION_EVENT_AXIS_Y:
+        value += mYOffset;
+        break;
+    }
+    return value;
+}
+
 void MotionEvent::offsetLocation(float xOffset, float yOffset) {
     mXOffset += xOffset;
     mYOffset += yOffset;
 }
 
-// class InputDeviceInfo
+static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
+    float* value = c.editAxisValue(axis);
+    if (value) {
+        *value *= scaleFactor;
+    }
+}
+
+void MotionEvent::scale(float scaleFactor) {
+    mXOffset *= scaleFactor;
+    mYOffset *= scaleFactor;
+    mXPrecision *= scaleFactor;
+    mYPrecision *= scaleFactor;
+
+    size_t numSamples = mSamplePointerCoords.size();
+    for (size_t i = 0; i < numSamples; i++) {
+        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
+        // No need to scale pressure or size since they are normalized.
+        // No need to scale orientation since it is meaningless to do so.
+        scaleAxisValue(c, AMOTION_EVENT_AXIS_X, scaleFactor);
+        scaleAxisValue(c, AMOTION_EVENT_AXIS_Y, scaleFactor);
+        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
+        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
+        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
+        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
+    }
+}
+
+#ifdef HAVE_ANDROID_OS
+static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
+    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
+    // Coordinate system: down is increasing Y, right is increasing X.
+    SkPoint vector;
+    vector.fX = SkFloatToScalar(sinf(angleRadians));
+    vector.fY = SkFloatToScalar(-cosf(angleRadians));
+    matrix->mapVectors(& vector, 1);
+
+    // Derive the transformed vector's clockwise angle from vertical.
+    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
+    if (result < - M_PI_2) {
+        result += M_PI;
+    } else if (result > M_PI_2) {
+        result -= M_PI;
+    }
+    return result;
+}
+
+void MotionEvent::transform(const SkMatrix* matrix) {
+    float oldXOffset = mXOffset;
+    float oldYOffset = mYOffset;
+
+    // The tricky part of this implementation is to preserve the value of
+    // rawX and rawY.  So we apply the transformation to the first point
+    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
+    SkPoint point;
+    float rawX = getRawX(0);
+    float rawY = getRawY(0);
+    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
+            & point);
+    float newX = SkScalarToFloat(point.fX);
+    float newY = SkScalarToFloat(point.fY);
+    float newXOffset = newX - rawX;
+    float newYOffset = newY - rawY;
+
+    mXOffset = newXOffset;
+    mYOffset = newYOffset;
+
+    // Apply the transformation to all samples.
+    size_t numSamples = mSamplePointerCoords.size();
+    for (size_t i = 0; i < numSamples; i++) {
+        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
+        float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X);
+        float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y);
+        if (xPtr && yPtr) {
+            float x = *xPtr + oldXOffset;
+            float y = *yPtr + oldYOffset;
+            matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
+            *xPtr = SkScalarToFloat(point.fX) - newXOffset;
+            *yPtr = SkScalarToFloat(point.fY) - newYOffset;
+        }
+
+        float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
+        if (orientationPtr) {
+            *orientationPtr = transformAngle(matrix, *orientationPtr);
+        }
+    }
+}
+
+status_t MotionEvent::readFromParcel(Parcel* parcel) {
+    size_t pointerCount = parcel->readInt32();
+    size_t sampleCount = parcel->readInt32();
+    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
+        return BAD_VALUE;
+    }
+
+    mDeviceId = parcel->readInt32();
+    mSource = parcel->readInt32();
+    mAction = parcel->readInt32();
+    mFlags = parcel->readInt32();
+    mEdgeFlags = parcel->readInt32();
+    mMetaState = parcel->readInt32();
+    mXOffset = parcel->readFloat();
+    mYOffset = parcel->readFloat();
+    mXPrecision = parcel->readFloat();
+    mYPrecision = parcel->readFloat();
+    mDownTime = parcel->readInt64();
+
+    mPointerIds.clear();
+    mPointerIds.setCapacity(pointerCount);
+    mSampleEventTimes.clear();
+    mSampleEventTimes.setCapacity(sampleCount);
+    mSamplePointerCoords.clear();
+    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        mPointerIds.push(parcel->readInt32());
+    }
+
+    while (sampleCount-- > 0) {
+        mSampleEventTimes.push(parcel->readInt64());
+        for (size_t i = 0; i < pointerCount; i++) {
+            mSamplePointerCoords.push();
+            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
+            if (status) {
+                return status;
+            }
+        }
+    }
+    return OK;
+}
+
+status_t MotionEvent::writeToParcel(Parcel* parcel) const {
+    size_t pointerCount = mPointerIds.size();
+    size_t sampleCount = mSampleEventTimes.size();
+
+    parcel->writeInt32(pointerCount);
+    parcel->writeInt32(sampleCount);
+
+    parcel->writeInt32(mDeviceId);
+    parcel->writeInt32(mSource);
+    parcel->writeInt32(mAction);
+    parcel->writeInt32(mFlags);
+    parcel->writeInt32(mEdgeFlags);
+    parcel->writeInt32(mMetaState);
+    parcel->writeFloat(mXOffset);
+    parcel->writeFloat(mYOffset);
+    parcel->writeFloat(mXPrecision);
+    parcel->writeFloat(mYPrecision);
+    parcel->writeInt64(mDownTime);
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        parcel->writeInt32(mPointerIds.itemAt(i));
+    }
+
+    const PointerCoords* pc = mSamplePointerCoords.array();
+    for (size_t h = 0; h < sampleCount; h++) {
+        parcel->writeInt64(mSampleEventTimes.itemAt(h));
+        for (size_t i = 0; i < pointerCount; i++) {
+            status_t status = (pc++)->writeToParcel(parcel);
+            if (status) {
+                return status;
+            }
+        }
+    }
+    return OK;
+}
+#endif
+
+bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
+    if (source & AINPUT_SOURCE_CLASS_POINTER) {
+        // Specifically excludes HOVER_MOVE and SCROLL.
+        switch (action & AMOTION_EVENT_ACTION_MASK) {
+        case AMOTION_EVENT_ACTION_DOWN:
+        case AMOTION_EVENT_ACTION_MOVE:
+        case AMOTION_EVENT_ACTION_UP:
+        case AMOTION_EVENT_ACTION_POINTER_DOWN:
+        case AMOTION_EVENT_ACTION_POINTER_UP:
+        case AMOTION_EVENT_ACTION_CANCEL:
+        case AMOTION_EVENT_ACTION_OUTSIDE:
+            return true;
+        }
+    }
+    return false;
+}
+
+
+// --- InputDeviceInfo ---
 
 InputDeviceInfo::InputDeviceInfo() {
     initialize(-1, String8("uninitialized device info"));
@@ -193,23 +657,30 @@
     mMotionRanges.clear();
 }
 
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t rangeType) const {
-    ssize_t index = mMotionRanges.indexOfKey(rangeType);
-    return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
+const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
+        int32_t axis, uint32_t source) const {
+    size_t numRanges = mMotionRanges.size();
+    for (size_t i = 0; i < numRanges; i++) {
+        const MotionRange& range = mMotionRanges.itemAt(i);
+        if (range.axis == axis && range.source == source) {
+            return &range;
+        }
+    }
+    return NULL;
 }
 
 void InputDeviceInfo::addSource(uint32_t source) {
     mSources |= source;
 }
 
-void InputDeviceInfo::addMotionRange(int32_t rangeType, float min, float max,
+void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
         float flat, float fuzz) {
-    MotionRange range = { min, max, flat, fuzz };
-    addMotionRange(rangeType, range);
+    MotionRange range = { axis, source, min, max, flat, fuzz };
+    mMotionRanges.add(range);
 }
 
-void InputDeviceInfo::addMotionRange(int32_t rangeType, const MotionRange& range) {
-    mMotionRanges.add(rangeType, range);
+void InputDeviceInfo::addMotionRange(const MotionRange& range) {
+    mMotionRanges.add(range);
 }
 
 } // namespace android
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
deleted file mode 100644
index 46baf9d..0000000
--- a/libs/ui/InputDispatcher.cpp
+++ /dev/null
@@ -1,3520 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// The input dispatcher.
-//
-#define LOG_TAG "InputDispatcher"
-
-//#define LOG_NDEBUG 0
-
-// Log detailed debug messages about each inbound event notification to the dispatcher.
-#define DEBUG_INBOUND_EVENT_DETAILS 0
-
-// Log detailed debug messages about each outbound event processed by the dispatcher.
-#define DEBUG_OUTBOUND_EVENT_DETAILS 0
-
-// Log debug messages about batching.
-#define DEBUG_BATCHING 0
-
-// Log debug messages about the dispatch cycle.
-#define DEBUG_DISPATCH_CYCLE 0
-
-// Log debug messages about registrations.
-#define DEBUG_REGISTRATION 0
-
-// Log debug messages about performance statistics.
-#define DEBUG_PERFORMANCE_STATISTICS 0
-
-// Log debug messages about input event injection.
-#define DEBUG_INJECTION 0
-
-// Log debug messages about input event throttling.
-#define DEBUG_THROTTLING 0
-
-// Log debug messages about input focus tracking.
-#define DEBUG_FOCUS 0
-
-// Log debug messages about the app switch latency optimization.
-#define DEBUG_APP_SWITCH 0
-
-#include <cutils/log.h>
-#include <ui/InputDispatcher.h>
-#include <ui/PowerManager.h>
-
-#include <stddef.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-
-#define INDENT "  "
-#define INDENT2 "    "
-
-namespace android {
-
-// Delay before reporting long touch events to the power manager.
-const nsecs_t LONG_TOUCH_DELAY = 300 * 1000000LL; // 300 ms
-
-// Default input dispatching timeout if there is no focused application or paused window
-// from which to determine an appropriate dispatching timeout.
-const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
-
-// Amount of time to allow for all pending events to be processed when an app switch
-// key is on the way.  This is used to preempt input dispatch and drop input events
-// when an application takes too long to respond and the user has pressed an app switch key.
-const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
-
-
-static inline nsecs_t now() {
-    return systemTime(SYSTEM_TIME_MONOTONIC);
-}
-
-static inline const char* toString(bool value) {
-    return value ? "true" : "false";
-}
-
-static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
-    return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
-            >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-}
-
-static bool isValidKeyAction(int32_t action) {
-    switch (action) {
-    case AKEY_EVENT_ACTION_DOWN:
-    case AKEY_EVENT_ACTION_UP:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static bool validateKeyEvent(int32_t action) {
-    if (! isValidKeyAction(action)) {
-        LOGE("Key event has invalid action code 0x%x", action);
-        return false;
-    }
-    return true;
-}
-
-static bool isValidMotionAction(int32_t action, size_t pointerCount) {
-    switch (action & AMOTION_EVENT_ACTION_MASK) {
-    case AMOTION_EVENT_ACTION_DOWN:
-    case AMOTION_EVENT_ACTION_UP:
-    case AMOTION_EVENT_ACTION_CANCEL:
-    case AMOTION_EVENT_ACTION_MOVE:
-    case AMOTION_EVENT_ACTION_OUTSIDE:
-        return true;
-    case AMOTION_EVENT_ACTION_POINTER_DOWN:
-    case AMOTION_EVENT_ACTION_POINTER_UP: {
-        int32_t index = getMotionEventActionPointerIndex(action);
-        return index >= 0 && size_t(index) < pointerCount;
-    }
-    default:
-        return false;
-    }
-}
-
-static bool validateMotionEvent(int32_t action, size_t pointerCount,
-        const int32_t* pointerIds) {
-    if (! isValidMotionAction(action, pointerCount)) {
-        LOGE("Motion event has invalid action code 0x%x", action);
-        return false;
-    }
-    if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
-        LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
-                pointerCount, MAX_POINTERS);
-        return false;
-    }
-    BitSet32 pointerIdBits;
-    for (size_t i = 0; i < pointerCount; i++) {
-        int32_t id = pointerIds[i];
-        if (id < 0 || id > MAX_POINTER_ID) {
-            LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
-                    id, MAX_POINTER_ID);
-            return false;
-        }
-        if (pointerIdBits.hasBit(id)) {
-            LOGE("Motion event has duplicate pointer id %d", id);
-            return false;
-        }
-        pointerIdBits.markBit(id);
-    }
-    return true;
-}
-
-
-// --- InputWindow ---
-
-bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
-    return x >= touchableAreaLeft && x <= touchableAreaRight
-            && y >= touchableAreaTop && y <= touchableAreaBottom;
-}
-
-bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
-    return x >= frameLeft && x <= frameRight
-            && y >= frameTop && y <= frameBottom;
-}
-
-bool InputWindow::isTrustedOverlay() const {
-    return layoutParamsType == TYPE_INPUT_METHOD
-            || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
-            || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
-}
-
-
-// --- InputDispatcher ---
-
-InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
-    mPolicy(policy),
-    mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
-    mDispatchEnabled(true), mDispatchFrozen(false),
-    mFocusedWindow(NULL),
-    mFocusedApplication(NULL),
-    mCurrentInputTargetsValid(false),
-    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
-    mLooper = new Looper(false);
-
-    mInboundQueue.headSentinel.refCount = -1;
-    mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
-    mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
-
-    mInboundQueue.tailSentinel.refCount = -1;
-    mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
-    mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
-
-    mKeyRepeatState.lastKeyEntry = NULL;
-
-    int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
-    mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
-    mThrottleState.lastDeviceId = -1;
-
-#if DEBUG_THROTTLING
-    mThrottleState.originalSampleCount = 0;
-    LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
-#endif
-}
-
-InputDispatcher::~InputDispatcher() {
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        resetKeyRepeatLocked();
-        releasePendingEventLocked();
-        drainInboundQueueLocked();
-    }
-
-    while (mConnectionsByReceiveFd.size() != 0) {
-        unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
-    }
-}
-
-void InputDispatcher::dispatchOnce() {
-    nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
-    nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
-
-    nsecs_t nextWakeupTime = LONG_LONG_MAX;
-    { // acquire lock
-        AutoMutex _l(mLock);
-        dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
-
-        if (runCommandsLockedInterruptible()) {
-            nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
-        }
-    } // release lock
-
-    // Wait for callback or timeout or wake.  (make sure we round up, not down)
-    nsecs_t currentTime = now();
-    int32_t timeoutMillis;
-    if (nextWakeupTime > currentTime) {
-        uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
-        timeout = (timeout + 999999LL) / 1000000LL;
-        timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
-    } else {
-        timeoutMillis = 0;
-    }
-
-    mLooper->pollOnce(timeoutMillis);
-}
-
-void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
-        nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
-    nsecs_t currentTime = now();
-
-    // Reset the key repeat timer whenever we disallow key events, even if the next event
-    // is not a key.  This is to ensure that we abort a key repeat if the device is just coming
-    // out of sleep.
-    if (keyRepeatTimeout < 0) {
-        resetKeyRepeatLocked();
-    }
-
-    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
-    if (mDispatchFrozen) {
-#if DEBUG_FOCUS
-        LOGD("Dispatch frozen.  Waiting some more.");
-#endif
-        return;
-    }
-
-    // Optimize latency of app switches.
-    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
-    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
-    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
-    if (mAppSwitchDueTime < *nextWakeupTime) {
-        *nextWakeupTime = mAppSwitchDueTime;
-    }
-
-    // Ready to start a new event.
-    // If we don't already have a pending event, go grab one.
-    if (! mPendingEvent) {
-        if (mInboundQueue.isEmpty()) {
-            if (isAppSwitchDue) {
-                // The inbound queue is empty so the app switch key we were waiting
-                // for will never arrive.  Stop waiting for it.
-                resetPendingAppSwitchLocked(false);
-                isAppSwitchDue = false;
-            }
-
-            // Synthesize a key repeat if appropriate.
-            if (mKeyRepeatState.lastKeyEntry) {
-                if (currentTime >= mKeyRepeatState.nextRepeatTime) {
-                    mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
-                } else {
-                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
-                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
-                    }
-                }
-            }
-            if (! mPendingEvent) {
-                return;
-            }
-        } else {
-            // Inbound queue has at least one entry.
-            EventEntry* entry = mInboundQueue.headSentinel.next;
-
-            // Throttle the entry if it is a move event and there are no
-            // other events behind it in the queue.  Due to movement batching, additional
-            // samples may be appended to this event by the time the throttling timeout
-            // expires.
-            // TODO Make this smarter and consider throttling per device independently.
-            if (entry->type == EventEntry::TYPE_MOTION
-                    && !isAppSwitchDue
-                    && mDispatchEnabled
-                    && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
-                    && !entry->isInjected()) {
-                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
-                int32_t deviceId = motionEntry->deviceId;
-                uint32_t source = motionEntry->source;
-                if (! isAppSwitchDue
-                        && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
-                        && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
-                        && deviceId == mThrottleState.lastDeviceId
-                        && source == mThrottleState.lastSource) {
-                    nsecs_t nextTime = mThrottleState.lastEventTime
-                            + mThrottleState.minTimeBetweenEvents;
-                    if (currentTime < nextTime) {
-                        // Throttle it!
-#if DEBUG_THROTTLING
-                        LOGD("Throttling - Delaying motion event for "
-                                "device 0x%x, source 0x%08x by up to %0.3fms.",
-                                deviceId, source, (nextTime - currentTime) * 0.000001);
-#endif
-                        if (nextTime < *nextWakeupTime) {
-                            *nextWakeupTime = nextTime;
-                        }
-                        if (mThrottleState.originalSampleCount == 0) {
-                            mThrottleState.originalSampleCount =
-                                    motionEntry->countSamples();
-                        }
-                        return;
-                    }
-                }
-
-#if DEBUG_THROTTLING
-                if (mThrottleState.originalSampleCount != 0) {
-                    uint32_t count = motionEntry->countSamples();
-                    LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
-                            count - mThrottleState.originalSampleCount,
-                            mThrottleState.originalSampleCount, count);
-                    mThrottleState.originalSampleCount = 0;
-                }
-#endif
-
-                mThrottleState.lastEventTime = entry->eventTime < currentTime
-                        ? entry->eventTime : currentTime;
-                mThrottleState.lastDeviceId = deviceId;
-                mThrottleState.lastSource = source;
-            }
-
-            mInboundQueue.dequeue(entry);
-            mPendingEvent = entry;
-        }
-
-        // Poke user activity for this event.
-        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
-            pokeUserActivityLocked(mPendingEvent);
-        }
-    }
-
-    // Now we have an event to dispatch.
-    assert(mPendingEvent != NULL);
-    bool done = false;
-    DropReason dropReason = DROP_REASON_NOT_DROPPED;
-    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
-        dropReason = DROP_REASON_POLICY;
-    } else if (!mDispatchEnabled) {
-        dropReason = DROP_REASON_DISABLED;
-    }
-    switch (mPendingEvent->type) {
-    case EventEntry::TYPE_CONFIGURATION_CHANGED: {
-        ConfigurationChangedEntry* typedEntry =
-                static_cast<ConfigurationChangedEntry*>(mPendingEvent);
-        done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
-        dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
-        break;
-    }
-
-    case EventEntry::TYPE_KEY: {
-        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
-        if (isAppSwitchDue) {
-            if (isAppSwitchKeyEventLocked(typedEntry)) {
-                resetPendingAppSwitchLocked(true);
-                isAppSwitchDue = false;
-            } else if (dropReason == DROP_REASON_NOT_DROPPED) {
-                dropReason = DROP_REASON_APP_SWITCH;
-            }
-        }
-        done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
-                &dropReason, nextWakeupTime);
-        break;
-    }
-
-    case EventEntry::TYPE_MOTION: {
-        MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
-        if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
-            dropReason = DROP_REASON_APP_SWITCH;
-        }
-        done = dispatchMotionLocked(currentTime, typedEntry,
-                &dropReason, nextWakeupTime);
-        break;
-    }
-
-    default:
-        assert(false);
-        break;
-    }
-
-    if (done) {
-        if (dropReason != DROP_REASON_NOT_DROPPED) {
-            dropInboundEventLocked(mPendingEvent, dropReason);
-        }
-
-        releasePendingEventLocked();
-        *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
-    }
-}
-
-bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
-    bool needWake = mInboundQueue.isEmpty();
-    mInboundQueue.enqueueAtTail(entry);
-
-    switch (entry->type) {
-    case EventEntry::TYPE_KEY: {
-        KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
-        if (isAppSwitchKeyEventLocked(keyEntry)) {
-            if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
-                mAppSwitchSawKeyDown = true;
-            } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
-                if (mAppSwitchSawKeyDown) {
-#if DEBUG_APP_SWITCH
-                    LOGD("App switch is pending!");
-#endif
-                    mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
-                    mAppSwitchSawKeyDown = false;
-                    needWake = true;
-                }
-            }
-        }
-        break;
-    }
-    }
-
-    return needWake;
-}
-
-void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
-    const char* reason;
-    switch (dropReason) {
-    case DROP_REASON_POLICY:
-#if DEBUG_INBOUND_EVENT_DETAILS
-        LOGD("Dropped event because policy consumed it.");
-#endif
-        reason = "inbound event was dropped because the policy consumed it";
-        break;
-    case DROP_REASON_DISABLED:
-        LOGI("Dropped event because input dispatch is disabled.");
-        reason = "inbound event was dropped because input dispatch is disabled";
-        break;
-    case DROP_REASON_APP_SWITCH:
-        LOGI("Dropped event because of pending overdue app switch.");
-        reason = "inbound event was dropped because of pending overdue app switch";
-        break;
-    default:
-        assert(false);
-        return;
-    }
-
-    switch (entry->type) {
-    case EventEntry::TYPE_KEY:
-        synthesizeCancelationEventsForAllConnectionsLocked(
-                InputState::CANCEL_NON_POINTER_EVENTS, reason);
-        break;
-    case EventEntry::TYPE_MOTION: {
-        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
-        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
-            synthesizeCancelationEventsForAllConnectionsLocked(
-                    InputState::CANCEL_POINTER_EVENTS, reason);
-        } else {
-            synthesizeCancelationEventsForAllConnectionsLocked(
-                    InputState::CANCEL_NON_POINTER_EVENTS, reason);
-        }
-        break;
-    }
-    }
-}
-
-bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
-    return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
-}
-
-bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
-    return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
-            && isAppSwitchKeyCode(keyEntry->keyCode)
-            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
-            && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
-}
-
-bool InputDispatcher::isAppSwitchPendingLocked() {
-    return mAppSwitchDueTime != LONG_LONG_MAX;
-}
-
-void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
-    mAppSwitchDueTime = LONG_LONG_MAX;
-
-#if DEBUG_APP_SWITCH
-    if (handled) {
-        LOGD("App switch has arrived.");
-    } else {
-        LOGD("App switch was abandoned.");
-    }
-#endif
-}
-
-bool InputDispatcher::runCommandsLockedInterruptible() {
-    if (mCommandQueue.isEmpty()) {
-        return false;
-    }
-
-    do {
-        CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
-
-        Command command = commandEntry->command;
-        (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
-
-        commandEntry->connection.clear();
-        mAllocator.releaseCommandEntry(commandEntry);
-    } while (! mCommandQueue.isEmpty());
-    return true;
-}
-
-InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
-    CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
-    mCommandQueue.enqueueAtTail(commandEntry);
-    return commandEntry;
-}
-
-void InputDispatcher::drainInboundQueueLocked() {
-    while (! mInboundQueue.isEmpty()) {
-        EventEntry* entry = mInboundQueue.dequeueAtHead();
-        releaseInboundEventLocked(entry);
-    }
-}
-
-void InputDispatcher::releasePendingEventLocked() {
-    if (mPendingEvent) {
-        releaseInboundEventLocked(mPendingEvent);
-        mPendingEvent = NULL;
-    }
-}
-
-void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
-#if DEBUG_DISPATCH_CYCLE
-        LOGD("Injected inbound event was dropped.");
-#endif
-        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
-    }
-    mAllocator.releaseEventEntry(entry);
-}
-
-void InputDispatcher::resetKeyRepeatLocked() {
-    if (mKeyRepeatState.lastKeyEntry) {
-        mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
-        mKeyRepeatState.lastKeyEntry = NULL;
-    }
-}
-
-InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
-        nsecs_t currentTime, nsecs_t keyRepeatDelay) {
-    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
-
-    // Reuse the repeated key entry if it is otherwise unreferenced.
-    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
-            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
-    if (entry->refCount == 1) {
-        mAllocator.recycleKeyEntry(entry);
-        entry->eventTime = currentTime;
-        entry->policyFlags = policyFlags;
-        entry->repeatCount += 1;
-    } else {
-        KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
-                entry->deviceId, entry->source, policyFlags,
-                entry->action, entry->flags, entry->keyCode, entry->scanCode,
-                entry->metaState, entry->repeatCount + 1, entry->downTime);
-
-        mKeyRepeatState.lastKeyEntry = newEntry;
-        mAllocator.releaseKeyEntry(entry);
-
-        entry = newEntry;
-    }
-    entry->syntheticRepeat = true;
-
-    // Increment reference count since we keep a reference to the event in
-    // mKeyRepeatState.lastKeyEntry in addition to the one we return.
-    entry->refCount += 1;
-
-    mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
-    return entry;
-}
-
-bool InputDispatcher::dispatchConfigurationChangedLocked(
-        nsecs_t currentTime, ConfigurationChangedEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-    LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
-#endif
-
-    // Reset key repeating in case a keyboard device was added or removed or something.
-    resetKeyRepeatLocked();
-
-    // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doNotifyConfigurationChangedInterruptible);
-    commandEntry->eventTime = entry->eventTime;
-    return true;
-}
-
-bool InputDispatcher::dispatchKeyLocked(
-        nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
-        DropReason* dropReason, nsecs_t* nextWakeupTime) {
-    // Preprocessing.
-    if (! entry->dispatchInProgress) {
-        if (entry->repeatCount == 0
-                && entry->action == AKEY_EVENT_ACTION_DOWN
-                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
-                && !entry->isInjected()) {
-            if (mKeyRepeatState.lastKeyEntry
-                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
-                // We have seen two identical key downs in a row which indicates that the device
-                // driver is automatically generating key repeats itself.  We take note of the
-                // repeat here, but we disable our own next key repeat timer since it is clear that
-                // we will not need to synthesize key repeats ourselves.
-                entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
-                resetKeyRepeatLocked();
-                mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
-            } else {
-                // Not a repeat.  Save key down state in case we do see a repeat later.
-                resetKeyRepeatLocked();
-                mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
-            }
-            mKeyRepeatState.lastKeyEntry = entry;
-            entry->refCount += 1;
-        } else if (! entry->syntheticRepeat) {
-            resetKeyRepeatLocked();
-        }
-
-        if (entry->repeatCount == 1) {
-            entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
-        } else {
-            entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
-        }
-
-        entry->dispatchInProgress = true;
-        resetTargetsLocked();
-
-        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
-    }
-
-    // Give the policy a chance to intercept the key.
-    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
-        if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
-            CommandEntry* commandEntry = postCommandLocked(
-                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
-            if (mFocusedWindow) {
-                commandEntry->inputChannel = mFocusedWindow->inputChannel;
-            }
-            commandEntry->keyEntry = entry;
-            entry->refCount += 1;
-            return false; // wait for the command to run
-        } else {
-            entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
-        }
-    } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
-        if (*dropReason == DROP_REASON_NOT_DROPPED) {
-            *dropReason = DROP_REASON_POLICY;
-        }
-    }
-
-    // Clean up if dropping the event.
-    if (*dropReason != DROP_REASON_NOT_DROPPED) {
-        resetTargetsLocked();
-        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
-                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
-        return true;
-    }
-
-    // Identify targets.
-    if (! mCurrentInputTargetsValid) {
-        int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
-                entry, nextWakeupTime);
-        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
-            return false;
-        }
-
-        setInjectionResultLocked(entry, injectionResult);
-        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
-            return true;
-        }
-
-        addMonitoringTargetsLocked();
-        commitTargetsLocked();
-    }
-
-    // Dispatch the key.
-    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
-    return true;
-}
-
-void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-    LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
-            "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
-            "repeatCount=%d, downTime=%lld",
-            prefix,
-            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
-            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
-            entry->repeatCount, entry->downTime);
-#endif
-}
-
-bool InputDispatcher::dispatchMotionLocked(
-        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
-    // Preprocessing.
-    if (! entry->dispatchInProgress) {
-        entry->dispatchInProgress = true;
-        resetTargetsLocked();
-
-        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
-    }
-
-    // Clean up if dropping the event.
-    if (*dropReason != DROP_REASON_NOT_DROPPED) {
-        resetTargetsLocked();
-        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
-                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
-        return true;
-    }
-
-    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
-
-    // Identify targets.
-    if (! mCurrentInputTargetsValid) {
-        int32_t injectionResult;
-        if (isPointerEvent) {
-            // Pointer event.  (eg. touchscreen)
-            injectionResult = findTouchedWindowTargetsLocked(currentTime,
-                    entry, nextWakeupTime);
-        } else {
-            // Non touch event.  (eg. trackball)
-            injectionResult = findFocusedWindowTargetsLocked(currentTime,
-                    entry, nextWakeupTime);
-        }
-        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
-            return false;
-        }
-
-        setInjectionResultLocked(entry, injectionResult);
-        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
-            return true;
-        }
-
-        addMonitoringTargetsLocked();
-        commitTargetsLocked();
-    }
-
-    // Dispatch the motion.
-    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
-    return true;
-}
-
-
-void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-    LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
-            "action=0x%x, flags=0x%x, "
-            "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
-            prefix,
-            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
-            entry->action, entry->flags,
-            entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
-            entry->downTime);
-
-    // Print the most recent sample that we have available, this may change due to batching.
-    size_t sampleCount = 1;
-    const MotionSample* sample = & entry->firstSample;
-    for (; sample->next != NULL; sample = sample->next) {
-        sampleCount += 1;
-    }
-    for (uint32_t i = 0; i < entry->pointerCount; i++) {
-        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
-                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
-                "orientation=%f",
-                i, entry->pointerIds[i],
-                sample->pointerCoords[i].x, sample->pointerCoords[i].y,
-                sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
-                sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
-                sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
-                sample->pointerCoords[i].orientation);
-    }
-
-    // Keep in mind that due to batching, it is possible for the number of samples actually
-    // dispatched to change before the application finally consumed them.
-    if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
-        LOGD("  ... Total movement samples currently batched %d ...", sampleCount);
-    }
-#endif
-}
-
-void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
-        EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
-#if DEBUG_DISPATCH_CYCLE
-    LOGD("dispatchEventToCurrentInputTargets - "
-            "resumeWithAppendedMotionSample=%s",
-            toString(resumeWithAppendedMotionSample));
-#endif
-
-    assert(eventEntry->dispatchInProgress); // should already have been set to true
-
-    pokeUserActivityLocked(eventEntry);
-
-    for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
-        const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
-
-        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
-        if (connectionIndex >= 0) {
-            sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-            prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
-                    resumeWithAppendedMotionSample);
-        } else {
-#if DEBUG_FOCUS
-            LOGD("Dropping event delivery to target with channel '%s' because it "
-                    "is no longer registered with the input dispatcher.",
-                    inputTarget.inputChannel->getName().string());
-#endif
-        }
-    }
-}
-
-void InputDispatcher::resetTargetsLocked() {
-    mCurrentInputTargetsValid = false;
-    mCurrentInputTargets.clear();
-    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
-}
-
-void InputDispatcher::commitTargetsLocked() {
-    mCurrentInputTargetsValid = true;
-}
-
-int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
-        const EventEntry* entry, const InputApplication* application, const InputWindow* window,
-        nsecs_t* nextWakeupTime) {
-    if (application == NULL && window == NULL) {
-        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
-#if DEBUG_FOCUS
-            LOGD("Waiting for system to become ready for input.");
-#endif
-            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
-            mInputTargetWaitStartTime = currentTime;
-            mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
-            mInputTargetWaitTimeoutExpired = false;
-        }
-    } else {
-        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
-#if DEBUG_FOCUS
-            LOGD("Waiting for application to become ready for input: %s",
-                    getApplicationWindowLabelLocked(application, window).string());
-#endif
-            nsecs_t timeout = window ? window->dispatchingTimeout :
-                application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
-
-            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
-            mInputTargetWaitStartTime = currentTime;
-            mInputTargetWaitTimeoutTime = currentTime + timeout;
-            mInputTargetWaitTimeoutExpired = false;
-        }
-    }
-
-    if (mInputTargetWaitTimeoutExpired) {
-        return INPUT_EVENT_INJECTION_TIMED_OUT;
-    }
-
-    if (currentTime >= mInputTargetWaitTimeoutTime) {
-        onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
-
-        // Force poll loop to wake up immediately on next iteration once we get the
-        // ANR response back from the policy.
-        *nextWakeupTime = LONG_LONG_MIN;
-        return INPUT_EVENT_INJECTION_PENDING;
-    } else {
-        // Force poll loop to wake up when timeout is due.
-        if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
-            *nextWakeupTime = mInputTargetWaitTimeoutTime;
-        }
-        return INPUT_EVENT_INJECTION_PENDING;
-    }
-}
-
-void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
-        const sp<InputChannel>& inputChannel) {
-    if (newTimeout > 0) {
-        // Extend the timeout.
-        mInputTargetWaitTimeoutTime = now() + newTimeout;
-    } else {
-        // Give up.
-        mInputTargetWaitTimeoutExpired = true;
-
-        // Release the touch targets.
-        mTouchState.reset();
-
-        // Input state will not be realistic.  Mark it out of sync.
-        if (inputChannel.get()) {
-            ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
-            if (connectionIndex >= 0) {
-                sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-                synthesizeCancelationEventsForConnectionLocked(
-                        connection, InputState::CANCEL_ALL_EVENTS,
-                        "application not responding");
-            }
-        }
-    }
-}
-
-nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
-        nsecs_t currentTime) {
-    if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
-        return currentTime - mInputTargetWaitStartTime;
-    }
-    return 0;
-}
-
-void InputDispatcher::resetANRTimeoutsLocked() {
-#if DEBUG_FOCUS
-        LOGD("Resetting ANR timeouts.");
-#endif
-
-    // Reset input target wait timeout.
-    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
-}
-
-int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
-        const EventEntry* entry, nsecs_t* nextWakeupTime) {
-    mCurrentInputTargets.clear();
-
-    int32_t injectionResult;
-
-    // If there is no currently focused window and no focused application
-    // then drop the event.
-    if (! mFocusedWindow) {
-        if (mFocusedApplication) {
-#if DEBUG_FOCUS
-            LOGD("Waiting because there is no focused window but there is a "
-                    "focused application that may eventually add a window: %s.",
-                    getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
-#endif
-            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                    mFocusedApplication, NULL, nextWakeupTime);
-            goto Unresponsive;
-        }
-
-        LOGI("Dropping event because there is no focused window or focused application.");
-        injectionResult = INPUT_EVENT_INJECTION_FAILED;
-        goto Failed;
-    }
-
-    // Check permissions.
-    if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
-        injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
-        goto Failed;
-    }
-
-    // If the currently focused window is paused then keep waiting.
-    if (mFocusedWindow->paused) {
-#if DEBUG_FOCUS
-        LOGD("Waiting because focused window is paused.");
-#endif
-        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                mFocusedApplication, mFocusedWindow, nextWakeupTime);
-        goto Unresponsive;
-    }
-
-    // If the currently focused window is still working on previous events then keep waiting.
-    if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
-#if DEBUG_FOCUS
-        LOGD("Waiting because focused window still processing previous input.");
-#endif
-        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                mFocusedApplication, mFocusedWindow, nextWakeupTime);
-        goto Unresponsive;
-    }
-
-    // Success!  Output targets.
-    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-    addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
-
-    // Done.
-Failed:
-Unresponsive:
-    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
-    updateDispatchStatisticsLocked(currentTime, entry,
-            injectionResult, timeSpentWaitingForApplication);
-#if DEBUG_FOCUS
-    LOGD("findFocusedWindow finished: injectionResult=%d, "
-            "timeSpendWaitingForApplication=%0.1fms",
-            injectionResult, timeSpentWaitingForApplication / 1000000.0);
-#endif
-    return injectionResult;
-}
-
-int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
-        const MotionEntry* entry, nsecs_t* nextWakeupTime) {
-    enum InjectionPermission {
-        INJECTION_PERMISSION_UNKNOWN,
-        INJECTION_PERMISSION_GRANTED,
-        INJECTION_PERMISSION_DENIED
-    };
-
-    mCurrentInputTargets.clear();
-
-    nsecs_t startTime = now();
-
-    // For security reasons, we defer updating the touch state until we are sure that
-    // event injection will be allowed.
-    //
-    // FIXME In the original code, screenWasOff could never be set to true.
-    //       The reason is that the POLICY_FLAG_WOKE_HERE
-    //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
-    //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was
-    //       actually enqueued using the policyFlags that appeared in the final EV_SYN
-    //       events upon which no preprocessing took place.  So policyFlags was always 0.
-    //       In the new native input dispatcher we're a bit more careful about event
-    //       preprocessing so the touches we receive can actually have non-zero policyFlags.
-    //       Unfortunately we obtain undesirable behavior.
-    //
-    //       Here's what happens:
-    //
-    //       When the device dims in anticipation of going to sleep, touches
-    //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
-    //       the device to brighten and reset the user activity timer.
-    //       Touches on other windows (such as the launcher window)
-    //       are dropped.  Then after a moment, the device goes to sleep.  Oops.
-    //
-    //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
-    //       instead of POLICY_FLAG_WOKE_HERE...
-    //
-    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
-
-    int32_t action = entry->action;
-    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
-
-    // Update the touch state as needed based on the properties of the touch event.
-    int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
-    InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
-    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        mTempTouchState.reset();
-        mTempTouchState.down = true;
-    } else {
-        mTempTouchState.copyFrom(mTouchState);
-    }
-
-    bool isSplit = mTempTouchState.split && mTempTouchState.down;
-    if (maskedAction == AMOTION_EVENT_ACTION_DOWN
-            || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
-        /* Case 1: New splittable pointer going down. */
-
-        int32_t pointerIndex = getMotionEventActionPointerIndex(action);
-        int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
-        int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
-        const InputWindow* newTouchedWindow = NULL;
-        const InputWindow* topErrorWindow = NULL;
-
-        // Traverse windows from front to back to find touched window and outside targets.
-        size_t numWindows = mWindows.size();
-        for (size_t i = 0; i < numWindows; i++) {
-            const InputWindow* window = & mWindows.editItemAt(i);
-            int32_t flags = window->layoutParamsFlags;
-
-            if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
-                if (! topErrorWindow) {
-                    topErrorWindow = window;
-                }
-            }
-
-            if (window->visible) {
-                if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
-                    bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
-                            | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
-                    if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
-                        if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
-                            newTouchedWindow = window;
-                        }
-                        break; // found touched window, exit window loop
-                    }
-                }
-
-                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
-                        && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
-                    int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
-                    if (isWindowObscuredAtPointLocked(window, x, y)) {
-                        outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
-                    }
-
-                    mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
-                }
-            }
-        }
-
-        // If there is an error window but it is not taking focus (typically because
-        // it is invisible) then wait for it.  Any other focused window may in
-        // fact be in ANR state.
-        if (topErrorWindow && newTouchedWindow != topErrorWindow) {
-#if DEBUG_FOCUS
-            LOGD("Waiting because system error window is pending.");
-#endif
-            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                    NULL, NULL, nextWakeupTime);
-            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
-            goto Unresponsive;
-        }
-
-        // Figure out whether splitting will be allowed for this window.
-        if (newTouchedWindow
-                && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
-            // New window supports splitting.
-            isSplit = true;
-        } else if (isSplit) {
-            // New window does not support splitting but we have already split events.
-            // Assign the pointer to the first foreground window we find.
-            // (May be NULL which is why we put this code block before the next check.)
-            newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
-        }
-
-        // If we did not find a touched window then fail.
-        if (! newTouchedWindow) {
-            if (mFocusedApplication) {
-#if DEBUG_FOCUS
-                LOGD("Waiting because there is no touched window but there is a "
-                        "focused application that may eventually add a new window: %s.",
-                        getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
-#endif
-                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        mFocusedApplication, NULL, nextWakeupTime);
-                goto Unresponsive;
-            }
-
-            LOGI("Dropping event because there is no touched window or focused application.");
-            injectionResult = INPUT_EVENT_INJECTION_FAILED;
-            goto Failed;
-        }
-
-        // Set target flags.
-        int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
-        if (isSplit) {
-            targetFlags |= InputTarget::FLAG_SPLIT;
-        }
-        if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
-            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
-        }
-
-        // Update the temporary touch state.
-        BitSet32 pointerIds;
-        if (isSplit) {
-            uint32_t pointerId = entry->pointerIds[pointerIndex];
-            pointerIds.markBit(pointerId);
-        }
-        mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
-    } else {
-        /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
-
-        // If the pointer is not currently down, then ignore the event.
-        if (! mTempTouchState.down) {
-            LOGI("Dropping event because the pointer is not down.");
-            injectionResult = INPUT_EVENT_INJECTION_FAILED;
-            goto Failed;
-        }
-    }
-
-    // Check permission to inject into all touched foreground windows and ensure there
-    // is at least one touched foreground window.
-    {
-        bool haveForegroundWindow = false;
-        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
-            if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
-                haveForegroundWindow = true;
-                if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
-                    injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
-                    injectionPermission = INJECTION_PERMISSION_DENIED;
-                    goto Failed;
-                }
-            }
-        }
-        if (! haveForegroundWindow) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-            LOGD("Dropping event because there is no touched foreground window to receive it.");
-#endif
-            injectionResult = INPUT_EVENT_INJECTION_FAILED;
-            goto Failed;
-        }
-
-        // Permission granted to injection into all touched foreground windows.
-        injectionPermission = INJECTION_PERMISSION_GRANTED;
-    }
-
-    // Ensure all touched foreground windows are ready for new input.
-    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-        const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
-        if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
-            // If the touched window is paused then keep waiting.
-            if (touchedWindow.window->paused) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-                LOGD("Waiting because touched window is paused.");
-#endif
-                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        NULL, touchedWindow.window, nextWakeupTime);
-                goto Unresponsive;
-            }
-
-            // If the touched window is still working on previous events then keep waiting.
-            if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
-#if DEBUG_FOCUS
-                LOGD("Waiting because touched window still processing previous input.");
-#endif
-                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        NULL, touchedWindow.window, nextWakeupTime);
-                goto Unresponsive;
-            }
-        }
-    }
-
-    // If this is the first pointer going down and the touched window has a wallpaper
-    // then also add the touched wallpaper windows so they are locked in for the duration
-    // of the touch gesture.
-    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
-        if (foregroundWindow->hasWallpaper) {
-            for (size_t i = 0; i < mWindows.size(); i++) {
-                const InputWindow* window = & mWindows[i];
-                if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
-                    mTempTouchState.addOrUpdateWindow(window,
-                            InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
-                }
-            }
-        }
-    }
-
-    // Success!  Output targets.
-    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-
-    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-        const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
-        addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
-                touchedWindow.pointerIds);
-    }
-
-    // Drop the outside touch window since we will not care about them in the next iteration.
-    mTempTouchState.removeOutsideTouchWindows();
-
-Failed:
-    // Check injection permission once and for all.
-    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
-        if (checkInjectionPermission(NULL, entry->injectionState)) {
-            injectionPermission = INJECTION_PERMISSION_GRANTED;
-        } else {
-            injectionPermission = INJECTION_PERMISSION_DENIED;
-        }
-    }
-
-    // Update final pieces of touch state if the injector had permission.
-    if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
-        if (maskedAction == AMOTION_EVENT_ACTION_UP
-                || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
-            // All pointers up or canceled.
-            mTempTouchState.reset();
-        } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-            // First pointer went down.
-            if (mTouchState.down) {
-#if DEBUG_FOCUS
-                LOGD("Pointer down received while already down.");
-#endif
-            }
-        } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
-            // One pointer went up.
-            if (isSplit) {
-                int32_t pointerIndex = getMotionEventActionPointerIndex(action);
-                uint32_t pointerId = entry->pointerIds[pointerIndex];
-
-                for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
-                    TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
-                    if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
-                        touchedWindow.pointerIds.clearBit(pointerId);
-                        if (touchedWindow.pointerIds.isEmpty()) {
-                            mTempTouchState.windows.removeAt(i);
-                            continue;
-                        }
-                    }
-                    i += 1;
-                }
-            }
-        }
-
-        // Save changes to touch state.
-        mTouchState.copyFrom(mTempTouchState);
-    } else {
-#if DEBUG_FOCUS
-        LOGD("Not updating touch focus because injection was denied.");
-#endif
-    }
-
-Unresponsive:
-    // Reset temporary touch state to ensure we release unnecessary references to input channels.
-    mTempTouchState.reset();
-
-    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
-    updateDispatchStatisticsLocked(currentTime, entry,
-            injectionResult, timeSpentWaitingForApplication);
-#if DEBUG_FOCUS
-    LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
-            "timeSpentWaitingForApplication=%0.1fms",
-            injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
-#endif
-    return injectionResult;
-}
-
-void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
-        BitSet32 pointerIds) {
-    mCurrentInputTargets.push();
-
-    InputTarget& target = mCurrentInputTargets.editTop();
-    target.inputChannel = window->inputChannel;
-    target.flags = targetFlags;
-    target.xOffset = - window->frameLeft;
-    target.yOffset = - window->frameTop;
-    target.pointerIds = pointerIds;
-}
-
-void InputDispatcher::addMonitoringTargetsLocked() {
-    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
-        mCurrentInputTargets.push();
-
-        InputTarget& target = mCurrentInputTargets.editTop();
-        target.inputChannel = mMonitoringChannels[i];
-        target.flags = 0;
-        target.xOffset = 0;
-        target.yOffset = 0;
-    }
-}
-
-bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
-        const InjectionState* injectionState) {
-    if (injectionState
-            && (window == NULL || window->ownerUid != injectionState->injectorUid)
-            && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
-        if (window) {
-            LOGW("Permission denied: injecting event from pid %d uid %d to window "
-                    "with input channel %s owned by uid %d",
-                    injectionState->injectorPid, injectionState->injectorUid,
-                    window->inputChannel->getName().string(),
-                    window->ownerUid);
-        } else {
-            LOGW("Permission denied: injecting event from pid %d uid %d",
-                    injectionState->injectorPid, injectionState->injectorUid);
-        }
-        return false;
-    }
-    return true;
-}
-
-bool InputDispatcher::isWindowObscuredAtPointLocked(
-        const InputWindow* window, int32_t x, int32_t y) const {
-    size_t numWindows = mWindows.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        const InputWindow* other = & mWindows.itemAt(i);
-        if (other == window) {
-            break;
-        }
-        if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
-    ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
-    if (connectionIndex >= 0) {
-        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-        return connection->outboundQueue.isEmpty();
-    } else {
-        return true;
-    }
-}
-
-String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
-        const InputWindow* window) {
-    if (application) {
-        if (window) {
-            String8 label(application->name);
-            label.append(" - ");
-            label.append(window->name);
-            return label;
-        } else {
-            return application->name;
-        }
-    } else if (window) {
-        return window->name;
-    } else {
-        return String8("<unknown application or window>");
-    }
-}
-
-void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
-    int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
-    switch (eventEntry->type) {
-    case EventEntry::TYPE_MOTION: {
-        const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
-        if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
-            return;
-        }
-
-        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
-            switch (motionEntry->action) {
-            case AMOTION_EVENT_ACTION_DOWN:
-                eventType = POWER_MANAGER_TOUCH_EVENT;
-                break;
-            case AMOTION_EVENT_ACTION_UP:
-                eventType = POWER_MANAGER_TOUCH_UP_EVENT;
-                break;
-            default:
-                if (motionEntry->eventTime - motionEntry->downTime < LONG_TOUCH_DELAY) {
-                    eventType = POWER_MANAGER_TOUCH_EVENT;
-                } else {
-                    eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
-                }
-                break;
-            }
-        }
-        break;
-    }
-    case EventEntry::TYPE_KEY: {
-        const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
-        if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
-            return;
-        }
-        break;
-    }
-    }
-
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doPokeUserActivityLockedInterruptible);
-    commandEntry->eventTime = eventEntry->eventTime;
-    commandEntry->userActivityEventType = eventType;
-}
-
-void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
-        bool resumeWithAppendedMotionSample) {
-#if DEBUG_DISPATCH_CYCLE
-    LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
-            "xOffset=%f, yOffset=%f, "
-            "windowType=%d, pointerIds=0x%x, "
-            "resumeWithAppendedMotionSample=%s",
-            connection->getInputChannelName(), inputTarget->flags,
-            inputTarget->xOffset, inputTarget->yOffset,
-            inputTarget->windowType, inputTarget->pointerIds.value,
-            toString(resumeWithAppendedMotionSample));
-#endif
-
-    // Make sure we are never called for streaming when splitting across multiple windows.
-    bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
-    assert(! (resumeWithAppendedMotionSample && isSplit));
-
-    // Skip this event if the connection status is not normal.
-    // We don't want to enqueue additional outbound events if the connection is broken.
-    if (connection->status != Connection::STATUS_NORMAL) {
-#if DEBUG_DISPATCH_CYCLE
-        LOGD("channel '%s' ~ Dropping event because the channel status is %s",
-                connection->getInputChannelName(), connection->getStatusLabel());
-#endif
-        return;
-    }
-
-    // Split a motion event if needed.
-    if (isSplit) {
-        assert(eventEntry->type == EventEntry::TYPE_MOTION);
-
-        MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
-        if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
-            MotionEntry* splitMotionEntry = splitMotionEvent(
-                    originalMotionEntry, inputTarget->pointerIds);
-#if DEBUG_FOCUS
-            LOGD("channel '%s' ~ Split motion event.",
-                    connection->getInputChannelName());
-            logOutboundMotionDetailsLocked("  ", splitMotionEntry);
-#endif
-            eventEntry = splitMotionEntry;
-        }
-    }
-
-    // Resume the dispatch cycle with a freshly appended motion sample.
-    // First we check that the last dispatch entry in the outbound queue is for the same
-    // motion event to which we appended the motion sample.  If we find such a dispatch
-    // entry, and if it is currently in progress then we try to stream the new sample.
-    bool wasEmpty = connection->outboundQueue.isEmpty();
-
-    if (! wasEmpty && resumeWithAppendedMotionSample) {
-        DispatchEntry* motionEventDispatchEntry =
-                connection->findQueuedDispatchEntryForEvent(eventEntry);
-        if (motionEventDispatchEntry) {
-            // If the dispatch entry is not in progress, then we must be busy dispatching an
-            // earlier event.  Not a problem, the motion event is on the outbound queue and will
-            // be dispatched later.
-            if (! motionEventDispatchEntry->inProgress) {
-#if DEBUG_BATCHING
-                LOGD("channel '%s' ~ Not streaming because the motion event has "
-                        "not yet been dispatched.  "
-                        "(Waiting for earlier events to be consumed.)",
-                        connection->getInputChannelName());
-#endif
-                return;
-            }
-
-            // If the dispatch entry is in progress but it already has a tail of pending
-            // motion samples, then it must mean that the shared memory buffer filled up.
-            // Not a problem, when this dispatch cycle is finished, we will eventually start
-            // a new dispatch cycle to process the tail and that tail includes the newly
-            // appended motion sample.
-            if (motionEventDispatchEntry->tailMotionSample) {
-#if DEBUG_BATCHING
-                LOGD("channel '%s' ~ Not streaming because no new samples can "
-                        "be appended to the motion event in this dispatch cycle.  "
-                        "(Waiting for next dispatch cycle to start.)",
-                        connection->getInputChannelName());
-#endif
-                return;
-            }
-
-            // The dispatch entry is in progress and is still potentially open for streaming.
-            // Try to stream the new motion sample.  This might fail if the consumer has already
-            // consumed the motion event (or if the channel is broken).
-            MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
-            MotionSample* appendedMotionSample = motionEntry->lastSample;
-            status_t status = connection->inputPublisher.appendMotionSample(
-                    appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
-            if (status == OK) {
-#if DEBUG_BATCHING
-                LOGD("channel '%s' ~ Successfully streamed new motion sample.",
-                        connection->getInputChannelName());
-#endif
-                return;
-            }
-
-#if DEBUG_BATCHING
-            if (status == NO_MEMORY) {
-                LOGD("channel '%s' ~ Could not append motion sample to currently "
-                        "dispatched move event because the shared memory buffer is full.  "
-                        "(Waiting for next dispatch cycle to start.)",
-                        connection->getInputChannelName());
-            } else if (status == status_t(FAILED_TRANSACTION)) {
-                LOGD("channel '%s' ~ Could not append motion sample to currently "
-                        "dispatched move event because the event has already been consumed.  "
-                        "(Waiting for next dispatch cycle to start.)",
-                        connection->getInputChannelName());
-            } else {
-                LOGD("channel '%s' ~ Could not append motion sample to currently "
-                        "dispatched move event due to an error, status=%d.  "
-                        "(Waiting for next dispatch cycle to start.)",
-                        connection->getInputChannelName(), status);
-            }
-#endif
-            // Failed to stream.  Start a new tail of pending motion samples to dispatch
-            // in the next cycle.
-            motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
-            return;
-        }
-    }
-
-    // This is a new event.
-    // Enqueue a new dispatch entry onto the outbound queue for this connection.
-    DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
-            inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
-    if (dispatchEntry->hasForegroundTarget()) {
-        incrementPendingForegroundDispatchesLocked(eventEntry);
-    }
-
-    // Handle the case where we could not stream a new motion sample because the consumer has
-    // already consumed the motion event (otherwise the corresponding dispatch entry would
-    // still be in the outbound queue for this connection).  We set the head motion sample
-    // to the list starting with the newly appended motion sample.
-    if (resumeWithAppendedMotionSample) {
-#if DEBUG_BATCHING
-        LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
-                "that cannot be streamed because the motion event has already been consumed.",
-                connection->getInputChannelName());
-#endif
-        MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
-        dispatchEntry->headMotionSample = appendedMotionSample;
-    }
-
-    // Enqueue the dispatch entry.
-    connection->outboundQueue.enqueueAtTail(dispatchEntry);
-
-    // If the outbound queue was previously empty, start the dispatch cycle going.
-    if (wasEmpty) {
-        activateConnectionLocked(connection.get());
-        startDispatchCycleLocked(currentTime, connection);
-    }
-}
-
-void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection) {
-#if DEBUG_DISPATCH_CYCLE
-    LOGD("channel '%s' ~ startDispatchCycle",
-            connection->getInputChannelName());
-#endif
-
-    assert(connection->status == Connection::STATUS_NORMAL);
-    assert(! connection->outboundQueue.isEmpty());
-
-    DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
-    assert(! dispatchEntry->inProgress);
-
-    // Mark the dispatch entry as in progress.
-    dispatchEntry->inProgress = true;
-
-    // Update the connection's input state.
-    EventEntry* eventEntry = dispatchEntry->eventEntry;
-    InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
-
-#if FILTER_INPUT_EVENTS
-    // Filter out inconsistent sequences of input events.
-    // The input system may drop or inject events in a way that could violate implicit
-    // invariants on input state and potentially cause an application to crash
-    // or think that a key or pointer is stuck down.  Technically we make no guarantees
-    // of consistency but it would be nice to improve on this where possible.
-    // XXX: This code is a proof of concept only.  Not ready for prime time.
-    if (consistency == InputState::TOLERABLE) {
-#if DEBUG_DISPATCH_CYCLE
-        LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
-                "current input state but that is likely to be tolerated by the application.",
-                connection->getInputChannelName());
-#endif
-    } else if (consistency == InputState::BROKEN) {
-        LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
-                "current input state and that is likely to cause the application to crash.",
-                connection->getInputChannelName());
-        startNextDispatchCycleLocked(currentTime, connection);
-        return;
-    }
-#endif
-
-    // Publish the event.
-    status_t status;
-    switch (eventEntry->type) {
-    case EventEntry::TYPE_KEY: {
-        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
-
-        // Apply target flags.
-        int32_t action = keyEntry->action;
-        int32_t flags = keyEntry->flags;
-
-        // Publish the key event.
-        status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
-                action, flags, keyEntry->keyCode, keyEntry->scanCode,
-                keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
-                keyEntry->eventTime);
-
-        if (status) {
-            LOGE("channel '%s' ~ Could not publish key event, "
-                    "status=%d", connection->getInputChannelName(), status);
-            abortBrokenDispatchCycleLocked(currentTime, connection);
-            return;
-        }
-        break;
-    }
-
-    case EventEntry::TYPE_MOTION: {
-        MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
-
-        // Apply target flags.
-        int32_t action = motionEntry->action;
-        int32_t flags = motionEntry->flags;
-        if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
-            action = AMOTION_EVENT_ACTION_OUTSIDE;
-        }
-        if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
-            flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
-        }
-
-        // If headMotionSample is non-NULL, then it points to the first new sample that we
-        // were unable to dispatch during the previous cycle so we resume dispatching from
-        // that point in the list of motion samples.
-        // Otherwise, we just start from the first sample of the motion event.
-        MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
-        if (! firstMotionSample) {
-            firstMotionSample = & motionEntry->firstSample;
-        }
-
-        // Set the X and Y offset depending on the input source.
-        float xOffset, yOffset;
-        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
-            xOffset = dispatchEntry->xOffset;
-            yOffset = dispatchEntry->yOffset;
-        } else {
-            xOffset = 0.0f;
-            yOffset = 0.0f;
-        }
-
-        // Publish the motion event and the first motion sample.
-        status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
-                motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
-                xOffset, yOffset,
-                motionEntry->xPrecision, motionEntry->yPrecision,
-                motionEntry->downTime, firstMotionSample->eventTime,
-                motionEntry->pointerCount, motionEntry->pointerIds,
-                firstMotionSample->pointerCoords);
-
-        if (status) {
-            LOGE("channel '%s' ~ Could not publish motion event, "
-                    "status=%d", connection->getInputChannelName(), status);
-            abortBrokenDispatchCycleLocked(currentTime, connection);
-            return;
-        }
-
-        // Append additional motion samples.
-        MotionSample* nextMotionSample = firstMotionSample->next;
-        for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
-            status = connection->inputPublisher.appendMotionSample(
-                    nextMotionSample->eventTime, nextMotionSample->pointerCoords);
-            if (status == NO_MEMORY) {
-#if DEBUG_DISPATCH_CYCLE
-                    LOGD("channel '%s' ~ Shared memory buffer full.  Some motion samples will "
-                            "be sent in the next dispatch cycle.",
-                            connection->getInputChannelName());
-#endif
-                break;
-            }
-            if (status != OK) {
-                LOGE("channel '%s' ~ Could not append motion sample "
-                        "for a reason other than out of memory, status=%d",
-                        connection->getInputChannelName(), status);
-                abortBrokenDispatchCycleLocked(currentTime, connection);
-                return;
-            }
-        }
-
-        // Remember the next motion sample that we could not dispatch, in case we ran out
-        // of space in the shared memory buffer.
-        dispatchEntry->tailMotionSample = nextMotionSample;
-        break;
-    }
-
-    default: {
-        assert(false);
-    }
-    }
-
-    // Send the dispatch signal.
-    status = connection->inputPublisher.sendDispatchSignal();
-    if (status) {
-        LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
-                connection->getInputChannelName(), status);
-        abortBrokenDispatchCycleLocked(currentTime, connection);
-        return;
-    }
-
-    // Record information about the newly started dispatch cycle.
-    connection->lastEventTime = eventEntry->eventTime;
-    connection->lastDispatchTime = currentTime;
-
-    // Notify other system components.
-    onDispatchCycleStartedLocked(currentTime, connection);
-}
-
-void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection) {
-#if DEBUG_DISPATCH_CYCLE
-    LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
-            "%01.1fms since dispatch",
-            connection->getInputChannelName(),
-            connection->getEventLatencyMillis(currentTime),
-            connection->getDispatchLatencyMillis(currentTime));
-#endif
-
-    if (connection->status == Connection::STATUS_BROKEN
-            || connection->status == Connection::STATUS_ZOMBIE) {
-        return;
-    }
-
-    // Notify other system components.
-    onDispatchCycleFinishedLocked(currentTime, connection);
-
-    // Reset the publisher since the event has been consumed.
-    // We do this now so that the publisher can release some of its internal resources
-    // while waiting for the next dispatch cycle to begin.
-    status_t status = connection->inputPublisher.reset();
-    if (status) {
-        LOGE("channel '%s' ~ Could not reset publisher, status=%d",
-                connection->getInputChannelName(), status);
-        abortBrokenDispatchCycleLocked(currentTime, connection);
-        return;
-    }
-
-    startNextDispatchCycleLocked(currentTime, connection);
-}
-
-void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection) {
-    // Start the next dispatch cycle for this connection.
-    while (! connection->outboundQueue.isEmpty()) {
-        DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
-        if (dispatchEntry->inProgress) {
-             // Finish or resume current event in progress.
-            if (dispatchEntry->tailMotionSample) {
-                // We have a tail of undispatched motion samples.
-                // Reuse the same DispatchEntry and start a new cycle.
-                dispatchEntry->inProgress = false;
-                dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
-                dispatchEntry->tailMotionSample = NULL;
-                startDispatchCycleLocked(currentTime, connection);
-                return;
-            }
-            // Finished.
-            connection->outboundQueue.dequeueAtHead();
-            if (dispatchEntry->hasForegroundTarget()) {
-                decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
-            }
-            mAllocator.releaseDispatchEntry(dispatchEntry);
-        } else {
-            // If the head is not in progress, then we must have already dequeued the in
-            // progress event, which means we actually aborted it.
-            // So just start the next event for this connection.
-            startDispatchCycleLocked(currentTime, connection);
-            return;
-        }
-    }
-
-    // Outbound queue is empty, deactivate the connection.
-    deactivateConnectionLocked(connection.get());
-}
-
-void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection) {
-#if DEBUG_DISPATCH_CYCLE
-    LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
-            connection->getInputChannelName(), toString(broken));
-#endif
-
-    // Clear the outbound queue.
-    drainOutboundQueueLocked(connection.get());
-
-    // The connection appears to be unrecoverably broken.
-    // Ignore already broken or zombie connections.
-    if (connection->status == Connection::STATUS_NORMAL) {
-        connection->status = Connection::STATUS_BROKEN;
-
-        // Notify other system components.
-        onDispatchCycleBrokenLocked(currentTime, connection);
-    }
-}
-
-void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
-    while (! connection->outboundQueue.isEmpty()) {
-        DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
-        if (dispatchEntry->hasForegroundTarget()) {
-            decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
-        }
-        mAllocator.releaseDispatchEntry(dispatchEntry);
-    }
-
-    deactivateConnectionLocked(connection);
-}
-
-int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
-    InputDispatcher* d = static_cast<InputDispatcher*>(data);
-
-    { // acquire lock
-        AutoMutex _l(d->mLock);
-
-        ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
-        if (connectionIndex < 0) {
-            LOGE("Received spurious receive callback for unknown input channel.  "
-                    "fd=%d, events=0x%x", receiveFd, events);
-            return 0; // remove the callback
-        }
-
-        nsecs_t currentTime = now();
-
-        sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
-        if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
-            LOGE("channel '%s' ~ Consumer closed input channel or an error occurred.  "
-                    "events=0x%x", connection->getInputChannelName(), events);
-            d->abortBrokenDispatchCycleLocked(currentTime, connection);
-            d->runCommandsLockedInterruptible();
-            return 0; // remove the callback
-        }
-
-        if (! (events & ALOOPER_EVENT_INPUT)) {
-            LOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
-                    "events=0x%x", connection->getInputChannelName(), events);
-            return 1;
-        }
-
-        status_t status = connection->inputPublisher.receiveFinishedSignal();
-        if (status) {
-            LOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
-                    connection->getInputChannelName(), status);
-            d->abortBrokenDispatchCycleLocked(currentTime, connection);
-            d->runCommandsLockedInterruptible();
-            return 0; // remove the callback
-        }
-
-        d->finishDispatchCycleLocked(currentTime, connection);
-        d->runCommandsLockedInterruptible();
-        return 1;
-    } // release lock
-}
-
-void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
-        InputState::CancelationOptions options, const char* reason) {
-    for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
-        synthesizeCancelationEventsForConnectionLocked(
-                mConnectionsByReceiveFd.valueAt(i), options, reason);
-    }
-}
-
-void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
-        const sp<InputChannel>& channel, InputState::CancelationOptions options,
-        const char* reason) {
-    ssize_t index = getConnectionIndexLocked(channel);
-    if (index >= 0) {
-        synthesizeCancelationEventsForConnectionLocked(
-                mConnectionsByReceiveFd.valueAt(index), options, reason);
-    }
-}
-
-void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
-        const sp<Connection>& connection, InputState::CancelationOptions options,
-        const char* reason) {
-    nsecs_t currentTime = now();
-
-    mTempCancelationEvents.clear();
-    connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
-            mTempCancelationEvents, options);
-
-    if (! mTempCancelationEvents.isEmpty()
-            && connection->status != Connection::STATUS_BROKEN) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-        LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
-                "with reality: %s, options=%d.",
-                connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
-#endif
-        for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
-            EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
-            switch (cancelationEventEntry->type) {
-            case EventEntry::TYPE_KEY:
-                logOutboundKeyDetailsLocked("cancel - ",
-                        static_cast<KeyEntry*>(cancelationEventEntry));
-                break;
-            case EventEntry::TYPE_MOTION:
-                logOutboundMotionDetailsLocked("cancel - ",
-                        static_cast<MotionEntry*>(cancelationEventEntry));
-                break;
-            }
-
-            int32_t xOffset, yOffset;
-            const InputWindow* window = getWindowLocked(connection->inputChannel);
-            if (window) {
-                xOffset = -window->frameLeft;
-                yOffset = -window->frameTop;
-            } else {
-                xOffset = 0;
-                yOffset = 0;
-            }
-
-            DispatchEntry* cancelationDispatchEntry =
-                    mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
-                    0, xOffset, yOffset);
-            connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
-
-            mAllocator.releaseEventEntry(cancelationEventEntry);
-        }
-
-        if (!connection->outboundQueue.headSentinel.next->inProgress) {
-            startDispatchCycleLocked(currentTime, connection);
-        }
-    }
-}
-
-InputDispatcher::MotionEntry*
-InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
-    assert(pointerIds.value != 0);
-
-    uint32_t splitPointerIndexMap[MAX_POINTERS];
-    int32_t splitPointerIds[MAX_POINTERS];
-    PointerCoords splitPointerCoords[MAX_POINTERS];
-
-    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
-    uint32_t splitPointerCount = 0;
-
-    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
-            originalPointerIndex++) {
-        int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
-        if (pointerIds.hasBit(pointerId)) {
-            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
-            splitPointerIds[splitPointerCount] = pointerId;
-            splitPointerCoords[splitPointerCount] =
-                    originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
-            splitPointerCount += 1;
-        }
-    }
-    assert(splitPointerCount == pointerIds.count());
-
-    int32_t action = originalMotionEntry->action;
-    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
-    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
-            || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
-        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
-        int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
-        if (pointerIds.hasBit(pointerId)) {
-            if (pointerIds.count() == 1) {
-                // The first/last pointer went down/up.
-                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
-                        ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
-            } else {
-                // A secondary pointer went down/up.
-                uint32_t splitPointerIndex = 0;
-                while (pointerId != splitPointerIds[splitPointerIndex]) {
-                    splitPointerIndex += 1;
-                }
-                action = maskedAction | (splitPointerIndex
-                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
-            }
-        } else {
-            // An unrelated pointer changed.
-            action = AMOTION_EVENT_ACTION_MOVE;
-        }
-    }
-
-    MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
-            originalMotionEntry->eventTime,
-            originalMotionEntry->deviceId,
-            originalMotionEntry->source,
-            originalMotionEntry->policyFlags,
-            action,
-            originalMotionEntry->flags,
-            originalMotionEntry->metaState,
-            originalMotionEntry->edgeFlags,
-            originalMotionEntry->xPrecision,
-            originalMotionEntry->yPrecision,
-            originalMotionEntry->downTime,
-            splitPointerCount, splitPointerIds, splitPointerCoords);
-
-    for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
-            originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
-        for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
-                splitPointerIndex++) {
-            uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
-            splitPointerCoords[splitPointerIndex] =
-                    originalMotionSample->pointerCoords[originalPointerIndex];
-        }
-
-        mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
-                splitPointerCoords);
-    }
-
-    return splitMotionEntry;
-}
-
-void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
-#endif
-
-    bool needWake;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
-        needWake = enqueueInboundEventLocked(newEntry);
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
-void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
-        uint32_t policyFlags, int32_t action, int32_t flags,
-        int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
-            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
-            eventTime, deviceId, source, policyFlags, action, flags,
-            keyCode, scanCode, metaState, downTime);
-#endif
-    if (! validateKeyEvent(action)) {
-        return;
-    }
-
-    policyFlags |= POLICY_FLAG_TRUSTED;
-    mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
-            keyCode, scanCode, /*byref*/ policyFlags);
-
-    bool needWake;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        int32_t repeatCount = 0;
-        KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
-                deviceId, source, policyFlags, action, flags, keyCode, scanCode,
-                metaState, repeatCount, downTime);
-
-        needWake = enqueueInboundEventLocked(newEntry);
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
-void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
-        uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
-        uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
-        float xPrecision, float yPrecision, nsecs_t downTime) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
-            "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
-            "xPrecision=%f, yPrecision=%f, downTime=%lld",
-            eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
-            xPrecision, yPrecision, downTime);
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
-                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
-                "orientation=%f",
-                i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
-                pointerCoords[i].pressure, pointerCoords[i].size,
-                pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
-                pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
-                pointerCoords[i].orientation);
-    }
-#endif
-    if (! validateMotionEvent(action, pointerCount, pointerIds)) {
-        return;
-    }
-
-    policyFlags |= POLICY_FLAG_TRUSTED;
-    mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
-
-    bool needWake;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        // Attempt batching and streaming of move events.
-        if (action == AMOTION_EVENT_ACTION_MOVE) {
-            // BATCHING CASE
-            //
-            // Try to append a move sample to the tail of the inbound queue for this device.
-            // Give up if we encounter a non-move motion event for this device since that
-            // means we cannot append any new samples until a new motion event has started.
-            for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
-                    entry != & mInboundQueue.headSentinel; entry = entry->prev) {
-                if (entry->type != EventEntry::TYPE_MOTION) {
-                    // Keep looking for motion events.
-                    continue;
-                }
-
-                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
-                if (motionEntry->deviceId != deviceId) {
-                    // Keep looking for this device.
-                    continue;
-                }
-
-                if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
-                        || motionEntry->pointerCount != pointerCount
-                        || motionEntry->isInjected()) {
-                    // Last motion event in the queue for this device is not compatible for
-                    // appending new samples.  Stop here.
-                    goto NoBatchingOrStreaming;
-                }
-
-                // The last motion event is a move and is compatible for appending.
-                // Do the batching magic.
-                mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
-#if DEBUG_BATCHING
-                LOGD("Appended motion sample onto batch for most recent "
-                        "motion event for this device in the inbound queue.");
-#endif
-                return; // done!
-            }
-
-            // STREAMING CASE
-            //
-            // There is no pending motion event (of any kind) for this device in the inbound queue.
-            // Search the outbound queue for the current foreground targets to find a dispatched
-            // motion event that is still in progress.  If found, then, appen the new sample to
-            // that event and push it out to all current targets.  The logic in
-            // prepareDispatchCycleLocked takes care of the case where some targets may
-            // already have consumed the motion event by starting a new dispatch cycle if needed.
-            if (mCurrentInputTargetsValid) {
-                for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
-                    const InputTarget& inputTarget = mCurrentInputTargets[i];
-                    if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
-                        // Skip non-foreground targets.  We only want to stream if there is at
-                        // least one foreground target whose dispatch is still in progress.
-                        continue;
-                    }
-
-                    ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
-                    if (connectionIndex < 0) {
-                        // Connection must no longer be valid.
-                        continue;
-                    }
-
-                    sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-                    if (connection->outboundQueue.isEmpty()) {
-                        // This foreground target has an empty outbound queue.
-                        continue;
-                    }
-
-                    DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
-                    if (! dispatchEntry->inProgress
-                            || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
-                            || dispatchEntry->isSplit()) {
-                        // No motion event is being dispatched, or it is being split across
-                        // windows in which case we cannot stream.
-                        continue;
-                    }
-
-                    MotionEntry* motionEntry = static_cast<MotionEntry*>(
-                            dispatchEntry->eventEntry);
-                    if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
-                            || motionEntry->deviceId != deviceId
-                            || motionEntry->pointerCount != pointerCount
-                            || motionEntry->isInjected()) {
-                        // The motion event is not compatible with this move.
-                        continue;
-                    }
-
-                    // Hurray!  This foreground target is currently dispatching a move event
-                    // that we can stream onto.  Append the motion sample and resume dispatch.
-                    mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
-#if DEBUG_BATCHING
-                    LOGD("Appended motion sample onto batch for most recently dispatched "
-                            "motion event for this device in the outbound queues.  "
-                            "Attempting to stream the motion sample.");
-#endif
-                    nsecs_t currentTime = now();
-                    dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
-                            true /*resumeWithAppendedMotionSample*/);
-
-                    runCommandsLockedInterruptible();
-                    return; // done!
-                }
-            }
-
-NoBatchingOrStreaming:;
-        }
-
-        // Just enqueue a new motion event.
-        MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
-                deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
-                xPrecision, yPrecision, downTime,
-                pointerCount, pointerIds, pointerCoords);
-
-        needWake = enqueueInboundEventLocked(newEntry);
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
-void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
-        uint32_t policyFlags) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
-            switchCode, switchValue, policyFlags);
-#endif
-
-    policyFlags |= POLICY_FLAG_TRUSTED;
-    mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
-}
-
-int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
-        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
-            "syncMode=%d, timeoutMillis=%d",
-            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
-#endif
-
-    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
-
-    uint32_t policyFlags = POLICY_FLAG_INJECTED;
-    if (hasInjectionPermission(injectorPid, injectorUid)) {
-        policyFlags |= POLICY_FLAG_TRUSTED;
-    }
-
-    EventEntry* injectedEntry;
-    switch (event->getType()) {
-    case AINPUT_EVENT_TYPE_KEY: {
-        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
-        int32_t action = keyEvent->getAction();
-        if (! validateKeyEvent(action)) {
-            return INPUT_EVENT_INJECTION_FAILED;
-        }
-
-        nsecs_t eventTime = keyEvent->getEventTime();
-        int32_t deviceId = keyEvent->getDeviceId();
-        int32_t flags = keyEvent->getFlags();
-        int32_t keyCode = keyEvent->getKeyCode();
-        int32_t scanCode = keyEvent->getScanCode();
-        mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
-                keyCode, scanCode, /*byref*/ policyFlags);
-
-        mLock.lock();
-        injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
-                policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
-                keyEvent->getRepeatCount(), keyEvent->getDownTime());
-        break;
-    }
-
-    case AINPUT_EVENT_TYPE_MOTION: {
-        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
-        int32_t action = motionEvent->getAction();
-        size_t pointerCount = motionEvent->getPointerCount();
-        const int32_t* pointerIds = motionEvent->getPointerIds();
-        if (! validateMotionEvent(action, pointerCount, pointerIds)) {
-            return INPUT_EVENT_INJECTION_FAILED;
-        }
-
-        nsecs_t eventTime = motionEvent->getEventTime();
-        mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
-
-        mLock.lock();
-        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
-        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
-        MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
-                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
-                action, motionEvent->getFlags(),
-                motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
-                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
-                motionEvent->getDownTime(), uint32_t(pointerCount),
-                pointerIds, samplePointerCoords);
-        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
-            sampleEventTimes += 1;
-            samplePointerCoords += pointerCount;
-            mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
-        }
-        injectedEntry = motionEntry;
-        break;
-    }
-
-    default:
-        LOGW("Cannot inject event of type %d", event->getType());
-        return INPUT_EVENT_INJECTION_FAILED;
-    }
-
-    InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
-    if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
-        injectionState->injectionIsAsync = true;
-    }
-
-    injectionState->refCount += 1;
-    injectedEntry->injectionState = injectionState;
-
-    bool needWake = enqueueInboundEventLocked(injectedEntry);
-    mLock.unlock();
-
-    if (needWake) {
-        mLooper->wake();
-    }
-
-    int32_t injectionResult;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
-            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-        } else {
-            for (;;) {
-                injectionResult = injectionState->injectionResult;
-                if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
-                    break;
-                }
-
-                nsecs_t remainingTimeout = endTime - now();
-                if (remainingTimeout <= 0) {
-#if DEBUG_INJECTION
-                    LOGD("injectInputEvent - Timed out waiting for injection result "
-                            "to become available.");
-#endif
-                    injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
-                    break;
-                }
-
-                mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
-            }
-
-            if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
-                    && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
-                while (injectionState->pendingForegroundDispatches != 0) {
-#if DEBUG_INJECTION
-                    LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
-                            injectionState->pendingForegroundDispatches);
-#endif
-                    nsecs_t remainingTimeout = endTime - now();
-                    if (remainingTimeout <= 0) {
-#if DEBUG_INJECTION
-                    LOGD("injectInputEvent - Timed out waiting for pending foreground "
-                            "dispatches to finish.");
-#endif
-                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
-                        break;
-                    }
-
-                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
-                }
-            }
-        }
-
-        mAllocator.releaseInjectionState(injectionState);
-    } // release lock
-
-#if DEBUG_INJECTION
-    LOGD("injectInputEvent - Finished with result %d.  "
-            "injectorPid=%d, injectorUid=%d",
-            injectionResult, injectorPid, injectorUid);
-#endif
-
-    return injectionResult;
-}
-
-bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
-    return injectorUid == 0
-            || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
-}
-
-void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState) {
-#if DEBUG_INJECTION
-        LOGD("Setting input event injection result to %d.  "
-                "injectorPid=%d, injectorUid=%d",
-                 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
-#endif
-
-        if (injectionState->injectionIsAsync) {
-            // Log the outcome since the injector did not wait for the injection result.
-            switch (injectionResult) {
-            case INPUT_EVENT_INJECTION_SUCCEEDED:
-                LOGV("Asynchronous input event injection succeeded.");
-                break;
-            case INPUT_EVENT_INJECTION_FAILED:
-                LOGW("Asynchronous input event injection failed.");
-                break;
-            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
-                LOGW("Asynchronous input event injection permission denied.");
-                break;
-            case INPUT_EVENT_INJECTION_TIMED_OUT:
-                LOGW("Asynchronous input event injection timed out.");
-                break;
-            }
-        }
-
-        injectionState->injectionResult = injectionResult;
-        mInjectionResultAvailableCondition.broadcast();
-    }
-}
-
-void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState) {
-        injectionState->pendingForegroundDispatches += 1;
-    }
-}
-
-void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState) {
-        injectionState->pendingForegroundDispatches -= 1;
-
-        if (injectionState->pendingForegroundDispatches == 0) {
-            mInjectionSyncFinishedCondition.broadcast();
-        }
-    }
-}
-
-const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
-    for (size_t i = 0; i < mWindows.size(); i++) {
-        const InputWindow* window = & mWindows[i];
-        if (window->inputChannel == inputChannel) {
-            return window;
-        }
-    }
-    return NULL;
-}
-
-void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
-#if DEBUG_FOCUS
-    LOGD("setInputWindows");
-#endif
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        // Clear old window pointers.
-        sp<InputChannel> oldFocusedWindowChannel;
-        if (mFocusedWindow) {
-            oldFocusedWindowChannel = mFocusedWindow->inputChannel;
-            mFocusedWindow = NULL;
-        }
-
-        mWindows.clear();
-
-        // Loop over new windows and rebuild the necessary window pointers for
-        // tracking focus and touch.
-        mWindows.appendVector(inputWindows);
-
-        size_t numWindows = mWindows.size();
-        for (size_t i = 0; i < numWindows; i++) {
-            const InputWindow* window = & mWindows.itemAt(i);
-            if (window->hasFocus) {
-                mFocusedWindow = window;
-                break;
-            }
-        }
-
-        if (oldFocusedWindowChannel != NULL) {
-            if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
-#if DEBUG_FOCUS
-                LOGD("Focus left window: %s",
-                        oldFocusedWindowChannel->getName().string());
-#endif
-                synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
-                        InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
-                oldFocusedWindowChannel.clear();
-            }
-        }
-        if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
-#if DEBUG_FOCUS
-            LOGD("Focus entered window: %s",
-                    mFocusedWindow->inputChannel->getName().string());
-#endif
-        }
-
-        for (size_t i = 0; i < mTouchState.windows.size(); ) {
-            TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
-            const InputWindow* window = getWindowLocked(touchedWindow.channel);
-            if (window) {
-                touchedWindow.window = window;
-                i += 1;
-            } else {
-#if DEBUG_FOCUS
-                LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
-#endif
-                synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
-                        InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
-                mTouchState.windows.removeAt(i);
-            }
-        }
-
-#if DEBUG_FOCUS
-        //logDispatchStateLocked();
-#endif
-    } // release lock
-
-    // Wake up poll loop since it may need to make new input dispatching choices.
-    mLooper->wake();
-}
-
-void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
-#if DEBUG_FOCUS
-    LOGD("setFocusedApplication");
-#endif
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        releaseFocusedApplicationLocked();
-
-        if (inputApplication) {
-            mFocusedApplicationStorage = *inputApplication;
-            mFocusedApplication = & mFocusedApplicationStorage;
-        }
-
-#if DEBUG_FOCUS
-        //logDispatchStateLocked();
-#endif
-    } // release lock
-
-    // Wake up poll loop since it may need to make new input dispatching choices.
-    mLooper->wake();
-}
-
-void InputDispatcher::releaseFocusedApplicationLocked() {
-    if (mFocusedApplication) {
-        mFocusedApplication = NULL;
-        mFocusedApplicationStorage.handle.clear();
-    }
-}
-
-void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
-#if DEBUG_FOCUS
-    LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
-#endif
-
-    bool changed;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
-            if (mDispatchFrozen && !frozen) {
-                resetANRTimeoutsLocked();
-            }
-
-            if (mDispatchEnabled && !enabled) {
-                resetAndDropEverythingLocked("dispatcher is being disabled");
-            }
-
-            mDispatchEnabled = enabled;
-            mDispatchFrozen = frozen;
-            changed = true;
-        } else {
-            changed = false;
-        }
-
-#if DEBUG_FOCUS
-        //logDispatchStateLocked();
-#endif
-    } // release lock
-
-    if (changed) {
-        // Wake up poll loop since it may need to make new input dispatching choices.
-        mLooper->wake();
-    }
-}
-
-void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
-#if DEBUG_FOCUS
-    LOGD("Resetting and dropping all events (%s).", reason);
-#endif
-
-    synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
-
-    resetKeyRepeatLocked();
-    releasePendingEventLocked();
-    drainInboundQueueLocked();
-    resetTargetsLocked();
-
-    mTouchState.reset();
-}
-
-void InputDispatcher::logDispatchStateLocked() {
-    String8 dump;
-    dumpDispatchStateLocked(dump);
-
-    char* text = dump.lockBuffer(dump.size());
-    char* start = text;
-    while (*start != '\0') {
-        char* end = strchr(start, '\n');
-        if (*end == '\n') {
-            *(end++) = '\0';
-        }
-        LOGD("%s", start);
-        start = end;
-    }
-}
-
-void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
-    dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
-    dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
-
-    if (mFocusedApplication) {
-        dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
-                mFocusedApplication->name.string(),
-                mFocusedApplication->dispatchingTimeout / 1000000.0);
-    } else {
-        dump.append(INDENT "FocusedApplication: <null>\n");
-    }
-    dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
-            mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
-
-    dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
-    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
-    if (!mTouchState.windows.isEmpty()) {
-        dump.append(INDENT "TouchedWindows:\n");
-        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
-            const TouchedWindow& touchedWindow = mTouchState.windows[i];
-            dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
-                    i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
-                    touchedWindow.targetFlags);
-        }
-    } else {
-        dump.append(INDENT "TouchedWindows: <none>\n");
-    }
-
-    if (!mWindows.isEmpty()) {
-        dump.append(INDENT "Windows:\n");
-        for (size_t i = 0; i < mWindows.size(); i++) {
-            const InputWindow& window = mWindows[i];
-            dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
-                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
-                    "frame=[%d,%d][%d,%d], "
-                    "visibleFrame=[%d,%d][%d,%d], "
-                    "touchableArea=[%d,%d][%d,%d], "
-                    "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
-                    i, window.name.string(),
-                    toString(window.paused),
-                    toString(window.hasFocus),
-                    toString(window.hasWallpaper),
-                    toString(window.visible),
-                    toString(window.canReceiveKeys),
-                    window.layoutParamsFlags, window.layoutParamsType,
-                    window.layer,
-                    window.frameLeft, window.frameTop,
-                    window.frameRight, window.frameBottom,
-                    window.visibleFrameLeft, window.visibleFrameTop,
-                    window.visibleFrameRight, window.visibleFrameBottom,
-                    window.touchableAreaLeft, window.touchableAreaTop,
-                    window.touchableAreaRight, window.touchableAreaBottom,
-                    window.ownerPid, window.ownerUid,
-                    window.dispatchingTimeout / 1000000.0);
-        }
-    } else {
-        dump.append(INDENT "Windows: <none>\n");
-    }
-
-    if (!mMonitoringChannels.isEmpty()) {
-        dump.append(INDENT "MonitoringChannels:\n");
-        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
-            const sp<InputChannel>& channel = mMonitoringChannels[i];
-            dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
-        }
-    } else {
-        dump.append(INDENT "MonitoringChannels: <none>\n");
-    }
-
-    dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
-
-    if (!mActiveConnections.isEmpty()) {
-        dump.append(INDENT "ActiveConnections:\n");
-        for (size_t i = 0; i < mActiveConnections.size(); i++) {
-            const Connection* connection = mActiveConnections[i];
-            dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
-                    "inputState.isNeutral=%s\n",
-                    i, connection->getInputChannelName(), connection->getStatusLabel(),
-                    connection->outboundQueue.count(),
-                    toString(connection->inputState.isNeutral()));
-        }
-    } else {
-        dump.append(INDENT "ActiveConnections: <none>\n");
-    }
-
-    if (isAppSwitchPendingLocked()) {
-        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
-                (mAppSwitchDueTime - now()) / 1000000.0);
-    } else {
-        dump.append(INDENT "AppSwitch: not pending\n");
-    }
-}
-
-status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
-#if DEBUG_REGISTRATION
-    LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
-            toString(monitor));
-#endif
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (getConnectionIndexLocked(inputChannel) >= 0) {
-            LOGW("Attempted to register already registered input channel '%s'",
-                    inputChannel->getName().string());
-            return BAD_VALUE;
-        }
-
-        sp<Connection> connection = new Connection(inputChannel);
-        status_t status = connection->initialize();
-        if (status) {
-            LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
-                    inputChannel->getName().string(), status);
-            return status;
-        }
-
-        int32_t receiveFd = inputChannel->getReceivePipeFd();
-        mConnectionsByReceiveFd.add(receiveFd, connection);
-
-        if (monitor) {
-            mMonitoringChannels.push(inputChannel);
-        }
-
-        mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
-
-        runCommandsLockedInterruptible();
-    } // release lock
-    return OK;
-}
-
-status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
-#if DEBUG_REGISTRATION
-    LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
-#endif
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
-        if (connectionIndex < 0) {
-            LOGW("Attempted to unregister already unregistered input channel '%s'",
-                    inputChannel->getName().string());
-            return BAD_VALUE;
-        }
-
-        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-        mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
-
-        connection->status = Connection::STATUS_ZOMBIE;
-
-        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
-            if (mMonitoringChannels[i] == inputChannel) {
-                mMonitoringChannels.removeAt(i);
-                break;
-            }
-        }
-
-        mLooper->removeFd(inputChannel->getReceivePipeFd());
-
-        nsecs_t currentTime = now();
-        abortBrokenDispatchCycleLocked(currentTime, connection);
-
-        runCommandsLockedInterruptible();
-    } // release lock
-
-    // Wake the poll loop because removing the connection may have changed the current
-    // synchronization state.
-    mLooper->wake();
-    return OK;
-}
-
-ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
-    ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
-    if (connectionIndex >= 0) {
-        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-        if (connection->inputChannel.get() == inputChannel.get()) {
-            return connectionIndex;
-        }
-    }
-
-    return -1;
-}
-
-void InputDispatcher::activateConnectionLocked(Connection* connection) {
-    for (size_t i = 0; i < mActiveConnections.size(); i++) {
-        if (mActiveConnections.itemAt(i) == connection) {
-            return;
-        }
-    }
-    mActiveConnections.add(connection);
-}
-
-void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
-    for (size_t i = 0; i < mActiveConnections.size(); i++) {
-        if (mActiveConnections.itemAt(i) == connection) {
-            mActiveConnections.removeAt(i);
-            return;
-        }
-    }
-}
-
-void InputDispatcher::onDispatchCycleStartedLocked(
-        nsecs_t currentTime, const sp<Connection>& connection) {
-}
-
-void InputDispatcher::onDispatchCycleFinishedLocked(
-        nsecs_t currentTime, const sp<Connection>& connection) {
-}
-
-void InputDispatcher::onDispatchCycleBrokenLocked(
-        nsecs_t currentTime, const sp<Connection>& connection) {
-    LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
-            connection->getInputChannelName());
-
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
-    commandEntry->connection = connection;
-}
-
-void InputDispatcher::onANRLocked(
-        nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
-        nsecs_t eventTime, nsecs_t waitStartTime) {
-    LOGI("Application is not responding: %s.  "
-            "%01.1fms since event, %01.1fms since wait started",
-            getApplicationWindowLabelLocked(application, window).string(),
-            (currentTime - eventTime) / 1000000.0,
-            (currentTime - waitStartTime) / 1000000.0);
-
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doNotifyANRLockedInterruptible);
-    if (application) {
-        commandEntry->inputApplicationHandle = application->handle;
-    }
-    if (window) {
-        commandEntry->inputChannel = window->inputChannel;
-    }
-}
-
-void InputDispatcher::doNotifyConfigurationChangedInterruptible(
-        CommandEntry* commandEntry) {
-    mLock.unlock();
-
-    mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
-
-    mLock.lock();
-}
-
-void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
-        CommandEntry* commandEntry) {
-    sp<Connection> connection = commandEntry->connection;
-
-    if (connection->status != Connection::STATUS_ZOMBIE) {
-        mLock.unlock();
-
-        mPolicy->notifyInputChannelBroken(connection->inputChannel);
-
-        mLock.lock();
-    }
-}
-
-void InputDispatcher::doNotifyANRLockedInterruptible(
-        CommandEntry* commandEntry) {
-    mLock.unlock();
-
-    nsecs_t newTimeout = mPolicy->notifyANR(
-            commandEntry->inputApplicationHandle, commandEntry->inputChannel);
-
-    mLock.lock();
-
-    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
-}
-
-void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
-        CommandEntry* commandEntry) {
-    KeyEntry* entry = commandEntry->keyEntry;
-    mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
-            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
-            entry->downTime, entry->eventTime);
-
-    mLock.unlock();
-
-    bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
-            & mReusableKeyEvent, entry->policyFlags);
-
-    mLock.lock();
-
-    entry->interceptKeyResult = consumed
-            ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
-            : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
-    mAllocator.releaseKeyEntry(entry);
-}
-
-void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
-    mLock.unlock();
-
-    mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
-
-    mLock.lock();
-}
-
-void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
-        int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
-    // TODO Write some statistics about how long we spend waiting.
-}
-
-void InputDispatcher::dump(String8& dump) {
-    dump.append("Input Dispatcher State:\n");
-    dumpDispatchStateLocked(dump);
-}
-
-
-// --- InputDispatcher::Queue ---
-
-template <typename T>
-uint32_t InputDispatcher::Queue<T>::count() const {
-    uint32_t result = 0;
-    for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
-        result += 1;
-    }
-    return result;
-}
-
-
-// --- InputDispatcher::Allocator ---
-
-InputDispatcher::Allocator::Allocator() {
-}
-
-InputDispatcher::InjectionState*
-InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
-    InjectionState* injectionState = mInjectionStatePool.alloc();
-    injectionState->refCount = 1;
-    injectionState->injectorPid = injectorPid;
-    injectionState->injectorUid = injectorUid;
-    injectionState->injectionIsAsync = false;
-    injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
-    injectionState->pendingForegroundDispatches = 0;
-    return injectionState;
-}
-
-void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
-        nsecs_t eventTime, uint32_t policyFlags) {
-    entry->type = type;
-    entry->refCount = 1;
-    entry->dispatchInProgress = false;
-    entry->eventTime = eventTime;
-    entry->policyFlags = policyFlags;
-    entry->injectionState = NULL;
-}
-
-void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
-    if (entry->injectionState) {
-        releaseInjectionState(entry->injectionState);
-        entry->injectionState = NULL;
-    }
-}
-
-InputDispatcher::ConfigurationChangedEntry*
-InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
-    ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
-    initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
-    return entry;
-}
-
-InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
-        int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
-        int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
-        int32_t repeatCount, nsecs_t downTime) {
-    KeyEntry* entry = mKeyEntryPool.alloc();
-    initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
-
-    entry->deviceId = deviceId;
-    entry->source = source;
-    entry->action = action;
-    entry->flags = flags;
-    entry->keyCode = keyCode;
-    entry->scanCode = scanCode;
-    entry->metaState = metaState;
-    entry->repeatCount = repeatCount;
-    entry->downTime = downTime;
-    entry->syntheticRepeat = false;
-    entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
-    return entry;
-}
-
-InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
-        int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
-        int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
-        nsecs_t downTime, uint32_t pointerCount,
-        const int32_t* pointerIds, const PointerCoords* pointerCoords) {
-    MotionEntry* entry = mMotionEntryPool.alloc();
-    initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
-
-    entry->eventTime = eventTime;
-    entry->deviceId = deviceId;
-    entry->source = source;
-    entry->action = action;
-    entry->flags = flags;
-    entry->metaState = metaState;
-    entry->edgeFlags = edgeFlags;
-    entry->xPrecision = xPrecision;
-    entry->yPrecision = yPrecision;
-    entry->downTime = downTime;
-    entry->pointerCount = pointerCount;
-    entry->firstSample.eventTime = eventTime;
-    entry->firstSample.next = NULL;
-    entry->lastSample = & entry->firstSample;
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        entry->pointerIds[i] = pointerIds[i];
-        entry->firstSample.pointerCoords[i] = pointerCoords[i];
-    }
-    return entry;
-}
-
-InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
-        EventEntry* eventEntry,
-        int32_t targetFlags, float xOffset, float yOffset) {
-    DispatchEntry* entry = mDispatchEntryPool.alloc();
-    entry->eventEntry = eventEntry;
-    eventEntry->refCount += 1;
-    entry->targetFlags = targetFlags;
-    entry->xOffset = xOffset;
-    entry->yOffset = yOffset;
-    entry->inProgress = false;
-    entry->headMotionSample = NULL;
-    entry->tailMotionSample = NULL;
-    return entry;
-}
-
-InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
-    CommandEntry* entry = mCommandEntryPool.alloc();
-    entry->command = command;
-    return entry;
-}
-
-void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
-    injectionState->refCount -= 1;
-    if (injectionState->refCount == 0) {
-        mInjectionStatePool.free(injectionState);
-    } else {
-        assert(injectionState->refCount > 0);
-    }
-}
-
-void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
-    switch (entry->type) {
-    case EventEntry::TYPE_CONFIGURATION_CHANGED:
-        releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
-        break;
-    case EventEntry::TYPE_KEY:
-        releaseKeyEntry(static_cast<KeyEntry*>(entry));
-        break;
-    case EventEntry::TYPE_MOTION:
-        releaseMotionEntry(static_cast<MotionEntry*>(entry));
-        break;
-    default:
-        assert(false);
-        break;
-    }
-}
-
-void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
-        ConfigurationChangedEntry* entry) {
-    entry->refCount -= 1;
-    if (entry->refCount == 0) {
-        releaseEventEntryInjectionState(entry);
-        mConfigurationChangeEntryPool.free(entry);
-    } else {
-        assert(entry->refCount > 0);
-    }
-}
-
-void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
-    entry->refCount -= 1;
-    if (entry->refCount == 0) {
-        releaseEventEntryInjectionState(entry);
-        mKeyEntryPool.free(entry);
-    } else {
-        assert(entry->refCount > 0);
-    }
-}
-
-void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
-    entry->refCount -= 1;
-    if (entry->refCount == 0) {
-        releaseEventEntryInjectionState(entry);
-        for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
-            MotionSample* next = sample->next;
-            mMotionSamplePool.free(sample);
-            sample = next;
-        }
-        mMotionEntryPool.free(entry);
-    } else {
-        assert(entry->refCount > 0);
-    }
-}
-
-void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
-    releaseEventEntry(entry->eventEntry);
-    mDispatchEntryPool.free(entry);
-}
-
-void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
-    mCommandEntryPool.free(entry);
-}
-
-void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
-        nsecs_t eventTime, const PointerCoords* pointerCoords) {
-    MotionSample* sample = mMotionSamplePool.alloc();
-    sample->eventTime = eventTime;
-    uint32_t pointerCount = motionEntry->pointerCount;
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        sample->pointerCoords[i] = pointerCoords[i];
-    }
-
-    sample->next = NULL;
-    motionEntry->lastSample->next = sample;
-    motionEntry->lastSample = sample;
-}
-
-void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
-    releaseEventEntryInjectionState(keyEntry);
-
-    keyEntry->dispatchInProgress = false;
-    keyEntry->syntheticRepeat = false;
-    keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
-}
-
-
-// --- InputDispatcher::MotionEntry ---
-
-uint32_t InputDispatcher::MotionEntry::countSamples() const {
-    uint32_t count = 1;
-    for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
-        count += 1;
-    }
-    return count;
-}
-
-
-// --- InputDispatcher::InputState ---
-
-InputDispatcher::InputState::InputState() {
-}
-
-InputDispatcher::InputState::~InputState() {
-}
-
-bool InputDispatcher::InputState::isNeutral() const {
-    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
-}
-
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
-        const EventEntry* entry) {
-    switch (entry->type) {
-    case EventEntry::TYPE_KEY:
-        return trackKey(static_cast<const KeyEntry*>(entry));
-
-    case EventEntry::TYPE_MOTION:
-        return trackMotion(static_cast<const MotionEntry*>(entry));
-
-    default:
-        return CONSISTENT;
-    }
-}
-
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
-        const KeyEntry* entry) {
-    int32_t action = entry->action;
-    for (size_t i = 0; i < mKeyMementos.size(); i++) {
-        KeyMemento& memento = mKeyMementos.editItemAt(i);
-        if (memento.deviceId == entry->deviceId
-                && memento.source == entry->source
-                && memento.keyCode == entry->keyCode
-                && memento.scanCode == entry->scanCode) {
-            switch (action) {
-            case AKEY_EVENT_ACTION_UP:
-                mKeyMementos.removeAt(i);
-                return CONSISTENT;
-
-            case AKEY_EVENT_ACTION_DOWN:
-                return TOLERABLE;
-
-            default:
-                return BROKEN;
-            }
-        }
-    }
-
-    switch (action) {
-    case AKEY_EVENT_ACTION_DOWN: {
-        mKeyMementos.push();
-        KeyMemento& memento = mKeyMementos.editTop();
-        memento.deviceId = entry->deviceId;
-        memento.source = entry->source;
-        memento.keyCode = entry->keyCode;
-        memento.scanCode = entry->scanCode;
-        memento.downTime = entry->downTime;
-        return CONSISTENT;
-    }
-
-    default:
-        return BROKEN;
-    }
-}
-
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
-        const MotionEntry* entry) {
-    int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
-    for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        MotionMemento& memento = mMotionMementos.editItemAt(i);
-        if (memento.deviceId == entry->deviceId
-                && memento.source == entry->source) {
-            switch (action) {
-            case AMOTION_EVENT_ACTION_UP:
-            case AMOTION_EVENT_ACTION_CANCEL:
-                mMotionMementos.removeAt(i);
-                return CONSISTENT;
-
-            case AMOTION_EVENT_ACTION_DOWN:
-                return TOLERABLE;
-
-            case AMOTION_EVENT_ACTION_POINTER_DOWN:
-                if (entry->pointerCount == memento.pointerCount + 1) {
-                    memento.setPointers(entry);
-                    return CONSISTENT;
-                }
-                return BROKEN;
-
-            case AMOTION_EVENT_ACTION_POINTER_UP:
-                if (entry->pointerCount == memento.pointerCount - 1) {
-                    memento.setPointers(entry);
-                    return CONSISTENT;
-                }
-                return BROKEN;
-
-            case AMOTION_EVENT_ACTION_MOVE:
-                if (entry->pointerCount == memento.pointerCount) {
-                    return CONSISTENT;
-                }
-                return BROKEN;
-
-            default:
-                return BROKEN;
-            }
-        }
-    }
-
-    switch (action) {
-    case AMOTION_EVENT_ACTION_DOWN: {
-        mMotionMementos.push();
-        MotionMemento& memento = mMotionMementos.editTop();
-        memento.deviceId = entry->deviceId;
-        memento.source = entry->source;
-        memento.xPrecision = entry->xPrecision;
-        memento.yPrecision = entry->yPrecision;
-        memento.downTime = entry->downTime;
-        memento.setPointers(entry);
-        return CONSISTENT;
-    }
-
-    default:
-        return BROKEN;
-    }
-}
-
-void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
-    pointerCount = entry->pointerCount;
-    for (uint32_t i = 0; i < entry->pointerCount; i++) {
-        pointerIds[i] = entry->pointerIds[i];
-        pointerCoords[i] = entry->lastSample->pointerCoords[i];
-    }
-}
-
-void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
-        Allocator* allocator, Vector<EventEntry*>& outEvents,
-        CancelationOptions options) {
-    for (size_t i = 0; i < mKeyMementos.size(); ) {
-        const KeyMemento& memento = mKeyMementos.itemAt(i);
-        if (shouldCancelEvent(memento.source, options)) {
-            outEvents.push(allocator->obtainKeyEntry(currentTime,
-                    memento.deviceId, memento.source, 0,
-                    AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
-                    memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
-            mKeyMementos.removeAt(i);
-        } else {
-            i += 1;
-        }
-    }
-
-    for (size_t i = 0; i < mMotionMementos.size(); ) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
-        if (shouldCancelEvent(memento.source, options)) {
-            outEvents.push(allocator->obtainMotionEntry(currentTime,
-                    memento.deviceId, memento.source, 0,
-                    AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
-                    memento.xPrecision, memento.yPrecision, memento.downTime,
-                    memento.pointerCount, memento.pointerIds, memento.pointerCoords));
-            mMotionMementos.removeAt(i);
-        } else {
-            i += 1;
-        }
-    }
-}
-
-void InputDispatcher::InputState::clear() {
-    mKeyMementos.clear();
-    mMotionMementos.clear();
-}
-
-bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
-        CancelationOptions options) {
-    switch (options) {
-    case CANCEL_POINTER_EVENTS:
-        return eventSource & AINPUT_SOURCE_CLASS_POINTER;
-    case CANCEL_NON_POINTER_EVENTS:
-        return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
-    default:
-        return true;
-    }
-}
-
-
-// --- InputDispatcher::Connection ---
-
-InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
-        status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
-        lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
-}
-
-InputDispatcher::Connection::~Connection() {
-}
-
-status_t InputDispatcher::Connection::initialize() {
-    return inputPublisher.initialize();
-}
-
-const char* InputDispatcher::Connection::getStatusLabel() const {
-    switch (status) {
-    case STATUS_NORMAL:
-        return "NORMAL";
-
-    case STATUS_BROKEN:
-        return "BROKEN";
-
-    case STATUS_ZOMBIE:
-        return "ZOMBIE";
-
-    default:
-        return "UNKNOWN";
-    }
-}
-
-InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
-        const EventEntry* eventEntry) const {
-    for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
-            dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
-        if (dispatchEntry->eventEntry == eventEntry) {
-            return dispatchEntry;
-        }
-    }
-    return NULL;
-}
-
-
-// --- InputDispatcher::CommandEntry ---
-
-InputDispatcher::CommandEntry::CommandEntry() :
-    keyEntry(NULL) {
-}
-
-InputDispatcher::CommandEntry::~CommandEntry() {
-}
-
-
-// --- InputDispatcher::TouchState ---
-
-InputDispatcher::TouchState::TouchState() :
-    down(false), split(false) {
-}
-
-InputDispatcher::TouchState::~TouchState() {
-}
-
-void InputDispatcher::TouchState::reset() {
-    down = false;
-    split = false;
-    windows.clear();
-}
-
-void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
-    down = other.down;
-    split = other.split;
-    windows.clear();
-    windows.appendVector(other.windows);
-}
-
-void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
-        int32_t targetFlags, BitSet32 pointerIds) {
-    if (targetFlags & InputTarget::FLAG_SPLIT) {
-        split = true;
-    }
-
-    for (size_t i = 0; i < windows.size(); i++) {
-        TouchedWindow& touchedWindow = windows.editItemAt(i);
-        if (touchedWindow.window == window) {
-            touchedWindow.targetFlags |= targetFlags;
-            touchedWindow.pointerIds.value |= pointerIds.value;
-            return;
-        }
-    }
-
-    windows.push();
-
-    TouchedWindow& touchedWindow = windows.editTop();
-    touchedWindow.window = window;
-    touchedWindow.targetFlags = targetFlags;
-    touchedWindow.pointerIds = pointerIds;
-    touchedWindow.channel = window->inputChannel;
-}
-
-void InputDispatcher::TouchState::removeOutsideTouchWindows() {
-    for (size_t i = 0 ; i < windows.size(); ) {
-        if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
-            windows.removeAt(i);
-        } else {
-            i += 1;
-        }
-    }
-}
-
-const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
-    for (size_t i = 0; i < windows.size(); i++) {
-        if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
-            return windows[i].window;
-        }
-    }
-    return NULL;
-}
-
-
-// --- InputDispatcherThread ---
-
-InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
-        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
-}
-
-InputDispatcherThread::~InputDispatcherThread() {
-}
-
-bool InputDispatcherThread::threadLoop() {
-    mDispatcher->dispatchOnce();
-    return true;
-}
-
-} // namespace android
diff --git a/libs/ui/InputManager.cpp b/libs/ui/InputManager.cpp
deleted file mode 100644
index 09fce38..0000000
--- a/libs/ui/InputManager.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// The input manager.
-//
-#define LOG_TAG "InputManager"
-
-//#define LOG_NDEBUG 0
-
-#include <cutils/log.h>
-#include <ui/InputManager.h>
-#include <ui/InputReader.h>
-#include <ui/InputDispatcher.h>
-
-namespace android {
-
-InputManager::InputManager(
-        const sp<EventHubInterface>& eventHub,
-        const sp<InputReaderPolicyInterface>& readerPolicy,
-        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
-    mDispatcher = new InputDispatcher(dispatcherPolicy);
-    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
-    initialize();
-}
-
-InputManager::InputManager(
-        const sp<InputReaderInterface>& reader,
-        const sp<InputDispatcherInterface>& dispatcher) :
-        mReader(reader),
-        mDispatcher(dispatcher) {
-    initialize();
-}
-
-InputManager::~InputManager() {
-    stop();
-}
-
-void InputManager::initialize() {
-    mReaderThread = new InputReaderThread(mReader);
-    mDispatcherThread = new InputDispatcherThread(mDispatcher);
-}
-
-status_t InputManager::start() {
-    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
-    if (result) {
-        LOGE("Could not start InputDispatcher thread due to error %d.", result);
-        return result;
-    }
-
-    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
-    if (result) {
-        LOGE("Could not start InputReader thread due to error %d.", result);
-
-        mDispatcherThread->requestExit();
-        return result;
-    }
-
-    return OK;
-}
-
-status_t InputManager::stop() {
-    status_t result = mReaderThread->requestExitAndWait();
-    if (result) {
-        LOGW("Could not stop InputReader thread due to error %d.", result);
-    }
-
-    result = mDispatcherThread->requestExitAndWait();
-    if (result) {
-        LOGW("Could not stop InputDispatcher thread due to error %d.", result);
-    }
-
-    return OK;
-}
-
-sp<InputReaderInterface> InputManager::getReader() {
-    return mReader;
-}
-
-sp<InputDispatcherInterface> InputManager::getDispatcher() {
-    return mDispatcher;
-}
-
-} // namespace android
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
deleted file mode 100644
index 34e44e4..0000000
--- a/libs/ui/InputReader.cpp
+++ /dev/null
@@ -1,3528 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// The input reader.
-//
-#define LOG_TAG "InputReader"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages for each raw event received from the EventHub.
-#define DEBUG_RAW_EVENTS 0
-
-// Log debug messages about touch screen filtering hacks.
-#define DEBUG_HACKS 0
-
-// Log debug messages about virtual key processing.
-#define DEBUG_VIRTUAL_KEYS 0
-
-// Log debug messages about pointers.
-#define DEBUG_POINTERS 0
-
-// Log debug messages about pointer assignment calculations.
-#define DEBUG_POINTER_ASSIGNMENT 0
-
-#include <cutils/log.h>
-#include <ui/InputReader.h>
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-#include <math.h>
-
-#define INDENT "  "
-#define INDENT2 "    "
-#define INDENT3 "      "
-#define INDENT4 "        "
-
-namespace android {
-
-// --- Static Functions ---
-
-template<typename T>
-inline static T abs(const T& value) {
-    return value < 0 ? - value : value;
-}
-
-template<typename T>
-inline static T min(const T& a, const T& b) {
-    return a < b ? a : b;
-}
-
-template<typename T>
-inline static void swap(T& a, T& b) {
-    T temp = a;
-    a = b;
-    b = temp;
-}
-
-inline static float avg(float x, float y) {
-    return (x + y) / 2;
-}
-
-inline static float pythag(float x, float y) {
-    return sqrtf(x * x + y * y);
-}
-
-static inline const char* toString(bool value) {
-    return value ? "true" : "false";
-}
-
-
-int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
-    int32_t mask;
-    switch (keyCode) {
-    case AKEYCODE_ALT_LEFT:
-        mask = AMETA_ALT_LEFT_ON;
-        break;
-    case AKEYCODE_ALT_RIGHT:
-        mask = AMETA_ALT_RIGHT_ON;
-        break;
-    case AKEYCODE_SHIFT_LEFT:
-        mask = AMETA_SHIFT_LEFT_ON;
-        break;
-    case AKEYCODE_SHIFT_RIGHT:
-        mask = AMETA_SHIFT_RIGHT_ON;
-        break;
-    case AKEYCODE_SYM:
-        mask = AMETA_SYM_ON;
-        break;
-    default:
-        return oldMetaState;
-    }
-
-    int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask
-            & ~ (AMETA_ALT_ON | AMETA_SHIFT_ON);
-
-    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
-        newMetaState |= AMETA_ALT_ON;
-    }
-
-    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
-        newMetaState |= AMETA_SHIFT_ON;
-    }
-
-    return newMetaState;
-}
-
-static const int32_t keyCodeRotationMap[][4] = {
-        // key codes enumerated counter-clockwise with the original (unrotated) key first
-        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
-        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
-        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
-        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
-        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
-};
-static const int keyCodeRotationMapSize =
-        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
-
-int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
-    if (orientation != InputReaderPolicyInterface::ROTATION_0) {
-        for (int i = 0; i < keyCodeRotationMapSize; i++) {
-            if (keyCode == keyCodeRotationMap[i][0]) {
-                return keyCodeRotationMap[i][orientation];
-            }
-        }
-    }
-    return keyCode;
-}
-
-static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
-    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
-}
-
-
-// --- InputDeviceCalibration ---
-
-InputDeviceCalibration::InputDeviceCalibration() {
-}
-
-void InputDeviceCalibration::clear() {
-    mProperties.clear();
-}
-
-void InputDeviceCalibration::addProperty(const String8& key, const String8& value) {
-    mProperties.add(key, value);
-}
-
-bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const {
-    ssize_t index = mProperties.indexOfKey(key);
-    if (index < 0) {
-        return false;
-    }
-
-    outValue = mProperties.valueAt(index);
-    return true;
-}
-
-bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const {
-    String8 stringValue;
-    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
-        return false;
-    }
-
-    char* end;
-    int value = strtol(stringValue.string(), & end, 10);
-    if (*end != '\0') {
-        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected an integer.",
-                key.string(), stringValue.string());
-        return false;
-    }
-    outValue = value;
-    return true;
-}
-
-bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const {
-    String8 stringValue;
-    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
-        return false;
-    }
-
-    char* end;
-    float value = strtof(stringValue.string(), & end);
-    if (*end != '\0') {
-        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected a float.",
-                key.string(), stringValue.string());
-        return false;
-    }
-    outValue = value;
-    return true;
-}
-
-
-// --- InputReader ---
-
-InputReader::InputReader(const sp<EventHubInterface>& eventHub,
-        const sp<InputReaderPolicyInterface>& policy,
-        const sp<InputDispatcherInterface>& dispatcher) :
-        mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
-        mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
-    configureExcludedDevices();
-    updateGlobalMetaState();
-    updateInputConfiguration();
-}
-
-InputReader::~InputReader() {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        delete mDevices.valueAt(i);
-    }
-}
-
-void InputReader::loopOnce() {
-    RawEvent rawEvent;
-    mEventHub->getEvent(& rawEvent);
-
-#if DEBUG_RAW_EVENTS
-    LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d",
-            rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
-            rawEvent.value);
-#endif
-
-    process(& rawEvent);
-}
-
-void InputReader::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EventHubInterface::DEVICE_ADDED:
-        addDevice(rawEvent->deviceId);
-        break;
-
-    case EventHubInterface::DEVICE_REMOVED:
-        removeDevice(rawEvent->deviceId);
-        break;
-
-    case EventHubInterface::FINISHED_DEVICE_SCAN:
-        handleConfigurationChanged(rawEvent->when);
-        break;
-
-    default:
-        consumeEvent(rawEvent);
-        break;
-    }
-}
-
-void InputReader::addDevice(int32_t deviceId) {
-    String8 name = mEventHub->getDeviceName(deviceId);
-    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
-
-    InputDevice* device = createDevice(deviceId, name, classes);
-    device->configure();
-
-    if (device->isIgnored()) {
-        LOGI("Device added: id=0x%x, name=%s (ignored non-input device)", deviceId, name.string());
-    } else {
-        LOGI("Device added: id=0x%x, name=%s, sources=%08x", deviceId, name.string(),
-                device->getSources());
-    }
-
-    bool added = false;
-    { // acquire device registry writer lock
-        RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex < 0) {
-            mDevices.add(deviceId, device);
-            added = true;
-        }
-    } // release device registry writer lock
-
-    if (! added) {
-        LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
-        delete device;
-        return;
-    }
-}
-
-void InputReader::removeDevice(int32_t deviceId) {
-    bool removed = false;
-    InputDevice* device = NULL;
-    { // acquire device registry writer lock
-        RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex >= 0) {
-            device = mDevices.valueAt(deviceIndex);
-            mDevices.removeItemsAt(deviceIndex, 1);
-            removed = true;
-        }
-    } // release device registry writer lock
-
-    if (! removed) {
-        LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
-        return;
-    }
-
-    if (device->isIgnored()) {
-        LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)",
-                device->getId(), device->getName().string());
-    } else {
-        LOGI("Device removed: id=0x%x, name=%s, sources=%08x",
-                device->getId(), device->getName().string(), device->getSources());
-    }
-
-    device->reset();
-
-    delete device;
-}
-
-InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
-    InputDevice* device = new InputDevice(this, deviceId, name);
-
-    const int32_t associatedDisplayId = 0; // FIXME: hardcoded for current single-display devices
-
-    // Switch-like devices.
-    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
-        device->addMapper(new SwitchInputMapper(device));
-    }
-
-    // Keyboard-like devices.
-    uint32_t keyboardSources = 0;
-    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
-    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
-        keyboardSources |= AINPUT_SOURCE_KEYBOARD;
-    }
-    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
-        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
-    }
-    if (classes & INPUT_DEVICE_CLASS_DPAD) {
-        keyboardSources |= AINPUT_SOURCE_DPAD;
-    }
-
-    if (keyboardSources != 0) {
-        device->addMapper(new KeyboardInputMapper(device,
-                associatedDisplayId, keyboardSources, keyboardType));
-    }
-
-    // Trackball-like devices.
-    if (classes & INPUT_DEVICE_CLASS_TRACKBALL) {
-        device->addMapper(new TrackballInputMapper(device, associatedDisplayId));
-    }
-
-    // Touchscreen-like devices.
-    if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT) {
-        device->addMapper(new MultiTouchInputMapper(device, associatedDisplayId));
-    } else if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN) {
-        device->addMapper(new SingleTouchInputMapper(device, associatedDisplayId));
-    }
-
-    return device;
-}
-
-void InputReader::consumeEvent(const RawEvent* rawEvent) {
-    int32_t deviceId = rawEvent->deviceId;
-
-    { // acquire device registry reader lock
-        RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex < 0) {
-            LOGW("Discarding event for unknown deviceId %d.", deviceId);
-            return;
-        }
-
-        InputDevice* device = mDevices.valueAt(deviceIndex);
-        if (device->isIgnored()) {
-            //LOGD("Discarding event for ignored deviceId %d.", deviceId);
-            return;
-        }
-
-        device->process(rawEvent);
-    } // release device registry reader lock
-}
-
-void InputReader::handleConfigurationChanged(nsecs_t when) {
-    // Reset global meta state because it depends on the list of all configured devices.
-    updateGlobalMetaState();
-
-    // Update input configuration.
-    updateInputConfiguration();
-
-    // Enqueue configuration changed.
-    mDispatcher->notifyConfigurationChanged(when);
-}
-
-void InputReader::configureExcludedDevices() {
-    Vector<String8> excludedDeviceNames;
-    mPolicy->getExcludedDeviceNames(excludedDeviceNames);
-
-    for (size_t i = 0; i < excludedDeviceNames.size(); i++) {
-        mEventHub->addExcludedDevice(excludedDeviceNames[i]);
-    }
-}
-
-void InputReader::updateGlobalMetaState() {
-    { // acquire state lock
-        AutoMutex _l(mStateLock);
-
-        mGlobalMetaState = 0;
-
-        { // acquire device registry reader lock
-            RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
-            for (size_t i = 0; i < mDevices.size(); i++) {
-                InputDevice* device = mDevices.valueAt(i);
-                mGlobalMetaState |= device->getMetaState();
-            }
-        } // release device registry reader lock
-    } // release state lock
-}
-
-int32_t InputReader::getGlobalMetaState() {
-    { // acquire state lock
-        AutoMutex _l(mStateLock);
-
-        return mGlobalMetaState;
-    } // release state lock
-}
-
-void InputReader::updateInputConfiguration() {
-    { // acquire state lock
-        AutoMutex _l(mStateLock);
-
-        int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
-        int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
-        int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
-        { // acquire device registry reader lock
-            RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
-            InputDeviceInfo deviceInfo;
-            for (size_t i = 0; i < mDevices.size(); i++) {
-                InputDevice* device = mDevices.valueAt(i);
-                device->getDeviceInfo(& deviceInfo);
-                uint32_t sources = deviceInfo.getSources();
-
-                if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
-                    touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
-                }
-                if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
-                    navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
-                } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
-                    navigationConfig = InputConfiguration::NAVIGATION_DPAD;
-                }
-                if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
-                    keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
-                }
-            }
-        } // release device registry reader lock
-
-        mInputConfiguration.touchScreen = touchScreenConfig;
-        mInputConfiguration.keyboard = keyboardConfig;
-        mInputConfiguration.navigation = navigationConfig;
-    } // release state lock
-}
-
-void InputReader::disableVirtualKeysUntil(nsecs_t time) {
-    mDisableVirtualKeysTimeout = time;
-}
-
-bool InputReader::shouldDropVirtualKey(nsecs_t now,
-        InputDevice* device, int32_t keyCode, int32_t scanCode) {
-    if (now < mDisableVirtualKeysTimeout) {
-        LOGI("Dropping virtual key from device %s because virtual keys are "
-                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
-                device->getName().string(),
-                (mDisableVirtualKeysTimeout - now) * 0.000001,
-                keyCode, scanCode);
-        return true;
-    } else {
-        return false;
-    }
-}
-
-void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
-    { // acquire state lock
-        AutoMutex _l(mStateLock);
-
-        *outConfiguration = mInputConfiguration;
-    } // release state lock
-}
-
-status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
-    { // acquire device registry reader lock
-        RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex < 0) {
-            return NAME_NOT_FOUND;
-        }
-
-        InputDevice* device = mDevices.valueAt(deviceIndex);
-        if (device->isIgnored()) {
-            return NAME_NOT_FOUND;
-        }
-
-        device->getDeviceInfo(outDeviceInfo);
-        return OK;
-    } // release device registy reader lock
-}
-
-void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
-    outDeviceIds.clear();
-
-    { // acquire device registry reader lock
-        RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
-        size_t numDevices = mDevices.size();
-        for (size_t i = 0; i < numDevices; i++) {
-            InputDevice* device = mDevices.valueAt(i);
-            if (! device->isIgnored()) {
-                outDeviceIds.add(device->getId());
-            }
-        }
-    } // release device registy reader lock
-}
-
-int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
-        int32_t keyCode) {
-    return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState);
-}
-
-int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
-        int32_t scanCode) {
-    return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState);
-}
-
-int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
-    return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState);
-}
-
-int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
-        GetStateFunc getStateFunc) {
-    { // acquire device registry reader lock
-        RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
-        int32_t result = AKEY_STATE_UNKNOWN;
-        if (deviceId >= 0) {
-            ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-            if (deviceIndex >= 0) {
-                InputDevice* device = mDevices.valueAt(deviceIndex);
-                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                    result = (device->*getStateFunc)(sourceMask, code);
-                }
-            }
-        } else {
-            size_t numDevices = mDevices.size();
-            for (size_t i = 0; i < numDevices; i++) {
-                InputDevice* device = mDevices.valueAt(i);
-                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                    result = (device->*getStateFunc)(sourceMask, code);
-                    if (result >= AKEY_STATE_DOWN) {
-                        return result;
-                    }
-                }
-            }
-        }
-        return result;
-    } // release device registy reader lock
-}
-
-bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
-        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
-    memset(outFlags, 0, numCodes);
-    return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags);
-}
-
-bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    { // acquire device registry reader lock
-        RWLock::AutoRLock _rl(mDeviceRegistryLock);
-        bool result = false;
-        if (deviceId >= 0) {
-            ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-            if (deviceIndex >= 0) {
-                InputDevice* device = mDevices.valueAt(deviceIndex);
-                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                    result = device->markSupportedKeyCodes(sourceMask,
-                            numCodes, keyCodes, outFlags);
-                }
-            }
-        } else {
-            size_t numDevices = mDevices.size();
-            for (size_t i = 0; i < numDevices; i++) {
-                InputDevice* device = mDevices.valueAt(i);
-                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                    result |= device->markSupportedKeyCodes(sourceMask,
-                            numCodes, keyCodes, outFlags);
-                }
-            }
-        }
-        return result;
-    } // release device registy reader lock
-}
-
-void InputReader::dump(String8& dump) {
-    mEventHub->dump(dump);
-    dump.append("\n");
-
-    dump.append("Input Reader State:\n");
-
-    { // acquire device registry reader lock
-        RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
-        for (size_t i = 0; i < mDevices.size(); i++) {
-            mDevices.valueAt(i)->dump(dump);
-        }
-    } // release device registy reader lock
-}
-
-
-// --- InputReaderThread ---
-
-InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
-        Thread(/*canCallJava*/ true), mReader(reader) {
-}
-
-InputReaderThread::~InputReaderThread() {
-}
-
-bool InputReaderThread::threadLoop() {
-    mReader->loopOnce();
-    return true;
-}
-
-
-// --- InputDevice ---
-
-InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) :
-        mContext(context), mId(id), mName(name), mSources(0) {
-}
-
-InputDevice::~InputDevice() {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        delete mMappers[i];
-    }
-    mMappers.clear();
-}
-
-static void dumpMotionRange(String8& dump, const InputDeviceInfo& deviceInfo,
-        int32_t rangeType, const char* name) {
-    const InputDeviceInfo::MotionRange* range = deviceInfo.getMotionRange(rangeType);
-    if (range) {
-        dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
-                name, range->min, range->max, range->flat, range->fuzz);
-    }
-}
-
-void InputDevice::dump(String8& dump) {
-    InputDeviceInfo deviceInfo;
-    getDeviceInfo(& deviceInfo);
-
-    dump.appendFormat(INDENT "Device 0x%x: %s\n", deviceInfo.getId(),
-            deviceInfo.getName().string());
-    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
-    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
-    if (!deviceInfo.getMotionRanges().isEmpty()) {
-        dump.append(INDENT2 "Motion Ranges:\n");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_X, "X");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_Y, "Y");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_PRESSURE, "Pressure");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_SIZE, "Size");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MAJOR, "TouchMajor");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MINOR, "TouchMinor");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MAJOR, "ToolMajor");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MINOR, "ToolMinor");
-        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_ORIENTATION, "Orientation");
-    }
-
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->dump(dump);
-    }
-}
-
-void InputDevice::addMapper(InputMapper* mapper) {
-    mMappers.add(mapper);
-}
-
-void InputDevice::configure() {
-    if (! isIgnored()) {
-        mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration);
-    }
-
-    mSources = 0;
-
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->configure();
-        mSources |= mapper->getSources();
-    }
-}
-
-void InputDevice::reset() {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->reset();
-    }
-}
-
-void InputDevice::process(const RawEvent* rawEvent) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->process(rawEvent);
-    }
-}
-
-void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
-    outDeviceInfo->initialize(mId, mName);
-
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->populateDeviceInfo(outDeviceInfo);
-    }
-}
-
-int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
-}
-
-int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
-}
-
-int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
-}
-
-int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
-    int32_t result = AKEY_STATE_UNKNOWN;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
-            result = (mapper->*getStateFunc)(sourceMask, code);
-            if (result >= AKEY_STATE_DOWN) {
-                return result;
-            }
-        }
-    }
-    return result;
-}
-
-bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    bool result = false;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
-            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
-        }
-    }
-    return result;
-}
-
-int32_t InputDevice::getMetaState() {
-    int32_t result = 0;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        result |= mapper->getMetaState();
-    }
-    return result;
-}
-
-
-// --- InputMapper ---
-
-InputMapper::InputMapper(InputDevice* device) :
-        mDevice(device), mContext(device->getContext()) {
-}
-
-InputMapper::~InputMapper() {
-}
-
-void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    info->addSource(getSources());
-}
-
-void InputMapper::dump(String8& dump) {
-}
-
-void InputMapper::configure() {
-}
-
-void InputMapper::reset() {
-}
-
-int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-    return AKEY_STATE_UNKNOWN;
-}
-
-bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    return false;
-}
-
-int32_t InputMapper::getMetaState() {
-    return 0;
-}
-
-
-// --- SwitchInputMapper ---
-
-SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
-        InputMapper(device) {
-}
-
-SwitchInputMapper::~SwitchInputMapper() {
-}
-
-uint32_t SwitchInputMapper::getSources() {
-    return AINPUT_SOURCE_SWITCH;
-}
-
-void SwitchInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_SW:
-        processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value);
-        break;
-    }
-}
-
-void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
-    getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
-}
-
-int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
-}
-
-
-// --- KeyboardInputMapper ---
-
-KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId,
-        uint32_t sources, int32_t keyboardType) :
-        InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources),
-        mKeyboardType(keyboardType) {
-    initializeLocked();
-}
-
-KeyboardInputMapper::~KeyboardInputMapper() {
-}
-
-void KeyboardInputMapper::initializeLocked() {
-    mLocked.metaState = AMETA_NONE;
-    mLocked.downTime = 0;
-}
-
-uint32_t KeyboardInputMapper::getSources() {
-    return mSources;
-}
-
-void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    info->setKeyboardType(mKeyboardType);
-}
-
-void KeyboardInputMapper::dump(String8& dump) {
-    { // acquire lock
-        AutoMutex _l(mLock);
-        dump.append(INDENT2 "Keyboard Input Mapper:\n");
-        dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
-        dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
-        dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size());
-        dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState);
-        dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
-    } // release lock
-}
-
-void KeyboardInputMapper::reset() {
-    for (;;) {
-        int32_t keyCode, scanCode;
-        { // acquire lock
-            AutoMutex _l(mLock);
-
-            // Synthesize key up event on reset if keys are currently down.
-            if (mLocked.keyDowns.isEmpty()) {
-                initializeLocked();
-                break; // done
-            }
-
-            const KeyDown& keyDown = mLocked.keyDowns.top();
-            keyCode = keyDown.keyCode;
-            scanCode = keyDown.scanCode;
-        } // release lock
-
-        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-        processKey(when, false, keyCode, scanCode, 0);
-    }
-
-    InputMapper::reset();
-    getContext()->updateGlobalMetaState();
-}
-
-void KeyboardInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_KEY: {
-        int32_t scanCode = rawEvent->scanCode;
-        if (isKeyboardOrGamepadKey(scanCode)) {
-            processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
-                    rawEvent->flags);
-        }
-        break;
-    }
-    }
-}
-
-bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
-    return scanCode < BTN_MOUSE
-        || scanCode >= KEY_OK
-        || (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
-}
-
-void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
-        int32_t scanCode, uint32_t policyFlags) {
-    int32_t newMetaState;
-    nsecs_t downTime;
-    bool metaStateChanged = false;
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (down) {
-            // Rotate key codes according to orientation if needed.
-            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
-            if (mAssociatedDisplayId >= 0) {
-                int32_t orientation;
-                if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
-                    return;
-                }
-
-                keyCode = rotateKeyCode(keyCode, orientation);
-            }
-
-            // Add key down.
-            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
-            if (keyDownIndex >= 0) {
-                // key repeat, be sure to use same keycode as before in case of rotation
-                keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
-            } else {
-                // key down
-                if ((policyFlags & POLICY_FLAG_VIRTUAL)
-                        && mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {
-                    return;
-                }
-
-                mLocked.keyDowns.push();
-                KeyDown& keyDown = mLocked.keyDowns.editTop();
-                keyDown.keyCode = keyCode;
-                keyDown.scanCode = scanCode;
-            }
-
-            mLocked.downTime = when;
-        } else {
-            // Remove key down.
-            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
-            if (keyDownIndex >= 0) {
-                // key up, be sure to use same keycode as before in case of rotation
-                keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
-                mLocked.keyDowns.removeAt(size_t(keyDownIndex));
-            } else {
-                // key was not actually down
-                LOGI("Dropping key up from device %s because the key was not down.  "
-                        "keyCode=%d, scanCode=%d",
-                        getDeviceName().string(), keyCode, scanCode);
-                return;
-            }
-        }
-
-        int32_t oldMetaState = mLocked.metaState;
-        newMetaState = updateMetaState(keyCode, down, oldMetaState);
-        if (oldMetaState != newMetaState) {
-            mLocked.metaState = newMetaState;
-            metaStateChanged = true;
-        }
-
-        downTime = mLocked.downTime;
-    } // release lock
-
-    if (metaStateChanged) {
-        getContext()->updateGlobalMetaState();
-    }
-
-    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
-            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
-            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
-}
-
-ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
-    size_t n = mLocked.keyDowns.size();
-    for (size_t i = 0; i < n; i++) {
-        if (mLocked.keyDowns[i].scanCode == scanCode) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
-}
-
-int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
-}
-
-bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
-}
-
-int32_t KeyboardInputMapper::getMetaState() {
-    { // acquire lock
-        AutoMutex _l(mLock);
-        return mLocked.metaState;
-    } // release lock
-}
-
-
-// --- TrackballInputMapper ---
-
-TrackballInputMapper::TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId) :
-        InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
-    mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
-    mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
-    mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
-    mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
-
-    initializeLocked();
-}
-
-TrackballInputMapper::~TrackballInputMapper() {
-}
-
-uint32_t TrackballInputMapper::getSources() {
-    return AINPUT_SOURCE_TRACKBALL;
-}
-
-void TrackballInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    info->addMotionRange(AINPUT_MOTION_RANGE_X, -1.0f, 1.0f, 0.0f, mXScale);
-    info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
-}
-
-void TrackballInputMapper::dump(String8& dump) {
-    { // acquire lock
-        AutoMutex _l(mLock);
-        dump.append(INDENT2 "Trackball Input Mapper:\n");
-        dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
-        dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
-        dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
-        dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
-        dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
-    } // release lock
-}
-
-void TrackballInputMapper::initializeLocked() {
-    mAccumulator.clear();
-
-    mLocked.down = false;
-    mLocked.downTime = 0;
-}
-
-void TrackballInputMapper::reset() {
-    for (;;) {
-        { // acquire lock
-            AutoMutex _l(mLock);
-
-            if (! mLocked.down) {
-                initializeLocked();
-                break; // done
-            }
-        } // release lock
-
-        // Synthesize trackball button up event on reset.
-        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-        mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
-        mAccumulator.btnMouse = false;
-        sync(when);
-    }
-
-    InputMapper::reset();
-}
-
-void TrackballInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_KEY:
-        switch (rawEvent->scanCode) {
-        case BTN_MOUSE:
-            mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
-            mAccumulator.btnMouse = rawEvent->value != 0;
-            // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
-            // we need to ensure that we report the up/down promptly.
-            sync(rawEvent->when);
-            break;
-        }
-        break;
-
-    case EV_REL:
-        switch (rawEvent->scanCode) {
-        case REL_X:
-            mAccumulator.fields |= Accumulator::FIELD_REL_X;
-            mAccumulator.relX = rawEvent->value;
-            break;
-        case REL_Y:
-            mAccumulator.fields |= Accumulator::FIELD_REL_Y;
-            mAccumulator.relY = rawEvent->value;
-            break;
-        }
-        break;
-
-    case EV_SYN:
-        switch (rawEvent->scanCode) {
-        case SYN_REPORT:
-            sync(rawEvent->when);
-            break;
-        }
-        break;
-    }
-}
-
-void TrackballInputMapper::sync(nsecs_t when) {
-    uint32_t fields = mAccumulator.fields;
-    if (fields == 0) {
-        return; // no new state changes, so nothing to do
-    }
-
-    int motionEventAction;
-    PointerCoords pointerCoords;
-    nsecs_t downTime;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
-
-        if (downChanged) {
-            if (mAccumulator.btnMouse) {
-                mLocked.down = true;
-                mLocked.downTime = when;
-            } else {
-                mLocked.down = false;
-            }
-        }
-
-        downTime = mLocked.downTime;
-        float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
-        float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
-
-        if (downChanged) {
-            motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
-        } else {
-            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
-        }
-
-        pointerCoords.x = x;
-        pointerCoords.y = y;
-        pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
-        pointerCoords.size = 0;
-        pointerCoords.touchMajor = 0;
-        pointerCoords.touchMinor = 0;
-        pointerCoords.toolMajor = 0;
-        pointerCoords.toolMinor = 0;
-        pointerCoords.orientation = 0;
-
-        if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) {
-            // Rotate motion based on display orientation if needed.
-            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
-            int32_t orientation;
-            if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
-                return;
-            }
-
-            float temp;
-            switch (orientation) {
-            case InputReaderPolicyInterface::ROTATION_90:
-                temp = pointerCoords.x;
-                pointerCoords.x = pointerCoords.y;
-                pointerCoords.y = - temp;
-                break;
-
-            case InputReaderPolicyInterface::ROTATION_180:
-                pointerCoords.x = - pointerCoords.x;
-                pointerCoords.y = - pointerCoords.y;
-                break;
-
-            case InputReaderPolicyInterface::ROTATION_270:
-                temp = pointerCoords.x;
-                pointerCoords.x = - pointerCoords.y;
-                pointerCoords.y = temp;
-                break;
-            }
-        }
-    } // release lock
-
-    int32_t metaState = mContext->getGlobalMetaState();
-    int32_t pointerId = 0;
-    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, 0,
-            motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
-            1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
-
-    mAccumulator.clear();
-}
-
-int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
-        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
-    } else {
-        return AKEY_STATE_UNKNOWN;
-    }
-}
-
-
-// --- TouchInputMapper ---
-
-TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
-        InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
-    mLocked.surfaceOrientation = -1;
-    mLocked.surfaceWidth = -1;
-    mLocked.surfaceHeight = -1;
-
-    initializeLocked();
-}
-
-TouchInputMapper::~TouchInputMapper() {
-}
-
-uint32_t TouchInputMapper::getSources() {
-    return mAssociatedDisplayId >= 0 ? AINPUT_SOURCE_TOUCHSCREEN : AINPUT_SOURCE_TOUCHPAD;
-}
-
-void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        // Ensure surface information is up to date so that orientation changes are
-        // noticed immediately.
-        configureSurfaceLocked();
-
-        info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
-        info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
-
-        if (mLocked.orientedRanges.havePressure) {
-            info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
-                    mLocked.orientedRanges.pressure);
-        }
-
-        if (mLocked.orientedRanges.haveSize) {
-            info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
-                    mLocked.orientedRanges.size);
-        }
-
-        if (mLocked.orientedRanges.haveTouchSize) {
-            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
-                    mLocked.orientedRanges.touchMajor);
-            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
-                    mLocked.orientedRanges.touchMinor);
-        }
-
-        if (mLocked.orientedRanges.haveToolSize) {
-            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
-                    mLocked.orientedRanges.toolMajor);
-            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
-                    mLocked.orientedRanges.toolMinor);
-        }
-
-        if (mLocked.orientedRanges.haveOrientation) {
-            info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
-                    mLocked.orientedRanges.orientation);
-        }
-    } // release lock
-}
-
-void TouchInputMapper::dump(String8& dump) {
-    { // acquire lock
-        AutoMutex _l(mLock);
-        dump.append(INDENT2 "Touch Input Mapper:\n");
-        dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
-        dumpParameters(dump);
-        dumpVirtualKeysLocked(dump);
-        dumpRawAxes(dump);
-        dumpCalibration(dump);
-        dumpSurfaceLocked(dump);
-        dump.appendFormat(INDENT3 "Translation and Scaling Factors:");
-        dump.appendFormat(INDENT4 "XOrigin: %d\n", mLocked.xOrigin);
-        dump.appendFormat(INDENT4 "YOrigin: %d\n", mLocked.yOrigin);
-        dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
-        dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
-        dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision);
-        dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision);
-        dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale);
-        dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale);
-        dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias);
-        dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale);
-        dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
-        dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
-        dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
-        dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale);
-    } // release lock
-}
-
-void TouchInputMapper::initializeLocked() {
-    mCurrentTouch.clear();
-    mLastTouch.clear();
-    mDownTime = 0;
-
-    for (uint32_t i = 0; i < MAX_POINTERS; i++) {
-        mAveragingTouchFilter.historyStart[i] = 0;
-        mAveragingTouchFilter.historyEnd[i] = 0;
-    }
-
-    mJumpyTouchFilter.jumpyPointsDropped = 0;
-
-    mLocked.currentVirtualKey.down = false;
-
-    mLocked.orientedRanges.havePressure = false;
-    mLocked.orientedRanges.haveSize = false;
-    mLocked.orientedRanges.haveTouchSize = false;
-    mLocked.orientedRanges.haveToolSize = false;
-    mLocked.orientedRanges.haveOrientation = false;
-}
-
-void TouchInputMapper::configure() {
-    InputMapper::configure();
-
-    // Configure basic parameters.
-    configureParameters();
-
-    // Configure absolute axis information.
-    configureRawAxes();
-
-    // Prepare input device calibration.
-    parseCalibration();
-    resolveCalibration();
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-         // Configure surface dimensions and orientation.
-        configureSurfaceLocked();
-    } // release lock
-}
-
-void TouchInputMapper::configureParameters() {
-    mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
-    mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
-    mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
-    mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
-}
-
-void TouchInputMapper::dumpParameters(String8& dump) {
-    dump.appendFormat(INDENT3 "UseBadTouchFilter: %s\n",
-            toString(mParameters.useBadTouchFilter));
-    dump.appendFormat(INDENT3 "UseAveragingTouchFilter: %s\n",
-            toString(mParameters.useAveragingTouchFilter));
-    dump.appendFormat(INDENT3 "UseJumpyTouchFilter: %s\n",
-            toString(mParameters.useJumpyTouchFilter));
-}
-
-void TouchInputMapper::configureRawAxes() {
-    mRawAxes.x.clear();
-    mRawAxes.y.clear();
-    mRawAxes.pressure.clear();
-    mRawAxes.touchMajor.clear();
-    mRawAxes.touchMinor.clear();
-    mRawAxes.toolMajor.clear();
-    mRawAxes.toolMinor.clear();
-    mRawAxes.orientation.clear();
-}
-
-static void dumpAxisInfo(String8& dump, RawAbsoluteAxisInfo axis, const char* name) {
-    if (axis.valid) {
-        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d\n",
-                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
-    } else {
-        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
-    }
-}
-
-void TouchInputMapper::dumpRawAxes(String8& dump) {
-    dump.append(INDENT3 "Raw Axes:\n");
-    dumpAxisInfo(dump, mRawAxes.x, "X");
-    dumpAxisInfo(dump, mRawAxes.y, "Y");
-    dumpAxisInfo(dump, mRawAxes.pressure, "Pressure");
-    dumpAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor");
-    dumpAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor");
-    dumpAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor");
-    dumpAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor");
-    dumpAxisInfo(dump, mRawAxes.orientation, "Orientation");
-}
-
-bool TouchInputMapper::configureSurfaceLocked() {
-    // Update orientation and dimensions if needed.
-    int32_t orientation;
-    int32_t width, height;
-    if (mAssociatedDisplayId >= 0) {
-        // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
-        if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) {
-            return false;
-        }
-    } else {
-        orientation = InputReaderPolicyInterface::ROTATION_0;
-        width = mRawAxes.x.getRange();
-        height = mRawAxes.y.getRange();
-    }
-
-    bool orientationChanged = mLocked.surfaceOrientation != orientation;
-    if (orientationChanged) {
-        mLocked.surfaceOrientation = orientation;
-    }
-
-    bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
-    if (sizeChanged) {
-        LOGI("Device reconfigured: id=0x%x, name=%s, display size is now %dx%d",
-                getDeviceId(), getDeviceName().string(), width, height);
-
-        mLocked.surfaceWidth = width;
-        mLocked.surfaceHeight = height;
-
-        // Configure X and Y factors.
-        if (mRawAxes.x.valid && mRawAxes.y.valid) {
-            mLocked.xOrigin = mRawAxes.x.minValue;
-            mLocked.yOrigin = mRawAxes.y.minValue;
-            mLocked.xScale = float(width) / mRawAxes.x.getRange();
-            mLocked.yScale = float(height) / mRawAxes.y.getRange();
-            mLocked.xPrecision = 1.0f / mLocked.xScale;
-            mLocked.yPrecision = 1.0f / mLocked.yScale;
-
-            configureVirtualKeysLocked();
-        } else {
-            LOGW(INDENT "Touch device did not report support for X or Y axis!");
-            mLocked.xOrigin = 0;
-            mLocked.yOrigin = 0;
-            mLocked.xScale = 1.0f;
-            mLocked.yScale = 1.0f;
-            mLocked.xPrecision = 1.0f;
-            mLocked.yPrecision = 1.0f;
-        }
-
-        // Scale factor for terms that are not oriented in a particular axis.
-        // If the pixels are square then xScale == yScale otherwise we fake it
-        // by choosing an average.
-        mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
-
-        // Size of diagonal axis.
-        float diagonalSize = pythag(width, height);
-
-        // TouchMajor and TouchMinor factors.
-        if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
-            mLocked.orientedRanges.haveTouchSize = true;
-            mLocked.orientedRanges.touchMajor.min = 0;
-            mLocked.orientedRanges.touchMajor.max = diagonalSize;
-            mLocked.orientedRanges.touchMajor.flat = 0;
-            mLocked.orientedRanges.touchMajor.fuzz = 0;
-            mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
-        }
-
-        // ToolMajor and ToolMinor factors.
-        mLocked.toolSizeLinearScale = 0;
-        mLocked.toolSizeLinearBias = 0;
-        mLocked.toolSizeAreaScale = 0;
-        mLocked.toolSizeAreaBias = 0;
-        if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
-            if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) {
-                if (mCalibration.haveToolSizeLinearScale) {
-                    mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
-                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
-                    mLocked.toolSizeLinearScale = float(min(width, height))
-                            / mRawAxes.toolMajor.maxValue;
-                }
-
-                if (mCalibration.haveToolSizeLinearBias) {
-                    mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
-                }
-            } else if (mCalibration.toolSizeCalibration ==
-                    Calibration::TOOL_SIZE_CALIBRATION_AREA) {
-                if (mCalibration.haveToolSizeLinearScale) {
-                    mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
-                } else {
-                    mLocked.toolSizeLinearScale = min(width, height);
-                }
-
-                if (mCalibration.haveToolSizeLinearBias) {
-                    mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
-                }
-
-                if (mCalibration.haveToolSizeAreaScale) {
-                    mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale;
-                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
-                    mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue;
-                }
-
-                if (mCalibration.haveToolSizeAreaBias) {
-                    mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias;
-                }
-            }
-
-            mLocked.orientedRanges.haveToolSize = true;
-            mLocked.orientedRanges.toolMajor.min = 0;
-            mLocked.orientedRanges.toolMajor.max = diagonalSize;
-            mLocked.orientedRanges.toolMajor.flat = 0;
-            mLocked.orientedRanges.toolMajor.fuzz = 0;
-            mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
-        }
-
-        // Pressure factors.
-        mLocked.pressureScale = 0;
-        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
-            RawAbsoluteAxisInfo rawPressureAxis;
-            switch (mCalibration.pressureSource) {
-            case Calibration::PRESSURE_SOURCE_PRESSURE:
-                rawPressureAxis = mRawAxes.pressure;
-                break;
-            case Calibration::PRESSURE_SOURCE_TOUCH:
-                rawPressureAxis = mRawAxes.touchMajor;
-                break;
-            default:
-                rawPressureAxis.clear();
-            }
-
-            if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
-                    || mCalibration.pressureCalibration
-                            == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
-                if (mCalibration.havePressureScale) {
-                    mLocked.pressureScale = mCalibration.pressureScale;
-                } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
-                    mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
-                }
-            }
-
-            mLocked.orientedRanges.havePressure = true;
-            mLocked.orientedRanges.pressure.min = 0;
-            mLocked.orientedRanges.pressure.max = 1.0;
-            mLocked.orientedRanges.pressure.flat = 0;
-            mLocked.orientedRanges.pressure.fuzz = 0;
-        }
-
-        // Size factors.
-        mLocked.sizeScale = 0;
-        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
-            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
-                if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
-                    mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
-                }
-            }
-
-            mLocked.orientedRanges.haveSize = true;
-            mLocked.orientedRanges.size.min = 0;
-            mLocked.orientedRanges.size.max = 1.0;
-            mLocked.orientedRanges.size.flat = 0;
-            mLocked.orientedRanges.size.fuzz = 0;
-        }
-
-        // Orientation
-        mLocked.orientationScale = 0;
-        if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
-            if (mCalibration.orientationCalibration
-                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
-                if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
-                    mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
-                }
-            }
-
-            mLocked.orientedRanges.orientation.min = - M_PI_2;
-            mLocked.orientedRanges.orientation.max = M_PI_2;
-            mLocked.orientedRanges.orientation.flat = 0;
-            mLocked.orientedRanges.orientation.fuzz = 0;
-        }
-    }
-
-    if (orientationChanged || sizeChanged) {
-        // Compute oriented surface dimensions, precision, and scales.
-        float orientedXScale, orientedYScale;
-        switch (mLocked.surfaceOrientation) {
-        case InputReaderPolicyInterface::ROTATION_90:
-        case InputReaderPolicyInterface::ROTATION_270:
-            mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
-            mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
-            mLocked.orientedXPrecision = mLocked.yPrecision;
-            mLocked.orientedYPrecision = mLocked.xPrecision;
-            orientedXScale = mLocked.yScale;
-            orientedYScale = mLocked.xScale;
-            break;
-        default:
-            mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
-            mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
-            mLocked.orientedXPrecision = mLocked.xPrecision;
-            mLocked.orientedYPrecision = mLocked.yPrecision;
-            orientedXScale = mLocked.xScale;
-            orientedYScale = mLocked.yScale;
-            break;
-        }
-
-        // Configure position ranges.
-        mLocked.orientedRanges.x.min = 0;
-        mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth;
-        mLocked.orientedRanges.x.flat = 0;
-        mLocked.orientedRanges.x.fuzz = orientedXScale;
-
-        mLocked.orientedRanges.y.min = 0;
-        mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight;
-        mLocked.orientedRanges.y.flat = 0;
-        mLocked.orientedRanges.y.fuzz = orientedYScale;
-    }
-
-    return true;
-}
-
-void TouchInputMapper::dumpSurfaceLocked(String8& dump) {
-    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth);
-    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight);
-    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation);
-}
-
-void TouchInputMapper::configureVirtualKeysLocked() {
-    assert(mRawAxes.x.valid && mRawAxes.y.valid);
-
-    // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
-    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
-    getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
-
-    mLocked.virtualKeys.clear();
-
-    if (virtualKeyDefinitions.size() == 0) {
-        return;
-    }
-
-    mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
-
-    int32_t touchScreenLeft = mRawAxes.x.minValue;
-    int32_t touchScreenTop = mRawAxes.y.minValue;
-    int32_t touchScreenWidth = mRawAxes.x.getRange();
-    int32_t touchScreenHeight = mRawAxes.y.getRange();
-
-    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
-        const VirtualKeyDefinition& virtualKeyDefinition =
-                virtualKeyDefinitions[i];
-
-        mLocked.virtualKeys.add();
-        VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
-
-        virtualKey.scanCode = virtualKeyDefinition.scanCode;
-        int32_t keyCode;
-        uint32_t flags;
-        if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
-                & keyCode, & flags)) {
-            LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
-                    virtualKey.scanCode);
-            mLocked.virtualKeys.pop(); // drop the key
-            continue;
-        }
-
-        virtualKey.keyCode = keyCode;
-        virtualKey.flags = flags;
-
-        // convert the key definition's display coordinates into touch coordinates for a hit box
-        int32_t halfWidth = virtualKeyDefinition.width / 2;
-        int32_t halfHeight = virtualKeyDefinition.height / 2;
-
-        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
-                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
-        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
-                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
-        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
-                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
-        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
-                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
-
-    }
-}
-
-void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) {
-    if (!mLocked.virtualKeys.isEmpty()) {
-        dump.append(INDENT3 "Virtual Keys:\n");
-
-        for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) {
-            const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i);
-            dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
-                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
-                    i, virtualKey.scanCode, virtualKey.keyCode,
-                    virtualKey.hitLeft, virtualKey.hitRight,
-                    virtualKey.hitTop, virtualKey.hitBottom);
-        }
-    }
-}
-
-void TouchInputMapper::parseCalibration() {
-    const InputDeviceCalibration& in = getDevice()->getCalibration();
-    Calibration& out = mCalibration;
-
-    // Touch Size
-    out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT;
-    String8 touchSizeCalibrationString;
-    if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) {
-        if (touchSizeCalibrationString == "none") {
-            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE;
-        } else if (touchSizeCalibrationString == "geometric") {
-            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC;
-        } else if (touchSizeCalibrationString == "pressure") {
-            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
-        } else if (touchSizeCalibrationString != "default") {
-            LOGW("Invalid value for touch.touchSize.calibration: '%s'",
-                    touchSizeCalibrationString.string());
-        }
-    }
-
-    // Tool Size
-    out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT;
-    String8 toolSizeCalibrationString;
-    if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) {
-        if (toolSizeCalibrationString == "none") {
-            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
-        } else if (toolSizeCalibrationString == "geometric") {
-            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC;
-        } else if (toolSizeCalibrationString == "linear") {
-            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
-        } else if (toolSizeCalibrationString == "area") {
-            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA;
-        } else if (toolSizeCalibrationString != "default") {
-            LOGW("Invalid value for touch.toolSize.calibration: '%s'",
-                    toolSizeCalibrationString.string());
-        }
-    }
-
-    out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"),
-            out.toolSizeLinearScale);
-    out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"),
-            out.toolSizeLinearBias);
-    out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"),
-            out.toolSizeAreaScale);
-    out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"),
-            out.toolSizeAreaBias);
-    out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"),
-            out.toolSizeIsSummed);
-
-    // Pressure
-    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
-    String8 pressureCalibrationString;
-    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
-        if (pressureCalibrationString == "none") {
-            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
-        } else if (pressureCalibrationString == "physical") {
-            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
-        } else if (pressureCalibrationString == "amplitude") {
-            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
-        } else if (pressureCalibrationString != "default") {
-            LOGW("Invalid value for touch.pressure.calibration: '%s'",
-                    pressureCalibrationString.string());
-        }
-    }
-
-    out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT;
-    String8 pressureSourceString;
-    if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) {
-        if (pressureSourceString == "pressure") {
-            out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
-        } else if (pressureSourceString == "touch") {
-            out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
-        } else if (pressureSourceString != "default") {
-            LOGW("Invalid value for touch.pressure.source: '%s'",
-                    pressureSourceString.string());
-        }
-    }
-
-    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
-            out.pressureScale);
-
-    // Size
-    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
-    String8 sizeCalibrationString;
-    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
-        if (sizeCalibrationString == "none") {
-            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
-        } else if (sizeCalibrationString == "normalized") {
-            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
-        } else if (sizeCalibrationString != "default") {
-            LOGW("Invalid value for touch.size.calibration: '%s'",
-                    sizeCalibrationString.string());
-        }
-    }
-
-    // Orientation
-    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
-    String8 orientationCalibrationString;
-    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
-        if (orientationCalibrationString == "none") {
-            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
-        } else if (orientationCalibrationString == "interpolated") {
-            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
-        } else if (orientationCalibrationString != "default") {
-            LOGW("Invalid value for touch.orientation.calibration: '%s'",
-                    orientationCalibrationString.string());
-        }
-    }
-}
-
-void TouchInputMapper::resolveCalibration() {
-    // Pressure
-    switch (mCalibration.pressureSource) {
-    case Calibration::PRESSURE_SOURCE_DEFAULT:
-        if (mRawAxes.pressure.valid) {
-            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
-        } else if (mRawAxes.touchMajor.valid) {
-            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
-        }
-        break;
-
-    case Calibration::PRESSURE_SOURCE_PRESSURE:
-        if (! mRawAxes.pressure.valid) {
-            LOGW("Calibration property touch.pressure.source is 'pressure' but "
-                    "the pressure axis is not available.");
-        }
-        break;
-
-    case Calibration::PRESSURE_SOURCE_TOUCH:
-        if (! mRawAxes.touchMajor.valid) {
-            LOGW("Calibration property touch.pressure.source is 'touch' but "
-                    "the touchMajor axis is not available.");
-        }
-        break;
-
-    default:
-        break;
-    }
-
-    switch (mCalibration.pressureCalibration) {
-    case Calibration::PRESSURE_CALIBRATION_DEFAULT:
-        if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) {
-            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
-        } else {
-            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
-        }
-        break;
-
-    default:
-        break;
-    }
-
-    // Tool Size
-    switch (mCalibration.toolSizeCalibration) {
-    case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT:
-        if (mRawAxes.toolMajor.valid) {
-            mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
-        } else {
-            mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
-        }
-        break;
-
-    default:
-        break;
-    }
-
-    // Touch Size
-    switch (mCalibration.touchSizeCalibration) {
-    case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT:
-        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
-                && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
-            mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
-        } else {
-            mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE;
-        }
-        break;
-
-    default:
-        break;
-    }
-
-    // Size
-    switch (mCalibration.sizeCalibration) {
-    case Calibration::SIZE_CALIBRATION_DEFAULT:
-        if (mRawAxes.toolMajor.valid) {
-            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
-        } else {
-            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
-        }
-        break;
-
-    default:
-        break;
-    }
-
-    // Orientation
-    switch (mCalibration.orientationCalibration) {
-    case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
-        if (mRawAxes.orientation.valid) {
-            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
-        } else {
-            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
-        }
-        break;
-
-    default:
-        break;
-    }
-}
-
-void TouchInputMapper::dumpCalibration(String8& dump) {
-    dump.append(INDENT3 "Calibration:\n");
-
-    // Touch Size
-    switch (mCalibration.touchSizeCalibration) {
-    case Calibration::TOUCH_SIZE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.touchSize.calibration: none\n");
-        break;
-    case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
-        dump.append(INDENT4 "touch.touchSize.calibration: geometric\n");
-        break;
-    case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE:
-        dump.append(INDENT4 "touch.touchSize.calibration: pressure\n");
-        break;
-    default:
-        assert(false);
-    }
-
-    // Tool Size
-    switch (mCalibration.toolSizeCalibration) {
-    case Calibration::TOOL_SIZE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.toolSize.calibration: none\n");
-        break;
-    case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
-        dump.append(INDENT4 "touch.toolSize.calibration: geometric\n");
-        break;
-    case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
-        dump.append(INDENT4 "touch.toolSize.calibration: linear\n");
-        break;
-    case Calibration::TOOL_SIZE_CALIBRATION_AREA:
-        dump.append(INDENT4 "touch.toolSize.calibration: area\n");
-        break;
-    default:
-        assert(false);
-    }
-
-    if (mCalibration.haveToolSizeLinearScale) {
-        dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n",
-                mCalibration.toolSizeLinearScale);
-    }
-
-    if (mCalibration.haveToolSizeLinearBias) {
-        dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n",
-                mCalibration.toolSizeLinearBias);
-    }
-
-    if (mCalibration.haveToolSizeAreaScale) {
-        dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n",
-                mCalibration.toolSizeAreaScale);
-    }
-
-    if (mCalibration.haveToolSizeAreaBias) {
-        dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n",
-                mCalibration.toolSizeAreaBias);
-    }
-
-    if (mCalibration.haveToolSizeIsSummed) {
-        dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %d\n",
-                mCalibration.toolSizeIsSummed);
-    }
-
-    // Pressure
-    switch (mCalibration.pressureCalibration) {
-    case Calibration::PRESSURE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.pressure.calibration: none\n");
-        break;
-    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
-        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
-        break;
-    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
-        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
-        break;
-    default:
-        assert(false);
-    }
-
-    switch (mCalibration.pressureSource) {
-    case Calibration::PRESSURE_SOURCE_PRESSURE:
-        dump.append(INDENT4 "touch.pressure.source: pressure\n");
-        break;
-    case Calibration::PRESSURE_SOURCE_TOUCH:
-        dump.append(INDENT4 "touch.pressure.source: touch\n");
-        break;
-    case Calibration::PRESSURE_SOURCE_DEFAULT:
-        break;
-    default:
-        assert(false);
-    }
-
-    if (mCalibration.havePressureScale) {
-        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
-                mCalibration.pressureScale);
-    }
-
-    // Size
-    switch (mCalibration.sizeCalibration) {
-    case Calibration::SIZE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.size.calibration: none\n");
-        break;
-    case Calibration::SIZE_CALIBRATION_NORMALIZED:
-        dump.append(INDENT4 "touch.size.calibration: normalized\n");
-        break;
-    default:
-        assert(false);
-    }
-
-    // Orientation
-    switch (mCalibration.orientationCalibration) {
-    case Calibration::ORIENTATION_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.orientation.calibration: none\n");
-        break;
-    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
-        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
-        break;
-    default:
-        assert(false);
-    }
-}
-
-void TouchInputMapper::reset() {
-    // Synthesize touch up event if touch is currently down.
-    // This will also take care of finishing virtual key processing if needed.
-    if (mLastTouch.pointerCount != 0) {
-        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-        mCurrentTouch.clear();
-        syncTouch(when, true);
-    }
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-        initializeLocked();
-    } // release lock
-
-    InputMapper::reset();
-}
-
-void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
-    uint32_t policyFlags = 0;
-
-    // Preprocess pointer data.
-
-    if (mParameters.useBadTouchFilter) {
-        if (applyBadTouchFilter()) {
-            havePointerIds = false;
-        }
-    }
-
-    if (mParameters.useJumpyTouchFilter) {
-        if (applyJumpyTouchFilter()) {
-            havePointerIds = false;
-        }
-    }
-
-    if (! havePointerIds) {
-        calculatePointerIds();
-    }
-
-    TouchData temp;
-    TouchData* savedTouch;
-    if (mParameters.useAveragingTouchFilter) {
-        temp.copyFrom(mCurrentTouch);
-        savedTouch = & temp;
-
-        applyAveragingTouchFilter();
-    } else {
-        savedTouch = & mCurrentTouch;
-    }
-
-    // Process touches and virtual keys.
-
-    TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
-    if (touchResult == DISPATCH_TOUCH) {
-        detectGestures(when);
-        dispatchTouches(when, policyFlags);
-    }
-
-    // Copy current touch to last touch in preparation for the next cycle.
-
-    if (touchResult == DROP_STROKE) {
-        mLastTouch.clear();
-    } else {
-        mLastTouch.copyFrom(*savedTouch);
-    }
-}
-
-TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
-        nsecs_t when, uint32_t policyFlags) {
-    int32_t keyEventAction, keyEventFlags;
-    int32_t keyCode, scanCode, downTime;
-    TouchResult touchResult;
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        // Update surface size and orientation, including virtual key positions.
-        if (! configureSurfaceLocked()) {
-            return DROP_STROKE;
-        }
-
-        // Check for virtual key press.
-        if (mLocked.currentVirtualKey.down) {
-            if (mCurrentTouch.pointerCount == 0) {
-                // Pointer went up while virtual key was down.
-                mLocked.currentVirtualKey.down = false;
-#if DEBUG_VIRTUAL_KEYS
-                LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
-                        mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
-#endif
-                keyEventAction = AKEY_EVENT_ACTION_UP;
-                keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
-                touchResult = SKIP_TOUCH;
-                goto DispatchVirtualKey;
-            }
-
-            if (mCurrentTouch.pointerCount == 1) {
-                int32_t x = mCurrentTouch.pointers[0].x;
-                int32_t y = mCurrentTouch.pointers[0].y;
-                const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
-                if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
-                    // Pointer is still within the space of the virtual key.
-                    return SKIP_TOUCH;
-                }
-            }
-
-            // Pointer left virtual key area or another pointer also went down.
-            // Send key cancellation and drop the stroke so subsequent motions will be
-            // considered fresh downs.  This is useful when the user swipes away from the
-            // virtual key area into the main display surface.
-            mLocked.currentVirtualKey.down = false;
-#if DEBUG_VIRTUAL_KEYS
-            LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
-                    mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
-#endif
-            keyEventAction = AKEY_EVENT_ACTION_UP;
-            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
-                    | AKEY_EVENT_FLAG_CANCELED;
-
-            // Check whether the pointer moved inside the display area where we should
-            // start a new stroke.
-            int32_t x = mCurrentTouch.pointers[0].x;
-            int32_t y = mCurrentTouch.pointers[0].y;
-            if (isPointInsideSurfaceLocked(x, y)) {
-                mLastTouch.clear();
-                touchResult = DISPATCH_TOUCH;
-            } else {
-                touchResult = DROP_STROKE;
-            }
-        } else {
-            if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
-                // Pointer just went down.  Handle off-screen touches, if needed.
-                int32_t x = mCurrentTouch.pointers[0].x;
-                int32_t y = mCurrentTouch.pointers[0].y;
-                if (! isPointInsideSurfaceLocked(x, y)) {
-                    // If exactly one pointer went down, check for virtual key hit.
-                    // Otherwise we will drop the entire stroke.
-                    if (mCurrentTouch.pointerCount == 1) {
-                        const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
-                        if (virtualKey) {
-                            if (mContext->shouldDropVirtualKey(when, getDevice(),
-                                    virtualKey->keyCode, virtualKey->scanCode)) {
-                                return DROP_STROKE;
-                            }
-
-                            mLocked.currentVirtualKey.down = true;
-                            mLocked.currentVirtualKey.downTime = when;
-                            mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
-                            mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
-#if DEBUG_VIRTUAL_KEYS
-                            LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
-                                    mLocked.currentVirtualKey.keyCode,
-                                    mLocked.currentVirtualKey.scanCode);
-#endif
-                            keyEventAction = AKEY_EVENT_ACTION_DOWN;
-                            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
-                                    | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
-                            touchResult = SKIP_TOUCH;
-                            goto DispatchVirtualKey;
-                        }
-                    }
-                    return DROP_STROKE;
-                }
-            }
-            return DISPATCH_TOUCH;
-        }
-
-    DispatchVirtualKey:
-        // Collect remaining state needed to dispatch virtual key.
-        keyCode = mLocked.currentVirtualKey.keyCode;
-        scanCode = mLocked.currentVirtualKey.scanCode;
-        downTime = mLocked.currentVirtualKey.downTime;
-    } // release lock
-
-    // Dispatch virtual key.
-    int32_t metaState = mContext->getGlobalMetaState();
-    policyFlags |= POLICY_FLAG_VIRTUAL;
-    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
-            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
-    return touchResult;
-}
-
-void TouchInputMapper::detectGestures(nsecs_t when) {
-    // Disable all virtual key touches that happen within a short time interval of the
-    // most recent touch.  The idea is to filter out stray virtual key presses when
-    // interacting with the touch screen.
-    //
-    // Problems we're trying to solve:
-    //
-    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
-    //    virtual key area that is implemented by a separate touch panel and accidentally
-    //    triggers a virtual key.
-    //
-    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
-    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
-    //    are layed out below the screen near to where the on screen keyboard's space bar
-    //    is displayed.
-    if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
-        mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
-    }
-}
-
-void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
-    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
-    uint32_t lastPointerCount = mLastTouch.pointerCount;
-    if (currentPointerCount == 0 && lastPointerCount == 0) {
-        return; // nothing to do!
-    }
-
-    BitSet32 currentIdBits = mCurrentTouch.idBits;
-    BitSet32 lastIdBits = mLastTouch.idBits;
-
-    if (currentIdBits == lastIdBits) {
-        // No pointer id changes so this is a move event.
-        // The dispatcher takes care of batching moves so we don't have to deal with that here.
-        int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
-        dispatchTouch(when, policyFlags, & mCurrentTouch,
-                currentIdBits, -1, currentPointerCount, motionEventAction);
-    } else {
-        // There may be pointers going up and pointers going down and pointers moving
-        // all at the same time.
-        BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
-        BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
-        BitSet32 activeIdBits(lastIdBits.value);
-        uint32_t pointerCount = lastPointerCount;
-
-        // Produce an intermediate representation of the touch data that consists of the
-        // old location of pointers that have just gone up and the new location of pointers that
-        // have just moved but omits the location of pointers that have just gone down.
-        TouchData interimTouch;
-        interimTouch.copyFrom(mLastTouch);
-
-        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
-        bool moveNeeded = false;
-        while (!moveIdBits.isEmpty()) {
-            uint32_t moveId = moveIdBits.firstMarkedBit();
-            moveIdBits.clearBit(moveId);
-
-            int32_t oldIndex = mLastTouch.idToIndex[moveId];
-            int32_t newIndex = mCurrentTouch.idToIndex[moveId];
-            if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) {
-                interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex];
-                moveNeeded = true;
-            }
-        }
-
-        // Dispatch pointer up events using the interim pointer locations.
-        while (!upIdBits.isEmpty()) {
-            uint32_t upId = upIdBits.firstMarkedBit();
-            upIdBits.clearBit(upId);
-            BitSet32 oldActiveIdBits = activeIdBits;
-            activeIdBits.clearBit(upId);
-
-            int32_t motionEventAction;
-            if (activeIdBits.isEmpty()) {
-                motionEventAction = AMOTION_EVENT_ACTION_UP;
-            } else {
-                motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP;
-            }
-
-            dispatchTouch(when, policyFlags, &interimTouch,
-                    oldActiveIdBits, upId, pointerCount, motionEventAction);
-            pointerCount -= 1;
-        }
-
-        // Dispatch move events if any of the remaining pointers moved from their old locations.
-        // Although applications receive new locations as part of individual pointer up
-        // events, they do not generally handle them except when presented in a move event.
-        if (moveNeeded) {
-            dispatchTouch(when, policyFlags, &mCurrentTouch,
-                    activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE);
-        }
-
-        // Dispatch pointer down events using the new pointer locations.
-        while (!downIdBits.isEmpty()) {
-            uint32_t downId = downIdBits.firstMarkedBit();
-            downIdBits.clearBit(downId);
-            BitSet32 oldActiveIdBits = activeIdBits;
-            activeIdBits.markBit(downId);
-
-            int32_t motionEventAction;
-            if (oldActiveIdBits.isEmpty()) {
-                motionEventAction = AMOTION_EVENT_ACTION_DOWN;
-                mDownTime = when;
-            } else {
-                motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
-            }
-
-            pointerCount += 1;
-            dispatchTouch(when, policyFlags, &mCurrentTouch,
-                    activeIdBits, downId, pointerCount, motionEventAction);
-        }
-    }
-}
-
-void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
-        TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
-        int32_t motionEventAction) {
-    int32_t pointerIds[MAX_POINTERS];
-    PointerCoords pointerCoords[MAX_POINTERS];
-    int32_t motionEventEdgeFlags = 0;
-    float xPrecision, yPrecision;
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        // Walk through the the active pointers and map touch screen coordinates (TouchData) into
-        // display coordinates (PointerCoords) and adjust for display orientation.
-        for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
-            uint32_t id = idBits.firstMarkedBit();
-            idBits.clearBit(id);
-            uint32_t inIndex = touch->idToIndex[id];
-
-            const PointerData& in = touch->pointers[inIndex];
-
-            // X and Y
-            float x = float(in.x - mLocked.xOrigin) * mLocked.xScale;
-            float y = float(in.y - mLocked.yOrigin) * mLocked.yScale;
-
-            // ToolMajor and ToolMinor
-            float toolMajor, toolMinor;
-            switch (mCalibration.toolSizeCalibration) {
-            case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
-                toolMajor = in.toolMajor * mLocked.geometricScale;
-                if (mRawAxes.toolMinor.valid) {
-                    toolMinor = in.toolMinor * mLocked.geometricScale;
-                } else {
-                    toolMinor = toolMajor;
-                }
-                break;
-            case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
-                toolMajor = in.toolMajor != 0
-                        ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias
-                        : 0;
-                if (mRawAxes.toolMinor.valid) {
-                    toolMinor = in.toolMinor != 0
-                            ? in.toolMinor * mLocked.toolSizeLinearScale
-                                    + mLocked.toolSizeLinearBias
-                            : 0;
-                } else {
-                    toolMinor = toolMajor;
-                }
-                break;
-            case Calibration::TOOL_SIZE_CALIBRATION_AREA:
-                if (in.toolMajor != 0) {
-                    float diameter = sqrtf(in.toolMajor
-                            * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias);
-                    toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias;
-                } else {
-                    toolMajor = 0;
-                }
-                toolMinor = toolMajor;
-                break;
-            default:
-                toolMajor = 0;
-                toolMinor = 0;
-                break;
-            }
-
-            if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) {
-                toolMajor /= pointerCount;
-                toolMinor /= pointerCount;
-            }
-
-            // Pressure
-            float rawPressure;
-            switch (mCalibration.pressureSource) {
-            case Calibration::PRESSURE_SOURCE_PRESSURE:
-                rawPressure = in.pressure;
-                break;
-            case Calibration::PRESSURE_SOURCE_TOUCH:
-                rawPressure = in.touchMajor;
-                break;
-            default:
-                rawPressure = 0;
-            }
-
-            float pressure;
-            switch (mCalibration.pressureCalibration) {
-            case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
-            case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
-                pressure = rawPressure * mLocked.pressureScale;
-                break;
-            default:
-                pressure = 1;
-                break;
-            }
-
-            // TouchMajor and TouchMinor
-            float touchMajor, touchMinor;
-            switch (mCalibration.touchSizeCalibration) {
-            case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
-                touchMajor = in.touchMajor * mLocked.geometricScale;
-                if (mRawAxes.touchMinor.valid) {
-                    touchMinor = in.touchMinor * mLocked.geometricScale;
-                } else {
-                    touchMinor = touchMajor;
-                }
-                break;
-            case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE:
-                touchMajor = toolMajor * pressure;
-                touchMinor = toolMinor * pressure;
-                break;
-            default:
-                touchMajor = 0;
-                touchMinor = 0;
-                break;
-            }
-
-            if (touchMajor > toolMajor) {
-                touchMajor = toolMajor;
-            }
-            if (touchMinor > toolMinor) {
-                touchMinor = toolMinor;
-            }
-
-            // Size
-            float size;
-            switch (mCalibration.sizeCalibration) {
-            case Calibration::SIZE_CALIBRATION_NORMALIZED: {
-                float rawSize = mRawAxes.toolMinor.valid
-                        ? avg(in.toolMajor, in.toolMinor)
-                        : in.toolMajor;
-                size = rawSize * mLocked.sizeScale;
-                break;
-            }
-            default:
-                size = 0;
-                break;
-            }
-
-            // Orientation
-            float orientation;
-            switch (mCalibration.orientationCalibration) {
-            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
-                orientation = in.orientation * mLocked.orientationScale;
-                break;
-            default:
-                orientation = 0;
-            }
-
-            // Adjust coords for orientation.
-            switch (mLocked.surfaceOrientation) {
-            case InputReaderPolicyInterface::ROTATION_90: {
-                float xTemp = x;
-                x = y;
-                y = mLocked.surfaceWidth - xTemp;
-                orientation -= M_PI_2;
-                if (orientation < - M_PI_2) {
-                    orientation += M_PI;
-                }
-                break;
-            }
-            case InputReaderPolicyInterface::ROTATION_180: {
-                x = mLocked.surfaceWidth - x;
-                y = mLocked.surfaceHeight - y;
-                orientation = - orientation;
-                break;
-            }
-            case InputReaderPolicyInterface::ROTATION_270: {
-                float xTemp = x;
-                x = mLocked.surfaceHeight - y;
-                y = xTemp;
-                orientation += M_PI_2;
-                if (orientation > M_PI_2) {
-                    orientation -= M_PI;
-                }
-                break;
-            }
-            }
-
-            // Write output coords.
-            PointerCoords& out = pointerCoords[outIndex];
-            out.x = x;
-            out.y = y;
-            out.pressure = pressure;
-            out.size = size;
-            out.touchMajor = touchMajor;
-            out.touchMinor = touchMinor;
-            out.toolMajor = toolMajor;
-            out.toolMinor = toolMinor;
-            out.orientation = orientation;
-
-            pointerIds[outIndex] = int32_t(id);
-
-            if (id == changedId) {
-                motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-            }
-        }
-
-        // Check edge flags by looking only at the first pointer since the flags are
-        // global to the event.
-        if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
-            if (pointerCoords[0].x <= 0) {
-                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
-            } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
-                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
-            }
-            if (pointerCoords[0].y <= 0) {
-                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
-            } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
-                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
-            }
-        }
-
-        xPrecision = mLocked.orientedXPrecision;
-        yPrecision = mLocked.orientedYPrecision;
-    } // release lock
-
-    getDispatcher()->notifyMotion(when, getDeviceId(), getSources(), policyFlags,
-            motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
-            pointerCount, pointerIds, pointerCoords,
-            xPrecision, yPrecision, mDownTime);
-}
-
-bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
-    if (mRawAxes.x.valid && mRawAxes.y.valid) {
-        return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
-                && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
-    }
-    return true;
-}
-
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
-        int32_t x, int32_t y) {
-    size_t numVirtualKeys = mLocked.virtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mLocked.virtualKeys[i];
-
-#if DEBUG_VIRTUAL_KEYS
-        LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
-                "left=%d, top=%d, right=%d, bottom=%d",
-                x, y,
-                virtualKey.keyCode, virtualKey.scanCode,
-                virtualKey.hitLeft, virtualKey.hitTop,
-                virtualKey.hitRight, virtualKey.hitBottom);
-#endif
-
-        if (virtualKey.isHit(x, y)) {
-            return & virtualKey;
-        }
-    }
-
-    return NULL;
-}
-
-void TouchInputMapper::calculatePointerIds() {
-    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
-    uint32_t lastPointerCount = mLastTouch.pointerCount;
-
-    if (currentPointerCount == 0) {
-        // No pointers to assign.
-        mCurrentTouch.idBits.clear();
-    } else if (lastPointerCount == 0) {
-        // All pointers are new.
-        mCurrentTouch.idBits.clear();
-        for (uint32_t i = 0; i < currentPointerCount; i++) {
-            mCurrentTouch.pointers[i].id = i;
-            mCurrentTouch.idToIndex[i] = i;
-            mCurrentTouch.idBits.markBit(i);
-        }
-    } else if (currentPointerCount == 1 && lastPointerCount == 1) {
-        // Only one pointer and no change in count so it must have the same id as before.
-        uint32_t id = mLastTouch.pointers[0].id;
-        mCurrentTouch.pointers[0].id = id;
-        mCurrentTouch.idToIndex[id] = 0;
-        mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
-    } else {
-        // General case.
-        // We build a heap of squared euclidean distances between current and last pointers
-        // associated with the current and last pointer indices.  Then, we find the best
-        // match (by distance) for each current pointer.
-        PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
-
-        uint32_t heapSize = 0;
-        for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
-                currentPointerIndex++) {
-            for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
-                    lastPointerIndex++) {
-                int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
-                        - mLastTouch.pointers[lastPointerIndex].x;
-                int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
-                        - mLastTouch.pointers[lastPointerIndex].y;
-
-                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
-
-                // Insert new element into the heap (sift up).
-                heap[heapSize].currentPointerIndex = currentPointerIndex;
-                heap[heapSize].lastPointerIndex = lastPointerIndex;
-                heap[heapSize].distance = distance;
-                heapSize += 1;
-            }
-        }
-
-        // Heapify
-        for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
-            startIndex -= 1;
-            for (uint32_t parentIndex = startIndex; ;) {
-                uint32_t childIndex = parentIndex * 2 + 1;
-                if (childIndex >= heapSize) {
-                    break;
-                }
-
-                if (childIndex + 1 < heapSize
-                        && heap[childIndex + 1].distance < heap[childIndex].distance) {
-                    childIndex += 1;
-                }
-
-                if (heap[parentIndex].distance <= heap[childIndex].distance) {
-                    break;
-                }
-
-                swap(heap[parentIndex], heap[childIndex]);
-                parentIndex = childIndex;
-            }
-        }
-
-#if DEBUG_POINTER_ASSIGNMENT
-        LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
-        for (size_t i = 0; i < heapSize; i++) {
-            LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
-                    i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
-                    heap[i].distance);
-        }
-#endif
-
-        // Pull matches out by increasing order of distance.
-        // To avoid reassigning pointers that have already been matched, the loop keeps track
-        // of which last and current pointers have been matched using the matchedXXXBits variables.
-        // It also tracks the used pointer id bits.
-        BitSet32 matchedLastBits(0);
-        BitSet32 matchedCurrentBits(0);
-        BitSet32 usedIdBits(0);
-        bool first = true;
-        for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
-            for (;;) {
-                if (first) {
-                    // The first time through the loop, we just consume the root element of
-                    // the heap (the one with smallest distance).
-                    first = false;
-                } else {
-                    // Previous iterations consumed the root element of the heap.
-                    // Pop root element off of the heap (sift down).
-                    heapSize -= 1;
-                    assert(heapSize > 0);
-
-                    // Sift down.
-                    heap[0] = heap[heapSize];
-                    for (uint32_t parentIndex = 0; ;) {
-                        uint32_t childIndex = parentIndex * 2 + 1;
-                        if (childIndex >= heapSize) {
-                            break;
-                        }
-
-                        if (childIndex + 1 < heapSize
-                                && heap[childIndex + 1].distance < heap[childIndex].distance) {
-                            childIndex += 1;
-                        }
-
-                        if (heap[parentIndex].distance <= heap[childIndex].distance) {
-                            break;
-                        }
-
-                        swap(heap[parentIndex], heap[childIndex]);
-                        parentIndex = childIndex;
-                    }
-
-#if DEBUG_POINTER_ASSIGNMENT
-                    LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
-                    for (size_t i = 0; i < heapSize; i++) {
-                        LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
-                                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
-                                heap[i].distance);
-                    }
-#endif
-                }
-
-                uint32_t currentPointerIndex = heap[0].currentPointerIndex;
-                if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
-
-                uint32_t lastPointerIndex = heap[0].lastPointerIndex;
-                if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
-
-                matchedCurrentBits.markBit(currentPointerIndex);
-                matchedLastBits.markBit(lastPointerIndex);
-
-                uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
-                mCurrentTouch.pointers[currentPointerIndex].id = id;
-                mCurrentTouch.idToIndex[id] = currentPointerIndex;
-                usedIdBits.markBit(id);
-
-#if DEBUG_POINTER_ASSIGNMENT
-                LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
-                        lastPointerIndex, currentPointerIndex, id, heap[0].distance);
-#endif
-                break;
-            }
-        }
-
-        // Assign fresh ids to new pointers.
-        if (currentPointerCount > lastPointerCount) {
-            for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
-                uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
-                uint32_t id = usedIdBits.firstUnmarkedBit();
-
-                mCurrentTouch.pointers[currentPointerIndex].id = id;
-                mCurrentTouch.idToIndex[id] = currentPointerIndex;
-                usedIdBits.markBit(id);
-
-#if DEBUG_POINTER_ASSIGNMENT
-                LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
-                        currentPointerIndex, id);
-#endif
-
-                if (--i == 0) break; // done
-                matchedCurrentBits.markBit(currentPointerIndex);
-            }
-        }
-
-        // Fix id bits.
-        mCurrentTouch.idBits = usedIdBits;
-    }
-}
-
-/* Special hack for devices that have bad screen data: if one of the
- * points has moved more than a screen height from the last position,
- * then drop it. */
-bool TouchInputMapper::applyBadTouchFilter() {
-    // This hack requires valid axis parameters.
-    if (! mRawAxes.y.valid) {
-        return false;
-    }
-
-    uint32_t pointerCount = mCurrentTouch.pointerCount;
-
-    // Nothing to do if there are no points.
-    if (pointerCount == 0) {
-        return false;
-    }
-
-    // Don't do anything if a finger is going down or up.  We run
-    // here before assigning pointer IDs, so there isn't a good
-    // way to do per-finger matching.
-    if (pointerCount != mLastTouch.pointerCount) {
-        return false;
-    }
-
-    // We consider a single movement across more than a 7/16 of
-    // the long size of the screen to be bad.  This was a magic value
-    // determined by looking at the maximum distance it is feasible
-    // to actually move in one sample.
-    int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16;
-
-    // XXX The original code in InputDevice.java included commented out
-    //     code for testing the X axis.  Note that when we drop a point
-    //     we don't actually restore the old X either.  Strange.
-    //     The old code also tries to track when bad points were previously
-    //     detected but it turns out that due to the placement of a "break"
-    //     at the end of the loop, we never set mDroppedBadPoint to true
-    //     so it is effectively dead code.
-    // Need to figure out if the old code is busted or just overcomplicated
-    // but working as intended.
-
-    // Look through all new points and see if any are farther than
-    // acceptable from all previous points.
-    for (uint32_t i = pointerCount; i-- > 0; ) {
-        int32_t y = mCurrentTouch.pointers[i].y;
-        int32_t closestY = INT_MAX;
-        int32_t closestDeltaY = 0;
-
-#if DEBUG_HACKS
-        LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y);
-#endif
-
-        for (uint32_t j = pointerCount; j-- > 0; ) {
-            int32_t lastY = mLastTouch.pointers[j].y;
-            int32_t deltaY = abs(y - lastY);
-
-#if DEBUG_HACKS
-            LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d",
-                    j, lastY, deltaY);
-#endif
-
-            if (deltaY < maxDeltaY) {
-                goto SkipSufficientlyClosePoint;
-            }
-            if (deltaY < closestDeltaY) {
-                closestDeltaY = deltaY;
-                closestY = lastY;
-            }
-        }
-
-        // Must not have found a close enough match.
-#if DEBUG_HACKS
-        LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d",
-                i, y, closestY, closestDeltaY, maxDeltaY);
-#endif
-
-        mCurrentTouch.pointers[i].y = closestY;
-        return true; // XXX original code only corrects one point
-
-    SkipSufficientlyClosePoint: ;
-    }
-
-    // No change.
-    return false;
-}
-
-/* Special hack for devices that have bad screen data: drop points where
- * the coordinate value for one axis has jumped to the other pointer's location.
- */
-bool TouchInputMapper::applyJumpyTouchFilter() {
-    // This hack requires valid axis parameters.
-    if (! mRawAxes.y.valid) {
-        return false;
-    }
-
-    uint32_t pointerCount = mCurrentTouch.pointerCount;
-    if (mLastTouch.pointerCount != pointerCount) {
-#if DEBUG_HACKS
-        LOGD("JumpyTouchFilter: Different pointer count %d -> %d",
-                mLastTouch.pointerCount, pointerCount);
-        for (uint32_t i = 0; i < pointerCount; i++) {
-            LOGD("  Pointer %d (%d, %d)", i,
-                    mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
-        }
-#endif
-
-        if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
-            if (mLastTouch.pointerCount == 1 && pointerCount == 2) {
-                // Just drop the first few events going from 1 to 2 pointers.
-                // They're bad often enough that they're not worth considering.
-                mCurrentTouch.pointerCount = 1;
-                mJumpyTouchFilter.jumpyPointsDropped += 1;
-
-#if DEBUG_HACKS
-                LOGD("JumpyTouchFilter: Pointer 2 dropped");
-#endif
-                return true;
-            } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) {
-                // The event when we go from 2 -> 1 tends to be messed up too
-                mCurrentTouch.pointerCount = 2;
-                mCurrentTouch.pointers[0] = mLastTouch.pointers[0];
-                mCurrentTouch.pointers[1] = mLastTouch.pointers[1];
-                mJumpyTouchFilter.jumpyPointsDropped += 1;
-
-#if DEBUG_HACKS
-                for (int32_t i = 0; i < 2; i++) {
-                    LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i,
-                            mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
-                }
-#endif
-                return true;
-            }
-        }
-        // Reset jumpy points dropped on other transitions or if limit exceeded.
-        mJumpyTouchFilter.jumpyPointsDropped = 0;
-
-#if DEBUG_HACKS
-        LOGD("JumpyTouchFilter: Transition - drop limit reset");
-#endif
-        return false;
-    }
-
-    // We have the same number of pointers as last time.
-    // A 'jumpy' point is one where the coordinate value for one axis
-    // has jumped to the other pointer's location. No need to do anything
-    // else if we only have one pointer.
-    if (pointerCount < 2) {
-        return false;
-    }
-
-    if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
-        int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
-
-        // We only replace the single worst jumpy point as characterized by pointer distance
-        // in a single axis.
-        int32_t badPointerIndex = -1;
-        int32_t badPointerReplacementIndex = -1;
-        int32_t badPointerDistance = INT_MIN; // distance to be corrected
-
-        for (uint32_t i = pointerCount; i-- > 0; ) {
-            int32_t x = mCurrentTouch.pointers[i].x;
-            int32_t y = mCurrentTouch.pointers[i].y;
-
-#if DEBUG_HACKS
-            LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y);
-#endif
-
-            // Check if a touch point is too close to another's coordinates
-            bool dropX = false, dropY = false;
-            for (uint32_t j = 0; j < pointerCount; j++) {
-                if (i == j) {
-                    continue;
-                }
-
-                if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) {
-                    dropX = true;
-                    break;
-                }
-
-                if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) {
-                    dropY = true;
-                    break;
-                }
-            }
-            if (! dropX && ! dropY) {
-                continue; // not jumpy
-            }
-
-            // Find a replacement candidate by comparing with older points on the
-            // complementary (non-jumpy) axis.
-            int32_t distance = INT_MIN; // distance to be corrected
-            int32_t replacementIndex = -1;
-
-            if (dropX) {
-                // X looks too close.  Find an older replacement point with a close Y.
-                int32_t smallestDeltaY = INT_MAX;
-                for (uint32_t j = 0; j < pointerCount; j++) {
-                    int32_t deltaY = abs(y - mLastTouch.pointers[j].y);
-                    if (deltaY < smallestDeltaY) {
-                        smallestDeltaY = deltaY;
-                        replacementIndex = j;
-                    }
-                }
-                distance = abs(x - mLastTouch.pointers[replacementIndex].x);
-            } else {
-                // Y looks too close.  Find an older replacement point with a close X.
-                int32_t smallestDeltaX = INT_MAX;
-                for (uint32_t j = 0; j < pointerCount; j++) {
-                    int32_t deltaX = abs(x - mLastTouch.pointers[j].x);
-                    if (deltaX < smallestDeltaX) {
-                        smallestDeltaX = deltaX;
-                        replacementIndex = j;
-                    }
-                }
-                distance = abs(y - mLastTouch.pointers[replacementIndex].y);
-            }
-
-            // If replacing this pointer would correct a worse error than the previous ones
-            // considered, then use this replacement instead.
-            if (distance > badPointerDistance) {
-                badPointerIndex = i;
-                badPointerReplacementIndex = replacementIndex;
-                badPointerDistance = distance;
-            }
-        }
-
-        // Correct the jumpy pointer if one was found.
-        if (badPointerIndex >= 0) {
-#if DEBUG_HACKS
-            LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)",
-                    badPointerIndex,
-                    mLastTouch.pointers[badPointerReplacementIndex].x,
-                    mLastTouch.pointers[badPointerReplacementIndex].y);
-#endif
-
-            mCurrentTouch.pointers[badPointerIndex].x =
-                    mLastTouch.pointers[badPointerReplacementIndex].x;
-            mCurrentTouch.pointers[badPointerIndex].y =
-                    mLastTouch.pointers[badPointerReplacementIndex].y;
-            mJumpyTouchFilter.jumpyPointsDropped += 1;
-            return true;
-        }
-    }
-
-    mJumpyTouchFilter.jumpyPointsDropped = 0;
-    return false;
-}
-
-/* Special hack for devices that have bad screen data: aggregate and
- * compute averages of the coordinate data, to reduce the amount of
- * jitter seen by applications. */
-void TouchInputMapper::applyAveragingTouchFilter() {
-    for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) {
-        uint32_t id = mCurrentTouch.pointers[currentIndex].id;
-        int32_t x = mCurrentTouch.pointers[currentIndex].x;
-        int32_t y = mCurrentTouch.pointers[currentIndex].y;
-        int32_t pressure;
-        switch (mCalibration.pressureSource) {
-        case Calibration::PRESSURE_SOURCE_PRESSURE:
-            pressure = mCurrentTouch.pointers[currentIndex].pressure;
-            break;
-        case Calibration::PRESSURE_SOURCE_TOUCH:
-            pressure = mCurrentTouch.pointers[currentIndex].touchMajor;
-            break;
-        default:
-            pressure = 1;
-            break;
-        }
-
-        if (mLastTouch.idBits.hasBit(id)) {
-            // Pointer was down before and is still down now.
-            // Compute average over history trace.
-            uint32_t start = mAveragingTouchFilter.historyStart[id];
-            uint32_t end = mAveragingTouchFilter.historyEnd[id];
-
-            int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x;
-            int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y;
-            uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
-
-#if DEBUG_HACKS
-            LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld",
-                    id, distance);
-#endif
-
-            if (distance < AVERAGING_DISTANCE_LIMIT) {
-                // Increment end index in preparation for recording new historical data.
-                end += 1;
-                if (end > AVERAGING_HISTORY_SIZE) {
-                    end = 0;
-                }
-
-                // If the end index has looped back to the start index then we have filled
-                // the historical trace up to the desired size so we drop the historical
-                // data at the start of the trace.
-                if (end == start) {
-                    start += 1;
-                    if (start > AVERAGING_HISTORY_SIZE) {
-                        start = 0;
-                    }
-                }
-
-                // Add the raw data to the historical trace.
-                mAveragingTouchFilter.historyStart[id] = start;
-                mAveragingTouchFilter.historyEnd[id] = end;
-                mAveragingTouchFilter.historyData[end].pointers[id].x = x;
-                mAveragingTouchFilter.historyData[end].pointers[id].y = y;
-                mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure;
-
-                // Average over all historical positions in the trace by total pressure.
-                int32_t averagedX = 0;
-                int32_t averagedY = 0;
-                int32_t totalPressure = 0;
-                for (;;) {
-                    int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x;
-                    int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y;
-                    int32_t historicalPressure = mAveragingTouchFilter.historyData[start]
-                            .pointers[id].pressure;
-
-                    averagedX += historicalX * historicalPressure;
-                    averagedY += historicalY * historicalPressure;
-                    totalPressure += historicalPressure;
-
-                    if (start == end) {
-                        break;
-                    }
-
-                    start += 1;
-                    if (start > AVERAGING_HISTORY_SIZE) {
-                        start = 0;
-                    }
-                }
-
-                if (totalPressure != 0) {
-                    averagedX /= totalPressure;
-                    averagedY /= totalPressure;
-
-#if DEBUG_HACKS
-                    LOGD("AveragingTouchFilter: Pointer id %d - "
-                            "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
-                            averagedX, averagedY);
-#endif
-
-                    mCurrentTouch.pointers[currentIndex].x = averagedX;
-                    mCurrentTouch.pointers[currentIndex].y = averagedY;
-                }
-            } else {
-#if DEBUG_HACKS
-                LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
-#endif
-            }
-        } else {
-#if DEBUG_HACKS
-            LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id);
-#endif
-        }
-
-        // Reset pointer history.
-        mAveragingTouchFilter.historyStart[id] = 0;
-        mAveragingTouchFilter.historyEnd[id] = 0;
-        mAveragingTouchFilter.historyData[0].pointers[id].x = x;
-        mAveragingTouchFilter.historyData[0].pointers[id].y = y;
-        mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure;
-    }
-}
-
-int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
-            return AKEY_STATE_VIRTUAL;
-        }
-
-        size_t numVirtualKeys = mLocked.virtualKeys.size();
-        for (size_t i = 0; i < numVirtualKeys; i++) {
-            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
-            if (virtualKey.keyCode == keyCode) {
-                return AKEY_STATE_UP;
-            }
-        }
-    } // release lock
-
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
-            return AKEY_STATE_VIRTUAL;
-        }
-
-        size_t numVirtualKeys = mLocked.virtualKeys.size();
-        for (size_t i = 0; i < numVirtualKeys; i++) {
-            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
-            if (virtualKey.scanCode == scanCode) {
-                return AKEY_STATE_UP;
-            }
-        }
-    } // release lock
-
-    return AKEY_STATE_UNKNOWN;
-}
-
-bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        size_t numVirtualKeys = mLocked.virtualKeys.size();
-        for (size_t i = 0; i < numVirtualKeys; i++) {
-            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
-
-            for (size_t i = 0; i < numCodes; i++) {
-                if (virtualKey.keyCode == keyCodes[i]) {
-                    outFlags[i] = 1;
-                }
-            }
-        }
-    } // release lock
-
-    return true;
-}
-
-
-// --- SingleTouchInputMapper ---
-
-SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
-        TouchInputMapper(device, associatedDisplayId) {
-    initialize();
-}
-
-SingleTouchInputMapper::~SingleTouchInputMapper() {
-}
-
-void SingleTouchInputMapper::initialize() {
-    mAccumulator.clear();
-
-    mDown = false;
-    mX = 0;
-    mY = 0;
-    mPressure = 0; // default to 0 for devices that don't report pressure
-    mToolWidth = 0; // default to 0 for devices that don't report tool width
-}
-
-void SingleTouchInputMapper::reset() {
-    TouchInputMapper::reset();
-
-    initialize();
- }
-
-void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_KEY:
-        switch (rawEvent->scanCode) {
-        case BTN_TOUCH:
-            mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;
-            mAccumulator.btnTouch = rawEvent->value != 0;
-            // Don't sync immediately.  Wait until the next SYN_REPORT since we might
-            // not have received valid position information yet.  This logic assumes that
-            // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet.
-            break;
-        }
-        break;
-
-    case EV_ABS:
-        switch (rawEvent->scanCode) {
-        case ABS_X:
-            mAccumulator.fields |= Accumulator::FIELD_ABS_X;
-            mAccumulator.absX = rawEvent->value;
-            break;
-        case ABS_Y:
-            mAccumulator.fields |= Accumulator::FIELD_ABS_Y;
-            mAccumulator.absY = rawEvent->value;
-            break;
-        case ABS_PRESSURE:
-            mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE;
-            mAccumulator.absPressure = rawEvent->value;
-            break;
-        case ABS_TOOL_WIDTH:
-            mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH;
-            mAccumulator.absToolWidth = rawEvent->value;
-            break;
-        }
-        break;
-
-    case EV_SYN:
-        switch (rawEvent->scanCode) {
-        case SYN_REPORT:
-            sync(rawEvent->when);
-            break;
-        }
-        break;
-    }
-}
-
-void SingleTouchInputMapper::sync(nsecs_t when) {
-    uint32_t fields = mAccumulator.fields;
-    if (fields == 0) {
-        return; // no new state changes, so nothing to do
-    }
-
-    if (fields & Accumulator::FIELD_BTN_TOUCH) {
-        mDown = mAccumulator.btnTouch;
-    }
-
-    if (fields & Accumulator::FIELD_ABS_X) {
-        mX = mAccumulator.absX;
-    }
-
-    if (fields & Accumulator::FIELD_ABS_Y) {
-        mY = mAccumulator.absY;
-    }
-
-    if (fields & Accumulator::FIELD_ABS_PRESSURE) {
-        mPressure = mAccumulator.absPressure;
-    }
-
-    if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) {
-        mToolWidth = mAccumulator.absToolWidth;
-    }
-
-    mCurrentTouch.clear();
-
-    if (mDown) {
-        mCurrentTouch.pointerCount = 1;
-        mCurrentTouch.pointers[0].id = 0;
-        mCurrentTouch.pointers[0].x = mX;
-        mCurrentTouch.pointers[0].y = mY;
-        mCurrentTouch.pointers[0].pressure = mPressure;
-        mCurrentTouch.pointers[0].touchMajor = 0;
-        mCurrentTouch.pointers[0].touchMinor = 0;
-        mCurrentTouch.pointers[0].toolMajor = mToolWidth;
-        mCurrentTouch.pointers[0].toolMinor = mToolWidth;
-        mCurrentTouch.pointers[0].orientation = 0;
-        mCurrentTouch.idToIndex[0] = 0;
-        mCurrentTouch.idBits.markBit(0);
-    }
-
-    syncTouch(when, true);
-
-    mAccumulator.clear();
-}
-
-void SingleTouchInputMapper::configureRawAxes() {
-    TouchInputMapper::configureRawAxes();
-
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
-}
-
-
-// --- MultiTouchInputMapper ---
-
-MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
-        TouchInputMapper(device, associatedDisplayId) {
-    initialize();
-}
-
-MultiTouchInputMapper::~MultiTouchInputMapper() {
-}
-
-void MultiTouchInputMapper::initialize() {
-    mAccumulator.clear();
-}
-
-void MultiTouchInputMapper::reset() {
-    TouchInputMapper::reset();
-
-    initialize();
-}
-
-void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_ABS: {
-        uint32_t pointerIndex = mAccumulator.pointerCount;
-        Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex];
-
-        switch (rawEvent->scanCode) {
-        case ABS_MT_POSITION_X:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X;
-            pointer->absMTPositionX = rawEvent->value;
-            break;
-        case ABS_MT_POSITION_Y:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y;
-            pointer->absMTPositionY = rawEvent->value;
-            break;
-        case ABS_MT_TOUCH_MAJOR:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR;
-            pointer->absMTTouchMajor = rawEvent->value;
-            break;
-        case ABS_MT_TOUCH_MINOR:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR;
-            pointer->absMTTouchMinor = rawEvent->value;
-            break;
-        case ABS_MT_WIDTH_MAJOR:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
-            pointer->absMTWidthMajor = rawEvent->value;
-            break;
-        case ABS_MT_WIDTH_MINOR:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR;
-            pointer->absMTWidthMinor = rawEvent->value;
-            break;
-        case ABS_MT_ORIENTATION:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION;
-            pointer->absMTOrientation = rawEvent->value;
-            break;
-        case ABS_MT_TRACKING_ID:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID;
-            pointer->absMTTrackingId = rawEvent->value;
-            break;
-        case ABS_MT_PRESSURE:
-            pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE;
-            pointer->absMTPressure = rawEvent->value;
-            break;
-        }
-        break;
-    }
-
-    case EV_SYN:
-        switch (rawEvent->scanCode) {
-        case SYN_MT_REPORT: {
-            // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
-            uint32_t pointerIndex = mAccumulator.pointerCount;
-
-            if (mAccumulator.pointers[pointerIndex].fields) {
-                if (pointerIndex == MAX_POINTERS) {
-                    LOGW("MultiTouch device driver returned more than maximum of %d pointers.",
-                            MAX_POINTERS);
-                } else {
-                    pointerIndex += 1;
-                    mAccumulator.pointerCount = pointerIndex;
-                }
-            }
-
-            mAccumulator.pointers[pointerIndex].clear();
-            break;
-        }
-
-        case SYN_REPORT:
-            sync(rawEvent->when);
-            break;
-        }
-        break;
-    }
-}
-
-void MultiTouchInputMapper::sync(nsecs_t when) {
-    static const uint32_t REQUIRED_FIELDS =
-            Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y;
-
-    uint32_t inCount = mAccumulator.pointerCount;
-    uint32_t outCount = 0;
-    bool havePointerIds = true;
-
-    mCurrentTouch.clear();
-
-    for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
-        const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex];
-        uint32_t fields = inPointer.fields;
-
-        if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
-            // Some drivers send empty MT sync packets without X / Y to indicate a pointer up.
-            // Drop this finger.
-            continue;
-        }
-
-        PointerData& outPointer = mCurrentTouch.pointers[outCount];
-        outPointer.x = inPointer.absMTPositionX;
-        outPointer.y = inPointer.absMTPositionY;
-
-        if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
-            if (inPointer.absMTPressure <= 0) {
-                // Some devices send sync packets with X / Y but with a 0 pressure to indicate
-                // a pointer going up.  Drop this finger.
-                continue;
-            }
-            outPointer.pressure = inPointer.absMTPressure;
-        } else {
-            // Default pressure to 0 if absent.
-            outPointer.pressure = 0;
-        }
-
-        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
-            if (inPointer.absMTTouchMajor <= 0) {
-                // Some devices send sync packets with X / Y but with a 0 touch major to indicate
-                // a pointer going up.  Drop this finger.
-                continue;
-            }
-            outPointer.touchMajor = inPointer.absMTTouchMajor;
-        } else {
-            // Default touch area to 0 if absent.
-            outPointer.touchMajor = 0;
-        }
-
-        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
-            outPointer.touchMinor = inPointer.absMTTouchMinor;
-        } else {
-            // Assume touch area is circular.
-            outPointer.touchMinor = outPointer.touchMajor;
-        }
-
-        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
-            outPointer.toolMajor = inPointer.absMTWidthMajor;
-        } else {
-            // Default tool area to 0 if absent.
-            outPointer.toolMajor = 0;
-        }
-
-        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
-            outPointer.toolMinor = inPointer.absMTWidthMinor;
-        } else {
-            // Assume tool area is circular.
-            outPointer.toolMinor = outPointer.toolMajor;
-        }
-
-        if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
-            outPointer.orientation = inPointer.absMTOrientation;
-        } else {
-            // Default orientation to vertical if absent.
-            outPointer.orientation = 0;
-        }
-
-        // Assign pointer id using tracking id if available.
-        if (havePointerIds) {
-            if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
-                uint32_t id = uint32_t(inPointer.absMTTrackingId);
-
-                if (id > MAX_POINTER_ID) {
-#if DEBUG_POINTERS
-                    LOGD("Pointers: Ignoring driver provided pointer id %d because "
-                            "it is larger than max supported id %d",
-                            id, MAX_POINTER_ID);
-#endif
-                    havePointerIds = false;
-                }
-                else {
-                    outPointer.id = id;
-                    mCurrentTouch.idToIndex[id] = outCount;
-                    mCurrentTouch.idBits.markBit(id);
-                }
-            } else {
-                havePointerIds = false;
-            }
-        }
-
-        outCount += 1;
-    }
-
-    mCurrentTouch.pointerCount = outCount;
-
-    syncTouch(when, havePointerIds);
-
-    mAccumulator.clear();
-}
-
-void MultiTouchInputMapper::configureRawAxes() {
-    TouchInputMapper::configureRawAxes();
-
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation);
-    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure);
-}
-
-
-} // namespace android
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 2c6346e..5c57a76 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -35,8 +35,12 @@
 static const char INPUT_SIGNAL_DISPATCH = 'D';
 
 // Signal sent by the consumer to the producer to inform it that it has finished
-// consuming the most recent message.
-static const char INPUT_SIGNAL_FINISHED = 'f';
+// consuming the most recent message and it handled it.
+static const char INPUT_SIGNAL_FINISHED_HANDLED = 'f';
+
+// Signal sent by the consumer to the producer to inform it that it has finished
+// consuming the most recent message but it did not handle it.
+static const char INPUT_SIGNAL_FINISHED_UNHANDLED = 'u';
 
 
 // --- InputChannel ---
@@ -408,7 +412,8 @@
     // Cache essential information about the motion event to ensure that a malicious consumer
     // cannot confuse the publisher by modifying the contents of the shared memory buffer while
     // it is being updated.
-    if (action == AMOTION_EVENT_ACTION_MOVE) {
+    if (action == AMOTION_EVENT_ACTION_MOVE
+            || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
         mMotionEventPointerCount = pointerCount;
         mMotionEventSampleDataStride = InputMessage::sampleDataStride(pointerCount);
         mMotionEventSampleDataTail = InputMessage::sampleDataPtrIncrement(
@@ -497,7 +502,7 @@
     return mChannel->sendSignal(INPUT_SIGNAL_DISPATCH);
 }
 
-status_t InputPublisher::receiveFinishedSignal() {
+status_t InputPublisher::receiveFinishedSignal(bool* outHandled) {
 #if DEBUG_TRANSPORT_ACTIONS
     LOGD("channel '%s' publisher ~ receiveFinishedSignal",
             mChannel->getName().string());
@@ -506,9 +511,14 @@
     char signal;
     status_t result = mChannel->receiveSignal(& signal);
     if (result) {
+        *outHandled = false;
         return result;
     }
-    if (signal != INPUT_SIGNAL_FINISHED) {
+    if (signal == INPUT_SIGNAL_FINISHED_HANDLED) {
+        *outHandled = true;
+    } else if (signal == INPUT_SIGNAL_FINISHED_UNHANDLED) {
+        *outHandled = false;
+    } else {
         LOGE("channel '%s' publisher ~ Received unexpected signal '%c' from consumer",
                 mChannel->getName().string(), signal);
         return UNKNOWN_ERROR;
@@ -626,13 +636,15 @@
     return OK;
 }
 
-status_t InputConsumer::sendFinishedSignal() {
+status_t InputConsumer::sendFinishedSignal(bool handled) {
 #if DEBUG_TRANSPORT_ACTIONS
-    LOGD("channel '%s' consumer ~ sendFinishedSignal",
-            mChannel->getName().string());
+    LOGD("channel '%s' consumer ~ sendFinishedSignal: handled=%d",
+            mChannel->getName().string(), handled);
 #endif
 
-    return mChannel->sendSignal(INPUT_SIGNAL_FINISHED);
+    return mChannel->sendSignal(handled
+            ? INPUT_SIGNAL_FINISHED_HANDLED
+            : INPUT_SIGNAL_FINISHED_UNHANDLED);
 }
 
 status_t InputConsumer::receiveDispatchSignal() {
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
index e891181..2decfe9 100644
--- a/libs/ui/KeyCharacterMap.cpp
+++ b/libs/ui/KeyCharacterMap.cpp
@@ -1,263 +1,849 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
 #define LOG_TAG "KeyCharacterMap"
 
-#include <ui/KeyCharacterMap.h>
-#include <cutils/properties.h>
-
-#include <utils/Log.h>
-#include <sys/types.h>
-#include <unistd.h>
 #include <stdlib.h>
-#include <fcntl.h>
-#include <limits.h>
 #include <string.h>
+#include <android/keycodes.h>
+#include <ui/Keyboard.h>
+#include <ui/KeyCharacterMap.h>
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/Tokenizer.h>
+#include <utils/Timers.h>
 
-struct Header
-{
-    char magic[8];
-    unsigned int endian;
-    unsigned int version;
-    unsigned int keycount;
-    unsigned char kbdtype;
-    char padding[11];
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+// Enables debug output for mapping.
+#define DEBUG_MAPPING 0
+
+
+namespace android {
+
+static const char* WHITESPACE = " \t\r";
+static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:";
+
+struct Modifier {
+    const char* label;
+    int32_t metaState;
+};
+static const Modifier modifiers[] = {
+        { "shift", AMETA_SHIFT_ON },
+        { "lshift", AMETA_SHIFT_LEFT_ON },
+        { "rshift", AMETA_SHIFT_RIGHT_ON },
+        { "alt", AMETA_ALT_ON },
+        { "lalt", AMETA_ALT_LEFT_ON },
+        { "ralt", AMETA_ALT_RIGHT_ON },
+        { "ctrl", AMETA_CTRL_ON },
+        { "lctrl", AMETA_CTRL_LEFT_ON },
+        { "rctrl", AMETA_CTRL_RIGHT_ON },
+        { "meta", AMETA_META_ON },
+        { "lmeta", AMETA_META_LEFT_ON },
+        { "rmeta", AMETA_META_RIGHT_ON },
+        { "sym", AMETA_SYM_ON },
+        { "fn", AMETA_FUNCTION_ON },
+        { "capslock", AMETA_CAPS_LOCK_ON },
+        { "numlock", AMETA_NUM_LOCK_ON },
+        { "scrolllock", AMETA_SCROLL_LOCK_ON },
 };
 
-KeyCharacterMap::KeyCharacterMap()
-{
-}
-
-KeyCharacterMap::~KeyCharacterMap()
-{
-    free(m_keys);
-}
-
-unsigned short
-KeyCharacterMap::get(int keycode, int meta)
-{
-    Key* k = find_key(keycode);
-    if (k != NULL) {
-        return k->data[meta & META_MASK];
+#if DEBUG_MAPPING
+static String8 toString(const char16_t* chars, size_t numChars) {
+    String8 result;
+    for (size_t i = 0; i < numChars; i++) {
+        result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]);
     }
-    return 0;
+    return result;
+}
+#endif
+
+
+// --- KeyCharacterMap ---
+
+KeyCharacterMap::KeyCharacterMap() :
+    mType(KEYBOARD_TYPE_UNKNOWN) {
 }
 
-unsigned short
-KeyCharacterMap::getNumber(int keycode)
-{
-    Key* k = find_key(keycode);
-    if (k != NULL) {
-        return k->number;
+KeyCharacterMap::~KeyCharacterMap() {
+    for (size_t i = 0; i < mKeys.size(); i++) {
+        Key* key = mKeys.editValueAt(i);
+        delete key;
     }
-    return 0;
 }
 
-unsigned short
-KeyCharacterMap::getMatch(int keycode, const unsigned short* chars,
-                          int charsize, uint32_t modifiers)
-{
-    Key* k = find_key(keycode);
-    modifiers &= 3; // ignore the SYM key because we don't have keymap entries for it
-    if (k != NULL) {
-        const uint16_t* data = k->data;
-        for (int j=0; j<charsize; j++) {
-            uint16_t c = chars[j];
-            for (int i=0; i<(META_MASK + 1); i++) {
-                if ((modifiers == 0) || ((modifiers & i) != 0)) {
-                    if (c == data[i]) {
-                        return c;
+status_t KeyCharacterMap::load(const String8& filename, KeyCharacterMap** outMap) {
+    *outMap = NULL;
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::open(filename, &tokenizer);
+    if (status) {
+        LOGE("Error %d opening key character map file %s.", status, filename.string());
+    } else {
+        KeyCharacterMap* map = new KeyCharacterMap();
+        if (!map) {
+            LOGE("Error allocating key character map.");
+            status = NO_MEMORY;
+        } else {
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+            Parser parser(map, tokenizer);
+            status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+            LOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
+                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                    elapsedTime / 1000000.0);
+#endif
+            if (status) {
+                delete map;
+            } else {
+                *outMap = map;
+            }
+        }
+        delete tokenizer;
+    }
+    return status;
+}
+
+status_t KeyCharacterMap::loadByDeviceId(int32_t deviceId, KeyCharacterMap** outMap) {
+    *outMap = NULL;
+
+    String8 filename;
+    status_t result = getKeyCharacterMapFile(deviceId, filename);
+    if (!result) {
+        result = load(filename, outMap);
+    }
+    return result;
+}
+
+int32_t KeyCharacterMap::getKeyboardType() const {
+    return mType;
+}
+
+char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
+    char16_t result = 0;
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        result = key->label;
+    }
+#if DEBUG_MAPPING
+    LOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result);
+#endif
+    return result;
+}
+
+char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
+    char16_t result = 0;
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        result = key->number;
+    }
+#if DEBUG_MAPPING
+    LOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result);
+#endif
+    return result;
+}
+
+char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
+    char16_t result = 0;
+    const Key* key;
+    const Behavior* behavior;
+    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+        result = behavior->character;
+    }
+#if DEBUG_MAPPING
+    LOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
+#endif
+    return result;
+}
+
+bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
+        FallbackAction* outFallbackAction) const {
+    outFallbackAction->keyCode = 0;
+    outFallbackAction->metaState = 0;
+
+    bool result = false;
+    const Key* key;
+    const Behavior* behavior;
+    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+        if (behavior->fallbackKeyCode) {
+            outFallbackAction->keyCode = behavior->fallbackKeyCode;
+            outFallbackAction->metaState = metaState & ~behavior->metaState;
+            result = true;
+        }
+    }
+#if DEBUG_MAPPING
+    LOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
+            "fallback keyCode=%d, fallback metaState=0x%08x.",
+            keyCode, metaState, result ? "true" : "false",
+            outFallbackAction->keyCode, outFallbackAction->metaState);
+#endif
+    return result;
+}
+
+char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
+        int32_t metaState) const {
+    char16_t result = 0;
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        // Try to find the most general behavior that maps to this character.
+        // For example, the base key behavior will usually be last in the list.
+        // However, if we find a perfect meta state match for one behavior then use that one.
+        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
+            if (behavior->character) {
+                for (size_t i = 0; i < numChars; i++) {
+                    if (behavior->character == chars[i]) {
+                        result = behavior->character;
+                        if ((behavior->metaState & metaState) == behavior->metaState) {
+                            goto ExactMatch;
+                        }
+                        break;
                     }
                 }
             }
         }
+    ExactMatch: ;
     }
-    return 0;
+#if DEBUG_MAPPING
+    LOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
+            keyCode, toString(chars, numChars).string(), metaState, result);
+#endif
+    return result;
 }
 
-unsigned short
-KeyCharacterMap::getDisplayLabel(int keycode)
-{
-    Key* k = find_key(keycode);
-    if (k != NULL) {
-        return k->display_label;
+bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
+        Vector<KeyEvent>& outEvents) const {
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+
+    for (size_t i = 0; i < numChars; i++) {
+        int32_t keyCode, metaState;
+        char16_t ch = chars[i];
+        if (!findKey(ch, &keyCode, &metaState)) {
+#if DEBUG_MAPPING
+            LOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
+                    deviceId, toString(chars, numChars).string(), ch);
+#endif
+            return false;
+        }
+
+        int32_t currentMetaState = 0;
+        addMetaKeys(outEvents, deviceId, metaState, true, now, &currentMetaState);
+        addKey(outEvents, deviceId, keyCode, currentMetaState, true, now);
+        addKey(outEvents, deviceId, keyCode, currentMetaState, false, now);
+        addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
     }
-    return 0;
+#if DEBUG_MAPPING
+    LOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
+            deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
+    for (size_t i = 0; i < outEvents.size(); i++) {
+        LOGD("  Key: keyCode=%d, metaState=0x%08x, %s.",
+                outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
+                outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up");
+    }
+#endif
+    return true;
 }
 
-bool
-KeyCharacterMap::getKeyData(int keycode, unsigned short *displayLabel,
-                            unsigned short *number, unsigned short* results)
-{
-    Key* k = find_key(keycode);
-    if (k != NULL) {
-        memcpy(results, k->data, sizeof(short)*(META_MASK + 1));
-        *number = k->number;
-        *displayLabel = k->display_label;
+bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
+    ssize_t index = mKeys.indexOfKey(keyCode);
+    if (index >= 0) {
+        *outKey = mKeys.valueAt(index);
         return true;
-    } else {
-        return false;
     }
+    return false;
 }
 
-bool
-KeyCharacterMap::find_char(uint16_t c, uint32_t* key, uint32_t* mods)
-{
-    uint32_t N = m_keyCount;
-    for (int j=0; j<(META_MASK + 1); j++) {
-        Key const* keys = m_keys;
-        for (uint32_t i=0; i<N; i++) {
-            if (keys->data[j] == c) {
-                *key = keys->keycode;
-                *mods = j;
+bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
+        const Key** outKey, const Behavior** outBehavior) const {
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        const Behavior* behavior = key->firstBehavior;
+        while (behavior) {
+            if ((behavior->metaState & metaState) == behavior->metaState) {
+                *outKey = key;
+                *outBehavior = behavior;
                 return true;
             }
-            keys++;
+            behavior = behavior->next;
         }
     }
     return false;
 }
 
-bool
-KeyCharacterMap::getEvents(uint16_t* chars, size_t len,
-                           Vector<int32_t>* keys, Vector<uint32_t>* modifiers)
-{
-    for (size_t i=0; i<len; i++) {
-        uint32_t k, mods;
-        if (find_char(chars[i], &k, &mods)) {
-            keys->add(k);
-            modifiers->add(mods);
-        } else {
-            return false;
+bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
+    if (!ch) {
+        return false;
+    }
+
+    for (size_t i = 0; i < mKeys.size(); i++) {
+        const Key* key = mKeys.valueAt(i);
+
+        // Try to find the most general behavior that maps to this character.
+        // For example, the base key behavior will usually be last in the list.
+        const Behavior* found = NULL;
+        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
+            if (behavior->character == ch) {
+                found = behavior;
+            }
+        }
+        if (found) {
+            *outKeyCode = mKeys.keyAt(i);
+            *outMetaState = found->metaState;
+            return true;
         }
     }
-    return true;
+    return false;
 }
 
-KeyCharacterMap::Key*
-KeyCharacterMap::find_key(int keycode)
-{
-    Key* keys = m_keys;
-    int low = 0;
-    int high = m_keyCount - 1;
-    int mid;
-    int n;
-    while (low <= high) {
-        mid = (low + high) / 2;
-        n = keys[mid].keycode;
-        if (keycode < n) {
-            high = mid - 1;
-        } else if (keycode > n) {
-            low = mid + 1;
-        } else {
-            return keys + mid;
-        }
-    }
-    return NULL;
+void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
+    outEvents.push();
+    KeyEvent& event = outEvents.editTop();
+    event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD,
+            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
+            0, keyCode, 0, metaState, 0, time, time);
 }
 
-KeyCharacterMap*
-KeyCharacterMap::load(int id)
-{
-    KeyCharacterMap* rv = NULL;
-    char path[PATH_MAX];
-    char propName[100];
-    char dev[PROPERTY_VALUE_MAX];
-    char tmpfn[PROPERTY_VALUE_MAX];
-    int err;
-    const char* root = getenv("ANDROID_ROOT");
+void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+        int32_t* currentMetaState) {
+    // Add and remove meta keys symmetrically.
+    if (down) {
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
 
-    sprintf(propName, "hw.keyboards.%u.devname", id);
-    err = property_get(propName, dev, "");
-    if (err > 0) {
-        // replace all the spaces with underscores
-        strcpy(tmpfn, dev);
-        for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))
-            *p = '_';
-        snprintf(path, sizeof(path), "%s/usr/keychars/%s.kcm.bin", root, tmpfn);
-        //LOGD("load: dev='%s' path='%s'\n", dev, path);
-        rv = try_file(path);
-        if (rv != NULL) {
-            return rv;
-        }
-        LOGW("Error loading keycharmap file '%s'. %s='%s'", path, propName, dev);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
+                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
+                AMETA_SHIFT_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
+                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
+                AMETA_ALT_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
+                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
+                AMETA_CTRL_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
+                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
+                AMETA_META_ON, currentMetaState);
+
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
     } else {
-        LOGW("No keyboard for id %d", id);
-    }
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
 
-    snprintf(path, sizeof(path), "%s/usr/keychars/qwerty.kcm.bin", root);
-    rv = try_file(path);
-    if (rv == NULL) {
-        LOGE("Can't find any keycharmaps (also tried %s)", path);
-        return NULL;
-    }
-    LOGW("Using default keymap: %s", path);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
+                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
+                AMETA_META_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
+                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
+                AMETA_CTRL_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
+                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
+                AMETA_ALT_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
+                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
+                AMETA_SHIFT_ON, currentMetaState);
 
-    return rv;
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
+    }
 }
 
-KeyCharacterMap*
-KeyCharacterMap::try_file(const char* filename)
-{
-    KeyCharacterMap* rv = NULL;
-    Key* keys;
-    int fd;
-    off_t filesize;
-    Header header;
-    int err;
-    
-    fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        LOGW("Can't open keycharmap file");
-        return NULL;
+bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+        int32_t keyCode, int32_t keyMetaState,
+        int32_t* currentMetaState) {
+    if ((metaState & keyMetaState) == keyMetaState) {
+        *currentMetaState = updateMetaState(keyCode, down, *currentMetaState);
+        addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time);
+        return true;
     }
-
-    filesize = lseek(fd, 0, SEEK_END);
-    lseek(fd, 0, SEEK_SET);
-
-    // validate the header
-    if (filesize <= (off_t)sizeof(header)) {
-        LOGW("Bad keycharmap - filesize=%d\n", (int)filesize);
-        goto cleanup1;
-    }
-
-    err = read(fd, &header, sizeof(header));
-    if (err == -1) {
-        LOGW("Error reading keycharmap file");
-        goto cleanup1;
-    }
-
-    if (0 != memcmp(header.magic, "keychar", 8)) {
-        LOGW("Bad keycharmap magic token");
-        goto cleanup1;
-    }
-    if (header.endian != 0x12345678) {
-        LOGW("Bad keycharmap endians");
-        goto cleanup1;
-    }
-    if ((header.version & 0xff) != 2) {
-        LOGW("Only support keycharmap version 2 (got 0x%08x)", header.version);
-        goto cleanup1;
-    }
-    if (filesize < (off_t)(sizeof(Header)+(sizeof(Key)*header.keycount))) {
-        LOGW("Bad keycharmap file size\n");
-        goto cleanup1;
-    }
-
-    // read the key data
-    keys = (Key*)malloc(sizeof(Key)*header.keycount);
-    err = read(fd, keys, sizeof(Key)*header.keycount);
-    if (err == -1) {
-        LOGW("Error reading keycharmap file");
-        free(keys);
-        goto cleanup1;
-    }
-
-    // return the object
-    rv = new KeyCharacterMap;
-    rv->m_keyCount = header.keycount;
-    rv->m_keys = keys;
-    rv->m_type = header.kbdtype;
-
-cleanup1:
-    close(fd);
-
-    return rv;
+    return false;
 }
+
+void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+        int32_t leftKeyCode, int32_t leftKeyMetaState,
+        int32_t rightKeyCode, int32_t rightKeyMetaState,
+        int32_t eitherKeyMetaState,
+        int32_t* currentMetaState) {
+    bool specific = false;
+    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
+            leftKeyCode, leftKeyMetaState, currentMetaState);
+    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
+            rightKeyCode, rightKeyMetaState, currentMetaState);
+
+    if (!specific) {
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
+                leftKeyCode, eitherKeyMetaState, currentMetaState);
+    }
+}
+
+void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, nsecs_t time,
+        int32_t keyCode, int32_t keyMetaState,
+        int32_t* currentMetaState) {
+    if ((metaState & keyMetaState) == keyMetaState) {
+        *currentMetaState = updateMetaState(keyCode, true, *currentMetaState);
+        addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time);
+        *currentMetaState = updateMetaState(keyCode, false, *currentMetaState);
+        addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time);
+    }
+}
+
+
+// --- KeyCharacterMap::Key ---
+
+KeyCharacterMap::Key::Key() :
+        label(0), number(0), firstBehavior(NULL) {
+}
+
+KeyCharacterMap::Key::~Key() {
+    Behavior* behavior = firstBehavior;
+    while (behavior) {
+        Behavior* next = behavior->next;
+        delete behavior;
+        behavior = next;
+    }
+}
+
+
+// --- KeyCharacterMap::Behavior ---
+
+KeyCharacterMap::Behavior::Behavior() :
+        next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
+}
+
+
+// --- KeyCharacterMap::Parser ---
+
+KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer) :
+        mMap(map), mTokenizer(tokenizer), mState(STATE_TOP) {
+}
+
+KeyCharacterMap::Parser::~Parser() {
+}
+
+status_t KeyCharacterMap::Parser::parse() {
+    while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+        LOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+                mTokenizer->peekRemainderOfLine().string());
+#endif
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+
+        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+            switch (mState) {
+            case STATE_TOP: {
+                String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+                if (keywordToken == "type") {
+                    mTokenizer->skipDelimiters(WHITESPACE);
+                    status_t status = parseType();
+                    if (status) return status;
+                } else if (keywordToken == "key") {
+                    mTokenizer->skipDelimiters(WHITESPACE);
+                    status_t status = parseKey();
+                    if (status) return status;
+                } else {
+                    LOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
+                            keywordToken.string());
+                    return BAD_VALUE;
+                }
+                break;
+            }
+
+            case STATE_KEY: {
+                status_t status = parseKeyProperty();
+                if (status) return status;
+                break;
+            }
+            }
+
+            mTokenizer->skipDelimiters(WHITESPACE);
+            if (!mTokenizer->isEol()) {
+                LOGE("%s: Expected end of line, got '%s'.",
+                        mTokenizer->getLocation().string(),
+                        mTokenizer->peekRemainderOfLine().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->nextLine();
+    }
+
+    if (mState != STATE_TOP) {
+        LOGE("%s: Unterminated key description at end of file.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
+        LOGE("%s: Missing required keyboard 'type' declaration.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseType() {
+    if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) {
+        LOGE("%s: Duplicate keyboard 'type' declaration.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    KeyboardType type;
+    String8 typeToken = mTokenizer->nextToken(WHITESPACE);
+    if (typeToken == "NUMERIC") {
+        type = KEYBOARD_TYPE_NUMERIC;
+    } else if (typeToken == "PREDICTIVE") {
+        type = KEYBOARD_TYPE_PREDICTIVE;
+    } else if (typeToken == "ALPHA") {
+        type = KEYBOARD_TYPE_ALPHA;
+    } else if (typeToken == "FULL") {
+        type = KEYBOARD_TYPE_FULL;
+    } else if (typeToken == "SPECIAL_FUNCTION") {
+        type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
+    } else {
+        LOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
+                typeToken.string());
+        return BAD_VALUE;
+    }
+
+#if DEBUG_PARSER
+    LOGD("Parsed type: type=%d.", type);
+#endif
+    mMap->mType = type;
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseKey() {
+    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
+    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
+    if (!keyCode) {
+        LOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
+                keyCodeToken.string());
+        return BAD_VALUE;
+    }
+    if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
+        LOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
+                keyCodeToken.string());
+        return BAD_VALUE;
+    }
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
+    if (openBraceToken != "{") {
+        LOGE("%s: Expected '{' after key code label, got '%s'.",
+                mTokenizer->getLocation().string(), openBraceToken.string());
+        return BAD_VALUE;
+    }
+
+#if DEBUG_PARSER
+    LOGD("Parsed beginning of key: keyCode=%d.", keyCode);
+#endif
+    mKeyCode = keyCode;
+    mMap->mKeys.add(keyCode, new Key());
+    mState = STATE_KEY;
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseKeyProperty() {
+    String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
+    if (token == "}") {
+        mState = STATE_TOP;
+        return NO_ERROR;
+    }
+
+    Vector<Property> properties;
+
+    // Parse all comma-delimited property names up to the first colon.
+    for (;;) {
+        if (token == "label") {
+            properties.add(Property(PROPERTY_LABEL));
+        } else if (token == "number") {
+            properties.add(Property(PROPERTY_NUMBER));
+        } else {
+            int32_t metaState;
+            status_t status = parseModifier(token, &metaState);
+            if (status) {
+                LOGE("%s: Expected a property name or modifier, got '%s'.",
+                        mTokenizer->getLocation().string(), token.string());
+                return status;
+            }
+            properties.add(Property(PROPERTY_META, metaState));
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        if (!mTokenizer->isEol()) {
+            char ch = mTokenizer->nextChar();
+            if (ch == ':') {
+                break;
+            } else if (ch == ',') {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
+                continue;
+            }
+        }
+
+        LOGE("%s: Expected ',' or ':' after property name.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    // Parse behavior after the colon.
+    mTokenizer->skipDelimiters(WHITESPACE);
+
+    Behavior behavior;
+    bool haveCharacter = false;
+    bool haveFallback = false;
+
+    do {
+        char ch = mTokenizer->peekChar();
+        if (ch == '\'') {
+            char16_t character;
+            status_t status = parseCharacterLiteral(&character);
+            if (status || !character) {
+                LOGE("%s: Invalid character literal for key.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            if (haveCharacter) {
+                LOGE("%s: Cannot combine multiple character literals or 'none'.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            behavior.character = character;
+            haveCharacter = true;
+        } else {
+            token = mTokenizer->nextToken(WHITESPACE);
+            if (token == "none") {
+                if (haveCharacter) {
+                    LOGE("%s: Cannot combine multiple character literals or 'none'.",
+                            mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+                haveCharacter = true;
+            } else if (token == "fallback") {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                token = mTokenizer->nextToken(WHITESPACE);
+                int32_t keyCode = getKeyCodeByLabel(token.string());
+                if (!keyCode) {
+                    LOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
+                            mTokenizer->getLocation().string(),
+                            token.string());
+                    return BAD_VALUE;
+                }
+                if (haveFallback) {
+                    LOGE("%s: Cannot combine multiple fallback key codes.",
+                            mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+                behavior.fallbackKeyCode = keyCode;
+                haveFallback = true;
+            } else {
+                LOGE("%s: Expected a key behavior after ':'.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+    } while (!mTokenizer->isEol());
+
+    // Add the behavior.
+    Key* key = mMap->mKeys.valueFor(mKeyCode);
+    for (size_t i = 0; i < properties.size(); i++) {
+        const Property& property = properties.itemAt(i);
+        switch (property.property) {
+        case PROPERTY_LABEL:
+            if (key->label) {
+                LOGE("%s: Duplicate label for key.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            key->label = behavior.character;
+#if DEBUG_PARSER
+            LOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label);
+#endif
+            break;
+        case PROPERTY_NUMBER:
+            if (key->number) {
+                LOGE("%s: Duplicate number for key.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            key->number = behavior.character;
+#if DEBUG_PARSER
+            LOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number);
+#endif
+            break;
+        case PROPERTY_META: {
+            for (Behavior* b = key->firstBehavior; b; b = b->next) {
+                if (b->metaState == property.metaState) {
+                    LOGE("%s: Duplicate key behavior for modifier.",
+                            mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+            }
+            Behavior* newBehavior = new Behavior(behavior);
+            newBehavior->metaState = property.metaState;
+            newBehavior->next = key->firstBehavior;
+            key->firstBehavior = newBehavior;
+#if DEBUG_PARSER
+            LOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode,
+                    newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode);
+#endif
+            break;
+        }
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
+    if (token == "base") {
+        *outMetaState = 0;
+        return NO_ERROR;
+    }
+
+    int32_t combinedMeta = 0;
+
+    const char* str = token.string();
+    const char* start = str;
+    for (const char* cur = str; ; cur++) {
+        char ch = *cur;
+        if (ch == '+' || ch == '\0') {
+            size_t len = cur - start;
+            int32_t metaState = 0;
+            for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) {
+                if (strlen(modifiers[i].label) == len
+                        && strncmp(modifiers[i].label, start, len) == 0) {
+                    metaState = modifiers[i].metaState;
+                    break;
+                }
+            }
+            if (!metaState) {
+                return BAD_VALUE;
+            }
+            if (combinedMeta & metaState) {
+                LOGE("%s: Duplicate modifier combination '%s'.",
+                        mTokenizer->getLocation().string(), token.string());
+                return BAD_VALUE;
+            }
+
+            combinedMeta |= metaState;
+            start = cur + 1;
+
+            if (ch == '\0') {
+                break;
+            }
+        }
+    }
+    *outMetaState = combinedMeta;
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) {
+    char ch = mTokenizer->nextChar();
+    if (ch != '\'') {
+        goto Error;
+    }
+
+    ch = mTokenizer->nextChar();
+    if (ch == '\\') {
+        // Escape sequence.
+        ch = mTokenizer->nextChar();
+        if (ch == 'n') {
+            *outCharacter = '\n';
+        } else if (ch == 't') {
+            *outCharacter = '\t';
+        } else if (ch == '\\') {
+            *outCharacter = '\\';
+        } else if (ch == '\'') {
+            *outCharacter = '\'';
+        } else if (ch == '"') {
+            *outCharacter = '"';
+        } else if (ch == 'u') {
+            *outCharacter = 0;
+            for (int i = 0; i < 4; i++) {
+                ch = mTokenizer->nextChar();
+                int digit;
+                if (ch >= '0' && ch <= '9') {
+                    digit = ch - '0';
+                } else if (ch >= 'A' && ch <= 'F') {
+                    digit = ch - 'A' + 10;
+                } else if (ch >= 'a' && ch <= 'f') {
+                    digit = ch - 'a' + 10;
+                } else {
+                    goto Error;
+                }
+                *outCharacter = (*outCharacter << 4) | digit;
+            }
+        } else {
+            goto Error;
+        }
+    } else if (ch >= 32 && ch <= 126 && ch != '\'') {
+        // ASCII literal character.
+        *outCharacter = ch;
+    } else {
+        goto Error;
+    }
+
+    ch = mTokenizer->nextChar();
+    if (ch != '\'') {
+        goto Error;
+    }
+
+    // Ensure that we consumed the entire token.
+    if (mTokenizer->nextToken(WHITESPACE).isEmpty()) {
+        return NO_ERROR;
+    }
+
+Error:
+    LOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
+    return BAD_VALUE;
+}
+
+} // namespace android
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
index 15ae54c..8626a03 100644
--- a/libs/ui/KeyLayoutMap.cpp
+++ b/libs/ui/KeyLayoutMap.cpp
@@ -1,234 +1,340 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
 #define LOG_TAG "KeyLayoutMap"
 
-#include "KeyLayoutMap.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <utils/String8.h>
 #include <stdlib.h>
-#include <ui/KeycodeLabels.h>
+#include <android/keycodes.h>
+#include <ui/Keyboard.h>
+#include <ui/KeyLayoutMap.h>
 #include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/Tokenizer.h>
+#include <utils/Timers.h>
+
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+// Enables debug output for mapping.
+#define DEBUG_MAPPING 0
+
 
 namespace android {
 
-KeyLayoutMap::KeyLayoutMap()
-    :m_status(NO_INIT),
-     m_keys()
-{
+static const char* WHITESPACE = " \t\r";
+
+// --- KeyLayoutMap ---
+
+KeyLayoutMap::KeyLayoutMap() {
 }
 
-KeyLayoutMap::~KeyLayoutMap()
-{
+KeyLayoutMap::~KeyLayoutMap() {
 }
 
-static String8
-next_token(char const** p, int *line)
-{
-    bool begun = false;
-    const char* begin = *p;
-    const char* end = *p;
-    while (true) {
-        if (*end == '\n') {
-            (*line)++;
+status_t KeyLayoutMap::load(const String8& filename, KeyLayoutMap** outMap) {
+    *outMap = NULL;
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::open(filename, &tokenizer);
+    if (status) {
+        LOGE("Error %d opening key layout map file %s.", status, filename.string());
+    } else {
+        KeyLayoutMap* map = new KeyLayoutMap();
+        if (!map) {
+            LOGE("Error allocating key layout map.");
+            status = NO_MEMORY;
+        } else {
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+            Parser parser(map, tokenizer);
+            status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+            LOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
+                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                    elapsedTime / 1000000.0);
+#endif
+            if (status) {
+                delete map;
+            } else {
+                *outMap = map;
+            }
         }
-        switch (*end)
-        {
-            case '#':
-                if (begun) {
-                    *p = end;
-                    return String8(begin, end-begin);
-                } else {
-                    do {
-                        begin++;
-                        end++;
-                    } while (*begin != '\0' && *begin != '\n');
-                }
-            case '\0':
-            case ' ':
-            case '\n':
-            case '\r':
-            case '\t':
-                if (begun || (*end == '\0')) {
-                    *p = end;
-                    return String8(begin, end-begin);
-                } else {
-                    begin++;
-                    end++;
-                    break;
-                }
-            default:
-                end++;
-                begun = true;
-        }
+        delete tokenizer;
     }
+    return status;
 }
 
-static int32_t
-token_to_value(const char *literal, const KeycodeLabel *list)
-{
-    while (list->literal) {
-        if (0 == strcmp(literal, list->literal)) {
-            return list->value;
-        }
-        list++;
-    }
-    return list->value;
-}
-
-status_t
-KeyLayoutMap::load(const char* filename)
-{
-    int fd = open(filename, O_RDONLY);
-    if (fd < 0) {
-        LOGE("error opening file=%s err=%s\n", filename, strerror(errno));
-        m_status = errno;
-        return errno;
-    }
-
-    off_t len = lseek(fd, 0, SEEK_END);
-    off_t errlen = lseek(fd, 0, SEEK_SET);
-    if (len < 0 || errlen < 0) {
-        close(fd);
-        LOGE("error seeking file=%s err=%s\n", filename, strerror(errno));
-        m_status = errno;
-        return errno;
-    }
-
-    char* buf = (char*)malloc(len+1);
-    if (read(fd, buf, len) != len) {
-        LOGE("error reading file=%s err=%s\n", filename, strerror(errno));
-        m_status = errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
-        return errno != 0 ? errno : ((int)NOT_ENOUGH_DATA);
-    }
-    errno = 0;
-    buf[len] = '\0';
-
-    int32_t scancode = -1;
-    int32_t keycode = -1;
-    uint32_t flags = 0;
-    uint32_t tmp;
-    char* end;
-    status_t err = NO_ERROR;
-    int line = 1;
-    char const* p = buf;
-    enum { BEGIN, SCANCODE, KEYCODE, FLAG } state = BEGIN;
-    while (true) {
-        String8 token = next_token(&p, &line);
-        if (*p == '\0') {
-            break;
-        }
-        switch (state)
-        {
-            case BEGIN:
-                if (token == "key") {
-                    state = SCANCODE;
-                } else {
-                    LOGE("%s:%d: expected key, got '%s'\n", filename, line,
-                            token.string());
-                    err = BAD_VALUE;
-                    goto done;
-                }
-                break;
-            case SCANCODE:
-                scancode = strtol(token.string(), &end, 0);
-                if (*end != '\0') {
-                    LOGE("%s:%d: expected scancode (a number), got '%s'\n",
-                            filename, line, token.string());
-                    goto done;
-                }
-                //LOGI("%s:%d: got scancode %d\n", filename, line, scancode );
-                state = KEYCODE;
-                break;
-            case KEYCODE:
-                keycode = token_to_value(token.string(), KEYCODES);
-                //LOGI("%s:%d: got keycode %d for %s\n", filename, line, keycode, token.string() );
-                if (keycode == 0) {
-                    LOGE("%s:%d: expected keycode, got '%s'\n",
-                            filename, line, token.string());
-                    goto done;
-                }
-                state = FLAG;
-                break;
-            case FLAG:
-                if (token == "key") {
-                    if (scancode != -1) {
-                        //LOGI("got key decl scancode=%d keycode=%d"
-                        //       " flags=0x%08x\n", scancode, keycode, flags);
-                        Key k = { keycode, flags };
-                        m_keys.add(scancode, k);
-                        state = SCANCODE;
-                        scancode = -1;
-                        keycode = -1;
-                        flags = 0;
-                        break;
-                    }
-                }
-                tmp = token_to_value(token.string(), FLAGS);
-                //LOGI("%s:%d: got flags %x for %s\n", filename, line, tmp, token.string() );
-                if (tmp == 0) {
-                    LOGE("%s:%d: expected flag, got '%s'\n",
-                            filename, line, token.string());
-                    goto done;
-                }
-                flags |= tmp;
-                break;
-        }
-    }
-    if (state == FLAG && scancode != -1 ) {
-        //LOGI("got key decl scancode=%d keycode=%d"
-        //       " flags=0x%08x\n", scancode, keycode, flags);
-        Key k = { keycode, flags };
-        m_keys.add(scancode, k);
-    }
-
-done:
-    free(buf);
-    close(fd);
-
-    m_status = err;
-    return err;
-}
-
-status_t
-KeyLayoutMap::map(int32_t scancode, int32_t *keycode, uint32_t *flags) const
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-
-    ssize_t index = m_keys.indexOfKey(scancode);
+status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const {
+    ssize_t index = mKeys.indexOfKey(scanCode);
     if (index < 0) {
-        //LOGW("couldn't map scancode=%d\n", scancode);
+#if DEBUG_MAPPING
+        LOGD("mapKey: scanCode=%d ~ Failed.", scanCode);
+#endif
+        *keyCode = AKEYCODE_UNKNOWN;
+        *flags = 0;
         return NAME_NOT_FOUND;
     }
 
-    const Key& k = m_keys.valueAt(index);
-
-    *keycode = k.keycode;
+    const Key& k = mKeys.valueAt(index);
+    *keyCode = k.keyCode;
     *flags = k.flags;
 
-    //LOGD("mapped scancode=%d to keycode=%d flags=0x%08x\n", scancode,
-    //        keycode, flags);
-
+#if DEBUG_MAPPING
+    LOGD("mapKey: scanCode=%d ~ Result keyCode=%d, flags=0x%08x.", scanCode, *keyCode, *flags);
+#endif
     return NO_ERROR;
 }
 
-status_t
-KeyLayoutMap::findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-    
-    const size_t N = m_keys.size();
+status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
+    const size_t N = mKeys.size();
     for (size_t i=0; i<N; i++) {
-        if (m_keys.valueAt(i).keycode == keycode) {
-            outScancodes->add(m_keys.keyAt(i));
+        if (mKeys.valueAt(i).keyCode == keyCode) {
+            outScanCodes->add(mKeys.keyAt(i));
         }
     }
-    
+    return NO_ERROR;
+}
+
+status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
+    ssize_t index = mAxes.indexOfKey(scanCode);
+    if (index < 0) {
+#if DEBUG_MAPPING
+        LOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
+#endif
+        return NAME_NOT_FOUND;
+    }
+
+    *outAxisInfo = mAxes.valueAt(index);
+
+#if DEBUG_MAPPING
+    LOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
+            "splitValue=%d, flatOverride=%d.",
+            scanCode,
+            outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
+            outAxisInfo->splitValue, outAxisInfo->flatOverride);
+#endif
+    return NO_ERROR;
+}
+
+
+// --- KeyLayoutMap::Parser ---
+
+KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
+        mMap(map), mTokenizer(tokenizer) {
+}
+
+KeyLayoutMap::Parser::~Parser() {
+}
+
+status_t KeyLayoutMap::Parser::parse() {
+    while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+        LOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+                mTokenizer->peekRemainderOfLine().string());
+#endif
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+
+        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+            String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+            if (keywordToken == "key") {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                status_t status = parseKey();
+                if (status) return status;
+            } else if (keywordToken == "axis") {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                status_t status = parseAxis();
+                if (status) return status;
+            } else {
+                LOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
+                        keywordToken.string());
+                return BAD_VALUE;
+            }
+
+            mTokenizer->skipDelimiters(WHITESPACE);
+            if (!mTokenizer->isEol()) {
+                LOGE("%s: Expected end of line, got '%s'.",
+                        mTokenizer->getLocation().string(),
+                        mTokenizer->peekRemainderOfLine().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->nextLine();
+    }
+    return NO_ERROR;
+}
+
+status_t KeyLayoutMap::Parser::parseKey() {
+    String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
+    char* end;
+    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
+    if (*end) {
+        LOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(),
+                scanCodeToken.string());
+        return BAD_VALUE;
+    }
+    if (mMap->mKeys.indexOfKey(scanCode) >= 0) {
+        LOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(),
+                scanCodeToken.string());
+        return BAD_VALUE;
+    }
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
+    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
+    if (!keyCode) {
+        LOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
+                keyCodeToken.string());
+        return BAD_VALUE;
+    }
+
+    uint32_t flags = 0;
+    for (;;) {
+        mTokenizer->skipDelimiters(WHITESPACE);
+        if (mTokenizer->isEol()) break;
+
+        String8 flagToken = mTokenizer->nextToken(WHITESPACE);
+        uint32_t flag = getKeyFlagByLabel(flagToken.string());
+        if (!flag) {
+            LOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
+                    flagToken.string());
+            return BAD_VALUE;
+        }
+        if (flags & flag) {
+            LOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
+                    flagToken.string());
+            return BAD_VALUE;
+        }
+        flags |= flag;
+    }
+
+#if DEBUG_PARSER
+    LOGD("Parsed key: scanCode=%d, keyCode=%d, flags=0x%08x.", scanCode, keyCode, flags);
+#endif
+    Key key;
+    key.keyCode = keyCode;
+    key.flags = flags;
+    mMap->mKeys.add(scanCode, key);
+    return NO_ERROR;
+}
+
+status_t KeyLayoutMap::Parser::parseAxis() {
+    String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
+    char* end;
+    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
+    if (*end) {
+        LOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
+                scanCodeToken.string());
+        return BAD_VALUE;
+    }
+    if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
+        LOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
+                scanCodeToken.string());
+        return BAD_VALUE;
+    }
+
+    AxisInfo axisInfo;
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 token = mTokenizer->nextToken(WHITESPACE);
+    if (token == "invert") {
+        axisInfo.mode = AxisInfo::MODE_INVERT;
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 axisToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.axis = getAxisByLabel(axisToken.string());
+        if (axisInfo.axis < 0) {
+            LOGE("%s: Expected inverted axis label, got '%s'.",
+                    mTokenizer->getLocation().string(), axisToken.string());
+            return BAD_VALUE;
+        }
+    } else if (token == "split") {
+        axisInfo.mode = AxisInfo::MODE_SPLIT;
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 splitToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
+        if (*end) {
+            LOGE("%s: Expected split value, got '%s'.",
+                    mTokenizer->getLocation().string(), splitToken.string());
+            return BAD_VALUE;
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.axis = getAxisByLabel(lowAxisToken.string());
+        if (axisInfo.axis < 0) {
+            LOGE("%s: Expected low axis label, got '%s'.",
+                    mTokenizer->getLocation().string(), lowAxisToken.string());
+            return BAD_VALUE;
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
+        if (axisInfo.highAxis < 0) {
+            LOGE("%s: Expected high axis label, got '%s'.",
+                    mTokenizer->getLocation().string(), highAxisToken.string());
+            return BAD_VALUE;
+        }
+    } else {
+        axisInfo.axis = getAxisByLabel(token.string());
+        if (axisInfo.axis < 0) {
+            LOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
+                    mTokenizer->getLocation().string(), token.string());
+            return BAD_VALUE;
+        }
+    }
+
+    for (;;) {
+        mTokenizer->skipDelimiters(WHITESPACE);
+        if (mTokenizer->isEol()) {
+            break;
+        }
+        String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+        if (keywordToken == "flat") {
+            mTokenizer->skipDelimiters(WHITESPACE);
+            String8 flatToken = mTokenizer->nextToken(WHITESPACE);
+            axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
+            if (*end) {
+                LOGE("%s: Expected flat value, got '%s'.",
+                        mTokenizer->getLocation().string(), flatToken.string());
+                return BAD_VALUE;
+            }
+        } else {
+            LOGE("%s: Expected keyword 'flat', got '%s'.",
+                    mTokenizer->getLocation().string(), keywordToken.string());
+            return BAD_VALUE;
+        }
+    }
+
+#if DEBUG_PARSER
+    LOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
+            "splitValue=%d, flatOverride=%d.",
+            scanCode,
+            axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
+            axisInfo.splitValue, axisInfo.flatOverride);
+#endif
+    mMap->mAxes.add(scanCode, axisInfo);
     return NO_ERROR;
 }
 
diff --git a/libs/ui/KeyLayoutMap.h b/libs/ui/KeyLayoutMap.h
deleted file mode 100644
index 43f84ce..0000000
--- a/libs/ui/KeyLayoutMap.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef KEYLAYOUTMAP_H
-#define KEYLAYOUTMAP_H
-
-#include <utils/KeyedVector.h>
-
-namespace android {
-
-class KeyLayoutMap
-{
-public:
-    KeyLayoutMap();
-    ~KeyLayoutMap();
-
-    status_t load(const char* filename);
-
-    status_t map(int32_t scancode, int32_t *keycode, uint32_t *flags) const;
-    status_t findScancodes(int32_t keycode, Vector<int32_t>* outScancodes) const;
-
-private:
-    struct Key {
-        int32_t keycode;
-        uint32_t flags;
-    };
-
-    status_t m_status;
-    KeyedVector<int32_t,Key> m_keys;
-};
-
-};
-
-#endif // KEYLAYOUTMAP_H
diff --git a/libs/ui/Keyboard.cpp b/libs/ui/Keyboard.cpp
new file mode 100644
index 0000000..600a951
--- /dev/null
+++ b/libs/ui/Keyboard.cpp
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Keyboard"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <ui/Keyboard.h>
+#include <ui/KeycodeLabels.h>
+#include <ui/KeyLayoutMap.h>
+#include <ui/KeyCharacterMap.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <cutils/properties.h>
+
+namespace android {
+
+// --- KeyMap ---
+
+KeyMap::KeyMap() :
+        keyLayoutMap(NULL), keyCharacterMap(NULL) {
+}
+
+KeyMap::~KeyMap() {
+    delete keyLayoutMap;
+    delete keyCharacterMap;
+}
+
+status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
+        const PropertyMap* deviceConfiguration) {
+    // Use the configured key layout if available.
+    if (deviceConfiguration) {
+        String8 keyLayoutName;
+        if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
+                keyLayoutName)) {
+            status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName);
+            if (status == NAME_NOT_FOUND) {
+                LOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
+                        "it was not found.",
+                        deviceIdenfifier.name.string(), keyLayoutName.string());
+            }
+        }
+
+        String8 keyCharacterMapName;
+        if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
+                keyCharacterMapName)) {
+            status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName);
+            if (status == NAME_NOT_FOUND) {
+                LOGE("Configuration for keyboard device '%s' requested keyboard character "
+                        "map '%s' but it was not found.",
+                        deviceIdenfifier.name.string(), keyLayoutName.string());
+            }
+        }
+
+        if (isComplete()) {
+            return OK;
+        }
+    }
+
+    // Try searching by device identifier.
+    if (probeKeyMap(deviceIdenfifier, String8::empty())) {
+        return OK;
+    }
+
+    // Fall back on the Generic key map.
+    // TODO Apply some additional heuristics here to figure out what kind of
+    //      generic key map to use (US English, etc.) for typical external keyboards.
+    if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
+        return OK;
+    }
+
+    // Try the Virtual key map as a last resort.
+    if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
+        return OK;
+    }
+
+    // Give up!
+    LOGE("Could not determine key map for device '%s' and no default key maps were found!",
+            deviceIdenfifier.name.string());
+    return NAME_NOT_FOUND;
+}
+
+bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& keyMapName) {
+    if (!haveKeyLayout()) {
+        loadKeyLayout(deviceIdentifier, keyMapName);
+    }
+    if (!haveKeyCharacterMap()) {
+        loadKeyCharacterMap(deviceIdentifier, keyMapName);
+    }
+    return isComplete();
+}
+
+status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& name) {
+    String8 path(getPath(deviceIdentifier, name,
+            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
+    if (path.isEmpty()) {
+        return NAME_NOT_FOUND;
+    }
+
+    KeyLayoutMap* map;
+    status_t status = KeyLayoutMap::load(path, &map);
+    if (status) {
+        return status;
+    }
+
+    keyLayoutFile.setTo(path);
+    keyLayoutMap = map;
+    return OK;
+}
+
+status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& name) {
+    String8 path(getPath(deviceIdentifier, name,
+            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
+    if (path.isEmpty()) {
+        return NAME_NOT_FOUND;
+    }
+
+    KeyCharacterMap* map;
+    status_t status = KeyCharacterMap::load(path, &map);
+    if (status) {
+        return status;
+    }
+
+    keyCharacterMapFile.setTo(path);
+    keyCharacterMap = map;
+    return OK;
+}
+
+String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& name, InputDeviceConfigurationFileType type) {
+    return name.isEmpty()
+            ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
+            : getInputDeviceConfigurationFilePathByName(name, type);
+}
+
+
+// --- Global functions ---
+
+bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
+        const PropertyMap* deviceConfiguration, const KeyMap* keyMap) {
+    if (!keyMap->haveKeyCharacterMap()
+            || keyMap->keyCharacterMap->getKeyboardType()
+                    == KeyCharacterMap::KEYBOARD_TYPE_SPECIAL_FUNCTION) {
+        return false;
+    }
+
+    if (deviceConfiguration) {
+        bool builtIn = false;
+        if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn)
+                && builtIn) {
+            return true;
+        }
+    }
+
+    return strstr(deviceIdentifier.name.string(), "-keypad");
+}
+
+void setKeyboardProperties(int32_t deviceId,
+        const InputDeviceIdentifier& deviceIdentifier,
+        const String8& keyLayoutFile, const String8& keyCharacterMapFile) {
+    char propName[PROPERTY_KEY_MAX];
+    snprintf(propName, sizeof(propName), "hw.keyboards.%u.devname", deviceId);
+    property_set(propName, deviceIdentifier.name.string());
+    snprintf(propName, sizeof(propName), "hw.keyboards.%u.klfile", deviceId);
+    property_set(propName, keyLayoutFile.string());
+    snprintf(propName, sizeof(propName), "hw.keyboards.%u.kcmfile", deviceId);
+    property_set(propName, keyCharacterMapFile.string());
+}
+
+void clearKeyboardProperties(int32_t deviceId) {
+    char propName[PROPERTY_KEY_MAX];
+    snprintf(propName, sizeof(propName), "hw.keyboards.%u.devname", deviceId);
+    property_set(propName, "");
+    snprintf(propName, sizeof(propName), "hw.keyboards.%u.klfile", deviceId);
+    property_set(propName, "");
+    snprintf(propName, sizeof(propName), "hw.keyboards.%u.kcmfile", deviceId);
+    property_set(propName, "");
+}
+
+status_t getKeyCharacterMapFile(int32_t deviceId, String8& outKeyCharacterMapFile) {
+    if (deviceId != DEVICE_ID_VIRTUAL_KEYBOARD) {
+        char propName[PROPERTY_KEY_MAX];
+        char fn[PROPERTY_VALUE_MAX];
+        snprintf(propName, sizeof(propName), "hw.keyboards.%u.kcmfile", deviceId);
+        if (property_get(propName, fn, "") > 0) {
+            outKeyCharacterMapFile.setTo(fn);
+            return OK;
+        }
+    }
+
+    // Default to Virtual since the keyboard does not appear to be installed.
+    outKeyCharacterMapFile.setTo(getInputDeviceConfigurationFilePathByName(String8("Virtual"),
+            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
+    if (!outKeyCharacterMapFile.isEmpty()) {
+        return OK;
+    }
+
+    LOGE("Can't find any key character map files including the Virtual key map!");
+    return NAME_NOT_FOUND;
+}
+
+static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
+    while (list->literal) {
+        if (strcmp(literal, list->literal) == 0) {
+            return list->value;
+        }
+        list++;
+    }
+    return list->value;
+}
+
+static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
+    while (list->literal) {
+        if (list->value == value) {
+            return list->literal;
+        }
+        list++;
+    }
+    return NULL;
+}
+
+int32_t getKeyCodeByLabel(const char* label) {
+    return int32_t(lookupValueByLabel(label, KEYCODES));
+}
+
+uint32_t getKeyFlagByLabel(const char* label) {
+    return uint32_t(lookupValueByLabel(label, FLAGS));
+}
+
+int32_t getAxisByLabel(const char* label) {
+    return int32_t(lookupValueByLabel(label, AXES));
+}
+
+const char* getAxisLabel(int32_t axisId) {
+    return lookupLabelByValue(axisId, AXES);
+}
+
+static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
+    int32_t newMetaState;
+    if (down) {
+        newMetaState = oldMetaState | mask;
+    } else {
+        newMetaState = oldMetaState &
+                ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
+    }
+
+    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
+        newMetaState |= AMETA_ALT_ON;
+    }
+
+    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
+        newMetaState |= AMETA_SHIFT_ON;
+    }
+
+    if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
+        newMetaState |= AMETA_CTRL_ON;
+    }
+
+    if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
+        newMetaState |= AMETA_META_ON;
+    }
+    return newMetaState;
+}
+
+static int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) {
+    if (down) {
+        return oldMetaState;
+    } else {
+        return oldMetaState ^ mask;
+    }
+}
+
+int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
+    int32_t mask;
+    switch (keyCode) {
+    case AKEYCODE_ALT_LEFT:
+        return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_ALT_RIGHT:
+        return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_SHIFT_LEFT:
+        return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_SHIFT_RIGHT:
+        return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_SYM:
+        return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState);
+    case AKEYCODE_FUNCTION:
+        return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState);
+    case AKEYCODE_CTRL_LEFT:
+        return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_CTRL_RIGHT:
+        return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_META_LEFT:
+        return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_META_RIGHT:
+        return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_CAPS_LOCK:
+        return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState);
+    case AKEYCODE_NUM_LOCK:
+        return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState);
+    case AKEYCODE_SCROLL_LOCK:
+        return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState);
+    default:
+        return oldMetaState;
+    }
+}
+
+bool isMetaKey(int32_t keyCode) {
+    switch (keyCode) {
+    case AKEYCODE_ALT_LEFT:
+    case AKEYCODE_ALT_RIGHT:
+    case AKEYCODE_SHIFT_LEFT:
+    case AKEYCODE_SHIFT_RIGHT:
+    case AKEYCODE_SYM:
+    case AKEYCODE_FUNCTION:
+    case AKEYCODE_CTRL_LEFT:
+    case AKEYCODE_CTRL_RIGHT:
+    case AKEYCODE_META_LEFT:
+    case AKEYCODE_META_RIGHT:
+    case AKEYCODE_CAPS_LOCK:
+    case AKEYCODE_NUM_LOCK:
+    case AKEYCODE_SCROLL_LOCK:
+        return true;
+    default:
+        return false;
+    }
+}
+
+
+} // namespace android
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
deleted file mode 100644
index b082c53..0000000
--- a/libs/ui/Overlay.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2007 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 <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <utils/Errors.h>
-#include <binder/MemoryHeapBase.h>
-
-#include <ui/IOverlay.h>
-#include <ui/Overlay.h>
-
-#include <hardware/overlay.h>
-
-namespace android {
-
-Overlay::Overlay(const sp<OverlayRef>& overlayRef)
-    : mOverlayRef(overlayRef), mOverlayData(0), mStatus(NO_INIT)
-{
-    mOverlayData = NULL;
-    hw_module_t const* module;
-    if (overlayRef != 0) {
-        if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
-            if (overlay_data_open(module, &mOverlayData) == NO_ERROR) {
-                mStatus = mOverlayData->initialize(mOverlayData,
-                        overlayRef->mOverlayHandle);
-            }
-        }
-    }
-}
-
-Overlay::~Overlay() {
-    if (mOverlayData) {
-        overlay_data_close(mOverlayData);
-    }
-}
-
-status_t Overlay::dequeueBuffer(overlay_buffer_t* buffer)
-{
-    if (mStatus != NO_ERROR) return mStatus;
-    return  mOverlayData->dequeueBuffer(mOverlayData, buffer);
-}
-
-status_t Overlay::queueBuffer(overlay_buffer_t buffer)
-{
-    if (mStatus != NO_ERROR) return mStatus;
-    return mOverlayData->queueBuffer(mOverlayData, buffer);
-}
-
-status_t Overlay::resizeInput(uint32_t width, uint32_t height)
-{
-    if (mStatus != NO_ERROR) return mStatus;
-    return mOverlayData->resizeInput(mOverlayData, width, height);
-}
-
-status_t Overlay::setParameter(int param, int value)
-{
-    if (mStatus != NO_ERROR) return mStatus;
-    return mOverlayData->setParameter(mOverlayData, param, value);
-}
-
-status_t Overlay::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
-{
-    if (mStatus != NO_ERROR) return mStatus;
-    return mOverlayData->setCrop(mOverlayData, x, y, w, h);
-}
-
-status_t Overlay::getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h)
-{
-    if (mStatus != NO_ERROR) return mStatus;
-    return mOverlayData->getCrop(mOverlayData, x, y, w, h);
-}
-
-int32_t Overlay::getBufferCount() const
-{
-    if (mStatus != NO_ERROR) return mStatus;
-    return mOverlayData->getBufferCount(mOverlayData);
-}
-
-void* Overlay::getBufferAddress(overlay_buffer_t buffer)
-{
-    if (mStatus != NO_ERROR) return NULL;
-    return mOverlayData->getBufferAddress(mOverlayData, buffer);
-}
-
-void Overlay::destroy() {  
-
-    // Must delete the objects in reverse creation order, thus the
-    //  data side must be closed first and then the destroy send to
-    //  the control side.
-    if (mOverlayData) {
-        overlay_data_close(mOverlayData);
-        mOverlayData = NULL;
-    } else {
-        LOGD("Overlay::destroy mOverlayData is NULL");
-    }
-
-    if (mOverlayRef != 0) {
-        mOverlayRef->mOverlayChannel->destroy();
-    } else {
-        LOGD("Overlay::destroy mOverlayRef is NULL");
-    }
-}
-
-status_t Overlay::getStatus() const {
-    return mStatus;
-}
-
-overlay_handle_t Overlay::getHandleRef() const {
-    if (mStatus != NO_ERROR) return NULL;
-    return mOverlayRef->mOverlayHandle;
-}
-
-uint32_t Overlay::getWidth() const {
-    if (mStatus != NO_ERROR) return 0;
-    return mOverlayRef->mWidth;
-}
-
-uint32_t Overlay::getHeight() const {
-    if (mStatus != NO_ERROR) return 0;
-    return mOverlayRef->mHeight;
-}
-
-int32_t Overlay::getFormat() const {
-    if (mStatus != NO_ERROR) return -1;
-    return mOverlayRef->mFormat;
-}
-
-int32_t Overlay::getWidthStride() const {
-    if (mStatus != NO_ERROR) return 0;
-    return mOverlayRef->mWidthStride;
-}
-
-int32_t Overlay::getHeightStride() const {
-    if (mStatus != NO_ERROR) return 0;
-    return mOverlayRef->mHeightStride;
-}
-// ----------------------------------------------------------------------------
-
-OverlayRef::OverlayRef() 
- : mOverlayHandle(0),
-    mWidth(0), mHeight(0), mFormat(0), mWidthStride(0), mHeightStride(0),
-    mOwnHandle(true)
-{    
-}
-
-OverlayRef::OverlayRef(overlay_handle_t handle, const sp<IOverlay>& channel,
-         uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
-    : mOverlayHandle(handle), mOverlayChannel(channel),
-    mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs),
-    mOwnHandle(false)
-{
-}
-
-OverlayRef::~OverlayRef()
-{
-    if (mOwnHandle) {
-        native_handle_close(mOverlayHandle);
-        native_handle_delete(const_cast<native_handle*>(mOverlayHandle));
-    }
-}
-
-sp<OverlayRef> OverlayRef::readFromParcel(const Parcel& data) {
-    sp<OverlayRef> result;
-    sp<IOverlay> overlay = IOverlay::asInterface(data.readStrongBinder());
-    if (overlay != NULL) {
-        uint32_t w = data.readInt32();
-        uint32_t h = data.readInt32();
-        uint32_t f = data.readInt32();
-        uint32_t ws = data.readInt32();
-        uint32_t hs = data.readInt32();
-        native_handle* handle = data.readNativeHandle();
-
-        result = new OverlayRef();
-        result->mOverlayHandle = handle;
-        result->mOverlayChannel = overlay;
-        result->mWidth = w;
-        result->mHeight = h;
-        result->mFormat = f;
-        result->mWidthStride = ws;
-        result->mHeightStride = hs;
-    }
-    return result;
-}
-
-status_t OverlayRef::writeToParcel(Parcel* reply, const sp<OverlayRef>& o) {
-    if (o != NULL) {
-        reply->writeStrongBinder(o->mOverlayChannel->asBinder());
-        reply->writeInt32(o->mWidth);
-        reply->writeInt32(o->mHeight);
-        reply->writeInt32(o->mFormat);
-        reply->writeInt32(o->mWidthStride);
-        reply->writeInt32(o->mHeightStride);
-        reply->writeNativeHandle(o->mOverlayHandle);
-    } else {
-        reply->writeStrongBinder(NULL);
-    }
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 1994f6a..a060a5f 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -56,6 +56,9 @@
 Region::Region(const Region& rhs)
     : mBounds(rhs.mBounds), mStorage(rhs.mStorage)
 {
+#if VALIDATE_REGIONS
+    validate(rhs, "rhs copy-ctor");
+#endif
 }
 
 Region::Region(const Rect& rhs)
@@ -76,7 +79,8 @@
 Region& Region::operator = (const Region& rhs)
 {
 #if VALIDATE_REGIONS
-    validate(rhs, "operator=");
+    validate(*this, "this->operator=");
+    validate(rhs, "rhs.operator=");
 #endif
     mBounds = rhs.mBounds;
     mStorage = rhs.mStorage;
@@ -366,6 +370,12 @@
         const Region& lhs,
         const Region& rhs, int dx, int dy)
 {
+#if VALIDATE_REGIONS
+    validate(lhs, "boolean_operation (before): lhs");
+    validate(rhs, "boolean_operation (before): rhs");
+    validate(dst, "boolean_operation (before): dst");
+#endif
+
     size_t lhs_count;
     Rect const * const lhs_rects = lhs.getArray(&lhs_count);
 
diff --git a/libs/ui/VirtualKeyMap.cpp b/libs/ui/VirtualKeyMap.cpp
new file mode 100644
index 0000000..e756cdd
--- /dev/null
+++ b/libs/ui/VirtualKeyMap.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "VirtualKeyMap"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ui/VirtualKeyMap.h>
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/Tokenizer.h>
+#include <utils/Timers.h>
+
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+
+namespace android {
+
+static const char* WHITESPACE = " \t\r";
+static const char* WHITESPACE_OR_FIELD_DELIMITER = " \t\r:";
+
+
+// --- VirtualKeyMap ---
+
+VirtualKeyMap::VirtualKeyMap() {
+}
+
+VirtualKeyMap::~VirtualKeyMap() {
+}
+
+status_t VirtualKeyMap::load(const String8& filename, VirtualKeyMap** outMap) {
+    *outMap = NULL;
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::open(filename, &tokenizer);
+    if (status) {
+        LOGE("Error %d opening virtual key map file %s.", status, filename.string());
+    } else {
+        VirtualKeyMap* map = new VirtualKeyMap();
+        if (!map) {
+            LOGE("Error allocating virtual key map.");
+            status = NO_MEMORY;
+        } else {
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+            Parser parser(map, tokenizer);
+            status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+            LOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
+                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                    elapsedTime / 1000000.0);
+#endif
+            if (status) {
+                delete map;
+            } else {
+                *outMap = map;
+            }
+        }
+        delete tokenizer;
+    }
+    return status;
+}
+
+
+// --- VirtualKeyMap::Parser ---
+
+VirtualKeyMap::Parser::Parser(VirtualKeyMap* map, Tokenizer* tokenizer) :
+        mMap(map), mTokenizer(tokenizer) {
+}
+
+VirtualKeyMap::Parser::~Parser() {
+}
+
+status_t VirtualKeyMap::Parser::parse() {
+    while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+        LOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+                mTokenizer->peekRemainderOfLine().string());
+#endif
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+
+        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+            // Multiple keys can appear on one line or they can be broken up across multiple lines.
+            do {
+                String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
+                if (token != "0x01") {
+                    LOGE("%s: Unknown virtual key type, expected 0x01.",
+                          mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+
+                VirtualKeyDefinition defn;
+                bool success = parseNextIntField(&defn.scanCode)
+                        && parseNextIntField(&defn.centerX)
+                        && parseNextIntField(&defn.centerY)
+                        && parseNextIntField(&defn.width)
+                        && parseNextIntField(&defn.height);
+                if (!success) {
+                    LOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
+                          mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+
+#if DEBUG_PARSER
+                LOGD("Parsed virtual key: scanCode=%d, centerX=%d, centerY=%d, "
+                        "width=%d, height=%d",
+                        defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height);
+#endif
+                mMap->mVirtualKeys.push(defn);
+            } while (consumeFieldDelimiterAndSkipWhitespace());
+
+            if (!mTokenizer->isEol()) {
+                LOGE("%s: Expected end of line, got '%s'.",
+                        mTokenizer->getLocation().string(),
+                        mTokenizer->peekRemainderOfLine().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->nextLine();
+    }
+
+    return NO_ERROR;
+}
+
+bool VirtualKeyMap::Parser::consumeFieldDelimiterAndSkipWhitespace() {
+    mTokenizer->skipDelimiters(WHITESPACE);
+    if (mTokenizer->peekChar() == ':') {
+        mTokenizer->nextChar();
+        mTokenizer->skipDelimiters(WHITESPACE);
+        return true;
+    }
+    return false;
+}
+
+bool VirtualKeyMap::Parser::parseNextIntField(int32_t* outValue) {
+    if (!consumeFieldDelimiterAndSkipWhitespace()) {
+        return false;
+    }
+
+    String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
+    char* end;
+    *outValue = strtol(token.string(), &end, 0);
+    if (token.isEmpty() || *end != '\0') {
+        LOGE("Expected an integer, got '%s'.", token.string());
+        return false;
+    }
+    return true;
+}
+
+} // namespace android
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index aa017b9..e231971 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -7,8 +7,7 @@
 # Build the unit tests.
 test_src_files := \
     InputChannel_test.cpp \
-    InputReader_test.cpp \
-    InputDispatcher_test.cpp \
+    InputEvent_test.cpp \
     InputPublisherAndConsumer_test.cpp
 
 shared_libraries := \
@@ -20,7 +19,8 @@
 	libhardware \
 	libhardware_legacy \
 	libui \
-	libstlport
+	libstlport \
+	libskia
 
 static_libraries := \
 	libgtest \
@@ -30,7 +30,8 @@
     bionic \
     bionic/libstdc++/include \
     external/gtest/include \
-    external/stlport/stlport
+    external/stlport/stlport \
+    external/skia/include/core
 
 module_tags := eng tests
 
diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/ui/tests/InputChannel_test.cpp
index 6cec1c0..eff22ee 100644
--- a/libs/ui/tests/InputChannel_test.cpp
+++ b/libs/ui/tests/InputChannel_test.cpp
@@ -1,6 +1,18 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
+/*
+ * 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.
+ */
 
 #include <ui/InputTransport.h>
 #include <utils/Timers.h>
diff --git a/libs/ui/tests/InputDispatcher_test.cpp b/libs/ui/tests/InputDispatcher_test.cpp
deleted file mode 100644
index 8874dfe..0000000
--- a/libs/ui/tests/InputDispatcher_test.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-
-#include <ui/InputDispatcher.h>
-#include <gtest/gtest.h>
-#include <linux/input.h>
-
-namespace android {
-
-// An arbitrary time value.
-static const nsecs_t ARBITRARY_TIME = 1234;
-
-// An arbitrary device id.
-static const int32_t DEVICE_ID = 1;
-
-// An arbitrary injector pid / uid pair that has permission to inject events.
-static const int32_t INJECTOR_PID = 999;
-static const int32_t INJECTOR_UID = 1001;
-
-
-// --- FakeInputDispatcherPolicy ---
-
-class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
-protected:
-    virtual ~FakeInputDispatcherPolicy() {
-    }
-
-public:
-    FakeInputDispatcherPolicy() {
-    }
-
-private:
-    virtual void notifyConfigurationChanged(nsecs_t when) {
-    }
-
-    virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputChannel>& inputChannel) {
-        return 0;
-    }
-
-    virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
-    }
-
-    virtual nsecs_t getKeyRepeatTimeout() {
-        return 500 * 1000000LL;
-    }
-
-    virtual nsecs_t getKeyRepeatDelay() {
-        return 50 * 1000000LL;
-    }
-
-    virtual int32_t getMaxEventsPerSecond() {
-        return 60;
-    }
-
-    virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
-            int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
-            uint32_t& policyFlags) {
-    }
-
-    virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
-    }
-
-    virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
-            const KeyEvent* keyEvent, uint32_t policyFlags) {
-        return false;
-    }
-
-    virtual void notifySwitch(nsecs_t when,
-            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
-    }
-
-    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
-    }
-
-    virtual bool checkInjectEventsPermissionNonReentrant(
-            int32_t injectorPid, int32_t injectorUid) {
-        return false;
-    }
-};
-
-
-// --- InputDispatcherTest ---
-
-class InputDispatcherTest : public testing::Test {
-protected:
-    sp<FakeInputDispatcherPolicy> mFakePolicy;
-    sp<InputDispatcher> mDispatcher;
-
-    virtual void SetUp() {
-        mFakePolicy = new FakeInputDispatcherPolicy();
-        mDispatcher = new InputDispatcher(mFakePolicy);
-    }
-
-    virtual void TearDown() {
-        mFakePolicy.clear();
-        mDispatcher.clear();
-    }
-};
-
-
-TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
-    KeyEvent event;
-
-    // Rejects undefined key actions.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
-            /*action*/ -1, 0,
-            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject key events with undefined action.";
-
-    // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
-            AKEY_EVENT_ACTION_MULTIPLE, 0,
-            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject key events with ACTION_MULTIPLE.";
-}
-
-TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
-    MotionEvent event;
-    int32_t pointerIds[MAX_POINTERS + 1];
-    PointerCoords pointerCoords[MAX_POINTERS + 1];
-    for (int i = 0; i <= MAX_POINTERS; i++) {
-        pointerIds[i] = i;
-    }
-
-    // Rejects undefined motion actions.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with undefined action.";
-
-    // Rejects pointer down with invalid index.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with pointer down index too large.";
-
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with pointer down index too small.";
-
-    // Rejects pointer up with invalid index.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with pointer up index too large.";
-
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with pointer up index too small.";
-
-    // Rejects motion events with invalid number of pointers.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 0, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with 0 pointers.";
-
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ MAX_POINTERS + 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with more than MAX_POINTERS pointers.";
-
-    // Rejects motion events with invalid pointer ids.
-    pointerIds[0] = -1;
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with pointer ids less than 0.";
-
-    pointerIds[0] = MAX_POINTER_ID + 1;
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
-
-    // Rejects motion events with duplicate pointer ids.
-    pointerIds[0] = 1;
-    pointerIds[1] = 1;
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 2, pointerIds, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
-            << "Should reject motion events with duplicate pointer ids.";
-}
-
-} // namespace android
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
new file mode 100644
index 0000000..b77489e
--- /dev/null
+++ b/libs/ui/tests/InputEvent_test.cpp
@@ -0,0 +1,582 @@
+/*
+ * 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 <ui/Input.h>
+#include <gtest/gtest.h>
+#include <binder/Parcel.h>
+
+#include <math.h>
+#include <SkMatrix.h>
+
+namespace android {
+
+class BaseTest : public testing::Test {
+protected:
+    virtual void SetUp() { }
+    virtual void TearDown() { }
+};
+
+// --- PointerCoordsTest ---
+
+class PointerCoordsTest : public BaseTest {
+};
+
+TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
+    PointerCoords coords;
+    coords.clear();
+
+    ASSERT_EQ(0ULL, coords.bits);
+}
+
+TEST_F(PointerCoordsTest, AxisValues) {
+    float* valuePtr;
+    PointerCoords coords;
+    coords.clear();
+
+    // Check invariants when no axes are present.
+    ASSERT_EQ(0, coords.getAxisValue(0))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(0, coords.getAxisValue(1))
+            << "getAxisValue should return zero because axis is not present";
+
+    ASSERT_EQ(NULL, coords.editAxisValue(0))
+            << "editAxisValue should return null because axis is not present";
+
+    // Set first axis.
+    ASSERT_EQ(OK, coords.setAxisValue(1, 5));
+    ASSERT_EQ(0x00000002ULL, coords.bits);
+    ASSERT_EQ(5, coords.values[0]);
+
+    ASSERT_EQ(0, coords.getAxisValue(0))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(5, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+
+    // Set an axis with a higher id than all others.  (appending value at the end)
+    ASSERT_EQ(OK, coords.setAxisValue(3, 2));
+    ASSERT_EQ(0x0000000aULL, coords.bits);
+    ASSERT_EQ(5, coords.values[0]);
+    ASSERT_EQ(2, coords.values[1]);
+
+    ASSERT_EQ(0, coords.getAxisValue(0))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(5, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(0, coords.getAxisValue(2))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Set an axis with an id lower than all others.  (prepending value at beginning)
+    ASSERT_EQ(OK, coords.setAxisValue(0, 4));
+    ASSERT_EQ(0x0000000bULL, coords.bits);
+    ASSERT_EQ(4, coords.values[0]);
+    ASSERT_EQ(5, coords.values[1]);
+    ASSERT_EQ(2, coords.values[2]);
+
+    ASSERT_EQ(4, coords.getAxisValue(0))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(5, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(0, coords.getAxisValue(2))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Edit an existing axis value in place.
+    valuePtr = coords.editAxisValue(1);
+    ASSERT_EQ(5, *valuePtr)
+            << "editAxisValue should return pointer to axis value";
+
+    *valuePtr = 7;
+    ASSERT_EQ(7, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+
+    // Set an axis with an id between the others.  (inserting value in the middle)
+    ASSERT_EQ(OK, coords.setAxisValue(2, 1));
+    ASSERT_EQ(0x0000000fULL, coords.bits);
+    ASSERT_EQ(4, coords.values[0]);
+    ASSERT_EQ(7, coords.values[1]);
+    ASSERT_EQ(1, coords.values[2]);
+    ASSERT_EQ(2, coords.values[3]);
+
+    ASSERT_EQ(4, coords.getAxisValue(0))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(7, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(1, coords.getAxisValue(2))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Set an existing axis value in place.
+    ASSERT_EQ(OK, coords.setAxisValue(1, 6));
+    ASSERT_EQ(0x0000000fULL, coords.bits);
+    ASSERT_EQ(4, coords.values[0]);
+    ASSERT_EQ(6, coords.values[1]);
+    ASSERT_EQ(1, coords.values[2]);
+    ASSERT_EQ(2, coords.values[3]);
+
+    ASSERT_EQ(4, coords.getAxisValue(0))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(6, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(1, coords.getAxisValue(2))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Set maximum number of axes.
+    for (size_t axis = 4; axis < PointerCoords::MAX_AXES; axis++) {
+        ASSERT_EQ(OK, coords.setAxisValue(axis, axis));
+    }
+    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+
+    // Try to set one more axis beyond maximum number.
+    // Ensure bits are unchanged.
+    ASSERT_EQ(NO_MEMORY, coords.setAxisValue(PointerCoords::MAX_AXES, 100));
+    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+}
+
+TEST_F(PointerCoordsTest, Parcel) {
+    Parcel parcel;
+
+    PointerCoords inCoords;
+    inCoords.clear();
+    PointerCoords outCoords;
+
+    // Round trip with empty coords.
+    inCoords.writeToParcel(&parcel);
+    parcel.setDataPosition(0);
+    outCoords.readFromParcel(&parcel);
+
+    ASSERT_EQ(0ULL, outCoords.bits);
+
+    // Round trip with some values.
+    parcel.freeData();
+    inCoords.setAxisValue(2, 5);
+    inCoords.setAxisValue(5, 8);
+
+    inCoords.writeToParcel(&parcel);
+    parcel.setDataPosition(0);
+    outCoords.readFromParcel(&parcel);
+
+    ASSERT_EQ(outCoords.bits, inCoords.bits);
+    ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
+    ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
+}
+
+
+// --- KeyEventTest ---
+
+class KeyEventTest : public BaseTest {
+};
+
+TEST_F(KeyEventTest, Properties) {
+    KeyEvent event;
+
+    // Initialize and get properties.
+    const nsecs_t ARBITRARY_DOWN_TIME = 1;
+    const nsecs_t ARBITRARY_EVENT_TIME = 2;
+    event.initialize(2, AINPUT_SOURCE_GAMEPAD, AKEY_EVENT_ACTION_DOWN,
+            AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
+            AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
+
+    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
+    ASSERT_EQ(2, event.getDeviceId());
+    ASSERT_EQ(AINPUT_SOURCE_GAMEPAD, event.getSource());
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
+    ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
+    ASSERT_EQ(121, event.getScanCode());
+    ASSERT_EQ(AMETA_ALT_ON, event.getMetaState());
+    ASSERT_EQ(1, event.getRepeatCount());
+    ASSERT_EQ(ARBITRARY_DOWN_TIME, event.getDownTime());
+    ASSERT_EQ(ARBITRARY_EVENT_TIME, event.getEventTime());
+
+    // Set source.
+    event.setSource(AINPUT_SOURCE_JOYSTICK);
+    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+}
+
+
+// --- MotionEventTest ---
+
+class MotionEventTest : public BaseTest {
+protected:
+    static const nsecs_t ARBITRARY_DOWN_TIME;
+    static const nsecs_t ARBITRARY_EVENT_TIME;
+    static const float X_OFFSET;
+    static const float Y_OFFSET;
+
+    void initializeEventWithHistory(MotionEvent* event);
+    void assertEqualsEventWithHistory(const MotionEvent* event);
+};
+
+const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
+const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
+const float MotionEventTest::X_OFFSET = 1.0f;
+const float MotionEventTest::Y_OFFSET = 1.1f;
+
+void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
+    int32_t pointerIds[] = { 1, 2 };
+    PointerCoords pointerCoords[2];
+    pointerCoords[0].clear();
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 11);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 12);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 13);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 14);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 15);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
+    pointerCoords[1].clear();
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 23);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 24);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 25);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
+    event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
+            AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
+            AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON,
+            X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
+            ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
+            2, pointerIds, pointerCoords);
+
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 113);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 114);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 115);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 123);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 124);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 125);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
+    event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
+
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 213);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 214);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 215);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 223);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 224);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 225);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 226);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 227);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 228);
+    event->addSample(ARBITRARY_EVENT_TIME + 2, pointerCoords);
+}
+
+void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
+    // Check properties.
+    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
+    ASSERT_EQ(2, event->getDeviceId());
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, event->getSource());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
+    ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
+    ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
+    ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
+    ASSERT_EQ(X_OFFSET, event->getXOffset());
+    ASSERT_EQ(Y_OFFSET, event->getYOffset());
+    ASSERT_EQ(2.0f, event->getXPrecision());
+    ASSERT_EQ(2.1f, event->getYPrecision());
+    ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
+
+    ASSERT_EQ(2U, event->getPointerCount());
+    ASSERT_EQ(1, event->getPointerId(0));
+    ASSERT_EQ(2, event->getPointerId(1));
+
+    ASSERT_EQ(2U, event->getHistorySize());
+
+    // Check data.
+    ASSERT_EQ(ARBITRARY_EVENT_TIME, event->getHistoricalEventTime(0));
+    ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
+    ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
+
+    ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(211, event->getRawPointerCoords(0)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(221, event->getRawPointerCoords(1)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+
+    ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
+    ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
+    ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
+    ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
+    ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
+    ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
+
+    ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
+    ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
+    ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
+    ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
+    ASSERT_EQ(210, event->getRawX(0));
+    ASSERT_EQ(220, event->getRawX(1));
+
+    ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
+    ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
+    ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
+    ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
+    ASSERT_EQ(211, event->getRawY(0));
+    ASSERT_EQ(221, event->getRawY(1));
+
+    ASSERT_EQ(X_OFFSET + 10, event->getHistoricalX(0, 0));
+    ASSERT_EQ(X_OFFSET + 20, event->getHistoricalX(1, 0));
+    ASSERT_EQ(X_OFFSET + 110, event->getHistoricalX(0, 1));
+    ASSERT_EQ(X_OFFSET + 120, event->getHistoricalX(1, 1));
+    ASSERT_EQ(X_OFFSET + 210, event->getX(0));
+    ASSERT_EQ(X_OFFSET + 220, event->getX(1));
+
+    ASSERT_EQ(Y_OFFSET + 11, event->getHistoricalY(0, 0));
+    ASSERT_EQ(Y_OFFSET + 21, event->getHistoricalY(1, 0));
+    ASSERT_EQ(Y_OFFSET + 111, event->getHistoricalY(0, 1));
+    ASSERT_EQ(Y_OFFSET + 121, event->getHistoricalY(1, 1));
+    ASSERT_EQ(Y_OFFSET + 211, event->getY(0));
+    ASSERT_EQ(Y_OFFSET + 221, event->getY(1));
+
+    ASSERT_EQ(12, event->getHistoricalPressure(0, 0));
+    ASSERT_EQ(22, event->getHistoricalPressure(1, 0));
+    ASSERT_EQ(112, event->getHistoricalPressure(0, 1));
+    ASSERT_EQ(122, event->getHistoricalPressure(1, 1));
+    ASSERT_EQ(212, event->getPressure(0));
+    ASSERT_EQ(222, event->getPressure(1));
+
+    ASSERT_EQ(13, event->getHistoricalSize(0, 0));
+    ASSERT_EQ(23, event->getHistoricalSize(1, 0));
+    ASSERT_EQ(113, event->getHistoricalSize(0, 1));
+    ASSERT_EQ(123, event->getHistoricalSize(1, 1));
+    ASSERT_EQ(213, event->getSize(0));
+    ASSERT_EQ(223, event->getSize(1));
+
+    ASSERT_EQ(14, event->getHistoricalTouchMajor(0, 0));
+    ASSERT_EQ(24, event->getHistoricalTouchMajor(1, 0));
+    ASSERT_EQ(114, event->getHistoricalTouchMajor(0, 1));
+    ASSERT_EQ(124, event->getHistoricalTouchMajor(1, 1));
+    ASSERT_EQ(214, event->getTouchMajor(0));
+    ASSERT_EQ(224, event->getTouchMajor(1));
+
+    ASSERT_EQ(15, event->getHistoricalTouchMinor(0, 0));
+    ASSERT_EQ(25, event->getHistoricalTouchMinor(1, 0));
+    ASSERT_EQ(115, event->getHistoricalTouchMinor(0, 1));
+    ASSERT_EQ(125, event->getHistoricalTouchMinor(1, 1));
+    ASSERT_EQ(215, event->getTouchMinor(0));
+    ASSERT_EQ(225, event->getTouchMinor(1));
+
+    ASSERT_EQ(16, event->getHistoricalToolMajor(0, 0));
+    ASSERT_EQ(26, event->getHistoricalToolMajor(1, 0));
+    ASSERT_EQ(116, event->getHistoricalToolMajor(0, 1));
+    ASSERT_EQ(126, event->getHistoricalToolMajor(1, 1));
+    ASSERT_EQ(216, event->getToolMajor(0));
+    ASSERT_EQ(226, event->getToolMajor(1));
+
+    ASSERT_EQ(17, event->getHistoricalToolMinor(0, 0));
+    ASSERT_EQ(27, event->getHistoricalToolMinor(1, 0));
+    ASSERT_EQ(117, event->getHistoricalToolMinor(0, 1));
+    ASSERT_EQ(127, event->getHistoricalToolMinor(1, 1));
+    ASSERT_EQ(217, event->getToolMinor(0));
+    ASSERT_EQ(227, event->getToolMinor(1));
+
+    ASSERT_EQ(18, event->getHistoricalOrientation(0, 0));
+    ASSERT_EQ(28, event->getHistoricalOrientation(1, 0));
+    ASSERT_EQ(118, event->getHistoricalOrientation(0, 1));
+    ASSERT_EQ(128, event->getHistoricalOrientation(1, 1));
+    ASSERT_EQ(218, event->getOrientation(0));
+    ASSERT_EQ(228, event->getOrientation(1));
+}
+
+TEST_F(MotionEventTest, Properties) {
+    MotionEvent event;
+
+    // Initialize, add samples and check properties.
+    initializeEventWithHistory(&event);
+    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+
+    // Set source.
+    event.setSource(AINPUT_SOURCE_JOYSTICK);
+    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+
+    // Set action.
+    event.setAction(AMOTION_EVENT_ACTION_CANCEL);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
+
+    // Set meta state.
+    event.setMetaState(AMETA_CTRL_ON);
+    ASSERT_EQ(AMETA_CTRL_ON, event.getMetaState());
+}
+
+TEST_F(MotionEventTest, CopyFrom_KeepHistory) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    MotionEvent copy;
+    copy.copyFrom(&event, true /*keepHistory*/);
+
+    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+}
+
+TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    MotionEvent copy;
+    copy.copyFrom(&event, false /*keepHistory*/);
+
+    ASSERT_EQ(event.getPointerCount(), copy.getPointerCount());
+    ASSERT_EQ(0U, copy.getHistorySize());
+
+    ASSERT_EQ(event.getPointerId(0), copy.getPointerId(0));
+    ASSERT_EQ(event.getPointerId(1), copy.getPointerId(1));
+
+    ASSERT_EQ(event.getEventTime(), copy.getEventTime());
+
+    ASSERT_EQ(event.getX(0), copy.getX(0));
+}
+
+TEST_F(MotionEventTest, OffsetLocation) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    event.offsetLocation(5.0f, -2.0f);
+
+    ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
+    ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
+}
+
+TEST_F(MotionEventTest, Scale) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    event.scale(2.0f);
+
+    ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
+    ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
+
+    ASSERT_EQ(210 * 2, event.getRawX(0));
+    ASSERT_EQ(211 * 2, event.getRawY(0));
+    ASSERT_EQ((X_OFFSET + 210) * 2, event.getX(0));
+    ASSERT_EQ((Y_OFFSET + 211) * 2, event.getY(0));
+    ASSERT_EQ(212, event.getPressure(0));
+    ASSERT_EQ(213, event.getSize(0));
+    ASSERT_EQ(214 * 2, event.getTouchMajor(0));
+    ASSERT_EQ(215 * 2, event.getTouchMinor(0));
+    ASSERT_EQ(216 * 2, event.getToolMajor(0));
+    ASSERT_EQ(217 * 2, event.getToolMinor(0));
+    ASSERT_EQ(218, event.getOrientation(0));
+}
+
+TEST_F(MotionEventTest, Parcel) {
+    Parcel parcel;
+
+    MotionEvent inEvent;
+    initializeEventWithHistory(&inEvent);
+    MotionEvent outEvent;
+
+    // Round trip.
+    inEvent.writeToParcel(&parcel);
+    parcel.setDataPosition(0);
+    outEvent.readFromParcel(&parcel);
+
+    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
+}
+
+TEST_F(MotionEventTest, Transform) {
+    // Generate some points on a circle.
+    // Each point 'i' is a point on a circle of radius ROTATION centered at (3,2) at an angle
+    // of ARC * i degrees clockwise relative to the Y axis.
+    // The geometrical representation is irrelevant to the test, it's just easy to generate
+    // and check rotation.  We set the orientation to the same angle.
+    // Coordinate system: down is increasing Y, right is increasing X.
+    const float PI_180 = float(M_PI / 180);
+    const float RADIUS = 10;
+    const float ARC = 36;
+    const float ROTATION = ARC * 2;
+
+    const size_t pointerCount = 11;
+    int pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+    for (size_t i = 0; i < pointerCount; i++) {
+        float angle = float(i * ARC * PI_180);
+        pointerIds[i] = i;
+        pointerCoords[i].clear();
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
+    }
+    MotionEvent event;
+    event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+    float originalRawX = 0 + 3;
+    float originalRawY = -RADIUS + 2;
+
+    // Check original raw X and Y assumption.
+    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+    // Now translate the motion event so the circle's origin is at (0,0).
+    event.offsetLocation(-3, -2);
+
+    // Offsetting the location should preserve the raw X and Y of the first point.
+    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+    // Apply a rotation about the origin by ROTATION degrees clockwise.
+    SkMatrix matrix;
+    matrix.setRotate(ROTATION);
+    event.transform(&matrix);
+
+    // Check the points.
+    for (size_t i = 0; i < pointerCount; i++) {
+        float angle = float((i * ARC + ROTATION) * PI_180);
+        ASSERT_NEAR(sinf(angle) * RADIUS, event.getX(i), 0.001);
+        ASSERT_NEAR(-cosf(angle) * RADIUS, event.getY(i), 0.001);
+        ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
+    }
+
+    // Applying the transformation should preserve the raw X and Y of the first point.
+    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+}
+
+} // namespace android
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
index 952b974..6e18a4f 100644
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -1,6 +1,18 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
+/*
+ * 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.
+ */
 
 #include <ui/InputTransport.h>
 #include <utils/Timers.h>
@@ -118,13 +130,16 @@
     EXPECT_EQ(downTime, keyEvent->getDownTime());
     EXPECT_EQ(eventTime, keyEvent->getEventTime());
 
-    status = mConsumer->sendFinishedSignal();
+    status = mConsumer->sendFinishedSignal(true);
     ASSERT_EQ(OK, status)
             << "consumer sendFinishedSignal should return OK";
 
-    status = mPublisher->receiveFinishedSignal();
+    bool handled = false;
+    status = mPublisher->receiveFinishedSignal(&handled);
     ASSERT_EQ(OK, status)
             << "publisher receiveFinishedSignal should return OK";
+    ASSERT_TRUE(handled)
+            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
 
     status = mPublisher->reset();
     ASSERT_EQ(OK, status)
@@ -156,15 +171,17 @@
         sampleEventTimes.push(i + 10);
         for (size_t j = 0; j < pointerCount; j++) {
             samplePointerCoords.push();
-            samplePointerCoords.editTop().x = 100 * i + j;
-            samplePointerCoords.editTop().y = 200 * i + j;
-            samplePointerCoords.editTop().pressure = 0.5 * i + j;
-            samplePointerCoords.editTop().size = 0.7 * i + j;
-            samplePointerCoords.editTop().touchMajor = 1.5 * i + j;
-            samplePointerCoords.editTop().touchMinor = 1.7 * i + j;
-            samplePointerCoords.editTop().toolMajor = 2.5 * i + j;
-            samplePointerCoords.editTop().toolMinor = 2.7 * i + j;
-            samplePointerCoords.editTop().orientation = 3.5 * i + j;
+            PointerCoords& pc = samplePointerCoords.editTop();
+            pc.clear();
+            pc.setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i + j);
+            pc.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i + j);
         }
     }
 
@@ -236,27 +253,27 @@
         for (size_t i = 0; i < pointerCount; i++) {
             SCOPED_TRACE(i);
             size_t offset = sampleIndex * pointerCount + i;
-            EXPECT_EQ(samplePointerCoords[offset].x,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X),
                     motionEvent->getHistoricalRawX(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].y,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y),
                     motionEvent->getHistoricalRawY(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].x + xOffset,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
                     motionEvent->getHistoricalX(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].y + yOffset,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
                     motionEvent->getHistoricalY(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].pressure,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
                     motionEvent->getHistoricalPressure(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].size,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
                     motionEvent->getHistoricalSize(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].touchMajor,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
                     motionEvent->getHistoricalTouchMajor(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].touchMinor,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
                     motionEvent->getHistoricalTouchMinor(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].toolMajor,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
                     motionEvent->getHistoricalToolMajor(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].toolMinor,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
                     motionEvent->getHistoricalToolMinor(i, sampleIndex));
-            EXPECT_EQ(samplePointerCoords[offset].orientation,
+            EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
                     motionEvent->getHistoricalOrientation(i, sampleIndex));
         }
     }
@@ -266,26 +283,40 @@
     for (size_t i = 0; i < pointerCount; i++) {
         SCOPED_TRACE(i);
         size_t offset = lastSampleIndex * pointerCount + i;
-        EXPECT_EQ(samplePointerCoords[offset].x, motionEvent->getRawX(i));
-        EXPECT_EQ(samplePointerCoords[offset].y, motionEvent->getRawY(i));
-        EXPECT_EQ(samplePointerCoords[offset].x + xOffset, motionEvent->getX(i));
-        EXPECT_EQ(samplePointerCoords[offset].y + yOffset, motionEvent->getY(i));
-        EXPECT_EQ(samplePointerCoords[offset].pressure, motionEvent->getPressure(i));
-        EXPECT_EQ(samplePointerCoords[offset].size, motionEvent->getSize(i));
-        EXPECT_EQ(samplePointerCoords[offset].touchMajor, motionEvent->getTouchMajor(i));
-        EXPECT_EQ(samplePointerCoords[offset].touchMinor, motionEvent->getTouchMinor(i));
-        EXPECT_EQ(samplePointerCoords[offset].toolMajor, motionEvent->getToolMajor(i));
-        EXPECT_EQ(samplePointerCoords[offset].toolMinor, motionEvent->getToolMinor(i));
-        EXPECT_EQ(samplePointerCoords[offset].orientation, motionEvent->getOrientation(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X),
+                motionEvent->getRawX(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y),
+                motionEvent->getRawY(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
+                motionEvent->getX(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
+                motionEvent->getY(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+                motionEvent->getPressure(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+                motionEvent->getSize(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+                motionEvent->getTouchMajor(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+                motionEvent->getTouchMinor(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+                motionEvent->getToolMajor(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+                motionEvent->getToolMinor(i));
+        EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
+                motionEvent->getOrientation(i));
     }
 
-    status = mConsumer->sendFinishedSignal();
+    status = mConsumer->sendFinishedSignal(false);
     ASSERT_EQ(OK, status)
             << "consumer sendFinishedSignal should return OK";
 
-    status = mPublisher->receiveFinishedSignal();
+    bool handled = true;
+    status = mPublisher->receiveFinishedSignal(&handled);
     ASSERT_EQ(OK, status)
             << "publisher receiveFinishedSignal should return OK";
+    ASSERT_FALSE(handled)
+            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
 
     status = mPublisher->reset();
     ASSERT_EQ(OK, status)
@@ -322,7 +353,8 @@
 
     const size_t pointerCount = 1;
     int32_t pointerIds[pointerCount] = { 0 };
-    PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
+    PointerCoords pointerCoords[pointerCount];
+    pointerCoords[0].clear();
 
     status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             pointerCount, pointerIds, pointerCoords);
diff --git a/libs/ui/tests/InputReader_test.cpp b/libs/ui/tests/InputReader_test.cpp
deleted file mode 100644
index 09d1680..0000000
--- a/libs/ui/tests/InputReader_test.cpp
+++ /dev/null
@@ -1,3380 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-
-#include <ui/InputReader.h>
-#include <utils/List.h>
-#include <gtest/gtest.h>
-#include <math.h>
-
-namespace android {
-
-// An arbitrary time value.
-static const nsecs_t ARBITRARY_TIME = 1234;
-
-// Arbitrary display properties.
-static const int32_t DISPLAY_ID = 0;
-static const int32_t DISPLAY_WIDTH = 480;
-static const int32_t DISPLAY_HEIGHT = 800;
-
-// Error tolerance for floating point assertions.
-static const float EPSILON = 0.001f;
-
-template<typename T>
-static inline T min(T a, T b) {
-    return a < b ? a : b;
-}
-
-static inline float avg(float x, float y) {
-    return (x + y) / 2;
-}
-
-
-// --- FakeInputReaderPolicy ---
-
-class FakeInputReaderPolicy : public InputReaderPolicyInterface {
-    struct DisplayInfo {
-        int32_t width;
-        int32_t height;
-        int32_t orientation;
-    };
-
-    KeyedVector<int32_t, DisplayInfo> mDisplayInfos;
-    bool mFilterTouchEvents;
-    bool mFilterJumpyTouchEvents;
-    KeyedVector<String8, Vector<VirtualKeyDefinition> > mVirtualKeyDefinitions;
-    KeyedVector<String8, InputDeviceCalibration> mInputDeviceCalibrations;
-    Vector<String8> mExcludedDeviceNames;
-
-protected:
-    virtual ~FakeInputReaderPolicy() { }
-
-public:
-    FakeInputReaderPolicy() :
-            mFilterTouchEvents(false), mFilterJumpyTouchEvents(false) {
-    }
-
-    void removeDisplayInfo(int32_t displayId) {
-        mDisplayInfos.removeItem(displayId);
-    }
-
-    void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) {
-        removeDisplayInfo(displayId);
-
-        DisplayInfo info;
-        info.width = width;
-        info.height = height;
-        info.orientation = orientation;
-        mDisplayInfos.add(displayId, info);
-    }
-
-    void setFilterTouchEvents(bool enabled) {
-        mFilterTouchEvents = enabled;
-    }
-
-    void setFilterJumpyTouchEvents(bool enabled) {
-        mFilterJumpyTouchEvents = enabled;
-    }
-
-    void addInputDeviceCalibration(const String8& deviceName,
-            const InputDeviceCalibration& calibration) {
-        mInputDeviceCalibrations.add(deviceName, calibration);
-    }
-
-    void addInputDeviceCalibrationProperty(const String8& deviceName,
-            const String8& key, const String8& value) {
-        ssize_t index = mInputDeviceCalibrations.indexOfKey(deviceName);
-        if (index < 0) {
-            index = mInputDeviceCalibrations.add(deviceName, InputDeviceCalibration());
-        }
-        mInputDeviceCalibrations.editValueAt(index).addProperty(key, value);
-    }
-
-    void addVirtualKeyDefinition(const String8& deviceName,
-            const VirtualKeyDefinition& definition) {
-        if (mVirtualKeyDefinitions.indexOfKey(deviceName) < 0) {
-            mVirtualKeyDefinitions.add(deviceName, Vector<VirtualKeyDefinition>());
-        }
-
-        mVirtualKeyDefinitions.editValueFor(deviceName).push(definition);
-    }
-
-    void addExcludedDeviceName(const String8& deviceName) {
-        mExcludedDeviceNames.push(deviceName);
-    }
-
-private:
-    virtual bool getDisplayInfo(int32_t displayId,
-            int32_t* width, int32_t* height, int32_t* orientation) {
-        ssize_t index = mDisplayInfos.indexOfKey(displayId);
-        if (index >= 0) {
-            const DisplayInfo& info = mDisplayInfos.valueAt(index);
-            if (width) {
-                *width = info.width;
-            }
-            if (height) {
-                *height = info.height;
-            }
-            if (orientation) {
-                *orientation = info.orientation;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    virtual bool filterTouchEvents() {
-        return mFilterTouchEvents;
-    }
-
-    virtual bool filterJumpyTouchEvents() {
-        return mFilterJumpyTouchEvents;
-    }
-
-    virtual nsecs_t getVirtualKeyQuietTime() {
-        return 0;
-    }
-
-    virtual void getVirtualKeyDefinitions(const String8& deviceName,
-            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
-        ssize_t index = mVirtualKeyDefinitions.indexOfKey(deviceName);
-        if (index >= 0) {
-            outVirtualKeyDefinitions.appendVector(mVirtualKeyDefinitions.valueAt(index));
-        }
-    }
-
-    virtual void getInputDeviceCalibration(const String8& deviceName,
-            InputDeviceCalibration& outCalibration) {
-        ssize_t index = mInputDeviceCalibrations.indexOfKey(deviceName);
-        if (index >= 0) {
-            outCalibration = mInputDeviceCalibrations.valueAt(index);
-        }
-    }
-
-    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
-        outExcludedDeviceNames.appendVector(mExcludedDeviceNames);
-    }
-};
-
-
-// --- FakeInputDispatcher ---
-
-class FakeInputDispatcher : public InputDispatcherInterface {
-public:
-    struct NotifyConfigurationChangedArgs {
-        nsecs_t eventTime;
-    };
-
-    struct NotifyKeyArgs {
-        nsecs_t eventTime;
-        int32_t deviceId;
-        int32_t source;
-        uint32_t policyFlags;
-        int32_t action;
-        int32_t flags;
-        int32_t keyCode;
-        int32_t scanCode;
-        int32_t metaState;
-        nsecs_t downTime;
-    };
-
-    struct NotifyMotionArgs {
-        nsecs_t eventTime;
-        int32_t deviceId;
-        int32_t source;
-        uint32_t policyFlags;
-        int32_t action;
-        int32_t flags;
-        int32_t metaState;
-        int32_t edgeFlags;
-        uint32_t pointerCount;
-        Vector<int32_t> pointerIds;
-        Vector<PointerCoords> pointerCoords;
-        float xPrecision;
-        float yPrecision;
-        nsecs_t downTime;
-    };
-
-    struct NotifySwitchArgs {
-        nsecs_t when;
-        int32_t switchCode;
-        int32_t switchValue;
-        uint32_t policyFlags;
-    };
-
-private:
-    List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgs;
-    List<NotifyKeyArgs> mNotifyKeyArgs;
-    List<NotifyMotionArgs> mNotifyMotionArgs;
-    List<NotifySwitchArgs> mNotifySwitchArgs;
-
-protected:
-    virtual ~FakeInputDispatcher() { }
-
-public:
-    FakeInputDispatcher() {
-    }
-
-    void assertNotifyConfigurationChangedWasCalled(NotifyConfigurationChangedArgs* outArgs = NULL) {
-        ASSERT_FALSE(mNotifyConfigurationChangedArgs.empty())
-                << "Expected notifyConfigurationChanged() to have been called.";
-        if (outArgs) {
-            *outArgs = *mNotifyConfigurationChangedArgs.begin();
-        }
-        mNotifyConfigurationChangedArgs.erase(mNotifyConfigurationChangedArgs.begin());
-    }
-
-    void assertNotifyKeyWasCalled(NotifyKeyArgs* outArgs = NULL) {
-        ASSERT_FALSE(mNotifyKeyArgs.empty())
-                << "Expected notifyKey() to have been called.";
-        if (outArgs) {
-            *outArgs = *mNotifyKeyArgs.begin();
-        }
-        mNotifyKeyArgs.erase(mNotifyKeyArgs.begin());
-    }
-
-    void assertNotifyKeyWasNotCalled() {
-        ASSERT_TRUE(mNotifyKeyArgs.empty())
-                << "Expected notifyKey() to not have been called.";
-    }
-
-    void assertNotifyMotionWasCalled(NotifyMotionArgs* outArgs = NULL) {
-        ASSERT_FALSE(mNotifyMotionArgs.empty())
-                << "Expected notifyMotion() to have been called.";
-        if (outArgs) {
-            *outArgs = *mNotifyMotionArgs.begin();
-        }
-        mNotifyMotionArgs.erase(mNotifyMotionArgs.begin());
-    }
-
-    void assertNotifyMotionWasNotCalled() {
-        ASSERT_TRUE(mNotifyMotionArgs.empty())
-                << "Expected notifyMotion() to not have been called.";
-    }
-
-    void assertNotifySwitchWasCalled(NotifySwitchArgs* outArgs = NULL) {
-        ASSERT_FALSE(mNotifySwitchArgs.empty())
-                << "Expected notifySwitch() to have been called.";
-        if (outArgs) {
-            *outArgs = *mNotifySwitchArgs.begin();
-        }
-        mNotifySwitchArgs.erase(mNotifySwitchArgs.begin());
-    }
-
-private:
-    virtual void notifyConfigurationChanged(nsecs_t eventTime) {
-        NotifyConfigurationChangedArgs args;
-        args.eventTime = eventTime;
-        mNotifyConfigurationChangedArgs.push_back(args);
-    }
-
-    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
-            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
-            int32_t scanCode, int32_t metaState, nsecs_t downTime) {
-        NotifyKeyArgs args;
-        args.eventTime = eventTime;
-        args.deviceId = deviceId;
-        args.source = source;
-        args.policyFlags = policyFlags;
-        args.action = action;
-        args.flags = flags;
-        args.keyCode = keyCode;
-        args.scanCode = scanCode;
-        args.metaState = metaState;
-        args.downTime = downTime;
-        mNotifyKeyArgs.push_back(args);
-    }
-
-    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
-            uint32_t policyFlags, int32_t action, int32_t flags,
-            int32_t metaState, int32_t edgeFlags,
-            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
-            float xPrecision, float yPrecision, nsecs_t downTime) {
-        NotifyMotionArgs args;
-        args.eventTime = eventTime;
-        args.deviceId = deviceId;
-        args.source = source;
-        args.policyFlags = policyFlags;
-        args.action = action;
-        args.flags = flags;
-        args.metaState = metaState;
-        args.edgeFlags = edgeFlags;
-        args.pointerCount = pointerCount;
-        args.pointerIds.clear();
-        args.pointerIds.appendArray(pointerIds, pointerCount);
-        args.pointerCoords.clear();
-        args.pointerCoords.appendArray(pointerCoords, pointerCount);
-        args.xPrecision = xPrecision;
-        args.yPrecision = yPrecision;
-        args.downTime = downTime;
-        mNotifyMotionArgs.push_back(args);
-    }
-
-    virtual void notifySwitch(nsecs_t when,
-            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
-        NotifySwitchArgs args;
-        args.when = when;
-        args.switchCode = switchCode;
-        args.switchValue = switchValue;
-        args.policyFlags = policyFlags;
-        mNotifySwitchArgs.push_back(args);
-    }
-
-    virtual void dump(String8& dump) {
-        ADD_FAILURE() << "Should never be called by input reader.";
-    }
-
-    virtual void dispatchOnce() {
-        ADD_FAILURE() << "Should never be called by input reader.";
-    }
-
-    virtual int32_t injectInputEvent(const InputEvent* event,
-            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
-        ADD_FAILURE() << "Should never be called by input reader.";
-        return INPUT_EVENT_INJECTION_FAILED;
-    }
-
-    virtual void setInputWindows(const Vector<InputWindow>& inputWindows) {
-        ADD_FAILURE() << "Should never be called by input reader.";
-    }
-
-    virtual void setFocusedApplication(const InputApplication* inputApplication) {
-        ADD_FAILURE() << "Should never be called by input reader.";
-    }
-
-    virtual void setInputDispatchMode(bool enabled, bool frozen) {
-        ADD_FAILURE() << "Should never be called by input reader.";
-    }
-
-    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
-        ADD_FAILURE() << "Should never be called by input reader.";
-        return 0;
-    }
-
-    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) {
-        ADD_FAILURE() << "Should never be called by input reader.";
-        return 0;
-    }
-};
-
-
-// --- FakeEventHub ---
-
-class FakeEventHub : public EventHubInterface {
-    struct KeyInfo {
-        int32_t keyCode;
-        uint32_t flags;
-    };
-
-    struct Device {
-        String8 name;
-        uint32_t classes;
-        KeyedVector<int, RawAbsoluteAxisInfo> axes;
-        KeyedVector<int32_t, int32_t> keyCodeStates;
-        KeyedVector<int32_t, int32_t> scanCodeStates;
-        KeyedVector<int32_t, int32_t> switchStates;
-        KeyedVector<int32_t, KeyInfo> keys;
-
-        Device(const String8& name, uint32_t classes) :
-                name(name), classes(classes) {
-        }
-    };
-
-    KeyedVector<int32_t, Device*> mDevices;
-    Vector<String8> mExcludedDevices;
-    List<RawEvent> mEvents;
-
-protected:
-    virtual ~FakeEventHub() {
-        for (size_t i = 0; i < mDevices.size(); i++) {
-            delete mDevices.valueAt(i);
-        }
-    }
-
-public:
-    FakeEventHub() { }
-
-    void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
-        Device* device = new Device(name, classes);
-        mDevices.add(deviceId, device);
-
-        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0, 0, 0);
-    }
-
-    void removeDevice(int32_t deviceId) {
-        delete mDevices.valueFor(deviceId);
-        mDevices.removeItem(deviceId);
-
-        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0, 0, 0);
-    }
-
-    void finishDeviceScan() {
-        enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0, 0, 0);
-    }
-
-    void addAxis(int32_t deviceId, int axis,
-            int32_t minValue, int32_t maxValue, int flat, int fuzz) {
-        Device* device = getDevice(deviceId);
-
-        RawAbsoluteAxisInfo info;
-        info.valid = true;
-        info.minValue = minValue;
-        info.maxValue = maxValue;
-        info.flat = flat;
-        info.fuzz = fuzz;
-        device->axes.add(axis, info);
-    }
-
-    void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
-        Device* device = getDevice(deviceId);
-        device->keyCodeStates.replaceValueFor(keyCode, state);
-    }
-
-    void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
-        Device* device = getDevice(deviceId);
-        device->scanCodeStates.replaceValueFor(scanCode, state);
-    }
-
-    void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
-        Device* device = getDevice(deviceId);
-        device->switchStates.replaceValueFor(switchCode, state);
-    }
-
-    void addKey(int32_t deviceId, int32_t scanCode, int32_t keyCode, uint32_t flags) {
-        Device* device = getDevice(deviceId);
-        KeyInfo info;
-        info.keyCode = keyCode;
-        info.flags = flags;
-        device->keys.add(scanCode, info);
-    }
-
-    Vector<String8>& getExcludedDevices() {
-        return mExcludedDevices;
-    }
-
-    void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
-            int32_t scanCode, int32_t keyCode, int32_t value, uint32_t flags) {
-        RawEvent event;
-        event.when = when;
-        event.deviceId = deviceId;
-        event.type = type;
-        event.scanCode = scanCode;
-        event.keyCode = keyCode;
-        event.value = value;
-        event.flags = flags;
-        mEvents.push_back(event);
-    }
-
-    void assertQueueIsEmpty() {
-        ASSERT_EQ(size_t(0), mEvents.size())
-                << "Expected the event queue to be empty (fully consumed).";
-    }
-
-private:
-    Device* getDevice(int32_t deviceId) const {
-        ssize_t index = mDevices.indexOfKey(deviceId);
-        return index >= 0 ? mDevices.valueAt(index) : NULL;
-    }
-
-    virtual uint32_t getDeviceClasses(int32_t deviceId) const {
-        Device* device = getDevice(deviceId);
-        return device ? device->classes : 0;
-    }
-
-    virtual String8 getDeviceName(int32_t deviceId) const {
-        Device* device = getDevice(deviceId);
-        return device ? device->name : String8("unknown");
-    }
-
-    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-            RawAbsoluteAxisInfo* outAxisInfo) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->axes.indexOfKey(axis);
-            if (index >= 0) {
-                *outAxisInfo = device->axes.valueAt(index);
-                return OK;
-            }
-        }
-        return -1;
-    }
-
-    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
-            int32_t* outKeycode, uint32_t* outFlags) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->keys.indexOfKey(scancode);
-            if (index >= 0) {
-                if (outKeycode) {
-                    *outKeycode = device->keys.valueAt(index).keyCode;
-                }
-                if (outFlags) {
-                    *outFlags = device->keys.valueAt(index).flags;
-                }
-                return OK;
-            }
-        }
-        return NAME_NOT_FOUND;
-    }
-
-    virtual void addExcludedDevice(const char* deviceName) {
-        mExcludedDevices.add(String8(deviceName));
-    }
-
-    virtual bool getEvent(RawEvent* outEvent) {
-        if (mEvents.empty()) {
-            return false;
-        }
-
-        *outEvent = *mEvents.begin();
-        mEvents.erase(mEvents.begin());
-        return true;
-    }
-
-    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
-            if (index >= 0) {
-                return device->scanCodeStates.valueAt(index);
-            }
-        }
-        return AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
-            if (index >= 0) {
-                return device->keyCodeStates.valueAt(index);
-            }
-        }
-        return AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->switchStates.indexOfKey(sw);
-            if (index >= 0) {
-                return device->switchStates.valueAt(index);
-            }
-        }
-        return AKEY_STATE_UNKNOWN;
-    }
-
-    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
-            uint8_t* outFlags) const {
-        bool result = false;
-        Device* device = getDevice(deviceId);
-        if (device) {
-            for (size_t i = 0; i < numCodes; i++) {
-                for (size_t j = 0; j < device->keys.size(); j++) {
-                    if (keyCodes[i] == device->keys.valueAt(j).keyCode) {
-                        outFlags[i] = 1;
-                        result = true;
-                    }
-                }
-            }
-        }
-        return result;
-    }
-
-    virtual void dump(String8& dump) {
-    }
-};
-
-
-// --- FakeInputReaderContext ---
-
-class FakeInputReaderContext : public InputReaderContext {
-    sp<EventHubInterface> mEventHub;
-    sp<InputReaderPolicyInterface> mPolicy;
-    sp<InputDispatcherInterface> mDispatcher;
-    int32_t mGlobalMetaState;
-    bool mUpdateGlobalMetaStateWasCalled;
-
-public:
-    FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& policy,
-            const sp<InputDispatcherInterface>& dispatcher) :
-            mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
-            mGlobalMetaState(0) {
-    }
-
-    virtual ~FakeInputReaderContext() { }
-
-    void assertUpdateGlobalMetaStateWasCalled() {
-        ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
-                << "Expected updateGlobalMetaState() to have been called.";
-        mUpdateGlobalMetaStateWasCalled = false;
-    }
-
-    void setGlobalMetaState(int32_t state) {
-        mGlobalMetaState = state;
-    }
-
-private:
-    virtual void updateGlobalMetaState() {
-        mUpdateGlobalMetaStateWasCalled = true;
-    }
-
-    virtual int32_t getGlobalMetaState() {
-        return mGlobalMetaState;
-    }
-
-    virtual EventHubInterface* getEventHub() {
-        return mEventHub.get();
-    }
-
-    virtual InputReaderPolicyInterface* getPolicy() {
-        return mPolicy.get();
-    }
-
-    virtual InputDispatcherInterface* getDispatcher() {
-        return mDispatcher.get();
-    }
-
-    virtual void disableVirtualKeysUntil(nsecs_t time) {
-    }
-
-    virtual bool shouldDropVirtualKey(nsecs_t now,
-            InputDevice* device, int32_t keyCode, int32_t scanCode) {
-        return false;
-    }
-};
-
-
-// --- FakeInputMapper ---
-
-class FakeInputMapper : public InputMapper {
-    uint32_t mSources;
-    int32_t mKeyboardType;
-    int32_t mMetaState;
-    KeyedVector<int32_t, int32_t> mKeyCodeStates;
-    KeyedVector<int32_t, int32_t> mScanCodeStates;
-    KeyedVector<int32_t, int32_t> mSwitchStates;
-    Vector<int32_t> mSupportedKeyCodes;
-    RawEvent mLastEvent;
-
-    bool mConfigureWasCalled;
-    bool mResetWasCalled;
-    bool mProcessWasCalled;
-
-public:
-    FakeInputMapper(InputDevice* device, uint32_t sources) :
-            InputMapper(device),
-            mSources(sources), mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
-            mMetaState(0),
-            mConfigureWasCalled(false), mResetWasCalled(false), mProcessWasCalled(false) {
-    }
-
-    virtual ~FakeInputMapper() { }
-
-    void setKeyboardType(int32_t keyboardType) {
-        mKeyboardType = keyboardType;
-    }
-
-    void setMetaState(int32_t metaState) {
-        mMetaState = metaState;
-    }
-
-    void assertConfigureWasCalled() {
-        ASSERT_TRUE(mConfigureWasCalled)
-                << "Expected configure() to have been called.";
-        mConfigureWasCalled = false;
-    }
-
-    void assertResetWasCalled() {
-        ASSERT_TRUE(mResetWasCalled)
-                << "Expected reset() to have been called.";
-        mResetWasCalled = false;
-    }
-
-    void assertProcessWasCalled(RawEvent* outLastEvent = NULL) {
-        ASSERT_TRUE(mProcessWasCalled)
-                << "Expected process() to have been called.";
-        if (outLastEvent) {
-            *outLastEvent = mLastEvent;
-        }
-        mProcessWasCalled = false;
-    }
-
-    void setKeyCodeState(int32_t keyCode, int32_t state) {
-        mKeyCodeStates.replaceValueFor(keyCode, state);
-    }
-
-    void setScanCodeState(int32_t scanCode, int32_t state) {
-        mScanCodeStates.replaceValueFor(scanCode, state);
-    }
-
-    void setSwitchState(int32_t switchCode, int32_t state) {
-        mSwitchStates.replaceValueFor(switchCode, state);
-    }
-
-    void addSupportedKeyCode(int32_t keyCode) {
-        mSupportedKeyCodes.add(keyCode);
-    }
-
-private:
-    virtual uint32_t getSources() {
-        return mSources;
-    }
-
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) {
-        InputMapper::populateDeviceInfo(deviceInfo);
-
-        if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
-            deviceInfo->setKeyboardType(mKeyboardType);
-        }
-    }
-
-    virtual void configure() {
-        mConfigureWasCalled = true;
-    }
-
-    virtual void reset() {
-        mResetWasCalled = true;
-    }
-
-    virtual void process(const RawEvent* rawEvent) {
-        mLastEvent = *rawEvent;
-        mProcessWasCalled = true;
-    }
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-        ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
-        return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-        ssize_t index = mScanCodeStates.indexOfKey(scanCode);
-        return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-        ssize_t index = mSwitchStates.indexOfKey(switchCode);
-        return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
-    }
-
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags) {
-        bool result = false;
-        for (size_t i = 0; i < numCodes; i++) {
-            for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
-                if (keyCodes[i] == mSupportedKeyCodes[j]) {
-                    outFlags[i] = 1;
-                    result = true;
-                }
-            }
-        }
-        return result;
-    }
-
-    virtual int32_t getMetaState() {
-        return mMetaState;
-    }
-};
-
-
-// --- InstrumentedInputReader ---
-
-class InstrumentedInputReader : public InputReader {
-    InputDevice* mNextDevice;
-
-public:
-    InstrumentedInputReader(const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& policy,
-            const sp<InputDispatcherInterface>& dispatcher) :
-            InputReader(eventHub, policy, dispatcher) {
-    }
-
-    virtual ~InstrumentedInputReader() {
-        if (mNextDevice) {
-            delete mNextDevice;
-        }
-    }
-
-    void setNextDevice(InputDevice* device) {
-        mNextDevice = device;
-    }
-
-protected:
-    virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
-        if (mNextDevice) {
-            InputDevice* device = mNextDevice;
-            mNextDevice = NULL;
-            return device;
-        }
-        return InputReader::createDevice(deviceId, name, classes);
-    }
-
-    friend class InputReaderTest;
-};
-
-
-// --- InputReaderTest ---
-
-class InputReaderTest : public testing::Test {
-protected:
-    sp<FakeInputDispatcher> mFakeDispatcher;
-    sp<FakeInputReaderPolicy> mFakePolicy;
-    sp<FakeEventHub> mFakeEventHub;
-    sp<InstrumentedInputReader> mReader;
-
-    virtual void SetUp() {
-        mFakeEventHub = new FakeEventHub();
-        mFakePolicy = new FakeInputReaderPolicy();
-        mFakeDispatcher = new FakeInputDispatcher();
-
-        mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeDispatcher);
-    }
-
-    virtual void TearDown() {
-        mReader.clear();
-
-        mFakeDispatcher.clear();
-        mFakePolicy.clear();
-        mFakeEventHub.clear();
-    }
-
-    void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
-        mFakeEventHub->addDevice(deviceId, name, classes);
-        mFakeEventHub->finishDeviceScan();
-        mReader->loopOnce();
-        mReader->loopOnce();
-        mFakeEventHub->assertQueueIsEmpty();
-    }
-
-    FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
-            const String8& name, uint32_t classes, uint32_t sources) {
-        InputDevice* device = new InputDevice(mReader.get(), deviceId, name);
-        FakeInputMapper* mapper = new FakeInputMapper(device, sources);
-        device->addMapper(mapper);
-        mReader->setNextDevice(device);
-        addDevice(deviceId, name, classes);
-        return mapper;
-    }
-};
-
-TEST_F(InputReaderTest, GetInputConfiguration_WhenNoDevices_ReturnsDefaults) {
-    InputConfiguration config;
-    mReader->getInputConfiguration(&config);
-
-    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
-    ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation);
-    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
-}
-
-TEST_F(InputReaderTest, GetInputConfiguration_WhenAlphabeticKeyboardPresent_ReturnsQwertyKeyboard) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("keyboard"),
-            INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_ALPHAKEY));
-
-    InputConfiguration config;
-    mReader->getInputConfiguration(&config);
-
-    ASSERT_EQ(InputConfiguration::KEYBOARD_QWERTY, config.keyboard);
-    ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation);
-    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
-}
-
-TEST_F(InputReaderTest, GetInputConfiguration_WhenTouchScreenPresent_ReturnsFingerTouchScreen) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("touchscreen"),
-            INPUT_DEVICE_CLASS_TOUCHSCREEN));
-
-    InputConfiguration config;
-    mReader->getInputConfiguration(&config);
-
-    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
-    ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation);
-    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_FINGER, config.touchScreen);
-}
-
-TEST_F(InputReaderTest, GetInputConfiguration_WhenTrackballPresent_ReturnsTrackballNavigation) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("trackball"),
-            INPUT_DEVICE_CLASS_TRACKBALL));
-
-    InputConfiguration config;
-    mReader->getInputConfiguration(&config);
-
-    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
-    ASSERT_EQ(InputConfiguration::NAVIGATION_TRACKBALL, config.navigation);
-    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
-}
-
-TEST_F(InputReaderTest, GetInputConfiguration_WhenDPadPresent_ReturnsDPadNavigation) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("dpad"),
-            INPUT_DEVICE_CLASS_DPAD));
-
-    InputConfiguration config;
-    mReader->getInputConfiguration(&config);
-
-    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
-    ASSERT_EQ(InputConfiguration::NAVIGATION_DPAD, config.navigation);
-    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
-}
-
-TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsValid) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
-            INPUT_DEVICE_CLASS_KEYBOARD));
-
-    InputDeviceInfo info;
-    status_t result = mReader->getInputDeviceInfo(1, &info);
-
-    ASSERT_EQ(OK, result);
-    ASSERT_EQ(1, info.getId());
-    ASSERT_STREQ("keyboard", info.getName().string());
-    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, info.getKeyboardType());
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, info.getSources());
-    ASSERT_EQ(size_t(0), info.getMotionRanges().size());
-}
-
-TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsInvalid) {
-    InputDeviceInfo info;
-    status_t result = mReader->getInputDeviceInfo(-1, &info);
-
-    ASSERT_EQ(NAME_NOT_FOUND, result);
-}
-
-TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsIgnored) {
-    addDevice(1, String8("ignored"), 0); // no classes so device will be ignored
-
-    InputDeviceInfo info;
-    status_t result = mReader->getInputDeviceInfo(1, &info);
-
-    ASSERT_EQ(NAME_NOT_FOUND, result);
-}
-
-TEST_F(InputReaderTest, GetInputDeviceIds) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
-            INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_ALPHAKEY));
-    ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("trackball"),
-            INPUT_DEVICE_CLASS_TRACKBALL));
-
-    Vector<int32_t> ids;
-    mReader->getInputDeviceIds(ids);
-
-    ASSERT_EQ(size_t(2), ids.size());
-    ASSERT_EQ(1, ids[0]);
-    ASSERT_EQ(2, ids[1]);
-}
-
-TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
-            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
-    mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
-            AINPUT_SOURCE_ANY, AKEYCODE_A))
-            << "Should return unknown when the device id is >= 0 but unknown.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(1,
-            AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
-            AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-}
-
-TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
-            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
-    mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN);
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
-            AINPUT_SOURCE_ANY, KEY_A))
-            << "Should return unknown when the device id is >= 0 but unknown.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(1,
-            AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
-            AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-}
-
-TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
-            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
-    mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN);
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
-            AINPUT_SOURCE_ANY, SW_LID))
-            << "Should return unknown when the device id is >= 0 but unknown.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(1,
-            AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
-            AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-}
-
-TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
-            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
-    mapper->addSupportedKeyCode(AKEYCODE_A);
-    mapper->addSupportedKeyCode(AKEYCODE_B);
-
-    const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
-    uint8_t flags[4] = { 0, 0, 0, 1 };
-
-    ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, 4, keyCodes, flags))
-            << "Should return false when device id is >= 0 but unknown.";
-    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_FALSE(mReader->hasKeys(1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return false when device id is valid but the sources are not supported by the device.";
-    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_TRUE(mReader->hasKeys(1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-    ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return false when the device id is < 0 but the sources are not supported by any device.";
-    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_TRUE(mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-    ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
-}
-
-TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
-    addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD);
-
-    FakeInputDispatcher::NotifyConfigurationChangedArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyConfigurationChangedWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-}
-
-TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
-            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
-
-    mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, AKEYCODE_A, 1, POLICY_FLAG_WAKE);
-    mReader->loopOnce();
-    ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
-
-    RawEvent event;
-    ASSERT_NO_FATAL_FAILURE(mapper->assertProcessWasCalled(&event));
-    ASSERT_EQ(0, event.when);
-    ASSERT_EQ(1, event.deviceId);
-    ASSERT_EQ(EV_KEY, event.type);
-    ASSERT_EQ(KEY_A, event.scanCode);
-    ASSERT_EQ(AKEYCODE_A, event.keyCode);
-    ASSERT_EQ(1, event.value);
-    ASSERT_EQ(POLICY_FLAG_WAKE, event.flags);
-}
-
-
-// --- InputDeviceTest ---
-
-class InputDeviceTest : public testing::Test {
-protected:
-    static const char* DEVICE_NAME;
-    static const int32_t DEVICE_ID;
-
-    sp<FakeEventHub> mFakeEventHub;
-    sp<FakeInputReaderPolicy> mFakePolicy;
-    sp<FakeInputDispatcher> mFakeDispatcher;
-    FakeInputReaderContext* mFakeContext;
-
-    InputDevice* mDevice;
-
-    virtual void SetUp() {
-        mFakeEventHub = new FakeEventHub();
-        mFakePolicy = new FakeInputReaderPolicy();
-        mFakeDispatcher = new FakeInputDispatcher();
-        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
-
-        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
-    }
-
-    virtual void TearDown() {
-        delete mDevice;
-
-        delete mFakeContext;
-        mFakeDispatcher.clear();
-        mFakePolicy.clear();
-        mFakeEventHub.clear();
-    }
-};
-
-const char* InputDeviceTest::DEVICE_NAME = "device";
-const int32_t InputDeviceTest::DEVICE_ID = 1;
-
-TEST_F(InputDeviceTest, ImmutableProperties) {
-    ASSERT_EQ(DEVICE_ID, mDevice->getId());
-    ASSERT_STREQ(DEVICE_NAME, mDevice->getName());
-}
-
-TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
-    // Configuration.
-    mDevice->configure();
-
-    // Metadata.
-    ASSERT_TRUE(mDevice->isIgnored());
-    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
-
-    InputDeviceInfo info;
-    mDevice->getDeviceInfo(&info);
-    ASSERT_EQ(DEVICE_ID, info.getId());
-    ASSERT_STREQ(DEVICE_NAME, info.getName().string());
-    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
-    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
-
-    // State queries.
-    ASSERT_EQ(0, mDevice->getMetaState());
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
-            << "Ignored device should return unknown key code state.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
-            << "Ignored device should return unknown scan code state.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
-            << "Ignored device should return unknown switch state.";
-
-    const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
-    uint8_t flags[2] = { 0, 1 };
-    ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 2, keyCodes, flags))
-            << "Ignored device should never mark any key codes.";
-    ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
-    ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
-
-    // Reset.
-    mDevice->reset();
-}
-
-TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
-    // Configuration.
-    InputDeviceCalibration calibration;
-    calibration.addProperty(String8("key"), String8("value"));
-    mFakePolicy->addInputDeviceCalibration(String8(DEVICE_NAME), calibration);
-
-    FakeInputMapper* mapper1 = new FakeInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD);
-    mapper1->setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    mapper1->setMetaState(AMETA_ALT_ON);
-    mapper1->addSupportedKeyCode(AKEYCODE_A);
-    mapper1->addSupportedKeyCode(AKEYCODE_B);
-    mapper1->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
-    mapper1->setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
-    mapper1->setScanCodeState(2, AKEY_STATE_DOWN);
-    mapper1->setScanCodeState(3, AKEY_STATE_UP);
-    mapper1->setSwitchState(4, AKEY_STATE_DOWN);
-    mDevice->addMapper(mapper1);
-
-    FakeInputMapper* mapper2 = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN);
-    mapper2->setMetaState(AMETA_SHIFT_ON);
-    mDevice->addMapper(mapper2);
-
-    mDevice->configure();
-
-    String8 propertyValue;
-    ASSERT_TRUE(mDevice->getCalibration().tryGetProperty(String8("key"), propertyValue))
-            << "Device should have read calibration during configuration phase.";
-    ASSERT_STREQ("value", propertyValue.string());
-
-    ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled());
-    ASSERT_NO_FATAL_FAILURE(mapper2->assertConfigureWasCalled());
-
-    // Metadata.
-    ASSERT_FALSE(mDevice->isIgnored());
-    ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
-
-    InputDeviceInfo info;
-    mDevice->getDeviceInfo(&info);
-    ASSERT_EQ(DEVICE_ID, info.getId());
-    ASSERT_STREQ(DEVICE_NAME, info.getName().string());
-    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
-    ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
-
-    // State queries.
-    ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
-            << "Should query mappers and combine meta states.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown key code state when source not supported.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown scan code state when source not supported.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown switch state when source not supported.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
-            << "Should query mapper when source is supported.";
-    ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
-            << "Should query mapper when source is supported.";
-    ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
-            << "Should query mapper when source is supported.";
-
-    const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
-    uint8_t flags[4] = { 0, 0, 0, 1 };
-    ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should do nothing when source is unsupported.";
-    ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
-    ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
-    ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
-    ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
-
-    ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 4, keyCodes, flags))
-            << "Should query mapper when source is supported.";
-    ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
-    ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
-    ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
-    ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
-
-    // Event handling.
-    RawEvent event;
-    mDevice->process(&event);
-
-    ASSERT_NO_FATAL_FAILURE(mapper1->assertProcessWasCalled());
-    ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled());
-
-    // Reset.
-    mDevice->reset();
-
-    ASSERT_NO_FATAL_FAILURE(mapper1->assertResetWasCalled());
-    ASSERT_NO_FATAL_FAILURE(mapper2->assertResetWasCalled());
-}
-
-
-// --- InputMapperTest ---
-
-class InputMapperTest : public testing::Test {
-protected:
-    static const char* DEVICE_NAME;
-    static const int32_t DEVICE_ID;
-
-    sp<FakeEventHub> mFakeEventHub;
-    sp<FakeInputReaderPolicy> mFakePolicy;
-    sp<FakeInputDispatcher> mFakeDispatcher;
-    FakeInputReaderContext* mFakeContext;
-    InputDevice* mDevice;
-
-    virtual void SetUp() {
-        mFakeEventHub = new FakeEventHub();
-        mFakePolicy = new FakeInputReaderPolicy();
-        mFakeDispatcher = new FakeInputDispatcher();
-        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
-        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
-
-        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
-    }
-
-    virtual void TearDown() {
-        delete mDevice;
-        delete mFakeContext;
-        mFakeDispatcher.clear();
-        mFakePolicy.clear();
-        mFakeEventHub.clear();
-    }
-
-    void prepareCalibration(const char* key, const char* value) {
-        mFakePolicy->addInputDeviceCalibrationProperty(String8(DEVICE_NAME),
-                String8(key), String8(value));
-    }
-
-    void addMapperAndConfigure(InputMapper* mapper) {
-        mDevice->addMapper(mapper);
-        mDevice->configure();
-    }
-
-    static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type,
-            int32_t scanCode, int32_t keyCode, int32_t value, uint32_t flags) {
-        RawEvent event;
-        event.when = when;
-        event.deviceId = deviceId;
-        event.type = type;
-        event.scanCode = scanCode;
-        event.keyCode = keyCode;
-        event.value = value;
-        event.flags = flags;
-        mapper->process(&event);
-    }
-
-    static void assertMotionRange(const InputDeviceInfo& info,
-            int32_t rangeType, float min, float max, float flat, float fuzz) {
-        const InputDeviceInfo::MotionRange* range = info.getMotionRange(rangeType);
-        ASSERT_TRUE(range != NULL) << "Range: " << rangeType;
-        ASSERT_NEAR(min, range->min, EPSILON) << "Range: " << rangeType;
-        ASSERT_NEAR(max, range->max, EPSILON) << "Range: " << rangeType;
-        ASSERT_NEAR(flat, range->flat, EPSILON) << "Range: " << rangeType;
-        ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Range: " << rangeType;
-    }
-
-    static void assertPointerCoords(const PointerCoords& coords,
-            float x, float y, float pressure, float size,
-            float touchMajor, float touchMinor, float toolMajor, float toolMinor,
-            float orientation) {
-        ASSERT_NEAR(x, coords.x, 1);
-        ASSERT_NEAR(y, coords.y, 1);
-        ASSERT_NEAR(pressure, coords.pressure, EPSILON);
-        ASSERT_NEAR(size, coords.size, EPSILON);
-        ASSERT_NEAR(touchMajor, coords.touchMajor, 1);
-        ASSERT_NEAR(touchMinor, coords.touchMinor, 1);
-        ASSERT_NEAR(toolMajor, coords.toolMajor, 1);
-        ASSERT_NEAR(toolMinor, coords.toolMinor, 1);
-        ASSERT_NEAR(orientation, coords.orientation, EPSILON);
-    }
-};
-
-const char* InputMapperTest::DEVICE_NAME = "device";
-const int32_t InputMapperTest::DEVICE_ID = 1;
-
-
-// --- SwitchInputMapperTest ---
-
-class SwitchInputMapperTest : public InputMapperTest {
-protected:
-};
-
-TEST_F(SwitchInputMapperTest, GetSources) {
-    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources());
-}
-
-TEST_F(SwitchInputMapperTest, GetSwitchState) {
-    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 1);
-    ASSERT_EQ(1, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-
-    mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 0);
-    ASSERT_EQ(0, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-}
-
-TEST_F(SwitchInputMapperTest, Process) {
-    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
-    addMapperAndConfigure(mapper);
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 0, 1, 0);
-
-    FakeInputDispatcher::NotifySwitchArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifySwitchWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.when);
-    ASSERT_EQ(SW_LID, args.switchCode);
-    ASSERT_EQ(1, args.switchValue);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-}
-
-
-// --- KeyboardInputMapperTest ---
-
-class KeyboardInputMapperTest : public InputMapperTest {
-protected:
-    void testDPadKeyRotation(KeyboardInputMapper* mapper,
-            int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode);
-};
-
-void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper,
-        int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) {
-    FakeInputDispatcher::NotifyKeyArgs args;
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(originalScanCode, args.scanCode);
-    ASSERT_EQ(rotatedKeyCode, args.keyCode);
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(originalScanCode, args.scanCode);
-    ASSERT_EQ(rotatedKeyCode, args.keyCode);
-}
-
-
-TEST_F(KeyboardInputMapperTest, GetSources) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper->getSources());
-}
-
-TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    // Key down.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
-    FakeInputDispatcher::NotifyKeyArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Key up.
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
-            EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-}
-
-TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreNotDown_DoesNotSynthesizeKeyUp) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    // Key down.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    // Key up.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    // Reset.  Since no keys still down, should not synthesize any key ups.
-    mapper->reset();
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-}
-
-TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    // Metakey down.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    // Key down.
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
-            EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    // Reset.  Since two keys are still down, should synthesize two key ups in reverse order.
-    mapper->reset();
-
-    FakeInputDispatcher::NotifyKeyArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEYCODE_A, args.keyCode);
-    ASSERT_EQ(KEY_A, args.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEYCODE_SHIFT_LEFT, args.keyCode);
-    ASSERT_EQ(KEY_LEFTSHIFT, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
-
-    // And that's it.
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-}
-
-TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    // Initial metastate.
-    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
-
-    // Metakey down.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
-    FakeInputDispatcher::NotifyKeyArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
-    ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
-
-    // Key down.
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
-            EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
-
-    // Key up.
-    process(mapper, ARBITRARY_TIME + 2, DEVICE_ID,
-            EV_KEY, KEY_A, AKEYCODE_A, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
-
-    // Metakey up.
-    process(mapper, ARBITRARY_TIME + 3, DEVICE_ID,
-            EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
-    ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
-}
-
-TEST_F(KeyboardInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotateDPad) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
-}
-
-TEST_F(KeyboardInputMapperTest, Process_WhenAttachedToDisplay_ShouldRotateDPad) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, DISPLAY_ID,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_0);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_90);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN));
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_180);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_LEFT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT));
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_270);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_UP));
-
-    // Special case: if orientation changes while key is down, we still emit the same keycode
-    // in the key up as we did in the key down.
-    FakeInputDispatcher::NotifyKeyArgs args;
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_270);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(KEY_UP, args.scanCode);
-    ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_180);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(KEY_UP, args.scanCode);
-    ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
-}
-
-TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 1);
-    ASSERT_EQ(1, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
-
-    mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 0);
-    ASSERT_EQ(0, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
-}
-
-TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 1);
-    ASSERT_EQ(1, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
-
-    mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 0);
-    ASSERT_EQ(0, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
-}
-
-TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->addKey(DEVICE_ID, KEY_A, AKEYCODE_A, 0);
-
-    const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
-    uint8_t flags[2] = { 0, 0 };
-    ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 1, keyCodes, flags));
-    ASSERT_TRUE(flags[0]);
-    ASSERT_FALSE(flags[1]);
-}
-
-
-// --- TrackballInputMapperTest ---
-
-class TrackballInputMapperTest : public InputMapperTest {
-protected:
-    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
-
-    void testMotionRotation(TrackballInputMapper* mapper,
-            int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY);
-};
-
-const int32_t TrackballInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
-
-void TrackballInputMapperTest::testMotionRotation(TrackballInputMapper* mapper,
-        int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, originalX, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, originalY, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
-            float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD,
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(TrackballInputMapperTest, GetSources) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources());
-}
-
-TEST_F(TrackballInputMapperTest, PopulateDeviceInfo) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    InputDeviceInfo info;
-    mapper->populateDeviceInfo(&info);
-
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_X,
-            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_Y,
-            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
-}
-
-TEST_F(TrackballInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    // Button press.
-    // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(0, args.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(0, args.edgeFlags);
-    ASSERT_EQ(uint32_t(1), args.pointerCount);
-    ASSERT_EQ(0, args.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Button release.  Should have same down time.
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(0, args.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(0, args.edgeFlags);
-    ASSERT_EQ(uint32_t(1), args.pointerCount);
-    ASSERT_EQ(0, args.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-}
-
-TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    // Motion in X but not Y.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Motion in Y but not X.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NEAR(0.0f, args.pointerCoords[0].x, EPSILON);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    // Button press without following sync.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Button release without following sync.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(TrackballInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    // Combined X, Y and Button.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            1.0f / TRACKBALL_MOVEMENT_THRESHOLD, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
-            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Move X, Y a bit while pressed.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 2, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, 1, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
-            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Release Button.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeButtonUp) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    // Button press.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-
-    // Button release.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-
-    // Reset.  Should not synthesize button up since button is not pressed.
-    mapper->reset();
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    // Button press.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-
-    // Reset.  Should synthesize button up.
-    mapper->reset();
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(TrackballInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotateMotions) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
-}
-
-TEST_F(TrackballInputMapperTest, Process_WhenAttachedToDisplay_ShouldRotateMotions) {
-    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, DISPLAY_ID);
-    addMapperAndConfigure(mapper);
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_0);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_90);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1,  1));
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_180);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1, -1));
-
-    mFakePolicy->setDisplayInfo(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            InputReaderPolicyInterface::ROTATION_270);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1, -1));
-}
-
-
-// --- TouchInputMapperTest ---
-
-class TouchInputMapperTest : public InputMapperTest {
-protected:
-    static const int32_t RAW_X_MIN;
-    static const int32_t RAW_X_MAX;
-    static const int32_t RAW_Y_MIN;
-    static const int32_t RAW_Y_MAX;
-    static const int32_t RAW_TOUCH_MIN;
-    static const int32_t RAW_TOUCH_MAX;
-    static const int32_t RAW_TOOL_MIN;
-    static const int32_t RAW_TOOL_MAX;
-    static const int32_t RAW_PRESSURE_MIN;
-    static const int32_t RAW_PRESSURE_MAX;
-    static const int32_t RAW_ORIENTATION_MIN;
-    static const int32_t RAW_ORIENTATION_MAX;
-    static const int32_t RAW_ID_MIN;
-    static const int32_t RAW_ID_MAX;
-    static const float X_PRECISION;
-    static const float Y_PRECISION;
-
-    static const VirtualKeyDefinition VIRTUAL_KEYS[2];
-
-    enum Axes {
-        POSITION = 1 << 0,
-        TOUCH = 1 << 1,
-        TOOL = 1 << 2,
-        PRESSURE = 1 << 3,
-        ORIENTATION = 1 << 4,
-        MINOR = 1 << 5,
-        ID = 1 << 6,
-    };
-
-    void prepareDisplay(int32_t orientation);
-    void prepareVirtualKeys();
-    int32_t toRawX(float displayX);
-    int32_t toRawY(float displayY);
-    float toDisplayX(int32_t rawX);
-    float toDisplayY(int32_t rawY);
-};
-
-const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
-const int32_t TouchInputMapperTest::RAW_X_MAX = 1020;
-const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
-const int32_t TouchInputMapperTest::RAW_Y_MAX = 1010;
-const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
-const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
-const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = RAW_TOUCH_MIN;
-const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = RAW_TOUCH_MAX;
-const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
-const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
-const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
-const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN) / DISPLAY_WIDTH;
-const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN) / DISPLAY_HEIGHT;
-
-const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
-        { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
-        { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
-};
-
-void TouchInputMapperTest::prepareDisplay(int32_t orientation) {
-    mFakePolicy->setDisplayInfo(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation);
-}
-
-void TouchInputMapperTest::prepareVirtualKeys() {
-    mFakePolicy->addVirtualKeyDefinition(String8(DEVICE_NAME), VIRTUAL_KEYS[0]);
-    mFakePolicy->addVirtualKeyDefinition(String8(DEVICE_NAME), VIRTUAL_KEYS[1]);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, AKEYCODE_HOME, POLICY_FLAG_WAKE);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, AKEYCODE_MENU, POLICY_FLAG_WAKE);
-}
-
-int32_t TouchInputMapperTest::toRawX(float displayX) {
-    return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN) / DISPLAY_WIDTH + RAW_X_MIN);
-}
-
-int32_t TouchInputMapperTest::toRawY(float displayY) {
-    return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN) / DISPLAY_HEIGHT + RAW_Y_MIN);
-}
-
-float TouchInputMapperTest::toDisplayX(int32_t rawX) {
-    return float(rawX - RAW_X_MIN) * DISPLAY_WIDTH / (RAW_X_MAX - RAW_X_MIN);
-}
-
-float TouchInputMapperTest::toDisplayY(int32_t rawY) {
-    return float(rawY - RAW_Y_MIN) * DISPLAY_HEIGHT / (RAW_Y_MAX - RAW_Y_MIN);
-}
-
-
-// --- SingleTouchInputMapperTest ---
-
-class SingleTouchInputMapperTest : public TouchInputMapperTest {
-protected:
-    void prepareAxes(int axes);
-
-    void processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
-    void processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
-    void processUp(SingleTouchInputMapper* mappery);
-    void processPressure(SingleTouchInputMapper* mapper, int32_t pressure);
-    void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor);
-    void processSync(SingleTouchInputMapper* mapper);
-};
-
-void SingleTouchInputMapperTest::prepareAxes(int axes) {
-    if (axes & POSITION) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
-    }
-    if (axes & PRESSURE) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_PRESSURE, RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
-    }
-    if (axes & TOOL) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
-    }
-}
-
-void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0, 1, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, 0, x, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, 0, y, 0);
-}
-
-void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, 0, x, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, 0, y, 0);
-}
-
-void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0, 0, 0);
-}
-
-void SingleTouchInputMapperTest::processPressure(
-        SingleTouchInputMapper* mapper, int32_t pressure) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_PRESSURE, 0, pressure, 0);
-}
-
-void SingleTouchInputMapperTest::processToolMajor(
-        SingleTouchInputMapper* mapper, int32_t toolMajor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, 0, toolMajor, 0);
-}
-
-void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
-}
-
-
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenNotAttachedToADisplay_ReturnsTouchPad) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, -1);
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
-}
-
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenAttachedToADisplay_ReturnsTouchScreen) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources());
-}
-
-TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    // Unknown key.
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
-
-    // Virtual key is down.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
-
-    // Virtual key is up.
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
-}
-
-TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    // Unknown key.
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
-
-    // Virtual key is down.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
-
-    // Virtual key is up.
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
-}
-
-TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    const int32_t keys[2] = { AKEYCODE_HOME, AKEYCODE_A };
-    uint8_t flags[2] = { 0, 0 };
-    ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 2, keys, flags));
-    ASSERT_TRUE(flags[0]);
-    ASSERT_FALSE(flags[1]);
-}
-
-TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) {
-    // Note: Ideally we should send cancels but the implementation is more straightforward
-    // with up and this will only happen if a device is forcibly removed.
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    // Press virtual key.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    // Reset.  Since key is down, synthesize key up.
-    mapper->reset();
-
-    FakeInputDispatcher::NotifyKeyArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    //ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-}
-
-TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    // Press virtual key.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    // Release virtual key.
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
-
-    // Reset.  Since no key is down, nothing happens.
-    mapper->reset();
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    FakeInputDispatcher::NotifyKeyArgs args;
-
-    // Press virtual key.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Release virtual key.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Should not have sent any motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    FakeInputDispatcher::NotifyKeyArgs keyArgs;
-
-    // Press virtual key.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
-    ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
-    ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
-
-    // Move out of bounds.  This should generate a cancel and a pointer down since we moved
-    // into the display area.
-    y -= 100;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
-            | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
-    ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
-    ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
-
-    FakeInputDispatcher::NotifyMotionArgs motionArgs;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Keep moving out of bounds.  Should generate a pointer move.
-    y -= 50;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Release out of bounds.  Should generate a pointer up.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    FakeInputDispatcher::NotifyMotionArgs motionArgs;
-
-    // Initially go down out of bounds.
-    int32_t x = -10;
-    int32_t y = -10;
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-
-    // Move into the display area.  Should generate a pointer down.
-    x = 50;
-    y = 75;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Release.  Should generate a pointer up.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    FakeInputDispatcher::NotifyMotionArgs motionArgs;
-
-    // Down.
-    int32_t x = 100;
-    int32_t y = 125;
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Move.
-    x += 50;
-    y += 75;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Up.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_Rotation) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-
-    // Rotation 0.
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    processDown(mapper, toRawX(50), toRawY(75));
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(50, args.pointerCoords[0].x, 1);
-    ASSERT_NEAR(75, args.pointerCoords[0].y, 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
-
-    // Rotation 90.
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_90);
-    processDown(mapper, toRawX(50), toRawY(75));
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(75, args.pointerCoords[0].x, 1);
-    ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].y, 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
-
-    // Rotation 180.
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_180);
-    processDown(mapper, toRawX(50), toRawY(75));
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].x, 1);
-    ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].y, 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
-
-    // Rotation 270.
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_270);
-    processDown(mapper, toRawX(50), toRawY(75));
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].x, 1);
-    ASSERT_NEAR(50, args.pointerCoords[0].y, 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION | PRESSURE | TOOL);
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawPressure = 10;
-    int32_t rawToolMajor = 12;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
-    float size = float(rawToolMajor) / RAW_TOOL_MAX;
-    float tool = min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * size;
-    float touch = min(tool * pressure, tool);
-
-    processDown(mapper, rawX, rawY);
-    processPressure(mapper, rawPressure);
-    processToolMajor(mapper, rawToolMajor);
-    processSync(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, size, touch, touch, tool, tool, 0));
-}
-
-
-// --- MultiTouchInputMapperTest ---
-
-class MultiTouchInputMapperTest : public TouchInputMapperTest {
-protected:
-    void prepareAxes(int axes);
-
-    void processPosition(MultiTouchInputMapper* mapper, int32_t x, int32_t y);
-    void processTouchMajor(MultiTouchInputMapper* mapper, int32_t touchMajor);
-    void processTouchMinor(MultiTouchInputMapper* mapper, int32_t touchMinor);
-    void processToolMajor(MultiTouchInputMapper* mapper, int32_t toolMajor);
-    void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor);
-    void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation);
-    void processPressure(MultiTouchInputMapper* mapper, int32_t pressure);
-    void processId(MultiTouchInputMapper* mapper, int32_t id);
-    void processMTSync(MultiTouchInputMapper* mapper);
-    void processSync(MultiTouchInputMapper* mapper);
-};
-
-void MultiTouchInputMapperTest::prepareAxes(int axes) {
-    if (axes & POSITION) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
-    }
-    if (axes & TOUCH) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
-        if (axes & MINOR) {
-            mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
-                    RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
-        }
-    }
-    if (axes & TOOL) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
-        if (axes & MINOR) {
-            mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
-                    RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
-        }
-    }
-    if (axes & ORIENTATION) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_ORIENTATION,
-                RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
-    }
-    if (axes & PRESSURE) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_PRESSURE,
-                RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
-    }
-    if (axes & ID) {
-        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
-                RAW_ID_MIN, RAW_ID_MAX, 0, 0);
-    }
-}
-
-void MultiTouchInputMapperTest::processPosition(
-        MultiTouchInputMapper* mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_X, 0, x, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_Y, 0, y, 0);
-}
-
-void MultiTouchInputMapperTest::processTouchMajor(
-        MultiTouchInputMapper* mapper, int32_t touchMajor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MAJOR, 0, touchMajor, 0);
-}
-
-void MultiTouchInputMapperTest::processTouchMinor(
-        MultiTouchInputMapper* mapper, int32_t touchMinor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MINOR, 0, touchMinor, 0);
-}
-
-void MultiTouchInputMapperTest::processToolMajor(
-        MultiTouchInputMapper* mapper, int32_t toolMajor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MAJOR, 0, toolMajor, 0);
-}
-
-void MultiTouchInputMapperTest::processToolMinor(
-        MultiTouchInputMapper* mapper, int32_t toolMinor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MINOR, 0, toolMinor, 0);
-}
-
-void MultiTouchInputMapperTest::processOrientation(
-        MultiTouchInputMapper* mapper, int32_t orientation) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_ORIENTATION, 0, orientation, 0);
-}
-
-void MultiTouchInputMapperTest::processPressure(
-        MultiTouchInputMapper* mapper, int32_t pressure) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, 0, pressure, 0);
-}
-
-void MultiTouchInputMapperTest::processId(
-        MultiTouchInputMapper* mapper, int32_t id) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, 0, id, 0);
-}
-
-void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0, 0, 0);
-}
-
-void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
-}
-
-
-TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    FakeInputDispatcher::NotifyMotionArgs motionArgs;
-
-    // Two fingers down at once.
-    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
-    processPosition(mapper, x1, y1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_EQ(1, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Move.
-    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
-    processPosition(mapper, x1, y1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_EQ(1, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // First finger up.
-    x2 += 15; y2 -= 20;
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_EQ(1, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Move.
-    x2 += 20; y2 -= 25;
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // New finger down.
-    int32_t x3 = 700, y3 = 300;
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processPosition(mapper, x3, y3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_EQ(1, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Second finger up.
-    x3 += 30; y3 -= 20;
-    processPosition(mapper, x3, y3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_EQ(1, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Last finger up.
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION | ID);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    FakeInputDispatcher::NotifyMotionArgs motionArgs;
-
-    // Two fingers down at once.
-    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
-    processPosition(mapper, x1, y1);
-    processId(mapper, 1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerIds[0]);
-    ASSERT_EQ(2, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-
-    // Move.
-    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
-    processPosition(mapper, x1, y1);
-    processId(mapper, 1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerIds[0]);
-    ASSERT_EQ(2, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-
-    // First finger up.
-    x2 += 15; y2 -= 20;
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerIds[0]);
-    ASSERT_EQ(2, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(2, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-
-    // Move.
-    x2 += 20; y2 -= 25;
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(2, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-
-    // New finger down.
-    int32_t x3 = 700, y3 = 300;
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processPosition(mapper, x3, y3);
-    processId(mapper, 3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(2, motionArgs.pointerIds[0]);
-    ASSERT_EQ(3, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-
-    // Second finger up.
-    x3 += 30; y3 -= 20;
-    processPosition(mapper, x3, y3);
-    processId(mapper, 3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(2, motionArgs.pointerIds[0]);
-    ASSERT_EQ(3, motionArgs.pointerIds[1]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(3, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-
-    // Last finger up.
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(3, motionArgs.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR);
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawTouchMajor = 7;
-    int32_t rawTouchMinor = 6;
-    int32_t rawToolMajor = 9;
-    int32_t rawToolMinor = 8;
-    int32_t rawPressure = 11;
-    int32_t rawOrientation = 3;
-    int32_t id = 5;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
-    float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX;
-    float toolMajor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMajor / RAW_TOOL_MAX;
-    float toolMinor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMinor / RAW_TOOL_MAX;
-    float touchMajor = min(toolMajor * pressure, toolMajor);
-    float touchMinor = min(toolMinor * pressure, toolMinor);
-    float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processTouchMinor(mapper, rawTouchMinor);
-    processToolMajor(mapper, rawToolMajor);
-    processToolMinor(mapper, rawToolMinor);
-    processPressure(mapper, rawPressure);
-    processOrientation(mapper, rawOrientation);
-    processId(mapper, id);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(id, args.pointerIds[0]);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL | MINOR);
-    prepareCalibration("touch.touchSize.calibration", "geometric");
-    prepareCalibration("touch.toolSize.calibration", "geometric");
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawTouchMajor = 140;
-    int32_t rawTouchMinor = 120;
-    int32_t rawToolMajor = 180;
-    int32_t rawToolMinor = 160;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float pressure = float(rawTouchMajor) / RAW_TOUCH_MAX;
-    float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX;
-    float scale = avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN),
-            float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN));
-    float toolMajor = float(rawToolMajor) * scale;
-    float toolMinor = float(rawToolMinor) * scale;
-    float touchMajor = min(float(rawTouchMajor) * scale, toolMajor);
-    float touchMinor = min(float(rawTouchMinor) * scale, toolMinor);
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processTouchMinor(mapper, rawTouchMinor);
-    processToolMajor(mapper, rawToolMajor);
-    processToolMinor(mapper, rawToolMinor);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL);
-    prepareCalibration("touch.touchSize.calibration", "pressure");
-    prepareCalibration("touch.toolSize.calibration", "linear");
-    prepareCalibration("touch.toolSize.linearScale", "10");
-    prepareCalibration("touch.toolSize.linearBias", "160");
-    prepareCalibration("touch.toolSize.isSummed", "1");
-    prepareCalibration("touch.pressure.calibration", "amplitude");
-    prepareCalibration("touch.pressure.source", "touch");
-    prepareCalibration("touch.pressure.scale", "0.01");
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    // Note: We only provide a single common touch/tool value because the device is assumed
-    //       not to emit separate values for each pointer (isSummed = 1).
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawX2 = 150;
-    int32_t rawY2 = 250;
-    int32_t rawTouchMajor = 60;
-    int32_t rawToolMajor = 5;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float x2 = toDisplayX(rawX2);
-    float y2 = toDisplayY(rawY2);
-    float pressure = float(rawTouchMajor) * 0.01f;
-    float size = float(rawToolMajor) / RAW_TOOL_MAX;
-    float tool = (float(rawToolMajor) * 10.0f + 160.0f) / 2;
-    float touch = min(tool * pressure, tool);
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processToolMajor(mapper, rawToolMajor);
-    processMTSync(mapper);
-    processPosition(mapper, rawX2, rawY2);
-    processTouchMajor(mapper, rawTouchMajor);
-    processToolMajor(mapper, rawToolMajor);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            args.action);
-    ASSERT_EQ(size_t(2), args.pointerCount);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, size, touch, touch, tool, tool, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
-            x2, y2, pressure, size, touch, touch, tool, tool, 0));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
-    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL);
-    prepareCalibration("touch.touchSize.calibration", "pressure");
-    prepareCalibration("touch.toolSize.calibration", "area");
-    prepareCalibration("touch.toolSize.areaScale", "22");
-    prepareCalibration("touch.toolSize.areaBias", "1");
-    prepareCalibration("touch.toolSize.linearScale", "9.2");
-    prepareCalibration("touch.toolSize.linearBias", "3");
-    prepareCalibration("touch.pressure.calibration", "amplitude");
-    prepareCalibration("touch.pressure.source", "touch");
-    prepareCalibration("touch.pressure.scale", "0.01");
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawTouchMajor = 60;
-    int32_t rawToolMajor = 5;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float pressure = float(rawTouchMajor) * 0.01f;
-    float size = float(rawToolMajor) / RAW_TOOL_MAX;
-    float tool = sqrtf(float(rawToolMajor) * 22.0f + 1.0f) * 9.2f + 3.0f;
-    float touch = min(tool * pressure, tool);
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processToolMajor(mapper, rawToolMajor);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    FakeInputDispatcher::NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, size, touch, touch, tool, tool, 0));
-}
-
-} // namespace android
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index eb75ed8..e8d40ba 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -28,6 +28,7 @@
 	Flattenable.cpp \
 	ObbFile.cpp \
 	Pool.cpp \
+	PropertyMap.cpp \
 	RefBase.cpp \
 	ResourceTypes.cpp \
 	SharedBuffer.cpp \
@@ -41,6 +42,8 @@
 	TextOutput.cpp \
 	Threads.cpp \
 	Timers.cpp \
+	Tokenizer.cpp \
+	Unicode.cpp \
 	VectorImpl.cpp \
 	ZipFileCRO.cpp \
 	ZipFileRO.cpp \
@@ -67,11 +70,6 @@
 endif
 endif
 
-ifeq ($(HOST_OS),darwin)
-# MacOS doesn't have lseek64. However, off_t is 64-bit anyway.
-LOCAL_CFLAGS += -DOFF_T_IS_64_BIT
-endif
-
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
index cef7db4..a18294b 100644
--- a/libs/utils/Asset.cpp
+++ b/libs/utils/Asset.cpp
@@ -35,6 +35,9 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <assert.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 using namespace android;
 
@@ -62,7 +65,7 @@
         if (cur->isAllocated()) {
             res.append("    ");
             res.append(cur->getAssetSource());
-            off_t size = (cur->getLength()+512)/1024;
+            off64_t size = (cur->getLength()+512)/1024;
             char buf[64];
             sprintf(buf, ": %dK\n", (int)size);
             res.append(buf);
@@ -119,7 +122,7 @@
 {
     _FileAsset* pAsset;
     status_t result;
-    off_t length;
+    off64_t length;
     int fd;
 
     fd = open(fileName, O_RDONLY | O_BINARY);
@@ -132,12 +135,26 @@
      * always open things read-only it doesn't really matter, so there's
      * no value in incurring the extra overhead of an fstat() call.
      */
-    length = lseek(fd, 0, SEEK_END);
+    // TODO(kroot): replace this with fstat despite the plea above.
+#if 1
+    length = lseek64(fd, 0, SEEK_END);
     if (length < 0) {
         ::close(fd);
         return NULL;
     }
-    (void) lseek(fd, 0, SEEK_SET);
+    (void) lseek64(fd, 0, SEEK_SET);
+#else
+    struct stat st;
+    if (fstat(fd, &st) < 0) {
+        ::close(fd);
+        return NULL;
+    }
+
+    if (!S_ISREG(st.st_mode)) {
+        ::close(fd);
+        return NULL;
+    }
+#endif
 
     pAsset = new _FileAsset;
     result = pAsset->openChunk(fileName, fd, 0, length);
@@ -162,7 +179,7 @@
 {
     _CompressedAsset* pAsset;
     status_t result;
-    off_t fileLen;
+    off64_t fileLen;
     bool scanResult;
     long offset;
     int method;
@@ -215,7 +232,7 @@
 /*
  * Create a new Asset from part of an open file.
  */
-/*static*/ Asset* Asset::createFromFileSegment(int fd, off_t offset,
+/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset,
     size_t length, AccessMode mode)
 {
     _FileAsset* pAsset;
@@ -233,7 +250,7 @@
 /*
  * Create a new Asset from compressed data in an open file.
  */
-/*static*/ Asset* Asset::createFromCompressedData(int fd, off_t offset,
+/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset,
     int compressionMethod, size_t uncompressedLen, size_t compressedLen,
     AccessMode mode)
 {
@@ -295,9 +312,9 @@
  *
  * Returns the new chunk offset, or -1 if the seek is illegal.
  */
-off_t Asset::handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn)
+off64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn)
 {
-    off_t newOffset;
+    off64_t newOffset;
 
     switch (whence) {
     case SEEK_SET:
@@ -311,15 +328,15 @@
         break;
     default:
         LOGW("unexpected whence %d\n", whence);
-        // this was happening due to an off_t size mismatch
+        // this was happening due to an off64_t size mismatch
         assert(false);
-        return (off_t) -1;
+        return (off64_t) -1;
     }
 
     if (newOffset < 0 || newOffset > maxPosn) {
         LOGW("seek out of range: want %ld, end=%ld\n",
             (long) newOffset, (long) maxPosn);
-        return (off_t) -1;
+        return (off64_t) -1;
     }
 
     return newOffset;
@@ -353,7 +370,7 @@
  *
  * Zero-length chunks are allowed.
  */
-status_t _FileAsset::openChunk(const char* fileName, int fd, off_t offset, size_t length)
+status_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length)
 {
     assert(mFp == NULL);    // no reopen
     assert(mMap == NULL);
@@ -363,15 +380,15 @@
     /*
      * Seek to end to get file length.
      */
-    off_t fileLength;
-    fileLength = lseek(fd, 0, SEEK_END);
-    if (fileLength == (off_t) -1) {
+    off64_t fileLength;
+    fileLength = lseek64(fd, 0, SEEK_END);
+    if (fileLength == (off64_t) -1) {
         // probably a bad file descriptor
         LOGD("failed lseek (errno=%d)\n", errno);
         return UNKNOWN_ERROR;
     }
 
-    if ((off_t) (offset + length) > fileLength) {
+    if ((off64_t) (offset + length) > fileLength) {
         LOGD("start (%ld) + len (%ld) > end (%ld)\n",
             (long) offset, (long) length, (long) fileLength);
         return BAD_INDEX;
@@ -482,21 +499,21 @@
 /*
  * Seek to a new position.
  */
-off_t _FileAsset::seek(off_t offset, int whence)
+off64_t _FileAsset::seek(off64_t offset, int whence)
 {
-    off_t newPosn;
-    long actualOffset;
+    off64_t newPosn;
+    off64_t actualOffset;
 
     // compute new position within chunk
     newPosn = handleSeek(offset, whence, mOffset, mLength);
-    if (newPosn == (off_t) -1)
+    if (newPosn == (off64_t) -1)
         return newPosn;
 
-    actualOffset = (long) (mStart + newPosn);
+    actualOffset = mStart + newPosn;
 
     if (mFp != NULL) {
         if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
-            return (off_t) -1;
+            return (off64_t) -1;
     }
 
     mOffset = actualOffset - mStart;
@@ -603,7 +620,7 @@
     }
 }
 
-int _FileAsset::openFileDescriptor(off_t* outStart, off_t* outLength) const
+int _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const
 {
     if (mMap != NULL) {
         const char* fname = mMap->getFileName();
@@ -678,7 +695,7 @@
  * This currently just sets up some values and returns.  On the first
  * read, we expand the entire file into a buffer and return data from it.
  */
-status_t _CompressedAsset::openChunk(int fd, off_t offset,
+status_t _CompressedAsset::openChunk(int fd, off64_t offset,
     int compressionMethod, size_t uncompressedLen, size_t compressedLen)
 {
     assert(mFd < 0);        // no re-open
@@ -782,13 +799,13 @@
  * expensive, because it requires plowing through a bunch of compressed
  * data.
  */
-off_t _CompressedAsset::seek(off_t offset, int whence)
+off64_t _CompressedAsset::seek(off64_t offset, int whence)
 {
-    off_t newPosn;
+    off64_t newPosn;
 
     // compute new position within chunk
     newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
-    if (newPosn == (off_t) -1)
+    if (newPosn == (off64_t) -1)
         return newPosn;
 
     if (mZipInflater) {
diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp
index e1ba9b2..c220a90 100644
--- a/libs/utils/FileMap.cpp
+++ b/libs/utils/FileMap.cpp
@@ -63,16 +63,18 @@
         free(mFileName);
     }
 #ifdef HAVE_POSIX_FILEMAP    
-    if (munmap(mBasePtr, mBaseLength) != 0) {
+    if (mBasePtr && munmap(mBasePtr, mBaseLength) != 0) {
         LOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength);
     }
 #endif
 #ifdef HAVE_WIN32_FILEMAP
-    if ( UnmapViewOfFile(mBasePtr) == 0) {
+    if (mBasePtr && UnmapViewOfFile(mBasePtr) == 0) {
         LOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr, 
               GetLastError() );
     }
-    CloseHandle(mFileMapping);
+    if (mFileMapping != INVALID_HANDLE_VALUE) {
+        CloseHandle(mFileMapping);
+    }
     CloseHandle(mFileHandle);
 #endif
 }
@@ -86,11 +88,12 @@
  *
  * Returns "false" on failure.
  */
-bool FileMap::create(const char* origFileName, int fd, off_t offset, size_t length, bool readOnly)
+bool FileMap::create(const char* origFileName, int fd, off64_t offset, size_t length,
+        bool readOnly)
 {
 #ifdef HAVE_WIN32_FILEMAP
     int     adjust;
-    off_t   adjOffset;
+    off64_t adjOffset;
     size_t  adjLength;
 
     if (mPageSize == -1) {
@@ -129,7 +132,7 @@
 #endif
 #ifdef HAVE_POSIX_FILEMAP
     int     prot, flags, adjust;
-    off_t   adjOffset;
+    off64_t adjOffset;
     size_t  adjLength;
 
     void* ptr;
diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp
index a5363d6..18f858b 100644
--- a/libs/utils/Looper.cpp
+++ b/libs/utils/Looper.cpp
@@ -19,10 +19,27 @@
 
 #include <unistd.h>
 #include <fcntl.h>
+#include <limits.h>
 
 
 namespace android {
 
+// --- WeakMessageHandler ---
+
+WeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) :
+        mHandler(handler) {
+}
+
+void WeakMessageHandler::handleMessage(const Message& message) {
+    sp<MessageHandler> handler = mHandler.promote();
+    if (handler != NULL) {
+        handler->handleMessage(message);
+    }
+}
+
+
+// --- Looper ---
+
 #ifdef LOOPER_USES_EPOLL
 // Hint for number of file descriptors to be associated with the epoll instance.
 static const int EPOLL_SIZE_HINT = 8;
@@ -35,8 +52,8 @@
 static pthread_key_t gTLSKey = 0;
 
 Looper::Looper(bool allowNonCallbacks) :
-        mAllowNonCallbacks(allowNonCallbacks),
-        mResponseIndex(0) {
+        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
+        mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
     int wakeFds[2];
     int result = pipe(wakeFds);
     LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
@@ -161,17 +178,21 @@
     for (;;) {
         while (mResponseIndex < mResponses.size()) {
             const Response& response = mResponses.itemAt(mResponseIndex++);
-            if (! response.request.callback) {
+            ALooper_callbackFunc callback = response.request.callback;
+            if (!callback) {
+                int ident = response.request.ident;
+                int fd = response.request.fd;
+                int events = response.events;
+                void* data = response.request.data;
 #if DEBUG_POLL_AND_WAKE
                 LOGD("%p ~ pollOnce - returning signalled identifier %d: "
-                        "fd=%d, events=0x%x, data=%p", this,
-                        response.request.ident, response.request.fd,
-                        response.events, response.request.data);
+                        "fd=%d, events=0x%x, data=%p",
+                        this, ident, fd, events, data);
 #endif
-                if (outFd != NULL) *outFd = response.request.fd;
-                if (outEvents != NULL) *outEvents = response.events;
-                if (outData != NULL) *outData = response.request.data;
-                return response.request.ident;
+                if (outFd != NULL) *outFd = fd;
+                if (outEvents != NULL) *outEvents = events;
+                if (outData != NULL) *outData = data;
+                return ident;
             }
         }
 
@@ -194,6 +215,25 @@
     LOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
 #endif
 
+    // Adjust the timeout based on when the next message is due.
+    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
+        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+        if (mNextMessageUptime <= now) {
+            timeoutMillis = 0;
+        } else {
+            uint64_t delay = (mNextMessageUptime - now + 999999LL) / 1000000LL;
+            if (delay < INT_MAX
+                    && (timeoutMillis < 0 || int(delay) < timeoutMillis)) {
+                timeoutMillis = int(delay);
+            }
+        }
+#if DEBUG_POLL_AND_WAKE
+        LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
+                this, mNextMessageUptime - now, timeoutMillis);
+#endif
+    }
+
+    // Poll.
     int result = ALOOPER_POLL_WAKE;
     mResponses.clear();
     mResponseIndex = 0;
@@ -205,7 +245,6 @@
 #ifdef LOOPER_USES_EPOLL
     struct epoll_event eventItems[EPOLL_MAX_EVENTS];
     int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
-    bool acquiredLock = false;
 #else
     // Wait for wakeAndLock() waiters to run then set mPolling to true.
     mLock.lock();
@@ -219,16 +258,20 @@
     int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis);
 #endif
 
+    // Acquire lock.
+    mLock.lock();
+
+    // Check for poll error.
     if (eventCount < 0) {
         if (errno == EINTR) {
             goto Done;
         }
-
         LOGW("Poll failed with an unexpected error, errno=%d", errno);
         result = ALOOPER_POLL_ERROR;
         goto Done;
     }
 
+    // Check for poll timeout.
     if (eventCount == 0) {
 #if DEBUG_POLL_AND_WAKE
         LOGD("%p ~ pollOnce - timeout", this);
@@ -237,6 +280,7 @@
         goto Done;
     }
 
+    // Handle all events.
 #if DEBUG_POLL_AND_WAKE
     LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
 #endif
@@ -252,11 +296,6 @@
                 LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
             }
         } else {
-            if (! acquiredLock) {
-                mLock.lock();
-                acquiredLock = true;
-            }
-
             ssize_t requestIndex = mRequests.indexOfKey(fd);
             if (requestIndex >= 0) {
                 int events = 0;
@@ -271,9 +310,6 @@
             }
         }
     }
-    if (acquiredLock) {
-        mLock.unlock();
-    }
 Done: ;
 #else
     for (size_t i = 0; i < requestedCount; i++) {
@@ -301,15 +337,12 @@
             }
         }
     }
-
 Done:
     // Set mPolling to false and wake up the wakeAndLock() waiters.
-    mLock.lock();
     mPolling = false;
     if (mWaiters != 0) {
         mAwake.broadcast();
     }
-    mLock.unlock();
 #endif
 
 #ifdef LOOPER_STATISTICS
@@ -335,19 +368,59 @@
     }
 #endif
 
+    // Invoke pending message callbacks.
+    mNextMessageUptime = LLONG_MAX;
+    while (mMessageEnvelopes.size() != 0) {
+        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+        const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
+        if (messageEnvelope.uptime <= now) {
+            // Remove the envelope from the list.
+            // We keep a strong reference to the handler until the call to handleMessage
+            // finishes.  Then we drop it so that the handler can be deleted *before*
+            // we reacquire our lock.
+            { // obtain handler
+                sp<MessageHandler> handler = messageEnvelope.handler;
+                Message message = messageEnvelope.message;
+                mMessageEnvelopes.removeAt(0);
+                mSendingMessage = true;
+                mLock.unlock();
+
+#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
+                LOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
+                        this, handler.get(), message.what);
+#endif
+                handler->handleMessage(message);
+            } // release handler
+
+            mLock.lock();
+            mSendingMessage = false;
+            result = ALOOPER_POLL_CALLBACK;
+        } else {
+            // The last message left at the head of the queue determines the next wakeup time.
+            mNextMessageUptime = messageEnvelope.uptime;
+            break;
+        }
+    }
+
+    // Release lock.
+    mLock.unlock();
+
+    // Invoke all response callbacks.
     for (size_t i = 0; i < mResponses.size(); i++) {
         const Response& response = mResponses.itemAt(i);
-        if (response.request.callback) {
+        ALooper_callbackFunc callback = response.request.callback;
+        if (callback) {
+            int fd = response.request.fd;
+            int events = response.events;
+            void* data = response.request.data;
 #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
-            LOGD("%p ~ pollOnce - invoking callback: fd=%d, events=0x%x, data=%p", this,
-                    response.request.fd, response.events, response.request.data);
+            LOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
+                    this, callback, fd, events, data);
 #endif
-            int callbackResult = response.request.callback(
-                    response.request.fd, response.events, response.request.data);
+            int callbackResult = callback(fd, events, data);
             if (callbackResult == 0) {
-                removeFd(response.request.fd);
+                removeFd(fd);
             }
-
             result = ALOOPER_POLL_CALLBACK;
         }
     }
@@ -593,4 +666,83 @@
 }
 #endif
 
+void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
+    sendMessageAtTime(LLONG_MIN, handler, message);
+}
+
+void Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
+        const Message& message) {
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    sendMessageAtTime(now + uptimeDelay, handler, message);
+}
+
+void Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
+        const Message& message) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d",
+            this, uptime, handler.get(), message.what);
+#endif
+
+    size_t i = 0;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        size_t messageCount = mMessageEnvelopes.size();
+        while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {
+            i += 1;
+        }
+
+        MessageEnvelope messageEnvelope(uptime, handler, message);
+        mMessageEnvelopes.insertAt(messageEnvelope, i, 1);
+
+        // Optimization: If the Looper is currently sending a message, then we can skip
+        // the call to wake() because the next thing the Looper will do after processing
+        // messages is to decide when the next wakeup time should be.  In fact, it does
+        // not even matter whether this code is running on the Looper thread.
+        if (mSendingMessage) {
+            return;
+        }
+    } // release lock
+
+    // Wake the poll loop only when we enqueue a new message at the head.
+    if (i == 0) {
+        wake();
+    }
+}
+
+void Looper::removeMessages(const sp<MessageHandler>& handler) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ removeMessages - handler=%p", this, handler.get());
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
+            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
+            if (messageEnvelope.handler == handler) {
+                mMessageEnvelopes.removeAt(i);
+            }
+        }
+    } // release lock
+}
+
+void Looper::removeMessages(const sp<MessageHandler>& handler, int what) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what);
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
+            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
+            if (messageEnvelope.handler == handler
+                    && messageEnvelope.message.what == what) {
+                mMessageEnvelopes.removeAt(i);
+            }
+        }
+    } // release lock
+}
+
 } // namespace android
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
index 2c3724c..2907b56 100644
--- a/libs/utils/ObbFile.cpp
+++ b/libs/utils/ObbFile.cpp
@@ -22,6 +22,8 @@
 #include <unistd.h>
 
 #define LOG_TAG "ObbFile"
+
+#include <utils/Compat.h>
 #include <utils/Log.h>
 #include <utils/ObbFile.h>
 
@@ -67,17 +69,6 @@
     _rc; })
 #endif
 
-/*
- * Work around situations where off_t is 64-bit and use off64_t in
- * situations where it's 32-bit.
- */
-#ifdef OFF_T_IS_64_BIT
-#define my_lseek64 lseek
-typedef off_t my_off64_t;
-#else
-#define my_lseek64 lseek64
-typedef off64_t my_off64_t;
-#endif
 
 namespace android {
 
@@ -125,7 +116,7 @@
 
 bool ObbFile::parseObbFile(int fd)
 {
-    my_off64_t fileLength = my_lseek64(fd, 0, SEEK_END);
+    off64_t fileLength = lseek64(fd, 0, SEEK_END);
 
     if (fileLength < kFooterMinSize) {
         if (fileLength < 0) {
@@ -140,7 +131,7 @@
     size_t footerSize;
 
     {
-        my_lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
+        lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
 
         char *footer = new char[kFooterTagSize];
         actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
@@ -171,8 +162,8 @@
         }
     }
 
-    my_off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
-    if (my_lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
+    off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
+    if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
         LOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
         return false;
     }
@@ -211,10 +202,10 @@
 
     memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
 
-    uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
-    if (packageNameLen <= 0
+    size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
+    if (packageNameLen == 0
             || packageNameLen > (footerSize - kPackageNameOffset)) {
-        LOGW("bad ObbFile package name length (0x%04x; 0x%04x possible)\n",
+        LOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n",
                 packageNameLen, footerSize - kPackageNameOffset);
         free(scanBuf);
         return false;
@@ -257,7 +248,7 @@
         return false;
     }
 
-    my_lseek64(fd, 0, SEEK_END);
+    lseek64(fd, 0, SEEK_END);
 
     if (mPackageName.size() == 0 || mVersion == -1) {
         LOGW("tried to write uninitialized ObbFile data\n");
diff --git a/libs/utils/PropertyMap.cpp b/libs/utils/PropertyMap.cpp
new file mode 100644
index 0000000..d472d45
--- /dev/null
+++ b/libs/utils/PropertyMap.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#define LOG_TAG "PropertyMap"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <utils/PropertyMap.h>
+#include <utils/Log.h>
+
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+
+namespace android {
+
+static const char* WHITESPACE = " \t\r";
+static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r=";
+
+
+// --- PropertyMap ---
+
+PropertyMap::PropertyMap() {
+}
+
+PropertyMap::~PropertyMap() {
+}
+
+void PropertyMap::clear() {
+    mProperties.clear();
+}
+
+void PropertyMap::addProperty(const String8& key, const String8& value) {
+    mProperties.add(key, value);
+}
+
+bool PropertyMap::hasProperty(const String8& key) const {
+    return mProperties.indexOfKey(key) >= 0;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const {
+    ssize_t index = mProperties.indexOfKey(key);
+    if (index < 0) {
+        return false;
+    }
+
+    outValue = mProperties.valueAt(index);
+    return true;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const {
+    int32_t intValue;
+    if (!tryGetProperty(key, intValue)) {
+        return false;
+    }
+
+    outValue = intValue;
+    return true;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    int value = strtol(stringValue.string(), & end, 10);
+    if (*end != '\0') {
+        LOGW("Property key '%s' has invalid value '%s'.  Expected an integer.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    float value = strtof(stringValue.string(), & end);
+    if (*end != '\0') {
+        LOGW("Property key '%s' has invalid value '%s'.  Expected a float.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+void PropertyMap::addAll(const PropertyMap* map) {
+    for (size_t i = 0; i < map->mProperties.size(); i++) {
+        mProperties.add(map->mProperties.keyAt(i), map->mProperties.valueAt(i));
+    }
+}
+
+status_t PropertyMap::load(const String8& filename, PropertyMap** outMap) {
+    *outMap = NULL;
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::open(filename, &tokenizer);
+    if (status) {
+        LOGE("Error %d opening property file %s.", status, filename.string());
+    } else {
+        PropertyMap* map = new PropertyMap();
+        if (!map) {
+            LOGE("Error allocating property map.");
+            status = NO_MEMORY;
+        } else {
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+            Parser parser(map, tokenizer);
+            status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+            LOGD("Parsed property file '%s' %d lines in %0.3fms.",
+                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                    elapsedTime / 1000000.0);
+#endif
+            if (status) {
+                delete map;
+            } else {
+                *outMap = map;
+            }
+        }
+        delete tokenizer;
+    }
+    return status;
+}
+
+
+// --- PropertyMap::Parser ---
+
+PropertyMap::Parser::Parser(PropertyMap* map, Tokenizer* tokenizer) :
+        mMap(map), mTokenizer(tokenizer) {
+}
+
+PropertyMap::Parser::~Parser() {
+}
+
+status_t PropertyMap::Parser::parse() {
+    while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+        LOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+                mTokenizer->peekRemainderOfLine().string());
+#endif
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+
+        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+            String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
+            if (keyToken.isEmpty()) {
+                LOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+
+            mTokenizer->skipDelimiters(WHITESPACE);
+
+            if (mTokenizer->nextChar() != '=') {
+                LOGE("%s: Expected '=' between property key and value.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+
+            mTokenizer->skipDelimiters(WHITESPACE);
+
+            String8 valueToken = mTokenizer->nextToken(WHITESPACE);
+            if (valueToken.find("\\", 0) >= 0 || valueToken.find("\"", 0) >= 0) {
+                LOGE("%s: Found reserved character '\\' or '\"' in property value.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+
+            mTokenizer->skipDelimiters(WHITESPACE);
+            if (!mTokenizer->isEol()) {
+                LOGE("%s: Expected end of line, got '%s'.",
+                        mTokenizer->getLocation().string(),
+                        mTokenizer->peekRemainderOfLine().string());
+                return BAD_VALUE;
+            }
+
+            if (mMap->hasProperty(keyToken)) {
+                LOGE("%s: Duplicate property value for key '%s'.",
+                        mTokenizer->getLocation().string(), keyToken.string());
+                return BAD_VALUE;
+            }
+
+            mMap->addProperty(keyToken, valueToken);
+        }
+
+        mTokenizer->nextLine();
+    }
+    return NO_ERROR;
+}
+
+} // namespace android
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index 0bd1af4..bb6c125 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -20,9 +20,9 @@
 
 #include <utils/Atomic.h>
 #include <utils/CallStack.h>
-#include <utils/KeyedVector.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
+#include <utils/TextOutput.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -34,6 +34,7 @@
 
 // compile with refcounting debugging enabled
 #define DEBUG_REFS                      0
+#define DEBUG_REFS_FATAL_SANITY_CHECKS  0
 #define DEBUG_REFS_ENABLED_BY_DEFAULT   1
 #define DEBUG_REFS_CALLSTACK_ENABLED    1
 
@@ -69,8 +70,10 @@
 
     void addStrongRef(const void* /*id*/) { }
     void removeStrongRef(const void* /*id*/) { }
+    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
     void addWeakRef(const void* /*id*/) { }
     void removeWeakRef(const void* /*id*/) { }
+    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
     void printRefs() const { }
     void trackMe(bool, bool) { }
 
@@ -86,39 +89,91 @@
         , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
         , mRetain(false)
     {
-        //LOGI("NEW weakref_impl %p for RefBase %p", this, base);
     }
     
     ~weakref_impl()
     {
-        LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!");
-        LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!");
+        bool dumpStack = false;
+        if (!mRetain && mStrongRefs != NULL) {
+            dumpStack = true;
+#if DEBUG_REFS_FATAL_SANITY_CHECKS
+            LOG_ALWAYS_FATAL("Strong references remain!");
+#else
+            LOGE("Strong references remain:");
+#endif
+            ref_entry* refs = mStrongRefs;
+            while (refs) {
+                char inc = refs->ref >= 0 ? '+' : '-';
+                LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
+#if DEBUG_REFS_CALLSTACK_ENABLED
+                refs->stack.dump();
+#endif;
+                refs = refs->next;
+            }
+        }
+
+        if (!mRetain && mWeakRefs != NULL) {
+            dumpStack = true;
+#if DEBUG_REFS_FATAL_SANITY_CHECKS
+            LOG_ALWAYS_FATAL("Weak references remain:");
+#else
+            LOGE("Weak references remain!");
+#endif
+            ref_entry* refs = mWeakRefs;
+            while (refs) {
+                char inc = refs->ref >= 0 ? '+' : '-';
+                LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
+#if DEBUG_REFS_CALLSTACK_ENABLED
+                refs->stack.dump();
+#endif;
+                refs = refs->next;
+            }
+        }
+        if (dumpStack) {
+            LOGE("above errors at:");
+            CallStack stack;
+            stack.update();
+            stack.dump();
+        }
     }
 
-    void addStrongRef(const void* id)
-    {
+    void addStrongRef(const void* id) {
+        //LOGD_IF(mTrackEnabled,
+        //        "addStrongRef: RefBase=%p, id=%p", mBase, id);
         addRef(&mStrongRefs, id, mStrong);
     }
 
-    void removeStrongRef(const void* id)
-    {
-        if (!mRetain)
+    void removeStrongRef(const void* id) {
+        //LOGD_IF(mTrackEnabled,
+        //        "removeStrongRef: RefBase=%p, id=%p", mBase, id);
+        if (!mRetain) {
             removeRef(&mStrongRefs, id);
-        else
+        } else {
             addRef(&mStrongRefs, id, -mStrong);
+        }
     }
 
-    void addWeakRef(const void* id)
-    {
+    void renameStrongRefId(const void* old_id, const void* new_id) {
+        //LOGD_IF(mTrackEnabled,
+        //        "renameStrongRefId: RefBase=%p, oid=%p, nid=%p",
+        //        mBase, old_id, new_id);
+        renameRefsId(mStrongRefs, old_id, new_id);
+    }
+
+    void addWeakRef(const void* id) {
         addRef(&mWeakRefs, id, mWeak);
     }
 
-    void removeWeakRef(const void* id)
-    {
-        if (!mRetain)
+    void removeWeakRef(const void* id) {
+        if (!mRetain) {
             removeRef(&mWeakRefs, id);
-        else
+        } else {
             addRef(&mWeakRefs, id, -mWeak);
+        }
+    }
+
+    void renameWeakRefId(const void* old_id, const void* new_id) {
+        renameRefsId(mWeakRefs, old_id, new_id);
     }
 
     void trackMe(bool track, bool retain)
@@ -132,8 +187,7 @@
         String8 text;
 
         {
-            AutoMutex _l(const_cast<weakref_impl*>(this)->mMutex);
-    
+            Mutex::Autolock _l(const_cast<weakref_impl*>(this)->mMutex);
             char buf[128];
             sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
             text.append(buf);
@@ -172,6 +226,7 @@
     {
         if (mTrackEnabled) {
             AutoMutex _l(mMutex);
+
             ref_entry* ref = new ref_entry;
             // Reference count at the time of the snapshot, but before the
             // update.  Positive value means we increment, negative--we
@@ -181,7 +236,6 @@
 #if DEBUG_REFS_CALLSTACK_ENABLED
             ref->stack.update(2);
 #endif
-            
             ref->next = *refs;
             *refs = ref;
         }
@@ -192,20 +246,52 @@
         if (mTrackEnabled) {
             AutoMutex _l(mMutex);
             
-            ref_entry* ref = *refs;
+            ref_entry* const head = *refs;
+            ref_entry* ref = head;
             while (ref != NULL) {
                 if (ref->id == id) {
                     *refs = ref->next;
                     delete ref;
                     return;
                 }
-                
                 refs = &ref->next;
                 ref = *refs;
             }
-            
-            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",
-                             id, mBase, this);
+
+#if DEBUG_REFS_FATAL_SANITY_CHECKS
+            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p"
+                    "(weakref_type %p) that doesn't exist!",
+                    id, mBase, this);
+#endif
+
+            LOGE("RefBase: removing id %p on RefBase %p"
+                    "(weakref_type %p) that doesn't exist!",
+                    id, mBase, this);
+
+            ref = head;
+            while (ref) {
+                char inc = ref->ref >= 0 ? '+' : '-';
+                LOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
+                ref = ref->next;
+            }
+
+            CallStack stack;
+            stack.update();
+            stack.dump();
+        }
+    }
+
+    void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)
+    {
+        if (mTrackEnabled) {
+            AutoMutex _l(mMutex);
+            ref_entry* ref = r;
+            while (ref != NULL) {
+                if (ref->id == old_id) {
+                    ref->id = new_id;
+                }
+                ref = ref->next;
+            }
         }
     }
 
@@ -235,44 +321,6 @@
     // on removeref that match the address ones.
     bool mRetain;
 
-#if 0
-    void addRef(KeyedVector<const void*, int32_t>* refs, const void* id)
-    {
-        AutoMutex _l(mMutex);
-        ssize_t i = refs->indexOfKey(id);
-        if (i >= 0) {
-            ++(refs->editValueAt(i));
-        } else {
-            i = refs->add(id, 1);
-        }
-    }
-
-    void removeRef(KeyedVector<const void*, int32_t>* refs, const void* id)
-    {
-        AutoMutex _l(mMutex);
-        ssize_t i = refs->indexOfKey(id);
-        LOG_ALWAYS_FATAL_IF(i < 0, "RefBase: removing id %p that doesn't exist!", id);
-        if (i >= 0) {
-            int32_t val = --(refs->editValueAt(i));
-            if (val == 0) {
-                refs->removeItemsAt(i);
-            }
-        }
-    }
-
-    void printRefs(const KeyedVector<const void*, int32_t>& refs)
-    {
-        const size_t N=refs.size();
-        for (size_t i=0; i<N; i++) {
-            printf("\tID %p: %d remain\n", refs.keyAt(i), refs.valueAt(i));
-        }
-    }
-
-    mutable Mutex mMutex;
-    KeyedVector<const void*, int32_t> mStrongRefs;
-    KeyedVector<const void*, int32_t> mWeakRefs;
-#endif
-
 #endif
 };
 
@@ -281,7 +329,6 @@
 void RefBase::incStrong(const void* id) const
 {
     weakref_impl* const refs = mRefs;
-    refs->addWeakRef(id);
     refs->incWeak(id);
     
     refs->addStrongRef(id);
@@ -313,14 +360,12 @@
             delete this;
         }
     }
-    refs->removeWeakRef(id);
     refs->decWeak(id);
 }
 
 void RefBase::forceIncStrong(const void* id) const
 {
     weakref_impl* const refs = mRefs;
-    refs->addWeakRef(id);
     refs->incWeak(id);
     
     refs->addStrongRef(id);
@@ -372,7 +417,7 @@
         if (impl->mStrong == INITIAL_STRONG_VALUE)
             delete impl->mBase;
         else {
-//            LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
+            // LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
             delete impl;
         }
     } else {
@@ -432,7 +477,6 @@
         }
     }
     
-    impl->addWeakRef(id);
     impl->addStrongRef(id);
 
 #if PRINT_REFS
@@ -450,7 +494,7 @@
 bool RefBase::weakref_type::attemptIncWeak(const void* id)
 {
     weakref_impl* const impl = static_cast<weakref_impl*>(this);
-    
+
     int32_t curCount = impl->mWeak;
     LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
                this);
@@ -497,14 +541,11 @@
 RefBase::RefBase()
     : mRefs(new weakref_impl(this))
 {
-//    LOGV("Creating refs %p with RefBase %p\n", mRefs, this);
 }
 
 RefBase::~RefBase()
 {
-//    LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs);
     if (mRefs->mWeak == 0) {
-//        LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this);
         delete mRefs;
     }
 }
@@ -530,5 +571,37 @@
 void RefBase::onLastWeakRef(const void* /*id*/)
 {
 }
-        
+
+// ---------------------------------------------------------------------------
+
+void RefBase::moveReferences(void* dst, void const* src, size_t n,
+        const ReferenceConverterBase& caster)
+{
+#if DEBUG_REFS
+    const size_t itemSize = caster.getReferenceTypeSize();
+    for (size_t i=0 ; i<n ; i++) {
+        void*       d = reinterpret_cast<void      *>(intptr_t(dst) + i*itemSize);
+        void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize);
+        RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d)));
+        ref->mRefs->renameStrongRefId(s, d);
+        ref->mRefs->renameWeakRefId(s, d);
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+TextOutput& printStrongPointer(TextOutput& to, const void* val)
+{
+    to << "sp<>(" << val << ")";
+    return to;
+}
+
+TextOutput& printWeakPointer(TextOutput& to, const void* val)
+{
+    to << "wp<>(" << val << ")";
+    return to;
+}
+
+
 }; // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 7fb7ae3..7197ad7 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -317,6 +317,12 @@
             mStringPoolSize =
                 (mHeader->header.size-mHeader->stringsStart)/charSize;
         } else {
+            // check invariant: styles starts before end of data
+            if (mHeader->stylesStart >= (mHeader->header.size-sizeof(uint16_t))) {
+                LOGW("Bad style block: style block starts at %d past data size of %d\n",
+                    (int)mHeader->stylesStart, (int)mHeader->header.size);
+                return (mError=BAD_TYPE);
+            }
             // check invariant: styles follow the strings
             if (mHeader->stylesStart <= mHeader->stringsStart) {
                 LOGW("Bad style block: style block starts at %d, before strings at %d\n",
@@ -438,15 +444,51 @@
     }
 }
 
-#define DECODE_LENGTH(str, chrsz, len) \
-    len = *(str); \
-    if (*(str)&(1<<(chrsz*8-1))) { \
-        (str)++; \
-        len = (((len)&((1<<(chrsz*8-1))-1))<<(chrsz*8)) + *(str); \
-    } \
-    (str)++;
+/**
+ * Strings in UTF-16 format have length indicated by a length encoded in the
+ * stored data. It is either 1 or 2 characters of length data. This allows a
+ * maximum length of 0x7FFFFFF (2147483647 bytes), but if you're storing that
+ * much data in a string, you're abusing them.
+ *
+ * If the high bit is set, then there are two characters or 4 bytes of length
+ * data encoded. In that case, drop the high bit of the first character and
+ * add it together with the next character.
+ */
+static inline size_t
+decodeLength(const char16_t** str)
+{
+    size_t len = **str;
+    if ((len & 0x8000) != 0) {
+        (*str)++;
+        len = ((len & 0x7FFF) << 16) | **str;
+    }
+    (*str)++;
+    return len;
+}
 
-const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
+/**
+ * Strings in UTF-8 format have length indicated by a length encoded in the
+ * stored data. It is either 1 or 2 characters of length data. This allows a
+ * maximum length of 0x7FFF (32767 bytes), but you should consider storing
+ * text in another way if you're using that much data in a single string.
+ *
+ * If the high bit is set, then there are two characters or 2 bytes of length
+ * data encoded. In that case, drop the high bit of the first character and
+ * add it together with the next character.
+ */
+static inline size_t
+decodeLength(const uint8_t** str)
+{
+    size_t len = **str;
+    if ((len & 0x80) != 0) {
+        (*str)++;
+        len = ((len & 0x7F) << 8) | **str;
+    }
+    (*str)++;
+    return len;
+}
+
+const uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const
 {
     if (mError == NO_ERROR && idx < mHeader->stringCount) {
         const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
@@ -455,37 +497,51 @@
             if (!isUTF8) {
                 const char16_t* strings = (char16_t*)mStrings;
                 const char16_t* str = strings+off;
-                DECODE_LENGTH(str, sizeof(char16_t), *outLen)
-                if ((uint32_t)(str+*outLen-strings) < mStringPoolSize) {
+
+                *u16len = decodeLength(&str);
+                if ((uint32_t)(str+*u16len-strings) < mStringPoolSize) {
                     return str;
                 } else {
                     LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                            (int)idx, (int)(str+*outLen-strings), (int)mStringPoolSize);
+                            (int)idx, (int)(str+*u16len-strings), (int)mStringPoolSize);
                 }
             } else {
                 const uint8_t* strings = (uint8_t*)mStrings;
-                const uint8_t* str = strings+off;
-                DECODE_LENGTH(str, sizeof(uint8_t), *outLen)
-                size_t encLen;
-                DECODE_LENGTH(str, sizeof(uint8_t), encLen)
-                if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
+                const uint8_t* u8str = strings+off;
+
+                *u16len = decodeLength(&u8str);
+                size_t u8len = decodeLength(&u8str);
+
+                // encLen must be less than 0x7FFF due to encoding.
+                if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {
                     AutoMutex lock(mDecodeLock);
+
                     if (mCache[idx] != NULL) {
                         return mCache[idx];
                     }
-                    char16_t *u16str = (char16_t *)calloc(*outLen+1, sizeof(char16_t));
+
+                    ssize_t actualLen = utf8_to_utf16_length(u8str, u8len);
+                    if (actualLen < 0 || (size_t)actualLen != *u16len) {
+                        LOGW("Bad string block: string #%lld decoded length is not correct "
+                                "%lld vs %llu\n",
+                                (long long)idx, (long long)actualLen, (long long)*u16len);
+                        return NULL;
+                    }
+
+                    char16_t *u16str = (char16_t *)calloc(*u16len+1, sizeof(char16_t));
                     if (!u16str) {
                         LOGW("No memory when trying to allocate decode cache for string #%d\n",
                                 (int)idx);
                         return NULL;
                     }
-                    const unsigned char *u8src = reinterpret_cast<const unsigned char *>(str);
-                    utf8_to_utf16(u8src, encLen, u16str, *outLen);
+
+                    utf8_to_utf16(u8str, u8len, u16str);
                     mCache[idx] = u16str;
                     return u16str;
                 } else {
-                    LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                            (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
+                    LOGW("Bad string block: string #%lld extends to %lld, past end at %lld\n",
+                            (long long)idx, (long long)(u8str+u8len-strings),
+                            (long long)mStringPoolSize);
                 }
             }
         } else {
@@ -506,9 +562,8 @@
             if (isUTF8) {
                 const uint8_t* strings = (uint8_t*)mStrings;
                 const uint8_t* str = strings+off;
-                DECODE_LENGTH(str, sizeof(uint8_t), *outLen)
-                size_t encLen;
-                DECODE_LENGTH(str, sizeof(uint8_t), encLen)
+                *outLen = decodeLength(&str);
+                size_t encLen = decodeLength(&str);
                 if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
                     return (const char*)str;
                 } else {
@@ -1878,13 +1933,19 @@
         outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen);
         outName->name = grp->basePackage->keyStrings.stringAt(
             dtohl(entry->key.index), &outName->nameLen);
+
+        // If we have a bad index for some reason, we should abort.
+        if (outName->type == NULL || outName->name == NULL) {
+            return false;
+        }
+
         return true;
     }
 
     return false;
 }
 
-ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag,
+ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag, uint16_t density,
         uint32_t* outSpecFlags, ResTable_config* outConfig) const
 {
     if (mError != NO_ERROR) {
@@ -1914,7 +1975,7 @@
     memset(&bestItem, 0, sizeof(bestItem)); // make the compiler shut up
 
     if (outSpecFlags != NULL) *outSpecFlags = 0;
-    
+
     // Look through all resource packages, starting with the most
     // recently added.
     const PackageGroup* const grp = mPackageGroups[p];
@@ -1922,6 +1983,22 @@
         LOGW("Bad identifier when getting value for resource number 0x%08x", resID);
         return BAD_INDEX;
     }
+
+    // Allow overriding density
+    const ResTable_config* desiredConfig = &mParams;
+    ResTable_config* overrideConfig = NULL;
+    if (density > 0) {
+        overrideConfig = (ResTable_config*) malloc(sizeof(ResTable_config));
+        if (overrideConfig == NULL) {
+            LOGE("Couldn't malloc ResTable_config for overrides: %s", strerror(errno));
+            return BAD_INDEX;
+        }
+        memcpy(overrideConfig, &mParams, sizeof(ResTable_config));
+        overrideConfig->density = density;
+        desiredConfig = overrideConfig;
+    }
+
+    ssize_t rc = BAD_VALUE;
     size_t ip = grp->packages.size();
     while (ip > 0) {
         ip--;
@@ -1931,12 +2008,13 @@
         const ResTable_type* type;
         const ResTable_entry* entry;
         const Type* typeClass;
-        ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
+        ssize_t offset = getEntry(package, t, e, desiredConfig, &type, &entry, &typeClass);
         if (offset <= 0) {
             if (offset < 0) {
                 LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",
                         resID, t, e, ip, (int)offset);
-                return offset;
+                rc = offset;
+                goto out;
             }
             continue;
         }
@@ -1951,13 +2029,14 @@
 
         TABLE_NOISY(aout << "Resource type data: "
               << HexDump(type, dtohl(type->header.size)) << endl);
-        
+
         if ((size_t)offset > (dtohl(type->header.size)-sizeof(Res_value))) {
             LOGW("ResTable_item at %d is beyond type chunk data %d",
                  (int)offset, dtohl(type->header.size));
-            return BAD_TYPE;
+            rc = BAD_TYPE;
+            goto out;
         }
-        
+
         const Res_value* item =
             (const Res_value*)(((const uint8_t*)type) + offset);
         ResTable_config thisConfig;
@@ -1999,10 +2078,16 @@
                          outValue->data, &len)).string()
                      : "",
                      outValue->data));
-        return bestPackage->header->index;
+        rc = bestPackage->header->index;
+        goto out;
     }
 
-    return BAD_VALUE;
+out:
+    if (overrideConfig != NULL) {
+        free(overrideConfig);
+    }
+
+    return rc;
 }
 
 ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
@@ -2015,7 +2100,7 @@
         if (outLastRef) *outLastRef = value->data;
         uint32_t lastRef = value->data;
         uint32_t newFlags = 0;
-        const ssize_t newIndex = getResource(value->data, value, true, &newFlags,
+        const ssize_t newIndex = getResource(value->data, value, true, 0, &newFlags,
                 outConfig);
         if (newIndex == BAD_INDEX) {
             return BAD_INDEX;
@@ -2609,6 +2694,24 @@
         *outType = *defType;
     }
     *outName = String16(p, end-p);
+    if(**outPackage == 0) {
+        if(outErrorMsg) {
+            *outErrorMsg = "Resource package cannot be an empty string";
+        }
+        return false;
+    }
+    if(**outType == 0) {
+        if(outErrorMsg) {
+            *outErrorMsg = "Resource type cannot be an empty string";
+        }
+        return false;
+    }
+    if(**outName == 0) {
+        if(outErrorMsg) {
+            *outErrorMsg = "Resource id cannot be an empty string";
+        }
+        return false;
+    }
     return true;
 }
 
@@ -3600,9 +3703,9 @@
 void ResTable::getLocales(Vector<String8>* locales) const
 {
     Vector<ResTable_config> configs;
-    LOGD("calling getConfigurations");
+    LOGV("calling getConfigurations");
     getConfigurations(&configs);
-    LOGD("called getConfigurations size=%d", (int)configs.size());
+    LOGV("called getConfigurations size=%d", (int)configs.size());
     const size_t I = configs.size();
     for (size_t i=0; i<I; i++) {
         char locale[6];
@@ -4159,13 +4262,16 @@
                                     | (0x00ff0000 & ((typeIndex+1)<<16))
                                     | (0x0000ffff & (entryIndex));
                         resource_name resName;
-                        this->getResourceName(resID, &resName);
-                        printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
-                            resID,
-                            CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                            CHAR16_TO_CSTR(resName.type, resName.typeLen),
-                            CHAR16_TO_CSTR(resName.name, resName.nameLen),
-                            dtohl(typeConfigs->typeSpecFlags[entryIndex]));
+                        if (this->getResourceName(resID, &resName)) {
+                            printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
+                                resID,
+                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                                CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                                CHAR16_TO_CSTR(resName.name, resName.nameLen),
+                                dtohl(typeConfigs->typeSpecFlags[entryIndex]));
+                        } else {
+                            printf("      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID);
+                        }
                     }
                 }
                 for (size_t configIndex=0; configIndex<NTC; configIndex++) {
@@ -4372,11 +4478,14 @@
                                     | (0x00ff0000 & ((typeIndex+1)<<16))
                                     | (0x0000ffff & (entryIndex));
                         resource_name resName;
-                        this->getResourceName(resID, &resName);
-                        printf("        resource 0x%08x %s:%s/%s: ", resID,
-                                CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                                CHAR16_TO_CSTR(resName.type, resName.typeLen),
-                                CHAR16_TO_CSTR(resName.name, resName.nameLen));
+                        if (this->getResourceName(resID, &resName)) {
+                            printf("        resource 0x%08x %s:%s/%s: ", resID,
+                                    CHAR16_TO_CSTR(resName.package, resName.packageLen),
+                                    CHAR16_TO_CSTR(resName.type, resName.typeLen),
+                                    CHAR16_TO_CSTR(resName.name, resName.nameLen));
+                        } else {
+                            printf("        INVALID RESOURCE 0x%08x: ", resID);
+                        }
                         if ((thisOffset&0x3) != 0) {
                             printf("NON-INTEGER OFFSET: %p\n", (void*)thisOffset);
                             continue;
@@ -4434,18 +4543,19 @@
                                 print_value(pkg, value);
                             } else if (bagPtr != NULL) {
                                 const int N = dtohl(bagPtr->count);
-                                const ResTable_map* mapPtr = (const ResTable_map*)
-                                        (((const uint8_t*)ent) + esize);
+                                const uint8_t* baseMapPtr = (const uint8_t*)ent;
+                                size_t mapOffset = esize;
+                                const ResTable_map* mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
                                 printf("          Parent=0x%08x, Count=%d\n",
                                     dtohl(bagPtr->parent.ident), N);
-                                for (int i=0; i<N; i++) {
+                                for (int i=0; i<N && mapOffset < (typeSize-sizeof(ResTable_map)); i++) {
                                     printf("          #%i (Key=0x%08x): ",
                                         i, dtohl(mapPtr->name.ident));
                                     value.copyFrom_dtoh(mapPtr->value);
                                     print_value(pkg, value);
                                     const size_t size = dtohs(mapPtr->value.size);
-                                    mapPtr = (ResTable_map*)(((const uint8_t*)mapPtr)
-                                            + size + sizeof(*mapPtr)-sizeof(mapPtr->value));
+                                    mapOffset += size + sizeof(*mapPtr)-sizeof(mapPtr->value);
+                                    mapPtr = (ResTable_map*)(baseMapPtr+mapOffset);
                                 }
                             }
                         }
diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/utils/StreamingZipInflater.cpp
index 1f62ac5..5a162cc 100644
--- a/libs/utils/StreamingZipInflater.cpp
+++ b/libs/utils/StreamingZipInflater.cpp
@@ -31,7 +31,7 @@
 /*
  * Streaming access to compressed asset data in an open fd
  */
-StreamingZipInflater::StreamingZipInflater(int fd, off_t compDataStart,
+StreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,
         size_t uncompSize, size_t compSize) {
     mFd = fd;
     mDataMap = NULL;
@@ -210,7 +210,7 @@
 // seeking backwards requires uncompressing fom the beginning, so is very
 // expensive.  seeking forwards only requires uncompressing from the current
 // position to the destination.
-off_t StreamingZipInflater::seekAbsolute(off_t absoluteInputPosition) {
+off64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {
     if (absoluteInputPosition < mOutCurPosition) {
         // rewind and reprocess the data from the beginning
         if (!mStreamNeedsInit) {
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
index eab7b2b..4ce1664 100644
--- a/libs/utils/String16.cpp
+++ b/libs/utils/String16.cpp
@@ -18,228 +18,17 @@
 
 #include <utils/Debug.h>
 #include <utils/Log.h>
+#include <utils/Unicode.h>
 #include <utils/String8.h>
 #include <utils/TextOutput.h>
 #include <utils/threads.h>
 
 #include <private/utils/Static.h>
 
-#ifdef HAVE_WINSOCK
-# undef  nhtol
-# undef  htonl
-# undef  nhtos
-# undef  htons
-
-# ifdef HAVE_LITTLE_ENDIAN
-#  define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
-#  define htonl(x)    ntohl(x)
-#  define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
-#  define htons(x)    ntohs(x)
-# else
-#  define ntohl(x)    (x)
-#  define htonl(x)    (x)
-#  define ntohs(x)    (x)
-#  define htons(x)    (x)
-# endif
-#else
-# include <netinet/in.h>
-#endif
-
 #include <memory.h>
 #include <stdio.h>
 #include <ctype.h>
 
-// ---------------------------------------------------------------------------
-
-int strcmp16(const char16_t *s1, const char16_t *s2)
-{
-  char16_t ch;
-  int d = 0;
-
-  while ( 1 ) {
-    d = (int)(ch = *s1++) - (int)*s2++;
-    if ( d || !ch )
-      break;
-  }
-
-  return d;
-}
-
-int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
-{
-  char16_t ch;
-  int d = 0;
-
-  while ( n-- ) {
-    d = (int)(ch = *s1++) - (int)*s2++;
-    if ( d || !ch )
-      break;
-  }
-
-  return d;
-}
-
-char16_t *strcpy16(char16_t *dst, const char16_t *src)
-{
-  char16_t *q = dst;
-  const char16_t *p = src;
-  char16_t ch;
-
-  do {
-    *q++ = ch = *p++;
-  } while ( ch );
-
-  return dst;
-}
-
-size_t strlen16(const char16_t *s)
-{
-  const char16_t *ss = s;
-  while ( *ss )
-    ss++;
-  return ss-s;
-}
-
-
-char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
-{
-  char16_t *q = dst;
-  const char16_t *p = src;
-  char ch;
-
-  while (n) {
-    n--;
-    *q++ = ch = *p++;
-    if ( !ch )
-      break;
-  }
-
-  *q = 0;
-
-  return dst;
-}
-
-size_t strnlen16(const char16_t *s, size_t maxlen)
-{
-  const char16_t *ss = s;
-
-  /* Important: the maxlen test must precede the reference through ss;
-     since the byte beyond the maximum may segfault */
-  while ((maxlen > 0) && *ss) {
-    ss++;
-    maxlen--;
-  }
-  return ss-s;
-}
-
-int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
-{
-    const char16_t* e1 = s1+n1;
-    const char16_t* e2 = s2+n2;
-
-    while (s1 < e1 && s2 < e2) {
-        const int d = (int)*s1++ - (int)*s2++;
-        if (d) {
-            return d;
-        }
-    }
-
-    return n1 < n2
-        ? (0 - (int)*s2)
-        : (n1 > n2
-           ? ((int)*s1 - 0)
-           : 0);
-}
-
-int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
-{
-    const char16_t* e1 = s1H+n1;
-    const char16_t* e2 = s2N+n2;
-
-    while (s1H < e1 && s2N < e2) {
-        const char16_t c2 = ntohs(*s2N);
-        const int d = (int)*s1H++ - (int)c2;
-        s2N++;
-        if (d) {
-            return d;
-        }
-    }
-
-    return n1 < n2
-        ? (0 - (int)ntohs(*s2N))
-        : (n1 > n2
-           ? ((int)*s1H - 0)
-           : 0);
-}
-
-static inline size_t
-utf8_char_len(uint8_t ch)
-{
-    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
-}
-
-#define UTF8_SHIFT_AND_MASK(unicode, byte)  (unicode)<<=6; (unicode) |= (0x3f & (byte));
-
-static inline uint32_t
-utf8_to_utf32(const uint8_t *src, size_t length)
-{
-    uint32_t unicode;
-
-    switch (length)
-    {
-        case 1:
-            return src[0];
-        case 2:
-            unicode = src[0] & 0x1f;
-            UTF8_SHIFT_AND_MASK(unicode, src[1])
-            return unicode;
-        case 3:
-            unicode = src[0] & 0x0f;
-            UTF8_SHIFT_AND_MASK(unicode, src[1])
-            UTF8_SHIFT_AND_MASK(unicode, src[2])
-            return unicode;
-        case 4:
-            unicode = src[0] & 0x07;
-            UTF8_SHIFT_AND_MASK(unicode, src[1])
-            UTF8_SHIFT_AND_MASK(unicode, src[2])
-            UTF8_SHIFT_AND_MASK(unicode, src[3])
-            return unicode;
-        default:
-            return 0xffff;
-    }
-    
-    //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
-}
-
-void
-utf8_to_utf16(const uint8_t *src, size_t srcLen,
-        char16_t* dst, const size_t dstLen)
-{
-    const uint8_t* const end = src + srcLen;
-    const char16_t* const dstEnd = dst + dstLen;
-    while (src < end && dst < dstEnd) {
-        size_t len = utf8_char_len(*src);
-        uint32_t codepoint = utf8_to_utf32((const uint8_t*)src, len);
-
-        // Convert the UTF32 codepoint to one or more UTF16 codepoints
-        if (codepoint <= 0xFFFF) {
-            // Single UTF16 character
-            *dst++ = (char16_t) codepoint;
-        } else {
-            // Multiple UTF16 characters with surrogates
-            codepoint = codepoint - 0x10000;
-            *dst++ = (char16_t) ((codepoint >> 10) + 0xD800);
-            *dst++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
-        }
-
-        src += len;
-    }
-    if (dst < dstEnd) {
-        *dst = 0;
-    }
-}
-
-// ---------------------------------------------------------------------------
 
 namespace android {
 
@@ -270,37 +59,33 @@
 
 // ---------------------------------------------------------------------------
 
-static char16_t* allocFromUTF8(const char* in, size_t len)
+static char16_t* allocFromUTF8(const char* u8str, size_t u8len)
 {
-    if (len == 0) return getEmptyString();
-    
-    size_t chars = 0;
-    const char* end = in+len;
-    const char* p = in;
-    
-    while (p < end) {
-        chars++;
-        int utf8len = utf8_char_len(*p);
-        uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, utf8len);
-        if (codepoint > 0xFFFF) chars++; // this will be a surrogate pair in utf16
-        p += utf8len;
+    if (u8len == 0) return getEmptyString();
+
+    const uint8_t* u8cur = (const uint8_t*) u8str;
+
+    const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);
+    if (u16len < 0) {
+        return getEmptyString();
     }
-    
-    size_t bufSize = (chars+1)*sizeof(char16_t);
-    SharedBuffer* buf = SharedBuffer::alloc(bufSize);
+
+    const uint8_t* const u8end = u8cur + u8len;
+
+    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
     if (buf) {
-        p = in;
-        char16_t* str = (char16_t*)buf->data();
-        
-        utf8_to_utf16((const uint8_t*)p, len, str, bufSize);
+        u8cur = (const uint8_t*) u8str;
+        char16_t* u16str = (char16_t*)buf->data();
+
+        utf8_to_utf16(u8cur, u8len, u16str);
 
         //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
         //printHexData(1, str, buf->size(), 16, 1);
         //printf("\n");
         
-        return str;
+        return u16str;
     }
-    
+
     return getEmptyString();
 }
 
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index 1c4f80c..0bc5aff 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -17,6 +17,8 @@
 #include <utils/String8.h>
 
 #include <utils/Log.h>
+#include <utils/Unicode.h>
+#include <utils/SharedBuffer.h>
 #include <utils/String16.h>
 #include <utils/TextOutput.h>
 #include <utils/threads.h>
@@ -34,94 +36,10 @@
 
 namespace android {
 
-static const char32_t kByteMask = 0x000000BF;
-static const char32_t kByteMark = 0x00000080;
-
-// Surrogates aren't valid for UTF-32 characters, so define some
-// constants that will let us screen them out.
-static const char32_t kUnicodeSurrogateHighStart  = 0x0000D800;
-static const char32_t kUnicodeSurrogateHighEnd    = 0x0000DBFF;
-static const char32_t kUnicodeSurrogateLowStart   = 0x0000DC00;
-static const char32_t kUnicodeSurrogateLowEnd     = 0x0000DFFF;
-static const char32_t kUnicodeSurrogateStart      = kUnicodeSurrogateHighStart;
-static const char32_t kUnicodeSurrogateEnd        = kUnicodeSurrogateLowEnd;
-static const char32_t kUnicodeMaxCodepoint        = 0x0010FFFF;
-
-// Mask used to set appropriate bits in first byte of UTF-8 sequence,
-// indexed by number of bytes in the sequence.
-// 0xxxxxxx
-// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000
-// 110yyyyx 10xxxxxx
-// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0
-// 1110yyyy 10yxxxxx 10xxxxxx
-// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0
-// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
-// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0
-static const char32_t kFirstByteMark[] = {
-    0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
-};
-
 // Separator used by resource paths. This is not platform dependent contrary
 // to OS_PATH_SEPARATOR.
 #define RES_PATH_SEPARATOR '/'
 
-// Return number of utf8 bytes required for the character.
-static size_t utf32_to_utf8_bytes(char32_t srcChar)
-{
-    size_t bytesToWrite;
-
-    // Figure out how many bytes the result will require.
-    if (srcChar < 0x00000080)
-    {
-        bytesToWrite = 1;
-    }
-    else if (srcChar < 0x00000800)
-    {
-        bytesToWrite = 2;
-    }
-    else if (srcChar < 0x00010000)
-    {
-        if ((srcChar < kUnicodeSurrogateStart)
-         || (srcChar > kUnicodeSurrogateEnd))
-        {
-            bytesToWrite = 3;
-        }
-        else
-        {
-            // Surrogates are invalid UTF-32 characters.
-            return 0;
-        }
-    }
-    // Max code point for Unicode is 0x0010FFFF.
-    else if (srcChar <= kUnicodeMaxCodepoint)
-    {
-        bytesToWrite = 4;
-    }
-    else
-    {
-        // Invalid UTF-32 character.
-        return 0;
-    }
-
-    return bytesToWrite;
-}
-
-// Write out the source character to <dstP>.
-
-static void utf32_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes)
-{
-    dstP += bytes;
-    switch (bytes)
-    {   /* note: everything falls through. */
-        case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
-        case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
-        case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
-        case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
-    }
-}
-
-// ---------------------------------------------------------------------------
-
 static SharedBuffer* gEmptyStringBuf = NULL;
 static char* gEmptyString = NULL;
 
@@ -175,62 +93,47 @@
     return getEmptyString();
 }
 
-template<typename T, typename L>
-static char* allocFromUTF16OrUTF32(const T* in, L len)
-{
-    if (len == 0) return getEmptyString();
-
-    size_t bytes = 0;
-    const T* end = in+len;
-    const T* p = in;
-
-    while (p < end) {
-        bytes += utf32_to_utf8_bytes(*p);
-        p++;
-    }
-
-    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
-    LOG_ASSERT(buf, "Unable to allocate shared buffer");
-    if (buf) {
-        p = in;
-        char* str = (char*)buf->data();
-        char* d = str;
-        while (p < end) {
-            const T c = *p++;
-            size_t len = utf32_to_utf8_bytes(c);
-            utf32_to_utf8((uint8_t*)d, c, len);
-            d += len;
-        }
-        *d = 0;
-
-        return str;
-    }
-
-    return getEmptyString();
-}
-
 static char* allocFromUTF16(const char16_t* in, size_t len)
 {
     if (len == 0) return getEmptyString();
 
-    const size_t bytes = utf8_length_from_utf16(in, len);
+    const ssize_t bytes = utf16_to_utf8_length(in, len);
+    if (bytes < 0) {
+        return getEmptyString();
+    }
 
     SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
     LOG_ASSERT(buf, "Unable to allocate shared buffer");
-    if (buf) {
-        char* str = (char*)buf->data();
-
-        utf16_to_utf8(in, len, str, bytes+1);
-
-        return str;
+    if (!buf) {
+        return getEmptyString();
     }
 
-    return getEmptyString();
+    char* str = (char*)buf->data();
+    utf16_to_utf8(in, len, str);
+    return str;
 }
 
 static char* allocFromUTF32(const char32_t* in, size_t len)
 {
-    return allocFromUTF16OrUTF32<char32_t, size_t>(in, len);
+    if (len == 0) {
+        return getEmptyString();
+    }
+
+    const ssize_t bytes = utf32_to_utf8_length(in, len);
+    if (bytes < 0) {
+        return getEmptyString();
+    }
+
+    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (!buf) {
+        return getEmptyString();
+    }
+
+    char* str = (char*) buf->data();
+    utf32_to_utf8(in, len, str);
+
+    return str;
 }
 
 // ---------------------------------------------------------------------------
@@ -292,6 +195,29 @@
     SharedBuffer::bufferFromData(mString)->release();
 }
 
+String8 String8::format(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+
+    String8 result(formatV(fmt, args));
+
+    va_end(args);
+    return result;
+}
+
+String8 String8::formatV(const char* fmt, va_list args)
+{
+    String8 result;
+    result.appendFormatV(fmt, args);
+    return result;
+}
+
+void String8::clear() {
+    SharedBuffer::bufferFromData(mString)->release();
+    mString = getEmptyString();
+}
+
 void String8::setTo(const String8& other)
 {
     SharedBuffer::bufferFromData(other.mString)->acquire();
@@ -374,22 +300,28 @@
 
 status_t String8::appendFormat(const char* fmt, ...)
 {
-    va_list ap;
-    va_start(ap, fmt);
+    va_list args;
+    va_start(args, fmt);
 
+    status_t result = appendFormatV(fmt, args);
+
+    va_end(args);
+    return result;
+}
+
+status_t String8::appendFormatV(const char* fmt, va_list args)
+{
     int result = NO_ERROR;
-    int n = vsnprintf(NULL, 0, fmt, ap);
+    int n = vsnprintf(NULL, 0, fmt, args);
     if (n != 0) {
         size_t oldLength = length();
         char* buf = lockBuffer(oldLength + n);
         if (buf) {
-            vsnprintf(buf + oldLength, n + 1, fmt, ap);
+            vsnprintf(buf + oldLength, n + 1, fmt, args);
         } else {
             result = NO_MEMORY;
         }
     }
-
-    va_end(ap);
     return result;
 }
 
@@ -505,17 +437,17 @@
 
 size_t String8::getUtf32Length() const
 {
-    return utf32_length(mString, length());
+    return utf8_to_utf32_length(mString, length());
 }
 
 int32_t String8::getUtf32At(size_t index, size_t *next_index) const
 {
-    return utf32_at(mString, length(), index, next_index);
+    return utf32_from_utf8_at(mString, length(), index, next_index);
 }
 
-size_t String8::getUtf32(char32_t* dst, size_t dst_len) const
+void String8::getUtf32(char32_t* dst) const
 {
-    return utf8_to_utf32(mString, length(), dst, dst_len);
+    utf8_to_utf32(mString, length(), dst);
 }
 
 TextOutput& operator<<(TextOutput& to, const String8& val)
@@ -700,241 +632,3 @@
 }
 
 }; // namespace android
-
-// ---------------------------------------------------------------------------
-
-size_t strlen32(const char32_t *s)
-{
-  const char32_t *ss = s;
-  while ( *ss )
-    ss++;
-  return ss-s;
-}
-
-size_t strnlen32(const char32_t *s, size_t maxlen)
-{
-  const char32_t *ss = s;
-  while ((maxlen > 0) && *ss) {
-    ss++;
-    maxlen--;
-  }
-  return ss-s;
-}
-
-size_t utf8_length(const char *src)
-{
-    const char *cur = src;
-    size_t ret = 0;
-    while (*cur != '\0') {
-        const char first_char = *cur++;
-        if ((first_char & 0x80) == 0) { // ASCII
-            ret += 1;
-            continue;
-        }
-        // (UTF-8's character must not be like 10xxxxxx,
-        //  but 110xxxxx, 1110xxxx, ... or 1111110x)
-        if ((first_char & 0x40) == 0) {
-            return 0;
-        }
-
-        int32_t mask, to_ignore_mask;
-        size_t num_to_read = 0;
-        char32_t utf32 = 0;
-        for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;
-             num_to_read < 5 && (first_char & mask);
-             num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
-            if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx
-                return 0;
-            }
-            // 0x3F == 00111111
-            utf32 = (utf32 << 6) + (*cur++ & 0x3F);
-        }
-        // "first_char" must be (110xxxxx - 11110xxx)
-        if (num_to_read == 5) {
-            return 0;
-        }
-        to_ignore_mask |= mask;
-        utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));
-        if (utf32 > android::kUnicodeMaxCodepoint) {
-            return 0;
-        }
-
-        ret += num_to_read;
-    }
-    return ret;
-}
-
-size_t utf32_length(const char *src, size_t src_len)
-{
-    if (src == NULL || src_len == 0) {
-        return 0;
-    }
-    size_t ret = 0;
-    const char* cur;
-    const char* end;
-    size_t num_to_skip;
-    for (cur = src, end = src + src_len, num_to_skip = 1;
-         cur < end;
-         cur += num_to_skip, ret++) {
-        const char first_char = *cur;
-        num_to_skip = 1;
-        if ((first_char & 0x80) == 0) {  // ASCII
-            continue;
-        }
-        int32_t mask;
-
-        for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {
-        }
-    }
-    return ret;
-}
-
-size_t utf8_length_from_utf32(const char32_t *src, size_t src_len)
-{
-    if (src == NULL || src_len == 0) {
-        return 0;
-    }
-    size_t ret = 0;
-    const char32_t *end = src + src_len;
-    while (src < end) {
-        ret += android::utf32_to_utf8_bytes(*src++);
-    }
-    return ret;
-}
-
-size_t utf8_length_from_utf16(const char16_t *src, size_t src_len)
-{
-    if (src == NULL || src_len == 0) {
-        return 0;
-    }
-    size_t ret = 0;
-    const char16_t* const end = src + src_len;
-    while (src < end) {
-        if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
-                && (*++src & 0xFC00) == 0xDC00) {
-            // surrogate pairs are always 4 bytes.
-            ret += 4;
-            src++;
-        } else {
-            ret += android::utf32_to_utf8_bytes((char32_t) *src++);
-        }
-    }
-    return ret;
-}
-
-static int32_t utf32_at_internal(const char* cur, size_t *num_read)
-{
-    const char first_char = *cur;
-    if ((first_char & 0x80) == 0) { // ASCII
-        *num_read = 1;
-        return *cur;
-    }
-    cur++;
-    char32_t mask, to_ignore_mask;
-    size_t num_to_read = 0;
-    char32_t utf32 = first_char;
-    for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80;
-         (first_char & mask);
-         num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
-        // 0x3F == 00111111
-        utf32 = (utf32 << 6) + (*cur++ & 0x3F);
-    }
-    to_ignore_mask |= mask;
-    utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1)));
-
-    *num_read = num_to_read;
-    return static_cast<int32_t>(utf32);
-}
-
-int32_t utf32_at(const char *src, size_t src_len,
-                 size_t index, size_t *next_index)
-{
-    if (index >= src_len) {
-        return -1;
-    }
-    size_t dummy_index;
-    if (next_index == NULL) {
-        next_index = &dummy_index;
-    }
-    size_t num_read;
-    int32_t ret = utf32_at_internal(src + index, &num_read);
-    if (ret >= 0) {
-        *next_index = index + num_read;
-    }
-
-    return ret;
-}
-
-size_t utf8_to_utf32(const char* src, size_t src_len,
-                     char32_t* dst, size_t dst_len)
-{
-    if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
-        return 0;
-    }
-
-    const char* cur = src;
-    const char* end = src + src_len;
-    char32_t* cur_utf32 = dst;
-    const char32_t* end_utf32 = dst + dst_len;
-    while (cur_utf32 < end_utf32 && cur < end) {
-        size_t num_read;
-        *cur_utf32++ =
-                static_cast<char32_t>(utf32_at_internal(cur, &num_read));
-        cur += num_read;
-    }
-    if (cur_utf32 < end_utf32) {
-        *cur_utf32 = 0;
-    }
-    return static_cast<size_t>(cur_utf32 - dst);
-}
-
-size_t utf32_to_utf8(const char32_t* src, size_t src_len,
-                     char* dst, size_t dst_len)
-{
-    if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
-        return 0;
-    }
-    const char32_t *cur_utf32 = src;
-    const char32_t *end_utf32 = src + src_len;
-    char *cur = dst;
-    const char *end = dst + dst_len;
-    while (cur_utf32 < end_utf32 && cur < end) {
-        size_t len = android::utf32_to_utf8_bytes(*cur_utf32);
-        android::utf32_to_utf8((uint8_t *)cur, *cur_utf32++, len);
-        cur += len;
-    }
-    if (cur < end) {
-        *cur = '\0';
-    }
-    return cur - dst;
-}
-
-size_t utf16_to_utf8(const char16_t* src, size_t src_len,
-                     char* dst, size_t dst_len)
-{
-    if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
-        return 0;
-    }
-    const char16_t* cur_utf16 = src;
-    const char16_t* const end_utf16 = src + src_len;
-    char *cur = dst;
-    const char* const end = dst + dst_len;
-    while (cur_utf16 < end_utf16 && cur < end) {
-        char32_t utf32;
-        // surrogate pairs
-        if ((*cur_utf16 & 0xFC00) == 0xD800 && (cur_utf16 + 1) < end_utf16) {
-            utf32 = (*cur_utf16++ - 0xD800) << 10;
-            utf32 |= *cur_utf16++ - 0xDC00;
-            utf32 += 0x10000;
-        } else {
-            utf32 = (char32_t) *cur_utf16++;
-        }
-        size_t len = android::utf32_to_utf8_bytes(utf32);
-        android::utf32_to_utf8((uint8_t*)cur, utf32, len);
-        cur += len;
-    }
-    if (cur < end) {
-        *cur = '\0';
-    }
-    return cur - dst;
-}
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
index 2bdc0ce..062e6d7 100644
--- a/libs/utils/SystemClock.cpp
+++ b/libs/utils/SystemClock.cpp
@@ -19,7 +19,7 @@
  * System clock functions.
  */
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
 #include <linux/ioctl.h>
 #include <linux/rtc.h>
 #include <utils/Atomic.h>
@@ -50,7 +50,7 @@
     return -1;
 #else
     struct timeval tv;
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     struct timespec ts;
     int fd;
     int res;
@@ -66,7 +66,7 @@
 
     LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     fd = open("/dev/alarm", O_RDWR);
     if(fd < 0) {
         LOGW("Unable to open alarm driver: %s\n", strerror(errno));
@@ -106,7 +106,7 @@
  */
 int64_t elapsedRealtime()
 {
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     static int s_fd = -1;
 
     if (s_fd == -1) {
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index b1bd828..8b5da0e 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -675,6 +675,9 @@
         mLock("Thread::mLock"),
         mStatus(NO_ERROR),
         mExitPending(false), mRunning(false)
+#ifdef HAVE_ANDROID_OS
+        , mTid(-1)
+#endif
 {
 }
 
@@ -715,6 +718,7 @@
         res = androidCreateRawThreadEtc(_threadLoop,
                 this, name, priority, stack, &mThread);
     }
+    // The new thread wakes up at _threadLoop, but immediately blocks on mLock
     
     if (res == false) {
         mStatus = UNKNOWN_ERROR;   // something happened!
@@ -730,16 +734,24 @@
     // here merely indicates successfully starting the thread and does not
     // imply successful termination/execution.
     return NO_ERROR;
+
+    // Exiting scope of mLock is a memory barrier and allows new thread to run
 }
 
 int Thread::_threadLoop(void* user)
 {
     Thread* const self = static_cast<Thread*>(user);
+
+    // force a memory barrier before reading any fields, in particular mHoldSelf
+    {
+    Mutex::Autolock _l(self->mLock);
+    }
+
     sp<Thread> strong(self->mHoldSelf);
     wp<Thread> weak(strong);
     self->mHoldSelf.clear();
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
     // this is very useful for debugging with gdb
     self->mTid = gettid();
 #endif
@@ -753,7 +765,7 @@
             self->mStatus = self->readyToRun();
             result = (self->mStatus == NO_ERROR);
 
-            if (result && !self->mExitPending) {
+            if (result && !self->exitPending()) {
                 // Binder threads (and maybe others) rely on threadLoop
                 // running at least once after a successful ::readyToRun()
                 // (unless, of course, the thread has already been asked to exit
@@ -770,18 +782,21 @@
             result = self->threadLoop();
         }
 
+        // establish a scope for mLock
+        {
+        Mutex::Autolock _l(self->mLock);
         if (result == false || self->mExitPending) {
             self->mExitPending = true;
-            self->mLock.lock();
             self->mRunning = false;
             // clear thread ID so that requestExitAndWait() does not exit if
             // called by a new thread using the same thread ID as this one.
             self->mThread = thread_id_t(-1);
+            // note that interested observers blocked in requestExitAndWait are
+            // awoken by broadcast, but blocked on mLock until break exits scope
             self->mThreadExitedCondition.broadcast();
-            self->mThread = thread_id_t(-1); // thread id could be reused
-            self->mLock.unlock();
             break;
         }
+        }
         
         // Release our strong reference, to let a chance to the thread
         // to die a peaceful death.
@@ -795,6 +810,7 @@
 
 void Thread::requestExit()
 {
+    Mutex::Autolock _l(mLock);
     mExitPending = true;
 }
 
@@ -815,6 +831,8 @@
     while (mRunning == true) {
         mThreadExitedCondition.wait(mLock);
     }
+    // This next line is probably not needed any more, but is being left for
+    // historical reference. Note that each interested party will clear flag.
     mExitPending = false;
 
     return mStatus;
@@ -822,6 +840,7 @@
 
 bool Thread::exitPending() const
 {
+    Mutex::Autolock _l(mLock);
     return mExitPending;
 }
 
diff --git a/libs/utils/Tokenizer.cpp b/libs/utils/Tokenizer.cpp
new file mode 100644
index 0000000..b3445b7
--- /dev/null
+++ b/libs/utils/Tokenizer.cpp
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Tokenizer"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+#include <utils/Tokenizer.h>
+
+// Enables debug output for the tokenizer.
+#define DEBUG_TOKENIZER 0
+
+
+namespace android {
+
+static inline bool isDelimiter(char ch, const char* delimiters) {
+    return strchr(delimiters, ch) != NULL;
+}
+
+Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length) :
+        mFilename(filename), mFileMap(fileMap),
+        mBuffer(buffer), mLength(length), mCurrent(buffer), mLineNumber(1) {
+}
+
+Tokenizer::~Tokenizer() {
+    if (mFileMap) {
+        mFileMap->release();
+    } else {
+        delete[] mBuffer;
+    }
+}
+
+status_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) {
+    *outTokenizer = NULL;
+
+    int result = NO_ERROR;
+    int fd = ::open(filename.string(), O_RDONLY);
+    if (fd < 0) {
+        result = -errno;
+        LOGE("Error opening file '%s', %s.", filename.string(), strerror(errno));
+    } else {
+        struct stat stat;
+        if (fstat(fd, &stat)) {
+            result = -errno;
+            LOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno));
+        } else {
+            size_t length = size_t(stat.st_size);
+
+            FileMap* fileMap = new FileMap();
+            char* buffer;
+            if (fileMap->create(NULL, fd, 0, length, true)) {
+                fileMap->advise(FileMap::SEQUENTIAL);
+                buffer = static_cast<char*>(fileMap->getDataPtr());
+            } else {
+                fileMap->release();
+                fileMap = NULL;
+
+                // Fall back to reading into a buffer since we can't mmap files in sysfs.
+                // The length we obtained from stat is wrong too (it will always be 4096)
+                // so we must trust that read will read the entire file.
+                buffer = new char[length];
+                ssize_t nrd = read(fd, buffer, length);
+                if (nrd < 0) {
+                    result = -errno;
+                    LOGE("Error reading file '%s', %s.", filename.string(), strerror(errno));
+                    delete[] buffer;
+                    buffer = NULL;
+                } else {
+                    length = size_t(nrd);
+                }
+            }
+
+            if (!result) {
+                *outTokenizer = new Tokenizer(filename, fileMap, buffer, length);
+            }
+        }
+        close(fd);
+    }
+    return result;
+}
+
+String8 Tokenizer::getLocation() const {
+    String8 result;
+    result.appendFormat("%s:%d", mFilename.string(), mLineNumber);
+    return result;
+}
+
+String8 Tokenizer::peekRemainderOfLine() const {
+    const char* end = getEnd();
+    const char* eol = mCurrent;
+    while (eol != end) {
+        char ch = *eol;
+        if (ch == '\n') {
+            break;
+        }
+        eol += 1;
+    }
+    return String8(mCurrent, eol - mCurrent);
+}
+
+String8 Tokenizer::nextToken(const char* delimiters) {
+#if DEBUG_TOKENIZER
+    LOGD("nextToken");
+#endif
+    const char* end = getEnd();
+    const char* tokenStart = mCurrent;
+    while (mCurrent != end) {
+        char ch = *mCurrent;
+        if (ch == '\n' || isDelimiter(ch, delimiters)) {
+            break;
+        }
+        mCurrent += 1;
+    }
+    return String8(tokenStart, mCurrent - tokenStart);
+}
+
+void Tokenizer::nextLine() {
+#if DEBUG_TOKENIZER
+    LOGD("nextLine");
+#endif
+    const char* end = getEnd();
+    while (mCurrent != end) {
+        char ch = *(mCurrent++);
+        if (ch == '\n') {
+            mLineNumber += 1;
+            break;
+        }
+    }
+}
+
+void Tokenizer::skipDelimiters(const char* delimiters) {
+#if DEBUG_TOKENIZER
+    LOGD("skipDelimiters");
+#endif
+    const char* end = getEnd();
+    while (mCurrent != end) {
+        char ch = *mCurrent;
+        if (ch == '\n' || !isDelimiter(ch, delimiters)) {
+            break;
+        }
+        mCurrent += 1;
+    }
+}
+
+} // namespace android
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
new file mode 100644
index 0000000..78c61b4
--- /dev/null
+++ b/libs/utils/Unicode.cpp
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2005 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 <utils/Unicode.h>
+
+#include <stddef.h>
+
+#ifdef HAVE_WINSOCK
+# undef  nhtol
+# undef  htonl
+# undef  nhtos
+# undef  htons
+
+# ifdef HAVE_LITTLE_ENDIAN
+#  define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
+#  define htonl(x)    ntohl(x)
+#  define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
+#  define htons(x)    ntohs(x)
+# else
+#  define ntohl(x)    (x)
+#  define htonl(x)    (x)
+#  define ntohs(x)    (x)
+#  define htons(x)    (x)
+# endif
+#else
+# include <netinet/in.h>
+#endif
+
+extern "C" {
+
+static const char32_t kByteMask = 0x000000BF;
+static const char32_t kByteMark = 0x00000080;
+
+// Surrogates aren't valid for UTF-32 characters, so define some
+// constants that will let us screen them out.
+static const char32_t kUnicodeSurrogateHighStart  = 0x0000D800;
+static const char32_t kUnicodeSurrogateHighEnd    = 0x0000DBFF;
+static const char32_t kUnicodeSurrogateLowStart   = 0x0000DC00;
+static const char32_t kUnicodeSurrogateLowEnd     = 0x0000DFFF;
+static const char32_t kUnicodeSurrogateStart      = kUnicodeSurrogateHighStart;
+static const char32_t kUnicodeSurrogateEnd        = kUnicodeSurrogateLowEnd;
+static const char32_t kUnicodeMaxCodepoint        = 0x0010FFFF;
+
+// Mask used to set appropriate bits in first byte of UTF-8 sequence,
+// indexed by number of bytes in the sequence.
+// 0xxxxxxx
+// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000
+// 110yyyyx 10xxxxxx
+// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0
+// 1110yyyy 10yxxxxx 10xxxxxx
+// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0
+// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx
+// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0
+static const char32_t kFirstByteMark[] = {
+    0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0
+};
+
+// --------------------------------------------------------------------------
+// UTF-32
+// --------------------------------------------------------------------------
+
+/**
+ * Return number of UTF-8 bytes required for the character. If the character
+ * is invalid, return size of 0.
+ */
+static inline size_t utf32_codepoint_utf8_length(char32_t srcChar)
+{
+    // Figure out how many bytes the result will require.
+    if (srcChar < 0x00000080) {
+        return 1;
+    } else if (srcChar < 0x00000800) {
+        return 2;
+    } else if (srcChar < 0x00010000) {
+        if ((srcChar < kUnicodeSurrogateStart) || (srcChar > kUnicodeSurrogateEnd)) {
+            return 3;
+        } else {
+            // Surrogates are invalid UTF-32 characters.
+            return 0;
+        }
+    }
+    // Max code point for Unicode is 0x0010FFFF.
+    else if (srcChar <= kUnicodeMaxCodepoint) {
+        return 4;
+    } else {
+        // Invalid UTF-32 character.
+        return 0;
+    }
+}
+
+// Write out the source character to <dstP>.
+
+static inline void utf32_codepoint_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes)
+{
+    dstP += bytes;
+    switch (bytes)
+    {   /* note: everything falls through. */
+        case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6;
+        case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]);
+    }
+}
+
+size_t strlen32(const char32_t *s)
+{
+  const char32_t *ss = s;
+  while ( *ss )
+    ss++;
+  return ss-s;
+}
+
+size_t strnlen32(const char32_t *s, size_t maxlen)
+{
+  const char32_t *ss = s;
+  while ((maxlen > 0) && *ss) {
+    ss++;
+    maxlen--;
+  }
+  return ss-s;
+}
+
+static inline int32_t utf32_at_internal(const char* cur, size_t *num_read)
+{
+    const char first_char = *cur;
+    if ((first_char & 0x80) == 0) { // ASCII
+        *num_read = 1;
+        return *cur;
+    }
+    cur++;
+    char32_t mask, to_ignore_mask;
+    size_t num_to_read = 0;
+    char32_t utf32 = first_char;
+    for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80;
+         (first_char & mask);
+         num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
+        // 0x3F == 00111111
+        utf32 = (utf32 << 6) + (*cur++ & 0x3F);
+    }
+    to_ignore_mask |= mask;
+    utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1)));
+
+    *num_read = num_to_read;
+    return static_cast<int32_t>(utf32);
+}
+
+int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index)
+{
+    if (index >= src_len) {
+        return -1;
+    }
+    size_t dummy_index;
+    if (next_index == NULL) {
+        next_index = &dummy_index;
+    }
+    size_t num_read;
+    int32_t ret = utf32_at_internal(src + index, &num_read);
+    if (ret >= 0) {
+        *next_index = index + num_read;
+    }
+
+    return ret;
+}
+
+ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len)
+{
+    if (src == NULL || src_len == 0) {
+        return -1;
+    }
+
+    size_t ret = 0;
+    const char32_t *end = src + src_len;
+    while (src < end) {
+        ret += utf32_codepoint_utf8_length(*src++);
+    }
+    return ret;
+}
+
+void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst)
+{
+    if (src == NULL || src_len == 0 || dst == NULL) {
+        return;
+    }
+
+    const char32_t *cur_utf32 = src;
+    const char32_t *end_utf32 = src + src_len;
+    char *cur = dst;
+    while (cur_utf32 < end_utf32) {
+        size_t len = utf32_codepoint_utf8_length(*cur_utf32);
+        utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len);
+        cur += len;
+    }
+    *cur = '\0';
+}
+
+// --------------------------------------------------------------------------
+// UTF-16
+// --------------------------------------------------------------------------
+
+int strcmp16(const char16_t *s1, const char16_t *s2)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( 1 ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
+{
+  char16_t ch;
+  int d = 0;
+
+  while ( n-- ) {
+    d = (int)(ch = *s1++) - (int)*s2++;
+    if ( d || !ch )
+      break;
+  }
+
+  return d;
+}
+
+char16_t *strcpy16(char16_t *dst, const char16_t *src)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char16_t ch;
+
+  do {
+    *q++ = ch = *p++;
+  } while ( ch );
+
+  return dst;
+}
+
+size_t strlen16(const char16_t *s)
+{
+  const char16_t *ss = s;
+  while ( *ss )
+    ss++;
+  return ss-s;
+}
+
+
+char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
+{
+  char16_t *q = dst;
+  const char16_t *p = src;
+  char ch;
+
+  while (n) {
+    n--;
+    *q++ = ch = *p++;
+    if ( !ch )
+      break;
+  }
+
+  *q = 0;
+
+  return dst;
+}
+
+size_t strnlen16(const char16_t *s, size_t maxlen)
+{
+  const char16_t *ss = s;
+
+  /* Important: the maxlen test must precede the reference through ss;
+     since the byte beyond the maximum may segfault */
+  while ((maxlen > 0) && *ss) {
+    ss++;
+    maxlen--;
+  }
+  return ss-s;
+}
+
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
+{
+    const char16_t* e1 = s1+n1;
+    const char16_t* e2 = s2+n2;
+
+    while (s1 < e1 && s2 < e2) {
+        const int d = (int)*s1++ - (int)*s2++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)*s2)
+        : (n1 > n2
+           ? ((int)*s1 - 0)
+           : 0);
+}
+
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
+{
+    const char16_t* e1 = s1H+n1;
+    const char16_t* e2 = s2N+n2;
+
+    while (s1H < e1 && s2N < e2) {
+        const char16_t c2 = ntohs(*s2N);
+        const int d = (int)*s1H++ - (int)c2;
+        s2N++;
+        if (d) {
+            return d;
+        }
+    }
+
+    return n1 < n2
+        ? (0 - (int)ntohs(*s2N))
+        : (n1 > n2
+           ? ((int)*s1H - 0)
+           : 0);
+}
+
+void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst)
+{
+    if (src == NULL || src_len == 0 || dst == NULL) {
+        return;
+    }
+
+    const char16_t* cur_utf16 = src;
+    const char16_t* const end_utf16 = src + src_len;
+    char *cur = dst;
+    while (cur_utf16 < end_utf16) {
+        char32_t utf32;
+        // surrogate pairs
+        if ((*cur_utf16 & 0xFC00) == 0xD800) {
+            utf32 = (*cur_utf16++ - 0xD800) << 10;
+            utf32 |= *cur_utf16++ - 0xDC00;
+            utf32 += 0x10000;
+        } else {
+            utf32 = (char32_t) *cur_utf16++;
+        }
+        const size_t len = utf32_codepoint_utf8_length(utf32);
+        utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len);
+        cur += len;
+    }
+    *cur = '\0';
+}
+
+// --------------------------------------------------------------------------
+// UTF-8
+// --------------------------------------------------------------------------
+
+ssize_t utf8_length(const char *src)
+{
+    const char *cur = src;
+    size_t ret = 0;
+    while (*cur != '\0') {
+        const char first_char = *cur++;
+        if ((first_char & 0x80) == 0) { // ASCII
+            ret += 1;
+            continue;
+        }
+        // (UTF-8's character must not be like 10xxxxxx,
+        //  but 110xxxxx, 1110xxxx, ... or 1111110x)
+        if ((first_char & 0x40) == 0) {
+            return -1;
+        }
+
+        int32_t mask, to_ignore_mask;
+        size_t num_to_read = 0;
+        char32_t utf32 = 0;
+        for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80;
+             num_to_read < 5 && (first_char & mask);
+             num_to_read++, to_ignore_mask |= mask, mask >>= 1) {
+            if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx
+                return -1;
+            }
+            // 0x3F == 00111111
+            utf32 = (utf32 << 6) + (*cur++ & 0x3F);
+        }
+        // "first_char" must be (110xxxxx - 11110xxx)
+        if (num_to_read == 5) {
+            return -1;
+        }
+        to_ignore_mask |= mask;
+        utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1));
+        if (utf32 > kUnicodeMaxCodepoint) {
+            return -1;
+        }
+
+        ret += num_to_read;
+    }
+    return ret;
+}
+
+ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
+{
+    if (src == NULL || src_len == 0) {
+        return -1;
+    }
+
+    size_t ret = 0;
+    const char16_t* const end = src + src_len;
+    while (src < end) {
+        if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
+                && (*++src & 0xFC00) == 0xDC00) {
+            // surrogate pairs are always 4 bytes.
+            ret += 4;
+            src++;
+        } else {
+            ret += utf32_codepoint_utf8_length((char32_t) *src++);
+        }
+    }
+    return ret;
+}
+
+/**
+ * Returns 1-4 based on the number of leading bits.
+ *
+ * 1111 -> 4
+ * 1110 -> 3
+ * 110x -> 2
+ * 10xx -> 1
+ * 0xxx -> 1
+ */
+static inline size_t utf8_codepoint_len(uint8_t ch)
+{
+    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
+}
+
+static inline void utf8_shift_and_mask(uint32_t* codePoint, const uint8_t byte)
+{
+    *codePoint <<= 6;
+    *codePoint |= 0x3F & byte;
+}
+
+size_t utf8_to_utf32_length(const char *src, size_t src_len)
+{
+    if (src == NULL || src_len == 0) {
+        return 0;
+    }
+    size_t ret = 0;
+    const char* cur;
+    const char* end;
+    size_t num_to_skip;
+    for (cur = src, end = src + src_len, num_to_skip = 1;
+         cur < end;
+         cur += num_to_skip, ret++) {
+        const char first_char = *cur;
+        num_to_skip = 1;
+        if ((first_char & 0x80) == 0) {  // ASCII
+            continue;
+        }
+        int32_t mask;
+
+        for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {
+        }
+    }
+    return ret;
+}
+
+void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst)
+{
+    if (src == NULL || src_len == 0 || dst == NULL) {
+        return;
+    }
+
+    const char* cur = src;
+    const char* const end = src + src_len;
+    char32_t* cur_utf32 = dst;
+    while (cur < end) {
+        size_t num_read;
+        *cur_utf32++ = static_cast<char32_t>(utf32_at_internal(cur, &num_read));
+        cur += num_read;
+    }
+    *cur_utf32 = 0;
+}
+
+static inline uint32_t utf8_to_utf32_codepoint(const uint8_t *src, size_t length)
+{
+    uint32_t unicode;
+
+    switch (length)
+    {
+        case 1:
+            return src[0];
+        case 2:
+            unicode = src[0] & 0x1f;
+            utf8_shift_and_mask(&unicode, src[1]);
+            return unicode;
+        case 3:
+            unicode = src[0] & 0x0f;
+            utf8_shift_and_mask(&unicode, src[1]);
+            utf8_shift_and_mask(&unicode, src[2]);
+            return unicode;
+        case 4:
+            unicode = src[0] & 0x07;
+            utf8_shift_and_mask(&unicode, src[1]);
+            utf8_shift_and_mask(&unicode, src[2]);
+            utf8_shift_and_mask(&unicode, src[3]);
+            return unicode;
+        default:
+            return 0xffff;
+    }
+
+    //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
+}
+
+ssize_t utf8_to_utf16_length(const uint8_t* u8str, size_t u8len)
+{
+    const uint8_t* const u8end = u8str + u8len;
+    const uint8_t* u8cur = u8str;
+
+    /* Validate that the UTF-8 is the correct len */
+    size_t u16measuredLen = 0;
+    while (u8cur < u8end) {
+        u16measuredLen++;
+        int u8charLen = utf8_codepoint_len(*u8cur);
+        uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8charLen);
+        if (codepoint > 0xFFFF) u16measuredLen++; // this will be a surrogate pair in utf16
+        u8cur += u8charLen;
+    }
+
+    /**
+     * Make sure that we ended where we thought we would and the output UTF-16
+     * will be exactly how long we were told it would be.
+     */
+    if (u8cur != u8end) {
+        return -1;
+    }
+
+    return u16measuredLen;
+}
+
+/**
+ * Convert a UTF-8 string to UTF-16. The destination UTF-16 buffer must have
+ * space for NULL at the end.
+ */
+void utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str)
+{
+    const uint8_t* const u8end = u8str + u8len;
+    const uint8_t* u8cur = u8str;
+    char16_t* u16cur = u16str;
+
+    while (u8cur < u8end) {
+        size_t u8len = utf8_codepoint_len(*u8cur);
+        uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len);
+
+        // Convert the UTF32 codepoint to one or more UTF16 codepoints
+        if (codepoint <= 0xFFFF) {
+            // Single UTF16 character
+            *u16cur++ = (char16_t) codepoint;
+        } else {
+            // Multiple UTF16 characters with surrogates
+            codepoint = codepoint - 0x10000;
+            *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800);
+            *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
+        }
+
+        u8cur += u8len;
+    }
+    *u16cur = 0;
+}
+
+}
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
index 16b219c..55dfd9f 100644
--- a/libs/utils/ZipFileCRO.cpp
+++ b/libs/utils/ZipFileCRO.cpp
@@ -40,7 +40,7 @@
 
 bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
         int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
+        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) {
     ZipFileRO* zip = (ZipFileRO*)zipToken;
     ZipEntryRO entry = (ZipEntryRO)entryToken;
     return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index 4261196..b18c383 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -146,7 +146,7 @@
         return NAME_NOT_FOUND;
     }
 
-    mFileLength = lseek(fd, 0, SEEK_END);
+    mFileLength = lseek64(fd, 0, SEEK_END);
     if (mFileLength < kEOCDLen) {
         TEMP_FAILURE_RETRY(close(fd));
         return UNKNOWN_ERROR;
@@ -202,7 +202,7 @@
     /*
      * Make sure this is a Zip archive.
      */
-    if (lseek(mFd, 0, SEEK_SET) != 0) {
+    if (lseek64(mFd, 0, SEEK_SET) != 0) {
         LOGW("seek to start failed: %s", strerror(errno));
         free(scanBuf);
         return false;
@@ -240,9 +240,9 @@
      *
      * We start by pulling in the last part of the file.
      */
-    off_t searchStart = mFileLength - readAmount;
+    off64_t searchStart = mFileLength - readAmount;
 
-    if (lseek(mFd, searchStart, SEEK_SET) != searchStart) {
+    if (lseek64(mFd, searchStart, SEEK_SET) != searchStart) {
         LOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
         free(scanBuf);
         return false;
@@ -274,7 +274,7 @@
         return false;
     }
 
-    off_t eocdOffset = searchStart + i;
+    off64_t eocdOffset = searchStart + i;
     const unsigned char* eocdPtr = scanBuf + i;
 
     assert(eocdOffset < mFileLength);
@@ -473,7 +473,7 @@
  * appear to be bogus.
  */
 bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-    size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
+    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
 {
     bool ret = false;
 
@@ -489,7 +489,7 @@
      * so we can just subtract back from that.
      */
     const unsigned char* ptr = (const unsigned char*) hashEntry.name;
-    off_t cdOffset = mDirectoryOffset;
+    off64_t cdOffset = mDirectoryOffset;
 
     ptr -= kCDELen;
 
@@ -536,12 +536,12 @@
 #ifdef HAVE_PREAD
         /*
          * This file descriptor might be from zygote's preloaded assets,
-         * so we need to do an pread() instead of a lseek() + read() to
+         * so we need to do an pread64() instead of a lseek64() + read() to
          * guarantee atomicity across the processes with the shared file
          * descriptors.
          */
         ssize_t actual =
-                TEMP_FAILURE_RETRY(pread(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
+                TEMP_FAILURE_RETRY(pread64(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
 
         if (actual != sizeof(lfhBuf)) {
             LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
@@ -556,17 +556,17 @@
         }
 #else /* HAVE_PREAD */
         /*
-         * For hosts don't have pread() we cannot guarantee atomic reads from
+         * For hosts don't have pread64() we cannot guarantee atomic reads from
          * an offset in a file. Android should never run on those platforms.
          * File descriptors inherited from a fork() share file offsets and
          * there would be nothing to protect from two different processes
-         * calling lseek() concurrently.
+         * calling lseek64() concurrently.
          */
 
         {
             AutoMutex _l(mFdLock);
 
-            if (lseek(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
+            if (lseek64(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
                 LOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
                 return false;
             }
@@ -579,7 +579,7 @@
             }
 
             if (get4LE(lfhBuf) != kLFHSignature) {
-                off_t actualOffset = lseek(mFd, 0, SEEK_CUR);
+                off64_t actualOffset = lseek64(mFd, 0, SEEK_CUR);
                 LOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
                         "got: offset=" ZD " data=0x%08lx\n",
                         localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
@@ -588,7 +588,7 @@
         }
 #endif /* HAVE_PREAD */
 
-        off_t dataOffset = localHdrOffset + kLFHLen
+        off64_t dataOffset = localHdrOffset + kLFHLen
             + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
         if (dataOffset >= cdOffset) {
             LOGW("bad data offset %ld in zip\n", (long) dataOffset);
@@ -596,14 +596,14 @@
         }
 
         /* check lengths */
-        if ((off_t)(dataOffset + compLen) > cdOffset) {
+        if ((off64_t)(dataOffset + compLen) > cdOffset) {
             LOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
                 (long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
             return false;
         }
 
         if (method == kCompressStored &&
-            (off_t)(dataOffset + uncompLen) > cdOffset)
+            (off64_t)(dataOffset + uncompLen) > cdOffset)
         {
             LOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
                 (long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
@@ -649,7 +649,7 @@
 
     FileMap* newMap;
     size_t compLen;
-    off_t offset;
+    off64_t offset;
 
     if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
         return NULL;
@@ -679,7 +679,7 @@
 
     int method;
     size_t uncompLen, compLen;
-    off_t offset;
+    off64_t offset;
     const unsigned char* ptr;
 
     getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
@@ -739,7 +739,7 @@
 
     int method;
     size_t uncompLen, compLen;
-    off_t offset;
+    off64_t offset;
     const unsigned char* ptr;
 
     getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
index 00077ee..72d4876 100644
--- a/libs/utils/tests/Android.mk
+++ b/libs/utils/tests/Android.mk
@@ -8,7 +8,8 @@
 test_src_files := \
 	ObbFile_test.cpp \
 	Looper_test.cpp \
-	String8_test.cpp
+	String8_test.cpp \
+	Unicode_test.cpp
 
 shared_libraries := \
 	libz \
diff --git a/libs/utils/tests/Looper_test.cpp b/libs/utils/tests/Looper_test.cpp
index cea1313..8bf2ba2 100644
--- a/libs/utils/tests/Looper_test.cpp
+++ b/libs/utils/tests/Looper_test.cpp
@@ -16,6 +16,13 @@
 
 namespace android {
 
+enum {
+    MSG_TEST1 = 1,
+    MSG_TEST2 = 2,
+    MSG_TEST3 = 3,
+    MSG_TEST4 = 4,
+};
+
 class DelayedWake : public DelayedTask {
     sp<Looper> mLooper;
 
@@ -82,6 +89,15 @@
     }
 };
 
+class StubMessageHandler : public MessageHandler {
+public:
+    Vector<Message> messages;
+
+    virtual void handleMessage(const Message& message) {
+        messages.push(message);
+    }
+};
+
 class LooperTest : public testing::Test {
 protected:
     sp<Looper> mLooper;
@@ -421,5 +437,257 @@
             << "replacement handler callback should be invoked";
 }
 
+TEST_F(LooperTest, SendMessage_WhenOneMessageIsEnqueue_ShouldInvokeHandlerDuringNextPoll) {
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessage(handler, Message(MSG_TEST1));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was already sent";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+    EXPECT_EQ(size_t(1), handler->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
+            << "handled message";
+}
+
+TEST_F(LooperTest, SendMessage_WhenMultipleMessagesAreEnqueued_ShouldInvokeHandlersInOrderDuringNextPoll) {
+    sp<StubMessageHandler> handler1 = new StubMessageHandler();
+    sp<StubMessageHandler> handler2 = new StubMessageHandler();
+    mLooper->sendMessage(handler1, Message(MSG_TEST1));
+    mLooper->sendMessage(handler2, Message(MSG_TEST2));
+    mLooper->sendMessage(handler1, Message(MSG_TEST3));
+    mLooper->sendMessage(handler1, Message(MSG_TEST4));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was already sent";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+    EXPECT_EQ(size_t(3), handler1->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler1->messages[0].what)
+            << "handled message";
+    EXPECT_EQ(MSG_TEST3, handler1->messages[1].what)
+            << "handled message";
+    EXPECT_EQ(MSG_TEST4, handler1->messages[2].what)
+            << "handled message";
+    EXPECT_EQ(size_t(1), handler2->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST2, handler2->messages[0].what)
+            << "handled message";
+}
+
+TEST_F(LooperTest, SendMessageDelayed_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessageDelayed(ms2ns(100), handler, Message(MSG_TEST1));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "first poll should end quickly because next message timeout was computed";
+    EXPECT_EQ(ALOOPER_POLL_WAKE, result)
+            << "pollOnce result should be ALOOPER_POLL_WAKE due to wakeup";
+    EXPECT_EQ(size_t(0), handler->messages.size())
+            << "no message handled yet";
+
+    result = mLooper->pollOnce(1000);
+    elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_EQ(size_t(1), handler->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
+            << "handled message";
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "second poll should end around the time of the delayed message dispatch";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+
+    result = mLooper->pollOnce(100);
+    elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "third poll should timeout";
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there were no messages left";
+}
+
+TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessageDelayed(ms2ns(-1000), handler, Message(MSG_TEST1));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was already sent";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+    EXPECT_EQ(size_t(1), handler->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
+            << "handled message";
+}
+
+TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessageDelayed(0, handler, Message(MSG_TEST1));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was already sent";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+    EXPECT_EQ(size_t(1), handler->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
+            << "handled message";
+}
+
+TEST_F(LooperTest, SendMessageAtTime_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) {
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessageAtTime(now + ms2ns(100), handler, Message(MSG_TEST1));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "first poll should end quickly because next message timeout was computed";
+    EXPECT_EQ(ALOOPER_POLL_WAKE, result)
+            << "pollOnce result should be ALOOPER_POLL_WAKE due to wakeup";
+    EXPECT_EQ(size_t(0), handler->messages.size())
+            << "no message handled yet";
+
+    result = mLooper->pollOnce(1000);
+    elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_EQ(size_t(1), handler->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
+            << "handled message";
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "second poll should end around the time of the delayed message dispatch";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+
+    result = mLooper->pollOnce(100);
+    elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "third poll should timeout";
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there were no messages left";
+}
+
+TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) {
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessageAtTime(now - ms2ns(1000), handler, Message(MSG_TEST1));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was already sent";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+    EXPECT_EQ(size_t(1), handler->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
+            << "handled message";
+}
+
+TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) {
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessageAtTime(now, handler, Message(MSG_TEST1));
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was already sent";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent";
+    EXPECT_EQ(size_t(1), handler->messages.size())
+            << "handled message";
+    EXPECT_EQ(MSG_TEST1, handler->messages[0].what)
+            << "handled message";
+}
+
+TEST_F(LooperTest, RemoveMessage_WhenRemovingAllMessagesForHandler_ShouldRemoveThoseMessage) {
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessage(handler, Message(MSG_TEST1));
+    mLooper->sendMessage(handler, Message(MSG_TEST2));
+    mLooper->sendMessage(handler, Message(MSG_TEST3));
+    mLooper->removeMessages(handler);
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was sent so looper was awoken";
+    EXPECT_EQ(ALOOPER_POLL_WAKE, result)
+            << "pollOnce result should be ALOOPER_POLL_WAKE because looper was awoken";
+    EXPECT_EQ(size_t(0), handler->messages.size())
+            << "no messages to handle";
+
+    result = mLooper->pollOnce(0);
+
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there was nothing to do";
+    EXPECT_EQ(size_t(0), handler->messages.size())
+            << "no messages to handle";
+}
+
+TEST_F(LooperTest, RemoveMessage_WhenRemovingSomeMessagesForHandler_ShouldRemoveThoseMessage) {
+    sp<StubMessageHandler> handler = new StubMessageHandler();
+    mLooper->sendMessage(handler, Message(MSG_TEST1));
+    mLooper->sendMessage(handler, Message(MSG_TEST2));
+    mLooper->sendMessage(handler, Message(MSG_TEST3));
+    mLooper->sendMessage(handler, Message(MSG_TEST4));
+    mLooper->removeMessages(handler, MSG_TEST3);
+    mLooper->removeMessages(handler, MSG_TEST1);
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because message was sent so looper was awoken";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because two messages were sent";
+    EXPECT_EQ(size_t(2), handler->messages.size())
+            << "no messages to handle";
+    EXPECT_EQ(MSG_TEST2, handler->messages[0].what)
+            << "handled message";
+    EXPECT_EQ(MSG_TEST4, handler->messages[1].what)
+            << "handled message";
+
+    result = mLooper->pollOnce(0);
+
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there was nothing to do";
+    EXPECT_EQ(size_t(2), handler->messages.size())
+            << "no more messages to handle";
+}
 
 } // namespace android
diff --git a/libs/utils/tests/Unicode_test.cpp b/libs/utils/tests/Unicode_test.cpp
new file mode 100644
index 0000000..18c130c
--- /dev/null
+++ b/libs/utils/tests/Unicode_test.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "Unicode_test"
+#include <utils/Log.h>
+#include <utils/Unicode.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+class UnicodeTest : public testing::Test {
+protected:
+    virtual void SetUp() {
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(UnicodeTest, UTF8toUTF16ZeroLength) {
+    ssize_t measured;
+
+    const uint8_t str[] = { };
+
+    measured = utf8_to_utf16_length(str, 0);
+    EXPECT_EQ(0, measured)
+            << "Zero length input should return zero length output.";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16ASCIILength) {
+    ssize_t measured;
+
+    // U+0030 or ASCII '0'
+    const uint8_t str[] = { 0x30 };
+
+    measured = utf8_to_utf16_length(str, sizeof(str));
+    EXPECT_EQ(1, measured)
+            << "ASCII glyphs should have a length of 1 char16_t";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16Plane1Length) {
+    ssize_t measured;
+
+    // U+2323 SMILE
+    const uint8_t str[] = { 0xE2, 0x8C, 0xA3 };
+
+    measured = utf8_to_utf16_length(str, sizeof(str));
+    EXPECT_EQ(1, measured)
+            << "Plane 1 glyphs should have a length of 1 char16_t";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16SurrogateLength) {
+    ssize_t measured;
+
+    // U+10000
+    const uint8_t str[] = { 0xF0, 0x90, 0x80, 0x80 };
+
+    measured = utf8_to_utf16_length(str, sizeof(str));
+    EXPECT_EQ(2, measured)
+            << "Surrogate pairs should have a length of 2 char16_t";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16TruncatedUTF8) {
+    ssize_t measured;
+
+    // Truncated U+2323 SMILE
+    // U+2323 SMILE
+    const uint8_t str[] = { 0xE2, 0x8C };
+
+    measured = utf8_to_utf16_length(str, sizeof(str));
+    EXPECT_EQ(-1, measured)
+            << "Truncated UTF-8 should return -1 to indicate invalid";
+}
+
+TEST_F(UnicodeTest, UTF8toUTF16Normal) {
+    const uint8_t str[] = {
+        0x30, // U+0030, 1 UTF-16 character
+        0xC4, 0x80, // U+0100, 1 UTF-16 character
+        0xE2, 0x8C, 0xA3, // U+2323, 1 UTF-16 character
+        0xF0, 0x90, 0x80, 0x80, // U+10000, 2 UTF-16 character
+    };
+
+    char16_t output[1 + 1 + 1 + 2 + 1]; // Room for NULL
+
+    utf8_to_utf16(str, sizeof(str), output);
+
+    EXPECT_EQ(0x0030, output[0])
+            << "should be U+0030";
+    EXPECT_EQ(0x0100, output[1])
+            << "should be U+0100";
+    EXPECT_EQ(0x2323, output[2])
+            << "should be U+2323";
+    EXPECT_EQ(0xD800, output[3])
+            << "should be first half of surrogate U+10000";
+    EXPECT_EQ(0xDC00, output[4])
+            << "should be second half of surrogate U+10000";
+    EXPECT_EQ(NULL, output[5])
+            << "should be NULL terminated";
+}
+
+}
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 5c09dcc..a1cb23a 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -40,7 +40,6 @@
 #include <pixelflinger/pixelflinger.h>
 
 #include <private/ui/android_natives_priv.h>
-#include <private/ui/sw_gralloc_handle.h>
 
 #include <hardware/copybit.h>
 
@@ -83,6 +82,11 @@
     if (ggl_unlikely(gEGLErrorKey == -1))
         return EGL_SUCCESS;
     GLint error = (GLint)pthread_getspecific(gEGLErrorKey);
+    if (error == 0) {
+        // The TLS key has been created by another thread, but the value for
+        // this thread has not been initialized.
+        return EGL_SUCCESS;
+    }
     pthread_setspecific(gEGLErrorKey, (void*)EGL_SUCCESS);
     return error;
 }
@@ -446,15 +450,10 @@
         android_native_buffer_t* buf, int usage, void** vaddr)
 {
     int err;
-    if (sw_gralloc_handle_t::validate(buf->handle) < 0) {
-        err = module->lock(module, buf->handle,
-                usage, 0, 0, buf->width, buf->height, vaddr);
-    } else {
-        sw_gralloc_handle_t const* hnd =
-                reinterpret_cast<sw_gralloc_handle_t const*>(buf->handle);
-        *vaddr = (void*)hnd->base;
-        err = NO_ERROR;
-    }
+
+    err = module->lock(module, buf->handle,
+            usage, 0, 0, buf->width, buf->height, vaddr);
+
     return err;
 }
 
@@ -462,9 +461,9 @@
 {
     if (!buf) return BAD_VALUE;
     int err = NO_ERROR;
-    if (sw_gralloc_handle_t::validate(buf->handle) < 0) {
-        err = module->unlock(module, buf->handle);
-    }
+
+    err = module->unlock(module, buf->handle);
+
     return err;
 }
 
@@ -546,7 +545,9 @@
     if (!dirtyRegion.isEmpty()) {
         dirtyRegion.andSelf(Rect(buffer->width, buffer->height));
         if (previousBuffer) {
-            const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion));
+            // This was const Region copyBack, but that causes an
+            // internal compile error on simulator builds
+            /*const*/ Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion));
             if (!copyBack.isEmpty()) {
                 void* prevBits;
                 if (lock(previousBuffer, 
@@ -1980,7 +1981,7 @@
     if (egl_display_t::is_valid(dpy) == EGL_FALSE)
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
     // TODO: eglSwapInterval()
-    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+    return EGL_TRUE;
 }
 
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index ae924cd..c8041fc 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -8,6 +8,7 @@
 
 LOCAL_SRC_FILES:= 	       \
 	EGL/egl.cpp 	       \
+	EGL/trace.cpp              \
 	EGL/getProcAddress.cpp.arm \
 	EGL/hooks.cpp 	       \
 	EGL/Loader.cpp 	       \
@@ -33,6 +34,7 @@
 LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\"
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -DEGL_TRACE=1
 
 ifeq ($(TARGET_BOARD_PLATFORM),msm7k)
 LOCAL_CFLAGS += -DADRENO130=1
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index d26d13e..e13af1c 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -22,7 +22,7 @@
 
 #include <sys/ioctl.h>
 
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
 #include <linux/android_pmem.h>
 #endif
 
@@ -61,6 +61,10 @@
         "EGL_KHR_image "
         "EGL_KHR_image_base "
         "EGL_KHR_image_pixmap "
+        "EGL_KHR_gl_texture_2D_image "
+        "EGL_KHR_gl_texture_cubemap_image "
+        "EGL_KHR_gl_renderbuffer_image "
+        "EGL_KHR_fence_sync "
         "EGL_ANDROID_image_native_buffer "
         "EGL_ANDROID_swap_rectangle "
         ;
@@ -246,9 +250,23 @@
     EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS];
 };
 
+struct egl_sync_t : public egl_object_t
+{
+    typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref;
+
+    egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync)
+        : dpy(dpy), context(context), sync(sync)
+    {
+    }
+    EGLDisplay dpy;
+    EGLContext context;
+    EGLSyncKHR sync;
+};
+
 typedef egl_surface_t::Ref  SurfaceRef;
 typedef egl_context_t::Ref  ContextRef;
 typedef egl_image_t::Ref    ImageRef;
+typedef egl_sync_t::Ref     SyncRef;
 
 struct tls_t
 {
@@ -272,6 +290,58 @@
 EGLAPI gl_hooks_t gHooksNoContext;
 EGLAPI pthread_key_t gGLWrapperKey = -1;
 
+#if EGL_TRACE
+
+EGLAPI pthread_key_t gGLTraceKey = -1;
+
+// ----------------------------------------------------------------------------
+
+static int gEGLTraceLevel;
+static int gEGLApplicationTraceLevel;
+extern EGLAPI gl_hooks_t gHooksTrace;
+
+static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
+    pthread_setspecific(gGLTraceKey, value);
+}
+
+gl_hooks_t const* getGLTraceThreadSpecific() {
+    return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey));
+}
+
+static void initEglTraceLevel() {
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.egl.trace", value, "0");
+    int propertyLevel = atoi(value);
+    int applicationLevel = gEGLApplicationTraceLevel;
+    gEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel;
+}
+
+static void setGLHooksThreadSpecific(gl_hooks_t const *value) {
+    if (gEGLTraceLevel > 0) {
+        setGlTraceThreadSpecific(value);
+        setGlThreadSpecific(&gHooksTrace);
+    } else {
+        setGlThreadSpecific(value);
+    }
+}
+
+/*
+ * Global entry point to allow applications to modify their own trace level.
+ * The effective trace level is the max of this level and the value of debug.egl.trace.
+ */
+extern "C"
+void setGLTraceLevel(int level) {
+    gEGLApplicationTraceLevel = level;
+}
+
+#else
+
+static inline void setGLHooksThreadSpecific(gl_hooks_t const *value) {
+    setGlThreadSpecific(value);
+}
+
+#endif
+
 // ----------------------------------------------------------------------------
 
 static __attribute__((noinline))
@@ -318,6 +388,12 @@
     return tls;
 }
 
+static inline void clearError() {
+    // This must clear the error from all the underlying EGL implementations as
+    // well as the EGL wrapper layer.
+    eglGetError();
+}
+
 template<typename T>
 static __attribute__((noinline))
 T setErrorEtc(const char* caller, int line, EGLint error, T returnValue) {
@@ -410,10 +486,6 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "glEGLImageTargetTexture2DOES",
-            (__eglMustCastToProperFunctionPointerType)NULL },
-    { "glEGLImageTargetRenderbufferStorageOES",
-            (__eglMustCastToProperFunctionPointerType)NULL },
 };
 
 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
@@ -450,13 +522,17 @@
 #if !USE_FAST_TLS_KEY
     pthread_key_create(&gGLWrapperKey, NULL);
 #endif
+#if EGL_TRACE
+    pthread_key_create(&gGLTraceKey, NULL);
+    initEglTraceLevel();
+#endif
     uint32_t addr = (uint32_t)((void*)gl_no_context);
     android_memset32(
             (uint32_t*)(void*)&gHooksNoContext, 
             addr, 
             sizeof(gHooksNoContext));
 
-    setGlThreadSpecific(&gHooksNoContext);
+    setGLHooksThreadSpecific(&gHooksNoContext);
 }
 
 static pthread_once_t once_control = PTHREAD_ONCE_INIT;
@@ -490,6 +566,11 @@
     return egl_to_native_cast<egl_image_t>(image);
 }
 
+static inline
+egl_sync_t* get_sync(EGLSyncKHR sync) {
+    return egl_to_native_cast<egl_sync_t>(sync);
+}
+
 static egl_connection_t* validate_display_config(
         EGLDisplay dpy, EGLConfig config,
         egl_display_t const*& dp)
@@ -633,6 +714,8 @@
 
 EGLDisplay eglGetDisplay(NativeDisplayType display)
 {
+    clearError();
+
     uint32_t index = uint32_t(display);
     if (index >= NUM_DISPLAYS) {
         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
@@ -652,6 +735,8 @@
 
 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
 {
+    clearError();
+
     egl_display_t * const dp = get_display(dpy);
     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 
@@ -663,9 +748,17 @@
         dp->refs++;
         return EGL_TRUE;
     }
-    
-    setGlThreadSpecific(&gHooksNoContext);
-    
+
+#if EGL_TRACE
+
+    // Called both at early_init time and at this time. (Early_init is pre-zygote, so
+    // the information from that call may be stale.)
+    initEglTraceLevel();
+
+#endif
+
+    setGLHooksThreadSpecific(&gHooksNoContext);
+
     // initialize each EGL and
     // build our own extension string first, based on the extension we know
     // and the extension supported by our client implementation
@@ -775,6 +868,8 @@
     // after eglTerminate() has been called. eglTerminate() only
     // terminates an EGLDisplay, not a EGL itself.
 
+    clearError();
+
     egl_display_t* const dp = get_display(dpy);
     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 
@@ -826,6 +921,8 @@
                             EGLConfig *configs,
                             EGLint config_size, EGLint *num_config)
 {
+    clearError();
+
     egl_display_t const * const dp = get_display(dpy);
     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 
@@ -850,6 +947,8 @@
                             EGLConfig *configs, EGLint config_size,
                             EGLint *num_config)
 {
+    clearError();
+
     egl_display_t const * const dp = get_display(dpy);
     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 
@@ -963,6 +1062,8 @@
 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
         EGLint attribute, EGLint *value)
 {
+    clearError();
+
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (!cnx) return EGL_FALSE;
@@ -984,6 +1085,8 @@
                                     NativeWindowType window,
                                     const EGLint *attrib_list)
 {
+    clearError();
+
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
@@ -991,6 +1094,16 @@
         EGLConfig iConfig = dp->configs[intptr_t(config)].config;
         EGLint format;
 
+        // for now fail if the window is not a Surface.
+        int type = -1;
+        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
+        if ((anw->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &type) != 0) ||
+                (type == NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT)) {
+            LOGE("native window is a SurfaceTextureClient (currently "
+                    "unsupported)");
+            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+        }
+
         // set the native window's buffers format to match this config
         if (cnx->egl.eglGetConfigAttrib(iDpy,
                 iConfig, EGL_NATIVE_VISUAL_ID, &format)) {
@@ -1014,6 +1127,8 @@
                                     NativePixmapType pixmap,
                                     const EGLint *attrib_list)
 {
+    clearError();
+
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
@@ -1032,6 +1147,8 @@
 EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
                                     const EGLint *attrib_list)
 {
+    clearError();
+
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
@@ -1049,6 +1166,8 @@
                                     
 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1071,6 +1190,8 @@
 EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
                             EGLint attribute, EGLint *value)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1098,6 +1219,8 @@
 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
                             EGLContext share_list, const EGLint *attrib_list)
 {
+    clearError();
+
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
@@ -1135,6 +1258,8 @@
 
 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
+    clearError();
+
     ContextRef _c(ctx);
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
     
@@ -1174,6 +1299,8 @@
 EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
                             EGLSurface read, EGLContext ctx)
 {
+    clearError();
+
     // get a reference to the object passed in
     ContextRef _c(ctx);
     SurfaceRef _d(draw);
@@ -1251,7 +1378,7 @@
         loseCurrent(cur_c);
 
         if (ctx != EGL_NO_CONTEXT) {
-            setGlThreadSpecific(c->cnx->hooks[c->version]);
+            setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
             setContext(ctx);
             _c.acquire();
             _r.acquire();
@@ -1259,7 +1386,7 @@
             c->read = read;
             c->draw = draw;
         } else {
-            setGlThreadSpecific(&gHooksNoContext);
+            setGLHooksThreadSpecific(&gHooksNoContext);
             setContext(EGL_NO_CONTEXT);
         }
     }
@@ -1270,6 +1397,8 @@
 EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
                             EGLint attribute, EGLint *value)
 {
+    clearError();
+
     ContextRef _c(ctx);
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
 
@@ -1296,6 +1425,8 @@
     // could be called before eglInitialize(), but we wouldn't have a context
     // then, and this function would correctly return EGL_NO_CONTEXT.
 
+    clearError();
+
     EGLContext ctx = getContext();
     return ctx;
 }
@@ -1305,6 +1436,8 @@
     // could be called before eglInitialize(), but we wouldn't have a context
     // then, and this function would correctly return EGL_NO_SURFACE.
 
+    clearError();
+
     EGLContext ctx = getContext();
     if (ctx) {
         egl_context_t const * const c = get_context(ctx);
@@ -1323,6 +1456,8 @@
     // could be called before eglInitialize(), but we wouldn't have a context
     // then, and this function would correctly return EGL_NO_DISPLAY.
 
+    clearError();
+
     EGLContext ctx = getContext();
     if (ctx) {
         egl_context_t const * const c = get_context(ctx);
@@ -1337,6 +1472,8 @@
     // could be called before eglInitialize(), but we wouldn't have a context
     // then, and this function would return GL_TRUE, which isn't wrong.
 
+    clearError();
+
     EGLBoolean res = EGL_TRUE;
     EGLContext ctx = getContext();
     if (ctx) {
@@ -1356,7 +1493,9 @@
 {
     // could be called before eglInitialize(), but we wouldn't have a context
     // then, and this function would return GL_TRUE, which isn't wrong.
-    
+
+    clearError();
+
     EGLBoolean res = EGL_TRUE;
     EGLContext ctx = getContext();
     if (ctx) {
@@ -1390,12 +1529,37 @@
     return result;
 }
 
+// Note: Similar implementations of these functions also exist in
+// gl2.cpp and gl.cpp, and are used by applications that call the
+// exported entry points directly.
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+
+static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_impl = NULL;
+static PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES_impl = NULL;
+
+static void glEGLImageTargetTexture2DOES_wrapper(GLenum target, GLeglImageOES image)
+{
+    GLeglImageOES implImage =
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    glEGLImageTargetTexture2DOES_impl(target, implImage);
+}
+
+static void glEGLImageTargetRenderbufferStorageOES_wrapper(GLenum target, GLeglImageOES image)
+{
+    GLeglImageOES implImage =
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    glEGLImageTargetRenderbufferStorageOES_impl(target, implImage);
+}
+
 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
 {
     // eglGetProcAddress() could be the very first function called
     // in which case we must make sure we've initialized ourselves, this
     // happens the first time egl_get_display() is called.
 
+    clearError();
+
     if (egl_init_drivers() == EGL_FALSE) {
         setError(EGL_BAD_PARAMETER, NULL);
         return  NULL;
@@ -1442,11 +1606,24 @@
                     // Extensions are independent of the bound context
                     cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
                     cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
+#if EGL_TRACE
+                    gHooksTrace.ext.extensions[slot] =
+#endif
                             cnx->egl.eglGetProcAddress(procname);
                 }
             }
             if (found) {
                 addr = gExtensionForwarders[slot];
+
+                if (!strcmp(procname, "glEGLImageTargetTexture2DOES")) {
+                    glEGLImageTargetTexture2DOES_impl = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)addr;
+                    addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetTexture2DOES_wrapper;
+                }
+                if (!strcmp(procname, "glEGLImageTargetRenderbufferStorageOES")) {
+                    glEGLImageTargetRenderbufferStorageOES_impl = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)addr;
+                    addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetRenderbufferStorageOES_wrapper;
+                }
+
                 gGLExtentionMap.add(name, addr);
                 gGLExtentionSlot++;
             }
@@ -1458,6 +1635,8 @@
 
 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
 {
+    clearError();
+
     SurfaceRef _s(draw);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1471,6 +1650,8 @@
 EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
                             NativePixmapType target)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1484,6 +1665,8 @@
 
 const char* eglQueryString(EGLDisplay dpy, EGLint name)
 {
+    clearError();
+
     egl_display_t const * const dp = get_display(dpy);
     switch (name) {
         case EGL_VENDOR:
@@ -1506,6 +1689,8 @@
 EGLBoolean eglSurfaceAttrib(
         EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1523,6 +1708,8 @@
 EGLBoolean eglBindTexImage(
         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1540,6 +1727,8 @@
 EGLBoolean eglReleaseTexImage(
         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1556,6 +1745,8 @@
 
 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
 {
+    clearError();
+
     egl_display_t * const dp = get_display(dpy);
     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 
@@ -1581,6 +1772,8 @@
 
 EGLBoolean eglWaitClient(void)
 {
+    clearError();
+
     // could be called before eglInitialize(), but we wouldn't have a context
     // then, and this function would return GL_TRUE, which isn't wrong.
     EGLBoolean res = EGL_TRUE;
@@ -1604,6 +1797,8 @@
 
 EGLBoolean eglBindAPI(EGLenum api)
 {
+    clearError();
+
     if (egl_init_drivers() == EGL_FALSE) {
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
     }
@@ -1625,6 +1820,8 @@
 
 EGLenum eglQueryAPI(void)
 {
+    clearError();
+
     if (egl_init_drivers() == EGL_FALSE) {
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
     }
@@ -1645,6 +1842,8 @@
 
 EGLBoolean eglReleaseThread(void)
 {
+    clearError();
+
     // If there is context bound to the thread, release it
     loseCurrent(get_context(getContext()));
 
@@ -1664,6 +1863,8 @@
           EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
           EGLConfig config, const EGLint *attrib_list)
 {
+    clearError();
+
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (!cnx) return EGL_FALSE;
@@ -1683,6 +1884,8 @@
 EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
         const EGLint *attrib_list)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1701,6 +1904,8 @@
 
 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1720,6 +1925,8 @@
 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
         EGLClientBuffer buffer, const EGLint *attrib_list)
 {
+    clearError();
+
     if (ctx != EGL_NO_CONTEXT) {
         ContextRef _c(ctx);
         if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
@@ -1791,6 +1998,8 @@
 
 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
 {
+    clearError();
+
     egl_display_t const * const dp = get_display(dpy);
      if (dp == 0) {
          return setError(EGL_BAD_DISPLAY, EGL_FALSE);
@@ -1822,6 +2031,120 @@
      return EGL_TRUE;
 }
 
+// ----------------------------------------------------------------------------
+// EGL_EGLEXT_VERSION 5
+// ----------------------------------------------------------------------------
+
+
+EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+    clearError();
+
+    EGLContext ctx = eglGetCurrentContext();
+    ContextRef _c(ctx);
+    if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
+    if (!validate_display_context(dpy, ctx))
+        return EGL_NO_SYNC_KHR;
+    egl_display_t const * const dp = get_display(dpy);
+    egl_context_t * const c = get_context(ctx);
+    EGLSyncKHR result = EGL_NO_SYNC_KHR;
+    if (c->cnx->egl.eglCreateSyncKHR) {
+        EGLSyncKHR sync = c->cnx->egl.eglCreateSyncKHR(
+                dp->disp[c->impl].dpy, type, attrib_list);
+        if (sync == EGL_NO_SYNC_KHR)
+            return sync;
+        result = (egl_sync_t*)new egl_sync_t(dpy, ctx, sync);
+    }
+    return (EGLSyncKHR)result;
+}
+
+EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+    clearError();
+
+    egl_display_t const * const dp = get_display(dpy);
+    if (dp == 0) {
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    }
+
+    SyncRef _s(sync);
+    if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+    egl_sync_t* syncObject = get_sync(sync);
+
+    EGLContext ctx = syncObject->context;
+    ContextRef _c(ctx);
+    if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+    if (!validate_display_context(dpy, ctx))
+        return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_context_t * const c = get_context(ctx);
+    if (c->cnx->egl.eglDestroySyncKHR) {
+        result = c->cnx->egl.eglDestroySyncKHR(
+                dp->disp[c->impl].dpy, syncObject->sync);
+        if (result)
+            _s.terminate();
+    }
+    return result;
+}
+
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+    clearError();
+
+    egl_display_t const * const dp = get_display(dpy);
+    if (dp == 0) {
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    }
+
+    SyncRef _s(sync);
+    if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+    egl_sync_t* syncObject = get_sync(sync);
+
+    EGLContext ctx = syncObject->context;
+    ContextRef _c(ctx);
+    if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+    if (!validate_display_context(dpy, ctx))
+        return EGL_FALSE;
+
+    egl_context_t * const c = get_context(ctx);
+
+    if (c->cnx->egl.eglClientWaitSyncKHR) {
+        return c->cnx->egl.eglClientWaitSyncKHR(
+                dp->disp[c->impl].dpy, syncObject->sync, flags, timeout);
+    }
+
+    return EGL_FALSE;
+}
+
+EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+    clearError();
+
+    egl_display_t const * const dp = get_display(dpy);
+    if (dp == 0) {
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    }
+
+    SyncRef _s(sync);
+    if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+    egl_sync_t* syncObject = get_sync(sync);
+
+    EGLContext ctx = syncObject->context;
+    ContextRef _c(ctx);
+    if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+    if (!validate_display_context(dpy, ctx))
+        return EGL_FALSE;
+
+    egl_context_t * const c = get_context(ctx);
+
+    if (c->cnx->egl.eglGetSyncAttribKHR) {
+        return c->cnx->egl.eglGetSyncAttribKHR(
+                dp->disp[c->impl].dpy, syncObject->sync, attribute, value);
+    }
+
+    return EGL_FALSE;
+}
 
 // ----------------------------------------------------------------------------
 // ANDROID extensions
@@ -1830,6 +2153,8 @@
 EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
         EGLint left, EGLint top, EGLint width, EGLint height)
 {
+    clearError();
+
     SurfaceRef _s(draw);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1843,8 +2168,3 @@
     }
     return setError(EGL_BAD_DISPLAY, NULL);
 }
-
-EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) { return 0; }
-EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) { return 0; }
-EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) { return 0; }
-
diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in
index 5d89287..63c3c19 100644
--- a/opengl/libs/EGL/egl_entries.in
+++ b/opengl/libs/EGL/egl_entries.in
@@ -51,6 +51,13 @@
 EGL_ENTRY(EGLImageKHR, eglCreateImageKHR,   EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *)
 EGL_ENTRY(EGLBoolean,  eglDestroyImageKHR,  EGLDisplay, EGLImageKHR)
 
+/* EGL_EGLEXT_VERSION 5 */
+
+EGL_ENTRY(EGLSyncKHR,   eglCreateSyncKHR,       EGLDisplay, EGLenum, const EGLint *)
+EGL_ENTRY(EGLBoolean,   eglDestroySyncKHR,      EGLDisplay, EGLSyncKHR)
+EGL_ENTRY(EGLint,       eglClientWaitSyncKHR,   EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR)
+EGL_ENTRY(EGLBoolean,   eglGetSyncAttribKHR,    EGLDisplay, EGLSyncKHR, EGLint, EGLint *)
+
 /* ANDROID extensions */
 
 EGL_ENTRY(EGLBoolean, eglSetSwapRectangleANDROID, EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint)
diff --git a/opengl/libs/EGL/trace.cpp b/opengl/libs/EGL/trace.cpp
new file mode 100644
index 0000000..d3e96ba
--- /dev/null
+++ b/opengl/libs/EGL/trace.cpp
@@ -0,0 +1,355 @@
+/*
+ ** Copyright 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.
+ */
+
+#if EGL_TRACE
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <cutils/log.h>
+
+#include "hooks.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+struct GLenumString {
+    GLenum e;
+    const char* s;
+};
+
+#undef GL_ENUM
+#define GL_ENUM(VAL,NAME) {VAL, #NAME},
+
+static GLenumString g_enumnames[] = {
+#include "enums.in"
+};
+#undef GL_ENUM
+
+static int compareGLEnum(const void* a, const void* b) {
+    return ((const GLenumString*) a)->e - ((const GLenumString*) b)->e;
+}
+
+static const char* GLEnumToString(GLenum e) {
+    GLenumString key = {e, ""};
+    const GLenumString* result = (const GLenumString*) bsearch(
+        &key, g_enumnames,
+        sizeof(g_enumnames) / sizeof(g_enumnames[0]),
+        sizeof(g_enumnames[0]), compareGLEnum);
+    if (result) {
+        return result->s;
+    }
+    return NULL;
+}
+
+static const char* GLbooleanToString(GLboolean arg) {
+    return arg ? "GL_TRUE" : "GL_FALSE";
+}
+
+static GLenumString g_bitfieldNames[] = {
+    {0x00004000, "GL_COLOR_BUFFER_BIT"},
+    {0x00000400, "GL_STENCIL_BUFFER_BIT"},
+    {0x00000100, "GL_DEPTH_BUFFER_BIT"}
+};
+
+class StringBuilder {
+    static const int lineSize = 500;
+    char line[lineSize];
+    int line_index;
+public:
+    StringBuilder() {
+        line_index = 0;
+        line[0] = '\0';
+    }
+    void append(const char* fmt, ...) {
+        va_list argp;
+        va_start(argp, fmt);
+        line_index += vsnprintf(line + line_index, lineSize-line_index, fmt, argp);
+        va_end(argp);
+    }
+    const char* getString() {
+        line_index = 0;
+        line[lineSize-1] = '\0';
+        return line;
+    }
+};
+
+
+static void TraceGLShaderSource(GLuint shader, GLsizei count,
+    const GLchar** string, const GLint* length) {
+    LOGD("const char* shaderSrc[] = {");
+    for (GLsizei i = 0; i < count; i++) {
+        const char* comma = i < count-1 ? "," : "";
+        const GLchar* s = string[i];
+        if (length) {
+            GLint len = length[i];
+            LOGD("    \"%*s\"%s", len, s, comma);
+        } else {
+            LOGD("    \"%s\"%s", s, comma);
+        }
+    }
+    LOGD("};");
+    if (length) {
+        LOGD("const GLint* shaderLength[] = {");
+        for (GLsizei i = 0; i < count; i++) {
+            const char* comma = i < count-1 ? "," : "";
+            GLint len = length[i];
+            LOGD("    \"%d\"%s", len, comma);
+        }
+        LOGD("};");
+        LOGD("glShaderSource(%u, %u, shaderSrc, shaderLength);",
+            shader, count);
+    } else {
+        LOGD("glShaderSource(%u, %u, shaderSrc, (const GLint*) 0);",
+            shader, count);
+    }
+}
+
+static void TraceValue(int elementCount, char type,
+        GLsizei chunkCount, GLsizei chunkSize, const void* value) {
+    StringBuilder stringBuilder;
+    GLsizei count = chunkCount * chunkSize;
+    bool isFloat = type == 'f';
+    const char* typeString = isFloat ? "GLfloat" : "GLint";
+    LOGD("const %s value[] = {", typeString);
+    for (GLsizei i = 0; i < count; i++) {
+        StringBuilder builder;
+        builder.append("    ");
+        for (int e = 0; e < elementCount; e++) {
+            const char* comma = ", ";
+            if (e == elementCount-1) {
+                if (i == count - 1) {
+                    comma = "";
+                } else {
+                    comma = ",";
+                }
+            }
+            if (isFloat) {
+                builder.append("%g%s", * (GLfloat*) value, comma);
+                value = (void*) (((GLfloat*) value) + 1);
+            } else {
+                builder.append("%d%s", * (GLint*) value, comma);
+                value = (void*) (((GLint*) value) + 1);
+            }
+        }
+        LOGD("%s", builder.getString());
+        if (chunkSize > 1 && i < count-1
+                && (i % chunkSize) == (chunkSize-1)) {
+            LOGD("%s", ""); // Print a blank line.
+        }
+    }
+    LOGD("};");
+}
+
+static void TraceUniformv(int elementCount, char type,
+        GLuint location, GLsizei count, const void* value) {
+    TraceValue(elementCount, type, count, 1, value);
+    LOGD("glUniform%d%c(%u, %u, value);", elementCount, type, location, count);
+}
+
+static void TraceUniformMatrix(int matrixSideLength,
+        GLuint location, GLsizei count, GLboolean transpose, const void* value) {
+    TraceValue(matrixSideLength, 'f', count, matrixSideLength, value);
+    LOGD("glUniformMatrix%dfv(%u, %u, %s, value);", matrixSideLength, location, count,
+            GLbooleanToString(transpose));
+}
+
+static void TraceGL(const char* name, int numArgs, ...) {
+    va_list argp;
+    va_start(argp, numArgs);
+    int nameLen = strlen(name);
+
+    // glShaderSource
+    if (nameLen == 14 && strcmp(name, "glShaderSource") == 0) {
+        va_arg(argp, const char*);
+        GLuint shader = va_arg(argp, GLuint);
+        va_arg(argp, const char*);
+        GLsizei count = va_arg(argp, GLsizei);
+        va_arg(argp, const char*);
+        const GLchar** string = (const GLchar**) va_arg(argp, void*);
+        va_arg(argp, const char*);
+        const GLint* length = (const GLint*) va_arg(argp, void*);
+        va_end(argp);
+        TraceGLShaderSource(shader, count, string, length);
+        return;
+    }
+
+    // glUniformXXv
+
+    if (nameLen == 12 && strncmp(name, "glUniform", 9) == 0 && name[11] == 'v') {
+        int elementCount = name[9] - '0'; // 1..4
+        char type = name[10]; // 'f' or 'i'
+        va_arg(argp, const char*);
+        GLuint location = va_arg(argp, GLuint);
+        va_arg(argp, const char*);
+        GLsizei count = va_arg(argp, GLsizei);
+        va_arg(argp, const char*);
+        const void* value = (const void*) va_arg(argp, void*);
+        va_end(argp);
+        TraceUniformv(elementCount, type, location, count, value);
+        return;
+    }
+
+    // glUniformMatrixXfv
+
+    if (nameLen == 18 && strncmp(name, "glUniformMatrix", 15) == 0
+            && name[16] == 'f' && name[17] == 'v') {
+        int matrixSideLength = name[15] - '0'; // 2..4
+        va_arg(argp, const char*);
+        GLuint location = va_arg(argp, GLuint);
+        va_arg(argp, const char*);
+        GLsizei count = va_arg(argp, GLsizei);
+        va_arg(argp, const char*);
+        GLboolean transpose = (GLboolean) va_arg(argp, int);
+        va_arg(argp, const char*);
+        const void* value = (const void*) va_arg(argp, void*);
+        va_end(argp);
+        TraceUniformMatrix(matrixSideLength, location, count, transpose, value);
+        return;
+    }
+
+    StringBuilder builder;
+    builder.append("%s(", name);
+    for (int i = 0; i < numArgs; i++) {
+        if (i > 0) {
+            builder.append(", ");
+        }
+        const char* type = va_arg(argp, const char*);
+        bool isPtr = type[strlen(type)-1] == '*'
+            || strcmp(type, "GLeglImageOES") == 0;
+        if (isPtr) {
+            const void* arg = va_arg(argp, const void*);
+            builder.append("(%s) 0x%08x", type, (size_t) arg);
+        } else if (strcmp(type, "GLbitfield") == 0) {
+            size_t arg = va_arg(argp, size_t);
+            bool first = true;
+            for (size_t i = 0; i < sizeof(g_bitfieldNames) / sizeof(g_bitfieldNames[0]); i++) {
+                const GLenumString* b = &g_bitfieldNames[i];
+                if (b->e & arg) {
+                    if (first) {
+                        first = false;
+                    } else {
+                        builder.append(" | ");
+                    }
+                    builder.append("%s", b->s);
+                    arg &= ~b->e;
+                }
+            }
+            if (first || arg != 0) {
+                if (!first) {
+                    builder.append(" | ");
+                }
+                builder.append("0x%08x", arg);
+            }
+        } else if (strcmp(type, "GLboolean") == 0) {
+            GLboolean arg = va_arg(argp, int);
+            builder.append("%s", GLbooleanToString(arg));
+        } else if (strcmp(type, "GLclampf") == 0) {
+            double arg = va_arg(argp, double);
+            builder.append("%g", arg);
+        } else if (strcmp(type, "GLenum") == 0) {
+            GLenum arg = va_arg(argp, int);
+            const char* s = GLEnumToString(arg);
+            if (s) {
+                builder.append("%s", s);
+            } else {
+                builder.append("0x%x", arg);
+            }
+        } else if (strcmp(type, "GLfixed") == 0) {
+            int arg = va_arg(argp, int);
+            builder.append("0x%08x", arg);
+        } else if (strcmp(type, "GLfloat") == 0) {
+            double arg = va_arg(argp, double);
+            builder.append("%g", arg);
+        } else if (strcmp(type, "GLint") == 0) {
+            int arg = va_arg(argp, int);
+            const char* s = NULL;
+            if (strcmp(name, "glTexParameteri") == 0) {
+                s = GLEnumToString(arg);
+            }
+            if (s) {
+                builder.append("%s", s);
+            } else {
+                builder.append("%d", arg);
+            }
+        } else if (strcmp(type, "GLintptr") == 0) {
+            int arg = va_arg(argp, unsigned int);
+            builder.append("%u", arg);
+        } else if (strcmp(type, "GLsizei") == 0) {
+            int arg = va_arg(argp, size_t);
+            builder.append("%u", arg);
+        } else if (strcmp(type, "GLsizeiptr") == 0) {
+            int arg = va_arg(argp, size_t);
+            builder.append("%u", arg);
+        } else if (strcmp(type, "GLuint") == 0) {
+            int arg = va_arg(argp, unsigned int);
+            builder.append("%u", arg);
+        } else {
+            builder.append("/* ??? %s */", type);
+            break;
+        }
+    }
+    builder.append(");");
+    LOGD("%s", builder.getString());
+    va_end(argp);
+}
+
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+#define TRACE_GL_VOID(_api, _args, _argList, ...)                         \
+static void Tracing_ ## _api _args {                                      \
+    TraceGL(#_api, __VA_ARGS__);                                          \
+    gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl;  \
+    _c->_api _argList;                                                    \
+}
+
+#define TRACE_GL(_type, _api, _args, _argList, ...)                       \
+static _type Tracing_ ## _api _args {                                     \
+    TraceGL(#_api, __VA_ARGS__);                                          \
+    gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl;  \
+    return _c->_api _argList;                                             \
+}
+
+extern "C" {
+#include "../trace.in"
+}
+#undef TRACE_GL_VOID
+#undef TRACE_GL
+
+#define GL_ENTRY(_r, _api, ...) Tracing_ ## _api,
+
+EGLAPI gl_hooks_t gHooksTrace = {
+    {
+        #include "entries.in"
+    },
+    {
+        {0}
+    }
+};
+#undef GL_ENTRY
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+#endif // EGL_TRACE
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 18dd483..fee4609 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -39,6 +39,8 @@
 #undef CALL_GL_API
 #undef CALL_GL_API_RETURN
 
+#define DEBUG_CALL_GL_API 0
+
 #if USE_FAST_TLS_KEY
 
     #ifdef HAVE_ARM_TLS_REGISTER
@@ -74,10 +76,24 @@
 
     #define API_ENTRY(_api) _api
 
+#if DEBUG_CALL_GL_API
+
     #define CALL_GL_API(_api, ...)                                       \
         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
-        _c->_api(__VA_ARGS__)
-    
+        _c->_api(__VA_ARGS__); \
+        GLenum status = GL_NO_ERROR; \
+        while ((status = glGetError()) != GL_NO_ERROR) { \
+            LOGD("[" #_api "] 0x%x", status); \
+        }
+
+#else
+
+    #define CALL_GL_API(_api, ...)                                       \
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
+        _c->_api(__VA_ARGS__);
+
+#endif
+
     #define CALL_GL_API_RETURN(_api, ...)                                \
         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
         return _c->_api(__VA_ARGS__)
diff --git a/opengl/libs/enums.in b/opengl/libs/enums.in
new file mode 100644
index 0000000..f9752c2
--- /dev/null
+++ b/opengl/libs/enums.in
@@ -0,0 +1,594 @@
+GL_ENUM(0x0000,GL_POINTS)
+GL_ENUM(0x0001,GL_LINES)
+GL_ENUM(0x0002,GL_LINE_LOOP)
+GL_ENUM(0x0003,GL_LINE_STRIP)
+GL_ENUM(0x0004,GL_TRIANGLES)
+GL_ENUM(0x0005,GL_TRIANGLE_STRIP)
+GL_ENUM(0x0006,GL_TRIANGLE_FAN)
+GL_ENUM(0x0104,GL_ADD)
+GL_ENUM(0x0200,GL_NEVER)
+GL_ENUM(0x0201,GL_LESS)
+GL_ENUM(0x0202,GL_EQUAL)
+GL_ENUM(0x0203,GL_LEQUAL)
+GL_ENUM(0x0204,GL_GREATER)
+GL_ENUM(0x0205,GL_NOTEQUAL)
+GL_ENUM(0x0206,GL_GEQUAL)
+GL_ENUM(0x0207,GL_ALWAYS)
+GL_ENUM(0x0300,GL_SRC_COLOR)
+GL_ENUM(0x0301,GL_ONE_MINUS_SRC_COLOR)
+GL_ENUM(0x0302,GL_SRC_ALPHA)
+GL_ENUM(0x0303,GL_ONE_MINUS_SRC_ALPHA)
+GL_ENUM(0x0304,GL_DST_ALPHA)
+GL_ENUM(0x0305,GL_ONE_MINUS_DST_ALPHA)
+GL_ENUM(0x0306,GL_DST_COLOR)
+GL_ENUM(0x0307,GL_ONE_MINUS_DST_COLOR)
+GL_ENUM(0x0308,GL_SRC_ALPHA_SATURATE)
+GL_ENUM(0x0404,GL_FRONT)
+GL_ENUM(0x0405,GL_BACK)
+GL_ENUM(0x0408,GL_FRONT_AND_BACK)
+GL_ENUM(0x0500,GL_INVALID_ENUM)
+GL_ENUM(0x0501,GL_INVALID_VALUE)
+GL_ENUM(0x0502,GL_INVALID_OPERATION)
+GL_ENUM(0x0503,GL_STACK_OVERFLOW)
+GL_ENUM(0x0504,GL_STACK_UNDERFLOW)
+GL_ENUM(0x0505,GL_OUT_OF_MEMORY)
+GL_ENUM(0x0506,GL_INVALID_FRAMEBUFFER_OPERATION_OES)
+GL_ENUM(0x0800,GL_EXP)
+GL_ENUM(0x0801,GL_EXP2)
+GL_ENUM(0x0900,GL_CW)
+GL_ENUM(0x0901,GL_CCW)
+GL_ENUM(0x0B00,GL_CURRENT_COLOR)
+GL_ENUM(0x0B02,GL_CURRENT_NORMAL)
+GL_ENUM(0x0B03,GL_CURRENT_TEXTURE_COORDS)
+GL_ENUM(0x0B10,GL_POINT_SMOOTH)
+GL_ENUM(0x0B11,GL_POINT_SIZE)
+GL_ENUM(0x0B12,GL_SMOOTH_POINT_SIZE_RANGE)
+GL_ENUM(0x0B20,GL_LINE_SMOOTH)
+GL_ENUM(0x0B21,GL_LINE_WIDTH)
+GL_ENUM(0x0B22,GL_SMOOTH_LINE_WIDTH_RANGE)
+GL_ENUM(0x0B44,GL_CULL_FACE)
+GL_ENUM(0x0B45,GL_CULL_FACE_MODE)
+GL_ENUM(0x0B46,GL_FRONT_FACE)
+GL_ENUM(0x0B50,GL_LIGHTING)
+GL_ENUM(0x0B52,GL_LIGHT_MODEL_TWO_SIDE)
+GL_ENUM(0x0B53,GL_LIGHT_MODEL_AMBIENT)
+GL_ENUM(0x0B54,GL_SHADE_MODEL)
+GL_ENUM(0x0B57,GL_COLOR_MATERIAL)
+GL_ENUM(0x0B60,GL_FOG)
+GL_ENUM(0x0B62,GL_FOG_DENSITY)
+GL_ENUM(0x0B63,GL_FOG_START)
+GL_ENUM(0x0B64,GL_FOG_END)
+GL_ENUM(0x0B65,GL_FOG_MODE)
+GL_ENUM(0x0B66,GL_FOG_COLOR)
+GL_ENUM(0x0B70,GL_DEPTH_RANGE)
+GL_ENUM(0x0B71,GL_DEPTH_TEST)
+GL_ENUM(0x0B72,GL_DEPTH_WRITEMASK)
+GL_ENUM(0x0B73,GL_DEPTH_CLEAR_VALUE)
+GL_ENUM(0x0B74,GL_DEPTH_FUNC)
+GL_ENUM(0x0B90,GL_STENCIL_TEST)
+GL_ENUM(0x0B91,GL_STENCIL_CLEAR_VALUE)
+GL_ENUM(0x0B92,GL_STENCIL_FUNC)
+GL_ENUM(0x0B93,GL_STENCIL_VALUE_MASK)
+GL_ENUM(0x0B94,GL_STENCIL_FAIL)
+GL_ENUM(0x0B95,GL_STENCIL_PASS_DEPTH_FAIL)
+GL_ENUM(0x0B96,GL_STENCIL_PASS_DEPTH_PASS)
+GL_ENUM(0x0B97,GL_STENCIL_REF)
+GL_ENUM(0x0B98,GL_STENCIL_WRITEMASK)
+GL_ENUM(0x0BA0,GL_MATRIX_MODE)
+GL_ENUM(0x0BA1,GL_NORMALIZE)
+GL_ENUM(0x0BA2,GL_VIEWPORT)
+GL_ENUM(0x0BA3,GL_MODELVIEW_STACK_DEPTH)
+GL_ENUM(0x0BA4,GL_PROJECTION_STACK_DEPTH)
+GL_ENUM(0x0BA5,GL_TEXTURE_STACK_DEPTH)
+GL_ENUM(0x0BA6,GL_MODELVIEW_MATRIX)
+GL_ENUM(0x0BA7,GL_PROJECTION_MATRIX)
+GL_ENUM(0x0BA8,GL_TEXTURE_MATRIX)
+GL_ENUM(0x0BC0,GL_ALPHA_TEST)
+GL_ENUM(0x0BC1,GL_ALPHA_TEST_FUNC)
+GL_ENUM(0x0BC2,GL_ALPHA_TEST_REF)
+GL_ENUM(0x0BD0,GL_DITHER)
+GL_ENUM(0x0BE0,GL_BLEND_DST)
+GL_ENUM(0x0BE1,GL_BLEND_SRC)
+GL_ENUM(0x0BE2,GL_BLEND)
+GL_ENUM(0x0BF0,GL_LOGIC_OP_MODE)
+GL_ENUM(0x0BF2,GL_COLOR_LOGIC_OP)
+GL_ENUM(0x0C10,GL_SCISSOR_BOX)
+GL_ENUM(0x0C11,GL_SCISSOR_TEST)
+GL_ENUM(0x0C22,GL_COLOR_CLEAR_VALUE)
+GL_ENUM(0x0C23,GL_COLOR_WRITEMASK)
+GL_ENUM(0x0C50,GL_PERSPECTIVE_CORRECTION_HINT)
+GL_ENUM(0x0C51,GL_POINT_SMOOTH_HINT)
+GL_ENUM(0x0C52,GL_LINE_SMOOTH_HINT)
+GL_ENUM(0x0C54,GL_FOG_HINT)
+GL_ENUM(0x0CF5,GL_UNPACK_ALIGNMENT)
+GL_ENUM(0x0D05,GL_PACK_ALIGNMENT)
+GL_ENUM(0x0D1C,GL_ALPHA_SCALE)
+GL_ENUM(0x0D31,GL_MAX_LIGHTS)
+GL_ENUM(0x0D32,GL_MAX_CLIP_PLANES)
+GL_ENUM(0x0D33,GL_MAX_TEXTURE_SIZE)
+GL_ENUM(0x0D36,GL_MAX_MODELVIEW_STACK_DEPTH)
+GL_ENUM(0x0D38,GL_MAX_PROJECTION_STACK_DEPTH)
+GL_ENUM(0x0D39,GL_MAX_TEXTURE_STACK_DEPTH)
+GL_ENUM(0x0D3A,GL_MAX_VIEWPORT_DIMS)
+GL_ENUM(0x0D50,GL_SUBPIXEL_BITS)
+GL_ENUM(0x0D52,GL_RED_BITS)
+GL_ENUM(0x0D53,GL_GREEN_BITS)
+GL_ENUM(0x0D54,GL_BLUE_BITS)
+GL_ENUM(0x0D55,GL_ALPHA_BITS)
+GL_ENUM(0x0D56,GL_DEPTH_BITS)
+GL_ENUM(0x0D57,GL_STENCIL_BITS)
+GL_ENUM(0x0DE1,GL_TEXTURE_2D)
+GL_ENUM(0x1100,GL_DONT_CARE)
+GL_ENUM(0x1101,GL_FASTEST)
+GL_ENUM(0x1102,GL_NICEST)
+GL_ENUM(0x1200,GL_AMBIENT)
+GL_ENUM(0x1201,GL_DIFFUSE)
+GL_ENUM(0x1202,GL_SPECULAR)
+GL_ENUM(0x1203,GL_POSITION)
+GL_ENUM(0x1204,GL_SPOT_DIRECTION)
+GL_ENUM(0x1205,GL_SPOT_EXPONENT)
+GL_ENUM(0x1206,GL_SPOT_CUTOFF)
+GL_ENUM(0x1207,GL_CONSTANT_ATTENUATION)
+GL_ENUM(0x1208,GL_LINEAR_ATTENUATION)
+GL_ENUM(0x1209,GL_QUADRATIC_ATTENUATION)
+GL_ENUM(0x1400,GL_BYTE)
+GL_ENUM(0x1401,GL_UNSIGNED_BYTE)
+GL_ENUM(0x1402,GL_SHORT)
+GL_ENUM(0x1403,GL_UNSIGNED_SHORT)
+GL_ENUM(0x1404,GL_INT)
+GL_ENUM(0x1405,GL_UNSIGNED_INT)
+GL_ENUM(0x1406,GL_FLOAT)
+GL_ENUM(0x140C,GL_FIXED)
+GL_ENUM(0x1500,GL_CLEAR)
+GL_ENUM(0x1501,GL_AND)
+GL_ENUM(0x1502,GL_AND_REVERSE)
+GL_ENUM(0x1503,GL_COPY)
+GL_ENUM(0x1504,GL_AND_INVERTED)
+GL_ENUM(0x1505,GL_NOOP)
+GL_ENUM(0x1506,GL_XOR)
+GL_ENUM(0x1507,GL_OR)
+GL_ENUM(0x1508,GL_NOR)
+GL_ENUM(0x1509,GL_EQUIV)
+GL_ENUM(0x150A,GL_INVERT)
+GL_ENUM(0x150B,GL_OR_REVERSE)
+GL_ENUM(0x150C,GL_COPY_INVERTED)
+GL_ENUM(0x150D,GL_OR_INVERTED)
+GL_ENUM(0x150E,GL_NAND)
+GL_ENUM(0x150F,GL_SET)
+GL_ENUM(0x1600,GL_EMISSION)
+GL_ENUM(0x1601,GL_SHININESS)
+GL_ENUM(0x1602,GL_AMBIENT_AND_DIFFUSE)
+GL_ENUM(0x1700,GL_MODELVIEW)
+GL_ENUM(0x1701,GL_PROJECTION)
+GL_ENUM(0x1702,GL_TEXTURE)
+GL_ENUM(0x1800,GL_COLOR_EXT)
+GL_ENUM(0x1801,GL_DEPTH_EXT)
+GL_ENUM(0x1802,GL_STENCIL_EXT)
+GL_ENUM(0x1901,GL_STENCIL_INDEX)
+GL_ENUM(0x1902,GL_DEPTH_COMPONENT)
+GL_ENUM(0x1906,GL_ALPHA)
+GL_ENUM(0x1907,GL_RGB)
+GL_ENUM(0x1908,GL_RGBA)
+GL_ENUM(0x1909,GL_LUMINANCE)
+GL_ENUM(0x190A,GL_LUMINANCE_ALPHA)
+GL_ENUM(0x1D00,GL_FLAT)
+GL_ENUM(0x1D01,GL_SMOOTH)
+GL_ENUM(0x1E00,GL_KEEP)
+GL_ENUM(0x1E01,GL_REPLACE)
+GL_ENUM(0x1E02,GL_INCR)
+GL_ENUM(0x1E03,GL_DECR)
+GL_ENUM(0x1F00,GL_VENDOR)
+GL_ENUM(0x1F01,GL_RENDERER)
+GL_ENUM(0x1F02,GL_VERSION)
+GL_ENUM(0x1F03,GL_EXTENSIONS)
+GL_ENUM(0x2100,GL_MODULATE)
+GL_ENUM(0x2101,GL_DECAL)
+GL_ENUM(0x2200,GL_TEXTURE_ENV_MODE)
+GL_ENUM(0x2201,GL_TEXTURE_ENV_COLOR)
+GL_ENUM(0x2300,GL_TEXTURE_ENV)
+GL_ENUM(0x2500,GL_TEXTURE_GEN_MODE_OES)
+GL_ENUM(0x2600,GL_NEAREST)
+GL_ENUM(0x2601,GL_LINEAR)
+GL_ENUM(0x2700,GL_NEAREST_MIPMAP_NEAREST)
+GL_ENUM(0x2701,GL_LINEAR_MIPMAP_NEAREST)
+GL_ENUM(0x2702,GL_NEAREST_MIPMAP_LINEAR)
+GL_ENUM(0x2703,GL_LINEAR_MIPMAP_LINEAR)
+GL_ENUM(0x2800,GL_TEXTURE_MAG_FILTER)
+GL_ENUM(0x2801,GL_TEXTURE_MIN_FILTER)
+GL_ENUM(0x2802,GL_TEXTURE_WRAP_S)
+GL_ENUM(0x2803,GL_TEXTURE_WRAP_T)
+GL_ENUM(0x2901,GL_REPEAT)
+GL_ENUM(0x2A00,GL_POLYGON_OFFSET_UNITS)
+GL_ENUM(0x3000,GL_CLIP_PLANE0)
+GL_ENUM(0x3001,GL_CLIP_PLANE1)
+GL_ENUM(0x3002,GL_CLIP_PLANE2)
+GL_ENUM(0x3003,GL_CLIP_PLANE3)
+GL_ENUM(0x3004,GL_CLIP_PLANE4)
+GL_ENUM(0x3005,GL_CLIP_PLANE5)
+GL_ENUM(0x4000,GL_LIGHT0)
+GL_ENUM(0x4001,GL_LIGHT1)
+GL_ENUM(0x4002,GL_LIGHT2)
+GL_ENUM(0x4003,GL_LIGHT3)
+GL_ENUM(0x4004,GL_LIGHT4)
+GL_ENUM(0x4005,GL_LIGHT5)
+GL_ENUM(0x4006,GL_LIGHT6)
+GL_ENUM(0x4007,GL_LIGHT7)
+GL_ENUM(0x8000,GL_COVERAGE_BUFFER_BIT_NV)
+GL_ENUM(0x8001,GL_CONSTANT_COLOR)
+GL_ENUM(0x8002,GL_ONE_MINUS_CONSTANT_COLOR)
+GL_ENUM(0x8003,GL_CONSTANT_ALPHA)
+GL_ENUM(0x8004,GL_ONE_MINUS_CONSTANT_ALPHA)
+GL_ENUM(0x8005,GL_BLEND_COLOR)
+GL_ENUM(0x8006,GL_FUNC_ADD_OES)
+GL_ENUM(0x8007,GL_MIN_EXT)
+GL_ENUM(0x8008,GL_MAX_EXT)
+GL_ENUM(0x8009,GL_BLEND_EQUATION_RGB_OES)
+GL_ENUM(0x800A,GL_FUNC_SUBTRACT_OES)
+GL_ENUM(0x800B,GL_FUNC_REVERSE_SUBTRACT_OES)
+GL_ENUM(0x8033,GL_UNSIGNED_SHORT_4_4_4_4)
+GL_ENUM(0x8034,GL_UNSIGNED_SHORT_5_5_5_1)
+GL_ENUM(0x8037,GL_POLYGON_OFFSET_FILL)
+GL_ENUM(0x8038,GL_POLYGON_OFFSET_FACTOR)
+GL_ENUM(0x803A,GL_RESCALE_NORMAL)
+GL_ENUM(0x8051,GL_RGB8_OES)
+GL_ENUM(0x8056,GL_RGBA4_OES)
+GL_ENUM(0x8057,GL_RGB5_A1_OES)
+GL_ENUM(0x8058,GL_RGBA8_OES)
+GL_ENUM(0x8069,GL_TEXTURE_BINDING_2D)
+GL_ENUM(0x806A,GL_TEXTURE_BINDING_3D_OES)
+GL_ENUM(0x806F,GL_TEXTURE_3D_OES)
+GL_ENUM(0x8072,GL_TEXTURE_WRAP_R_OES)
+GL_ENUM(0x8073,GL_MAX_3D_TEXTURE_SIZE_OES)
+GL_ENUM(0x8074,GL_VERTEX_ARRAY)
+GL_ENUM(0x8075,GL_NORMAL_ARRAY)
+GL_ENUM(0x8076,GL_COLOR_ARRAY)
+GL_ENUM(0x8078,GL_TEXTURE_COORD_ARRAY)
+GL_ENUM(0x807A,GL_VERTEX_ARRAY_SIZE)
+GL_ENUM(0x807B,GL_VERTEX_ARRAY_TYPE)
+GL_ENUM(0x807C,GL_VERTEX_ARRAY_STRIDE)
+GL_ENUM(0x807E,GL_NORMAL_ARRAY_TYPE)
+GL_ENUM(0x807F,GL_NORMAL_ARRAY_STRIDE)
+GL_ENUM(0x8081,GL_COLOR_ARRAY_SIZE)
+GL_ENUM(0x8082,GL_COLOR_ARRAY_TYPE)
+GL_ENUM(0x8083,GL_COLOR_ARRAY_STRIDE)
+GL_ENUM(0x8088,GL_TEXTURE_COORD_ARRAY_SIZE)
+GL_ENUM(0x8089,GL_TEXTURE_COORD_ARRAY_TYPE)
+GL_ENUM(0x808A,GL_TEXTURE_COORD_ARRAY_STRIDE)
+GL_ENUM(0x808E,GL_VERTEX_ARRAY_POINTER)
+GL_ENUM(0x808F,GL_NORMAL_ARRAY_POINTER)
+GL_ENUM(0x8090,GL_COLOR_ARRAY_POINTER)
+GL_ENUM(0x8092,GL_TEXTURE_COORD_ARRAY_POINTER)
+GL_ENUM(0x809D,GL_MULTISAMPLE)
+GL_ENUM(0x809E,GL_SAMPLE_ALPHA_TO_COVERAGE)
+GL_ENUM(0x809F,GL_SAMPLE_ALPHA_TO_ONE)
+GL_ENUM(0x80A0,GL_SAMPLE_COVERAGE)
+GL_ENUM(0x80A8,GL_SAMPLE_BUFFERS)
+GL_ENUM(0x80A9,GL_SAMPLES)
+GL_ENUM(0x80AA,GL_SAMPLE_COVERAGE_VALUE)
+GL_ENUM(0x80AB,GL_SAMPLE_COVERAGE_INVERT)
+GL_ENUM(0x80C8,GL_BLEND_DST_RGB_OES)
+GL_ENUM(0x80C9,GL_BLEND_SRC_RGB_OES)
+GL_ENUM(0x80CA,GL_BLEND_DST_ALPHA_OES)
+GL_ENUM(0x80CB,GL_BLEND_SRC_ALPHA_OES)
+GL_ENUM(0x80E1,GL_BGRA_EXT)
+GL_ENUM(0x8126,GL_POINT_SIZE_MIN)
+GL_ENUM(0x8127,GL_POINT_SIZE_MAX)
+GL_ENUM(0x8128,GL_POINT_FADE_THRESHOLD_SIZE)
+GL_ENUM(0x8129,GL_POINT_DISTANCE_ATTENUATION)
+GL_ENUM(0x812F,GL_CLAMP_TO_EDGE)
+GL_ENUM(0x8191,GL_GENERATE_MIPMAP)
+GL_ENUM(0x8192,GL_GENERATE_MIPMAP_HINT)
+GL_ENUM(0x81A5,GL_DEPTH_COMPONENT16_OES)
+GL_ENUM(0x81A6,GL_DEPTH_COMPONENT24_OES)
+GL_ENUM(0x81A7,GL_DEPTH_COMPONENT32_OES)
+GL_ENUM(0x8363,GL_UNSIGNED_SHORT_5_6_5)
+GL_ENUM(0x8365,GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT)
+GL_ENUM(0x8366,GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
+GL_ENUM(0x8368,GL_UNSIGNED_INT_2_10_10_10_REV_EXT)
+GL_ENUM(0x8370,GL_MIRRORED_REPEAT_OES)
+GL_ENUM(0x83F0,GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
+GL_ENUM(0x83F1,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+GL_ENUM(0x846D,GL_ALIASED_POINT_SIZE_RANGE)
+GL_ENUM(0x846E,GL_ALIASED_LINE_WIDTH_RANGE)
+GL_ENUM(0x84C0,GL_TEXTURE0)
+GL_ENUM(0x84C1,GL_TEXTURE1)
+GL_ENUM(0x84C2,GL_TEXTURE2)
+GL_ENUM(0x84C3,GL_TEXTURE3)
+GL_ENUM(0x84C4,GL_TEXTURE4)
+GL_ENUM(0x84C5,GL_TEXTURE5)
+GL_ENUM(0x84C6,GL_TEXTURE6)
+GL_ENUM(0x84C7,GL_TEXTURE7)
+GL_ENUM(0x84C8,GL_TEXTURE8)
+GL_ENUM(0x84C9,GL_TEXTURE9)
+GL_ENUM(0x84CA,GL_TEXTURE10)
+GL_ENUM(0x84CB,GL_TEXTURE11)
+GL_ENUM(0x84CC,GL_TEXTURE12)
+GL_ENUM(0x84CD,GL_TEXTURE13)
+GL_ENUM(0x84CE,GL_TEXTURE14)
+GL_ENUM(0x84CF,GL_TEXTURE15)
+GL_ENUM(0x84D0,GL_TEXTURE16)
+GL_ENUM(0x84D1,GL_TEXTURE17)
+GL_ENUM(0x84D2,GL_TEXTURE18)
+GL_ENUM(0x84D3,GL_TEXTURE19)
+GL_ENUM(0x84D4,GL_TEXTURE20)
+GL_ENUM(0x84D5,GL_TEXTURE21)
+GL_ENUM(0x84D6,GL_TEXTURE22)
+GL_ENUM(0x84D7,GL_TEXTURE23)
+GL_ENUM(0x84D8,GL_TEXTURE24)
+GL_ENUM(0x84D9,GL_TEXTURE25)
+GL_ENUM(0x84DA,GL_TEXTURE26)
+GL_ENUM(0x84DB,GL_TEXTURE27)
+GL_ENUM(0x84DC,GL_TEXTURE28)
+GL_ENUM(0x84DD,GL_TEXTURE29)
+GL_ENUM(0x84DE,GL_TEXTURE30)
+GL_ENUM(0x84DF,GL_TEXTURE31)
+GL_ENUM(0x84E0,GL_ACTIVE_TEXTURE)
+GL_ENUM(0x84E1,GL_CLIENT_ACTIVE_TEXTURE)
+GL_ENUM(0x84E2,GL_MAX_TEXTURE_UNITS)
+GL_ENUM(0x84E7,GL_SUBTRACT)
+GL_ENUM(0x84E8,GL_MAX_RENDERBUFFER_SIZE_OES)
+GL_ENUM(0x84F2,GL_ALL_COMPLETED_NV)
+GL_ENUM(0x84F3,GL_FENCE_STATUS_NV)
+GL_ENUM(0x84F4,GL_FENCE_CONDITION_NV)
+GL_ENUM(0x84F9,GL_DEPTH_STENCIL_OES)
+GL_ENUM(0x84FA,GL_UNSIGNED_INT_24_8_OES)
+GL_ENUM(0x84FD,GL_MAX_TEXTURE_LOD_BIAS_EXT)
+GL_ENUM(0x84FE,GL_TEXTURE_MAX_ANISOTROPY_EXT)
+GL_ENUM(0x84FF,GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
+GL_ENUM(0x8500,GL_TEXTURE_FILTER_CONTROL_EXT)
+GL_ENUM(0x8501,GL_TEXTURE_LOD_BIAS_EXT)
+GL_ENUM(0x8507,GL_INCR_WRAP_OES)
+GL_ENUM(0x8508,GL_DECR_WRAP_OES)
+GL_ENUM(0x8511,GL_NORMAL_MAP_OES)
+GL_ENUM(0x8512,GL_REFLECTION_MAP_OES)
+GL_ENUM(0x8513,GL_TEXTURE_CUBE_MAP_OES)
+GL_ENUM(0x8514,GL_TEXTURE_BINDING_CUBE_MAP_OES)
+GL_ENUM(0x8515,GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES)
+GL_ENUM(0x8516,GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES)
+GL_ENUM(0x8517,GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES)
+GL_ENUM(0x8518,GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES)
+GL_ENUM(0x8519,GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES)
+GL_ENUM(0x851A,GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES)
+GL_ENUM(0x851C,GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES)
+GL_ENUM(0x8570,GL_COMBINE)
+GL_ENUM(0x8571,GL_COMBINE_RGB)
+GL_ENUM(0x8572,GL_COMBINE_ALPHA)
+GL_ENUM(0x8573,GL_RGB_SCALE)
+GL_ENUM(0x8574,GL_ADD_SIGNED)
+GL_ENUM(0x8575,GL_INTERPOLATE)
+GL_ENUM(0x8576,GL_CONSTANT)
+GL_ENUM(0x8577,GL_PRIMARY_COLOR)
+GL_ENUM(0x8578,GL_PREVIOUS)
+GL_ENUM(0x8580,GL_SRC0_RGB)
+GL_ENUM(0x8581,GL_SRC1_RGB)
+GL_ENUM(0x8582,GL_SRC2_RGB)
+GL_ENUM(0x8588,GL_SRC0_ALPHA)
+GL_ENUM(0x8589,GL_SRC1_ALPHA)
+GL_ENUM(0x858A,GL_SRC2_ALPHA)
+GL_ENUM(0x8590,GL_OPERAND0_RGB)
+GL_ENUM(0x8591,GL_OPERAND1_RGB)
+GL_ENUM(0x8592,GL_OPERAND2_RGB)
+GL_ENUM(0x8598,GL_OPERAND0_ALPHA)
+GL_ENUM(0x8599,GL_OPERAND1_ALPHA)
+GL_ENUM(0x859A,GL_OPERAND2_ALPHA)
+GL_ENUM(0x85B5,GL_VERTEX_ARRAY_BINDING_OES)
+GL_ENUM(0x8622,GL_VERTEX_ATTRIB_ARRAY_ENABLED)
+GL_ENUM(0x8623,GL_VERTEX_ATTRIB_ARRAY_SIZE)
+GL_ENUM(0x8624,GL_VERTEX_ATTRIB_ARRAY_STRIDE)
+GL_ENUM(0x8625,GL_VERTEX_ATTRIB_ARRAY_TYPE)
+GL_ENUM(0x8626,GL_CURRENT_VERTEX_ATTRIB)
+GL_ENUM(0x8645,GL_VERTEX_ATTRIB_ARRAY_POINTER)
+GL_ENUM(0x86A2,GL_NUM_COMPRESSED_TEXTURE_FORMATS)
+GL_ENUM(0x86A3,GL_COMPRESSED_TEXTURE_FORMATS)
+GL_ENUM(0x86A4,GL_MAX_VERTEX_UNITS_OES)
+GL_ENUM(0x86A9,GL_WEIGHT_ARRAY_TYPE_OES)
+GL_ENUM(0x86AA,GL_WEIGHT_ARRAY_STRIDE_OES)
+GL_ENUM(0x86AB,GL_WEIGHT_ARRAY_SIZE_OES)
+GL_ENUM(0x86AC,GL_WEIGHT_ARRAY_POINTER_OES)
+GL_ENUM(0x86AD,GL_WEIGHT_ARRAY_OES)
+GL_ENUM(0x86AE,GL_DOT3_RGB)
+GL_ENUM(0x86AF,GL_DOT3_RGBA)
+GL_ENUM(0x8740,GL_Z400_BINARY_AMD)
+GL_ENUM(0x8741,GL_PROGRAM_BINARY_LENGTH_OES)
+GL_ENUM(0x8764,GL_BUFFER_SIZE)
+GL_ENUM(0x8765,GL_BUFFER_USAGE)
+GL_ENUM(0x87EE,GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD)
+GL_ENUM(0x87F9,GL_3DC_X_AMD)
+GL_ENUM(0x87FA,GL_3DC_XY_AMD)
+GL_ENUM(0x87FE,GL_NUM_PROGRAM_BINARY_FORMATS_OES)
+GL_ENUM(0x87FF,GL_PROGRAM_BINARY_FORMATS_OES)
+GL_ENUM(0x8800,GL_STENCIL_BACK_FUNC)
+GL_ENUM(0x8801,GL_STENCIL_BACK_FAIL)
+GL_ENUM(0x8802,GL_STENCIL_BACK_PASS_DEPTH_FAIL)
+GL_ENUM(0x8803,GL_STENCIL_BACK_PASS_DEPTH_PASS)
+GL_ENUM(0x8823,GL_WRITEONLY_RENDERING_QCOM)
+GL_ENUM(0x883D,GL_BLEND_EQUATION_ALPHA_OES)
+GL_ENUM(0x8840,GL_MATRIX_PALETTE_OES)
+GL_ENUM(0x8842,GL_MAX_PALETTE_MATRICES_OES)
+GL_ENUM(0x8843,GL_CURRENT_PALETTE_MATRIX_OES)
+GL_ENUM(0x8844,GL_MATRIX_INDEX_ARRAY_OES)
+GL_ENUM(0x8846,GL_MATRIX_INDEX_ARRAY_SIZE_OES)
+GL_ENUM(0x8847,GL_MATRIX_INDEX_ARRAY_TYPE_OES)
+GL_ENUM(0x8848,GL_MATRIX_INDEX_ARRAY_STRIDE_OES)
+GL_ENUM(0x8849,GL_MATRIX_INDEX_ARRAY_POINTER_OES)
+GL_ENUM(0x8861,GL_POINT_SPRITE_OES)
+GL_ENUM(0x8862,GL_COORD_REPLACE_OES)
+GL_ENUM(0x8869,GL_MAX_VERTEX_ATTRIBS)
+GL_ENUM(0x886A,GL_VERTEX_ATTRIB_ARRAY_NORMALIZED)
+GL_ENUM(0x8872,GL_MAX_TEXTURE_IMAGE_UNITS)
+GL_ENUM(0x8892,GL_ARRAY_BUFFER)
+GL_ENUM(0x8893,GL_ELEMENT_ARRAY_BUFFER)
+GL_ENUM(0x8894,GL_ARRAY_BUFFER_BINDING)
+GL_ENUM(0x8895,GL_ELEMENT_ARRAY_BUFFER_BINDING)
+GL_ENUM(0x8896,GL_VERTEX_ARRAY_BUFFER_BINDING)
+GL_ENUM(0x8897,GL_NORMAL_ARRAY_BUFFER_BINDING)
+GL_ENUM(0x8898,GL_COLOR_ARRAY_BUFFER_BINDING)
+GL_ENUM(0x889A,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING)
+GL_ENUM(0x889E,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES)
+GL_ENUM(0x889F,GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)
+GL_ENUM(0x88B9,GL_WRITE_ONLY_OES)
+GL_ENUM(0x88BB,GL_BUFFER_ACCESS_OES)
+GL_ENUM(0x88BC,GL_BUFFER_MAPPED_OES)
+GL_ENUM(0x88BD,GL_BUFFER_MAP_POINTER_OES)
+GL_ENUM(0x88E0,GL_STREAM_DRAW)
+GL_ENUM(0x88E4,GL_STATIC_DRAW)
+GL_ENUM(0x88E8,GL_DYNAMIC_DRAW)
+GL_ENUM(0x88F0,GL_DEPTH24_STENCIL8_OES)
+GL_ENUM(0x898A,GL_POINT_SIZE_ARRAY_TYPE_OES)
+GL_ENUM(0x898B,GL_POINT_SIZE_ARRAY_STRIDE_OES)
+GL_ENUM(0x898C,GL_POINT_SIZE_ARRAY_POINTER_OES)
+GL_ENUM(0x898D,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES)
+GL_ENUM(0x898E,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES)
+GL_ENUM(0x898F,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES)
+GL_ENUM(0x8B30,GL_FRAGMENT_SHADER)
+GL_ENUM(0x8B31,GL_VERTEX_SHADER)
+GL_ENUM(0x8B4C,GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+GL_ENUM(0x8B4D,GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
+GL_ENUM(0x8B4F,GL_SHADER_TYPE)
+GL_ENUM(0x8B50,GL_FLOAT_VEC2)
+GL_ENUM(0x8B51,GL_FLOAT_VEC3)
+GL_ENUM(0x8B52,GL_FLOAT_VEC4)
+GL_ENUM(0x8B53,GL_INT_VEC2)
+GL_ENUM(0x8B54,GL_INT_VEC3)
+GL_ENUM(0x8B55,GL_INT_VEC4)
+GL_ENUM(0x8B56,GL_BOOL)
+GL_ENUM(0x8B57,GL_BOOL_VEC2)
+GL_ENUM(0x8B58,GL_BOOL_VEC3)
+GL_ENUM(0x8B59,GL_BOOL_VEC4)
+GL_ENUM(0x8B5A,GL_FLOAT_MAT2)
+GL_ENUM(0x8B5B,GL_FLOAT_MAT3)
+GL_ENUM(0x8B5C,GL_FLOAT_MAT4)
+GL_ENUM(0x8B5E,GL_SAMPLER_2D)
+GL_ENUM(0x8B5F,GL_SAMPLER_3D_OES)
+GL_ENUM(0x8B60,GL_SAMPLER_CUBE)
+GL_ENUM(0x8B80,GL_DELETE_STATUS)
+GL_ENUM(0x8B81,GL_COMPILE_STATUS)
+GL_ENUM(0x8B82,GL_LINK_STATUS)
+GL_ENUM(0x8B83,GL_VALIDATE_STATUS)
+GL_ENUM(0x8B84,GL_INFO_LOG_LENGTH)
+GL_ENUM(0x8B85,GL_ATTACHED_SHADERS)
+GL_ENUM(0x8B86,GL_ACTIVE_UNIFORMS)
+GL_ENUM(0x8B87,GL_ACTIVE_UNIFORM_MAX_LENGTH)
+GL_ENUM(0x8B88,GL_SHADER_SOURCE_LENGTH)
+GL_ENUM(0x8B89,GL_ACTIVE_ATTRIBUTES)
+GL_ENUM(0x8B8A,GL_ACTIVE_ATTRIBUTE_MAX_LENGTH)
+GL_ENUM(0x8B8B,GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES)
+GL_ENUM(0x8B8C,GL_SHADING_LANGUAGE_VERSION)
+GL_ENUM(0x8B8D,GL_CURRENT_PROGRAM)
+GL_ENUM(0x8B90,GL_PALETTE4_RGB8_OES)
+GL_ENUM(0x8B91,GL_PALETTE4_RGBA8_OES)
+GL_ENUM(0x8B92,GL_PALETTE4_R5_G6_B5_OES)
+GL_ENUM(0x8B93,GL_PALETTE4_RGBA4_OES)
+GL_ENUM(0x8B94,GL_PALETTE4_RGB5_A1_OES)
+GL_ENUM(0x8B95,GL_PALETTE8_RGB8_OES)
+GL_ENUM(0x8B96,GL_PALETTE8_RGBA8_OES)
+GL_ENUM(0x8B97,GL_PALETTE8_R5_G6_B5_OES)
+GL_ENUM(0x8B98,GL_PALETTE8_RGBA4_OES)
+GL_ENUM(0x8B99,GL_PALETTE8_RGB5_A1_OES)
+GL_ENUM(0x8B9A,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES)
+GL_ENUM(0x8B9B,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES)
+GL_ENUM(0x8B9C,GL_POINT_SIZE_ARRAY_OES)
+GL_ENUM(0x8B9D,GL_TEXTURE_CROP_RECT_OES)
+GL_ENUM(0x8B9E,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES)
+GL_ENUM(0x8B9F,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES)
+GL_ENUM(0x8BC0,GL_COUNTER_TYPE_AMD)
+GL_ENUM(0x8BC1,GL_COUNTER_RANGE_AMD)
+GL_ENUM(0x8BC2,GL_UNSIGNED_INT64_AMD)
+GL_ENUM(0x8BC3,GL_PERCENTAGE_AMD)
+GL_ENUM(0x8BC4,GL_PERFMON_RESULT_AVAILABLE_AMD)
+GL_ENUM(0x8BC5,GL_PERFMON_RESULT_SIZE_AMD)
+GL_ENUM(0x8BC6,GL_PERFMON_RESULT_AMD)
+GL_ENUM(0x8BD2,GL_TEXTURE_WIDTH_QCOM)
+GL_ENUM(0x8BD3,GL_TEXTURE_HEIGHT_QCOM)
+GL_ENUM(0x8BD4,GL_TEXTURE_DEPTH_QCOM)
+GL_ENUM(0x8BD5,GL_TEXTURE_INTERNAL_FORMAT_QCOM)
+GL_ENUM(0x8BD6,GL_TEXTURE_FORMAT_QCOM)
+GL_ENUM(0x8BD7,GL_TEXTURE_TYPE_QCOM)
+GL_ENUM(0x8BD8,GL_TEXTURE_IMAGE_VALID_QCOM)
+GL_ENUM(0x8BD9,GL_TEXTURE_NUM_LEVELS_QCOM)
+GL_ENUM(0x8BDA,GL_TEXTURE_TARGET_QCOM)
+GL_ENUM(0x8BDB,GL_TEXTURE_OBJECT_VALID_QCOM)
+GL_ENUM(0x8BDC,GL_STATE_RESTORE)
+GL_ENUM(0x8C00,GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG)
+GL_ENUM(0x8C01,GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG)
+GL_ENUM(0x8C02,GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG)
+GL_ENUM(0x8C03,GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG)
+GL_ENUM(0x8C04,GL_MODULATE_COLOR_IMG)
+GL_ENUM(0x8C05,GL_RECIP_ADD_SIGNED_ALPHA_IMG)
+GL_ENUM(0x8C06,GL_TEXTURE_ALPHA_MODULATE_IMG)
+GL_ENUM(0x8C07,GL_FACTOR_ALPHA_MODULATE_IMG)
+GL_ENUM(0x8C08,GL_FRAGMENT_ALPHA_MODULATE_IMG)
+GL_ENUM(0x8C09,GL_ADD_BLEND_IMG)
+GL_ENUM(0x8C0A,GL_SGX_BINARY_IMG)
+GL_ENUM(0x8C92,GL_ATC_RGB_AMD)
+GL_ENUM(0x8C93,GL_ATC_RGBA_EXPLICIT_ALPHA_AMD)
+GL_ENUM(0x8CA3,GL_STENCIL_BACK_REF)
+GL_ENUM(0x8CA4,GL_STENCIL_BACK_VALUE_MASK)
+GL_ENUM(0x8CA5,GL_STENCIL_BACK_WRITEMASK)
+GL_ENUM(0x8CA6,GL_FRAMEBUFFER_BINDING_OES)
+GL_ENUM(0x8CA7,GL_RENDERBUFFER_BINDING_OES)
+GL_ENUM(0x8CD0,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES)
+GL_ENUM(0x8CD1,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES)
+GL_ENUM(0x8CD2,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES)
+GL_ENUM(0x8CD3,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES)
+GL_ENUM(0x8CD4,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES)
+GL_ENUM(0x8CD5,GL_FRAMEBUFFER_COMPLETE_OES)
+GL_ENUM(0x8CD6,GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES)
+GL_ENUM(0x8CD7,GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES)
+GL_ENUM(0x8CD9,GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES)
+GL_ENUM(0x8CDA,GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES)
+GL_ENUM(0x8CDD,GL_FRAMEBUFFER_UNSUPPORTED_OES)
+GL_ENUM(0x8CE0,GL_COLOR_ATTACHMENT0_OES)
+GL_ENUM(0x8D00,GL_DEPTH_ATTACHMENT_OES)
+GL_ENUM(0x8D20,GL_STENCIL_ATTACHMENT_OES)
+GL_ENUM(0x8D40,GL_FRAMEBUFFER_OES)
+GL_ENUM(0x8D41,GL_RENDERBUFFER_OES)
+GL_ENUM(0x8D42,GL_RENDERBUFFER_WIDTH_OES)
+GL_ENUM(0x8D43,GL_RENDERBUFFER_HEIGHT_OES)
+GL_ENUM(0x8D44,GL_RENDERBUFFER_INTERNAL_FORMAT_OES)
+GL_ENUM(0x8D46,GL_STENCIL_INDEX1_OES)
+GL_ENUM(0x8D47,GL_STENCIL_INDEX4_OES)
+GL_ENUM(0x8D48,GL_STENCIL_INDEX8_OES)
+GL_ENUM(0x8D50,GL_RENDERBUFFER_RED_SIZE_OES)
+GL_ENUM(0x8D51,GL_RENDERBUFFER_GREEN_SIZE_OES)
+GL_ENUM(0x8D52,GL_RENDERBUFFER_BLUE_SIZE_OES)
+GL_ENUM(0x8D53,GL_RENDERBUFFER_ALPHA_SIZE_OES)
+GL_ENUM(0x8D54,GL_RENDERBUFFER_DEPTH_SIZE_OES)
+GL_ENUM(0x8D55,GL_RENDERBUFFER_STENCIL_SIZE_OES)
+GL_ENUM(0x8D60,GL_TEXTURE_GEN_STR_OES)
+GL_ENUM(0x8D61,GL_HALF_FLOAT_OES)
+GL_ENUM(0x8D62,GL_RGB565_OES)
+GL_ENUM(0x8D64,GL_ETC1_RGB8_OES)
+GL_ENUM(0x8D65,GL_TEXTURE_EXTERNAL_OES)
+GL_ENUM(0x8D66,GL_SAMPLER_EXTERNAL_OES)
+GL_ENUM(0x8D67,GL_TEXTURE_BINDING_EXTERNAL_OES)
+GL_ENUM(0x8D68,GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES)
+GL_ENUM(0x8DF0,GL_LOW_FLOAT)
+GL_ENUM(0x8DF1,GL_MEDIUM_FLOAT)
+GL_ENUM(0x8DF2,GL_HIGH_FLOAT)
+GL_ENUM(0x8DF3,GL_LOW_INT)
+GL_ENUM(0x8DF4,GL_MEDIUM_INT)
+GL_ENUM(0x8DF5,GL_HIGH_INT)
+GL_ENUM(0x8DF6,GL_UNSIGNED_INT_10_10_10_2_OES)
+GL_ENUM(0x8DF7,GL_INT_10_10_10_2_OES)
+GL_ENUM(0x8DF8,GL_SHADER_BINARY_FORMATS)
+GL_ENUM(0x8DF9,GL_NUM_SHADER_BINARY_FORMATS)
+GL_ENUM(0x8DFA,GL_SHADER_COMPILER)
+GL_ENUM(0x8DFB,GL_MAX_VERTEX_UNIFORM_VECTORS)
+GL_ENUM(0x8DFC,GL_MAX_VARYING_VECTORS)
+GL_ENUM(0x8DFD,GL_MAX_FRAGMENT_UNIFORM_VECTORS)
+GL_ENUM(0x8E2C,GL_DEPTH_COMPONENT16_NONLINEAR_NV)
+GL_ENUM(0x8ED0,GL_COVERAGE_COMPONENT_NV)
+GL_ENUM(0x8ED1,GL_COVERAGE_COMPONENT4_NV)
+GL_ENUM(0x8ED2,GL_COVERAGE_ATTACHMENT_NV)
+GL_ENUM(0x8ED3,GL_COVERAGE_BUFFERS_NV)
+GL_ENUM(0x8ED4,GL_COVERAGE_SAMPLES_NV)
+GL_ENUM(0x8ED5,GL_COVERAGE_ALL_FRAGMENTS_NV)
+GL_ENUM(0x8ED6,GL_COVERAGE_EDGE_FRAGMENTS_NV)
+GL_ENUM(0x8ED7,GL_COVERAGE_AUTOMATIC_NV)
+GL_ENUM(0x8FA0,GL_PERFMON_GLOBAL_MODE_QCOM)
+GL_ENUM(0x9130,GL_SGX_PROGRAM_BINARY_IMG)
+GL_ENUM(0x9133,GL_RENDERBUFFER_SAMPLES_IMG)
+GL_ENUM(0x9134,GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG)
+GL_ENUM(0x9135,GL_MAX_SAMPLES_IMG)
+GL_ENUM(0x9136,GL_TEXTURE_SAMPLES_IMG)
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index 1ab58cc..812e26d 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -141,6 +141,11 @@
 
 #endif
 
+#if EGL_TRACE
+
+extern gl_hooks_t const* getGLTraceThreadSpecific();
+
+#endif
 
 // ----------------------------------------------------------------------------
 }; // namespace android
diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles
index 120cb4b..50bbf08 100755
--- a/opengl/libs/tools/genfiles
+++ b/opengl/libs/tools/genfiles
@@ -31,3 +31,14 @@
         | sort -t, -k2 \
         | awk -F, '!_[$2]++' \
             > ../entries.in
+
+./gltracegen ../entries.in >../trace.in
+
+cat ../../include/GLES/gl.h \
+    ../../include/GLES/glext.h \
+    ../../include/GLES2/gl2.h \
+    ../../include/GLES2/gl2ext.h \
+        | ./glenumsgen \
+        | sort \
+        > ../enums.in
+
diff --git a/opengl/libs/tools/glenumsgen b/opengl/libs/tools/glenumsgen
new file mode 100755
index 0000000..2ae5fbf
--- /dev/null
+++ b/opengl/libs/tools/glenumsgen
@@ -0,0 +1,38 @@
+#! /usr/bin/perl
+#
+# Copyright (C) 2010 Google Inc.
+#
+# 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.
+
+use strict;
+
+my %enumHash = ();
+
+while (my $line = <STDIN>) {
+  next if $line =~ /^\//;
+  # Skip bitfield definitions.
+  next if $line =~ /_BIT(\d+_|\s+)/;
+  if ($line !~ /^#define\s+(\S+)\s+(0x\S+)/) {
+    next;
+  }
+  my $enumName = $1;
+  my $enumValue = $2;
+  next if exists($enumHash { $enumValue });
+  $enumHash { $enumValue } = $enumName;
+  printf("GL_ENUM(%s,%s)\n", $enumValue, $enumName);
+}
+
+
+
+
+
diff --git a/opengl/libs/tools/gltracegen b/opengl/libs/tools/gltracegen
new file mode 100755
index 0000000..da42653
--- /dev/null
+++ b/opengl/libs/tools/gltracegen
@@ -0,0 +1,95 @@
+#! /usr/bin/perl
+#
+# Copyright (C) 2010 Google Inc.
+#
+# 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.
+
+use strict;
+
+sub rtrim($)
+{
+    my $string = shift;
+    $string =~ s/\s+$//;
+    return $string;
+}
+
+while (my $line = <>) {
+  next if $line =~ /^\//;
+  next if $line =~ /^#/;
+  next if $line =~ /^\s*$/;
+  if ($line !~ /^GL_ENTRY\(([^,]+), ([^,]+), ([^\)]+)\)/) {
+    next;
+  }
+  my $type = $1;
+  my $name = $2;
+  my $args = $3;
+  
+  my @args = split ',', $args;
+  my $len = scalar(@args);
+  my $nonVoidArgLen = 0;
+  for (my $num = 0; $num < $len; $num++) {
+    if ($args[$num] ne "void") {
+      $nonVoidArgLen++;
+    }
+  }
+  if ($type eq "void") {
+    printf("TRACE_GL_VOID(");
+  } else {
+    printf("TRACE_GL(%s, ", $type);
+  }
+  
+  printf("%s, (%s), (", $name, $args);
+    for (my $num = 0; $num < $len; $num++) {
+    if ($args[$num] ne "void") {
+      if ($num > 0) {
+        print ", ";
+      }
+      #
+      # extract the name from the parameter
+      # type name
+      # const type *name
+      # type *name
+      # type name[4]
+      #
+      if ($args[$num] =~ /(\S+\s)+\**\s*([\w]+)/) {
+        printf("%s", $2);
+      }
+    }
+  }
+  printf("), %d", $nonVoidArgLen);
+  for (my $num = 0; $num < $len; $num++) {
+    if ($args[$num] ne "void") {
+      #
+      # extract the name from the parameter
+      # type name
+      # const type *name
+      # type *name
+      # type name[4]
+      #
+      my $arg = $args[$num];
+      if ($arg =~ /(\S+\s)+\**\s*([\w]+)/) {
+        my $name = $2;
+        if ($arg =~ /((const )*(\S+\s)+\**)\s*([\w]+)/) {
+          my $type = rtrim($1);
+          printf(", \"%s\", %s", $type, $name);
+        }
+      }
+    }
+  }
+  printf(")\n");
+}
+
+
+
+
+
diff --git a/opengl/libs/trace.in b/opengl/libs/trace.in
new file mode 100644
index 0000000..3d492af
--- /dev/null
+++ b/opengl/libs/trace.in
@@ -0,0 +1,376 @@
+TRACE_GL_VOID(glActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture)
+TRACE_GL_VOID(glAlphaFunc, (GLenum func, GLclampf ref), (func, ref), 2, "GLenum", func, "GLclampf", ref)
+TRACE_GL_VOID(glAlphaFuncx, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref)
+TRACE_GL_VOID(glAlphaFuncxOES, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref)
+TRACE_GL_VOID(glAttachShader, (GLuint program, GLuint shader), (program, shader), 2, "GLuint", program, "GLuint", shader)
+TRACE_GL_VOID(glBeginPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor)
+TRACE_GL_VOID(glBindAttribLocation, (GLuint program, GLuint index, const GLchar* name), (program, index, name), 3, "GLuint", program, "GLuint", index, "const GLchar*", name)
+TRACE_GL_VOID(glBindBuffer, (GLenum target, GLuint buffer), (target, buffer), 2, "GLenum", target, "GLuint", buffer)
+TRACE_GL_VOID(glBindFramebuffer, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer)
+TRACE_GL_VOID(glBindFramebufferOES, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer)
+TRACE_GL_VOID(glBindRenderbuffer, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer)
+TRACE_GL_VOID(glBindRenderbufferOES, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer)
+TRACE_GL_VOID(glBindTexture, (GLenum target, GLuint texture), (target, texture), 2, "GLenum", target, "GLuint", texture)
+TRACE_GL_VOID(glBindVertexArrayOES, (GLuint array), (array), 1, "GLuint", array)
+TRACE_GL_VOID(glBlendColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), (red, green, blue, alpha), 4, "GLclampf", red, "GLclampf", green, "GLclampf", blue, "GLclampf", alpha)
+TRACE_GL_VOID(glBlendEquation, ( GLenum mode ), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glBlendEquationOES, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glBlendEquationSeparate, (GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), 2, "GLenum", modeRGB, "GLenum", modeAlpha)
+TRACE_GL_VOID(glBlendEquationSeparateOES, (GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), 2, "GLenum", modeRGB, "GLenum", modeAlpha)
+TRACE_GL_VOID(glBlendFunc, (GLenum sfactor, GLenum dfactor), (sfactor, dfactor), 2, "GLenum", sfactor, "GLenum", dfactor)
+TRACE_GL_VOID(glBlendFuncSeparate, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha)
+TRACE_GL_VOID(glBlendFuncSeparateOES, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha)
+TRACE_GL_VOID(glBufferData, (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage), (target, size, data, usage), 4, "GLenum", target, "GLsizeiptr", size, "const GLvoid *", data, "GLenum", usage)
+TRACE_GL_VOID(glBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data), (target, offset, size, data), 4, "GLenum", target, "GLintptr", offset, "GLsizeiptr", size, "const GLvoid *", data)
+TRACE_GL(GLenum, glCheckFramebufferStatus, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL(GLenum, glCheckFramebufferStatusOES, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL_VOID(glClear, (GLbitfield mask), (mask), 1, "GLbitfield", mask)
+TRACE_GL_VOID(glClearColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), (red, green, blue, alpha), 4, "GLclampf", red, "GLclampf", green, "GLclampf", blue, "GLclampf", alpha)
+TRACE_GL_VOID(glClearColorx, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha)
+TRACE_GL_VOID(glClearColorxOES, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha)
+TRACE_GL_VOID(glClearDepthf, (GLclampf depth), (depth), 1, "GLclampf", depth)
+TRACE_GL_VOID(glClearDepthfOES, (GLclampf depth), (depth), 1, "GLclampf", depth)
+TRACE_GL_VOID(glClearDepthx, (GLclampx depth), (depth), 1, "GLclampx", depth)
+TRACE_GL_VOID(glClearDepthxOES, (GLclampx depth), (depth), 1, "GLclampx", depth)
+TRACE_GL_VOID(glClearStencil, (GLint s), (s), 1, "GLint", s)
+TRACE_GL_VOID(glClientActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture)
+TRACE_GL_VOID(glClipPlanef, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation)
+TRACE_GL_VOID(glClipPlanefIMG, (GLenum p, const GLfloat *eqn), (p, eqn), 2, "GLenum", p, "const GLfloat *", eqn)
+TRACE_GL_VOID(glClipPlanefOES, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation)
+TRACE_GL_VOID(glClipPlanex, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation)
+TRACE_GL_VOID(glClipPlanexIMG, (GLenum p, const GLfixed *eqn), (p, eqn), 2, "GLenum", p, "const GLfixed *", eqn)
+TRACE_GL_VOID(glClipPlanexOES, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation)
+TRACE_GL_VOID(glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha), (red, green, blue, alpha), 4, "GLfloat", red, "GLfloat", green, "GLfloat", blue, "GLfloat", alpha)
+TRACE_GL_VOID(glColor4ub, (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha), (red, green, blue, alpha), 4, "GLubyte", red, "GLubyte", green, "GLubyte", blue, "GLubyte", alpha)
+TRACE_GL_VOID(glColor4x, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha)
+TRACE_GL_VOID(glColor4xOES, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha)
+TRACE_GL_VOID(glColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha), (red, green, blue, alpha), 4, "GLboolean", red, "GLboolean", green, "GLboolean", blue, "GLboolean", alpha)
+TRACE_GL_VOID(glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glCompileShader, (GLuint shader), (shader), 1, "GLuint", shader)
+TRACE_GL_VOID(glCompressedTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data), (target, level, internalformat, width, height, border, imageSize, data), 8, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLint", border, "GLsizei", imageSize, "const GLvoid *", data)
+TRACE_GL_VOID(glCompressedTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data), (target, level, internalformat, width, height, depth, border, imageSize, data), 9, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLsizei", imageSize, "const GLvoid*", data)
+TRACE_GL_VOID(glCompressedTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data), (target, level, xoffset, yoffset, width, height, format, imageSize, data), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLsizei", imageSize, "const GLvoid *", data)
+TRACE_GL_VOID(glCompressedTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLsizei", imageSize, "const GLvoid*", data)
+TRACE_GL_VOID(glCopyTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border), (target, level, internalformat, x, y, width, height, border), 8, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLint", border)
+TRACE_GL_VOID(glCopyTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, x, y, width, height), 8, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glCopyTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, zoffset, x, y, width, height), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glCoverageMaskNV, (GLboolean mask), (mask), 1, "GLboolean", mask)
+TRACE_GL_VOID(glCoverageOperationNV, (GLenum operation), (operation), 1, "GLenum", operation)
+TRACE_GL(GLuint, glCreateProgram, (void), (), 0)
+TRACE_GL(GLuint, glCreateShader, (GLenum type), (type), 1, "GLenum", type)
+TRACE_GL_VOID(glCullFace, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glCurrentPaletteMatrixOES, (GLuint matrixpaletteindex), (matrixpaletteindex), 1, "GLuint", matrixpaletteindex)
+TRACE_GL_VOID(glDeleteBuffers, (GLsizei n, const GLuint *buffers), (n, buffers), 2, "GLsizei", n, "const GLuint *", buffers)
+TRACE_GL_VOID(glDeleteFencesNV, (GLsizei n, const GLuint *fences), (n, fences), 2, "GLsizei", n, "const GLuint *", fences)
+TRACE_GL_VOID(glDeleteFramebuffers, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers)
+TRACE_GL_VOID(glDeleteFramebuffersOES, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers)
+TRACE_GL_VOID(glDeletePerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors)
+TRACE_GL_VOID(glDeleteProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glDeleteRenderbuffers, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers)
+TRACE_GL_VOID(glDeleteRenderbuffersOES, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers)
+TRACE_GL_VOID(glDeleteShader, (GLuint shader), (shader), 1, "GLuint", shader)
+TRACE_GL_VOID(glDeleteTextures, (GLsizei n, const GLuint *textures), (n, textures), 2, "GLsizei", n, "const GLuint *", textures)
+TRACE_GL_VOID(glDeleteVertexArraysOES, (GLsizei n, const GLuint *arrays), (n, arrays), 2, "GLsizei", n, "const GLuint *", arrays)
+TRACE_GL_VOID(glDepthFunc, (GLenum func), (func), 1, "GLenum", func)
+TRACE_GL_VOID(glDepthMask, (GLboolean flag), (flag), 1, "GLboolean", flag)
+TRACE_GL_VOID(glDepthRangef, (GLclampf zNear, GLclampf zFar), (zNear, zFar), 2, "GLclampf", zNear, "GLclampf", zFar)
+TRACE_GL_VOID(glDepthRangefOES, (GLclampf zNear, GLclampf zFar), (zNear, zFar), 2, "GLclampf", zNear, "GLclampf", zFar)
+TRACE_GL_VOID(glDepthRangex, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar)
+TRACE_GL_VOID(glDepthRangexOES, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar)
+TRACE_GL_VOID(glDetachShader, (GLuint program, GLuint shader), (program, shader), 2, "GLuint", program, "GLuint", shader)
+TRACE_GL_VOID(glDisable, (GLenum cap), (cap), 1, "GLenum", cap)
+TRACE_GL_VOID(glDisableClientState, (GLenum array), (array), 1, "GLenum", array)
+TRACE_GL_VOID(glDisableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl)
+TRACE_GL_VOID(glDisableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index)
+TRACE_GL_VOID(glDiscardFramebufferEXT, (GLenum target, GLsizei numAttachments, const GLenum *attachments), (target, numAttachments, attachments), 3, "GLenum", target, "GLsizei", numAttachments, "const GLenum *", attachments)
+TRACE_GL_VOID(glDrawArrays, (GLenum mode, GLint first, GLsizei count), (mode, first, count), 3, "GLenum", mode, "GLint", first, "GLsizei", count)
+TRACE_GL_VOID(glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices), (mode, count, type, indices), 4, "GLenum", mode, "GLsizei", count, "GLenum", type, "const GLvoid *", indices)
+TRACE_GL_VOID(glDrawTexfOES, (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height), (x, y, z, width, height), 5, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", width, "GLfloat", height)
+TRACE_GL_VOID(glDrawTexfvOES, (const GLfloat *coords), (coords), 1, "const GLfloat *", coords)
+TRACE_GL_VOID(glDrawTexiOES, (GLint x, GLint y, GLint z, GLint width, GLint height), (x, y, z, width, height), 5, "GLint", x, "GLint", y, "GLint", z, "GLint", width, "GLint", height)
+TRACE_GL_VOID(glDrawTexivOES, (const GLint *coords), (coords), 1, "const GLint *", coords)
+TRACE_GL_VOID(glDrawTexsOES, (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height), (x, y, z, width, height), 5, "GLshort", x, "GLshort", y, "GLshort", z, "GLshort", width, "GLshort", height)
+TRACE_GL_VOID(glDrawTexsvOES, (const GLshort *coords), (coords), 1, "const GLshort *", coords)
+TRACE_GL_VOID(glDrawTexxOES, (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height), (x, y, z, width, height), 5, "GLfixed", x, "GLfixed", y, "GLfixed", z, "GLfixed", width, "GLfixed", height)
+TRACE_GL_VOID(glDrawTexxvOES, (const GLfixed *coords), (coords), 1, "const GLfixed *", coords)
+TRACE_GL_VOID(glEGLImageTargetRenderbufferStorageOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image)
+TRACE_GL_VOID(glEGLImageTargetTexture2DOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image)
+TRACE_GL_VOID(glEnable, (GLenum cap), (cap), 1, "GLenum", cap)
+TRACE_GL_VOID(glEnableClientState, (GLenum array), (array), 1, "GLenum", array)
+TRACE_GL_VOID(glEnableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl)
+TRACE_GL_VOID(glEnableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index)
+TRACE_GL_VOID(glEndPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor)
+TRACE_GL_VOID(glEndTilingQCOM, (GLbitfield preserveMask), (preserveMask), 1, "GLbitfield", preserveMask)
+TRACE_GL_VOID(glExtGetBufferPointervQCOM, (GLenum target, GLvoid **params), (target, params), 2, "GLenum", target, "GLvoid **", params)
+TRACE_GL_VOID(glExtGetBuffersQCOM, (GLuint *buffers, GLint maxBuffers, GLint *numBuffers), (buffers, maxBuffers, numBuffers), 3, "GLuint *", buffers, "GLint", maxBuffers, "GLint *", numBuffers)
+TRACE_GL_VOID(glExtGetFramebuffersQCOM, (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers), (framebuffers, maxFramebuffers, numFramebuffers), 3, "GLuint *", framebuffers, "GLint", maxFramebuffers, "GLint *", numFramebuffers)
+TRACE_GL_VOID(glExtGetProgramBinarySourceQCOM, (GLuint program, GLenum shadertype, GLchar *source, GLint *length), (program, shadertype, source, length), 4, "GLuint", program, "GLenum", shadertype, "GLchar *", source, "GLint *", length)
+TRACE_GL_VOID(glExtGetProgramsQCOM, (GLuint *programs, GLint maxPrograms, GLint *numPrograms), (programs, maxPrograms, numPrograms), 3, "GLuint *", programs, "GLint", maxPrograms, "GLint *", numPrograms)
+TRACE_GL_VOID(glExtGetRenderbuffersQCOM, (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers), (renderbuffers, maxRenderbuffers, numRenderbuffers), 3, "GLuint *", renderbuffers, "GLint", maxRenderbuffers, "GLint *", numRenderbuffers)
+TRACE_GL_VOID(glExtGetShadersQCOM, (GLuint *shaders, GLint maxShaders, GLint *numShaders), (shaders, maxShaders, numShaders), 3, "GLuint *", shaders, "GLint", maxShaders, "GLint *", numShaders)
+TRACE_GL_VOID(glExtGetTexLevelParameterivQCOM, (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params), (texture, face, level, pname, params), 5, "GLuint", texture, "GLenum", face, "GLint", level, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glExtGetTexSubImageQCOM, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "GLvoid *", texels)
+TRACE_GL_VOID(glExtGetTexturesQCOM, (GLuint *textures, GLint maxTextures, GLint *numTextures), (textures, maxTextures, numTextures), 3, "GLuint *", textures, "GLint", maxTextures, "GLint *", numTextures)
+TRACE_GL(GLboolean, glExtIsProgramBinaryQCOM, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glExtTexObjectStateOverrideiQCOM, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glFinish, (void), (), 0)
+TRACE_GL_VOID(glFinishFenceNV, (GLuint fence), (fence), 1, "GLuint", fence)
+TRACE_GL_VOID(glFlush, (void), (), 0)
+TRACE_GL_VOID(glFogf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glFogfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glFogx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glFogxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glFogxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glFogxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glFramebufferRenderbuffer, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer)
+TRACE_GL_VOID(glFramebufferRenderbufferOES, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer)
+TRACE_GL_VOID(glFramebufferTexture2D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level)
+TRACE_GL_VOID(glFramebufferTexture2DMultisampleIMG, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples), (target, attachment, textarget, texture, level, samples), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLsizei", samples)
+TRACE_GL_VOID(glFramebufferTexture2DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level)
+TRACE_GL_VOID(glFramebufferTexture3DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset), (target, attachment, textarget, texture, level, zoffset), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLint", zoffset)
+TRACE_GL_VOID(glFrontFace, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glFrustumf, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glFrustumfOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glFrustumx, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glFrustumxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glGenBuffers, (GLsizei n, GLuint *buffers), (n, buffers), 2, "GLsizei", n, "GLuint *", buffers)
+TRACE_GL_VOID(glGenFencesNV, (GLsizei n, GLuint *fences), (n, fences), 2, "GLsizei", n, "GLuint *", fences)
+TRACE_GL_VOID(glGenFramebuffers, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers)
+TRACE_GL_VOID(glGenFramebuffersOES, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers)
+TRACE_GL_VOID(glGenPerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors)
+TRACE_GL_VOID(glGenRenderbuffers, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers)
+TRACE_GL_VOID(glGenRenderbuffersOES, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers)
+TRACE_GL_VOID(glGenTextures, (GLsizei n, GLuint *textures), (n, textures), 2, "GLsizei", n, "GLuint *", textures)
+TRACE_GL_VOID(glGenVertexArraysOES, (GLsizei n, GLuint *arrays), (n, arrays), 2, "GLsizei", n, "GLuint *", arrays)
+TRACE_GL_VOID(glGenerateMipmap, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL_VOID(glGenerateMipmapOES, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL_VOID(glGetActiveAttrib, (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name), 7, "GLuint", program, "GLuint", index, "GLsizei", bufsize, "GLsizei*", length, "GLint*", size, "GLenum*", type, "GLchar*", name)
+TRACE_GL_VOID(glGetActiveUniform, (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name), 7, "GLuint", program, "GLuint", index, "GLsizei", bufsize, "GLsizei*", length, "GLint*", size, "GLenum*", type, "GLchar*", name)
+TRACE_GL_VOID(glGetAttachedShaders, (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders), (program, maxcount, count, shaders), 4, "GLuint", program, "GLsizei", maxcount, "GLsizei*", count, "GLuint*", shaders)
+TRACE_GL(int, glGetAttribLocation, (GLuint program, const GLchar* name), (program, name), 2, "GLuint", program, "const GLchar*", name)
+TRACE_GL_VOID(glGetBooleanv, (GLenum pname, GLboolean *params), (pname, params), 2, "GLenum", pname, "GLboolean *", params)
+TRACE_GL_VOID(glGetBufferParameteriv, (GLenum target, GLenum pname, GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetBufferPointervOES, (GLenum target, GLenum pname, GLvoid ** params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLvoid **", params)
+TRACE_GL_VOID(glGetClipPlanef, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn)
+TRACE_GL_VOID(glGetClipPlanefOES, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn)
+TRACE_GL_VOID(glGetClipPlanex, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn)
+TRACE_GL_VOID(glGetClipPlanexOES, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn)
+TRACE_GL_VOID(glGetDriverControlStringQCOM, (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString), (driverControl, bufSize, length, driverControlString), 4, "GLuint", driverControl, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", driverControlString)
+TRACE_GL_VOID(glGetDriverControlsQCOM, (GLint *num, GLsizei size, GLuint *driverControls), (num, size, driverControls), 3, "GLint *", num, "GLsizei", size, "GLuint *", driverControls)
+TRACE_GL(GLenum, glGetError, (void), (), 0)
+TRACE_GL_VOID(glGetFenceivNV, (GLuint fence, GLenum pname, GLint *params), (fence, pname, params), 3, "GLuint", fence, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetFixedv, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetFixedvOES, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetFloatv, (GLenum pname, GLfloat *params), (pname, params), 2, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetFramebufferAttachmentParameteriv, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetFramebufferAttachmentParameterivOES, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetIntegerv, (GLenum pname, GLint *params), (pname, params), 2, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetLightfv, (GLenum light, GLenum pname, GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetLightxv, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetLightxvOES, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetMaterialfv, (GLenum face, GLenum pname, GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetMaterialxv, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetMaterialxvOES, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetPerfMonitorCounterDataAMD, (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten), (monitor, pname, dataSize, data, bytesWritten), 5, "GLuint", monitor, "GLenum", pname, "GLsizei", dataSize, "GLuint *", data, "GLint *", bytesWritten)
+TRACE_GL_VOID(glGetPerfMonitorCounterInfoAMD, (GLuint group, GLuint counter, GLenum pname, GLvoid *data), (group, counter, pname, data), 4, "GLuint", group, "GLuint", counter, "GLenum", pname, "GLvoid *", data)
+TRACE_GL_VOID(glGetPerfMonitorCounterStringAMD, (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString), (group, counter, bufSize, length, counterString), 5, "GLuint", group, "GLuint", counter, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", counterString)
+TRACE_GL_VOID(glGetPerfMonitorCountersAMD, (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters), (group, numCounters, maxActiveCounters, counterSize, counters), 5, "GLuint", group, "GLint *", numCounters, "GLint *", maxActiveCounters, "GLsizei", counterSize, "GLuint *", counters)
+TRACE_GL_VOID(glGetPerfMonitorGroupStringAMD, (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString), (group, bufSize, length, groupString), 4, "GLuint", group, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", groupString)
+TRACE_GL_VOID(glGetPerfMonitorGroupsAMD, (GLint *numGroups, GLsizei groupsSize, GLuint *groups), (numGroups, groupsSize, groups), 3, "GLint *", numGroups, "GLsizei", groupsSize, "GLuint *", groups)
+TRACE_GL_VOID(glGetPointerv, (GLenum pname, GLvoid **params), (pname, params), 2, "GLenum", pname, "GLvoid **", params)
+TRACE_GL_VOID(glGetProgramBinaryOES, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary), (program, bufSize, length, binaryFormat, binary), 5, "GLuint", program, "GLsizei", bufSize, "GLsizei *", length, "GLenum *", binaryFormat, "GLvoid *", binary)
+TRACE_GL_VOID(glGetProgramInfoLog, (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog), (program, bufsize, length, infolog), 4, "GLuint", program, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog)
+TRACE_GL_VOID(glGetProgramiv, (GLuint program, GLenum pname, GLint* params), (program, pname, params), 3, "GLuint", program, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetRenderbufferParameteriv, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetRenderbufferParameterivOES, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetShaderInfoLog, (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog), (shader, bufsize, length, infolog), 4, "GLuint", shader, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog)
+TRACE_GL_VOID(glGetShaderPrecisionFormat, (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision), (shadertype, precisiontype, range, precision), 4, "GLenum", shadertype, "GLenum", precisiontype, "GLint*", range, "GLint*", precision)
+TRACE_GL_VOID(glGetShaderSource, (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source), (shader, bufsize, length, source), 4, "GLuint", shader, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", source)
+TRACE_GL_VOID(glGetShaderiv, (GLuint shader, GLenum pname, GLint* params), (shader, pname, params), 3, "GLuint", shader, "GLenum", pname, "GLint*", params)
+TRACE_GL(const GLubyte *, glGetString, (GLenum name), (name), 1, "GLenum", name)
+TRACE_GL_VOID(glGetTexEnvfv, (GLenum env, GLenum pname, GLfloat *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetTexEnviv, (GLenum env, GLenum pname, GLint *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetTexEnvxv, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexEnvxvOES, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexGenfvOES, (GLenum coord, GLenum pname, GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetTexGenivOES, (GLenum coord, GLenum pname, GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetTexGenxvOES, (GLenum coord, GLenum pname, GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexParameterfv, (GLenum target, GLenum pname, GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfloat *", params)
+TRACE_GL_VOID(glGetTexParameteriv, (GLenum target, GLenum pname, GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint *", params)
+TRACE_GL_VOID(glGetTexParameterxv, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetTexParameterxvOES, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params)
+TRACE_GL(int, glGetUniformLocation, (GLuint program, const GLchar* name), (program, name), 2, "GLuint", program, "const GLchar*", name)
+TRACE_GL_VOID(glGetUniformfv, (GLuint program, GLint location, GLfloat* params), (program, location, params), 3, "GLuint", program, "GLint", location, "GLfloat*", params)
+TRACE_GL_VOID(glGetUniformiv, (GLuint program, GLint location, GLint* params), (program, location, params), 3, "GLuint", program, "GLint", location, "GLint*", params)
+TRACE_GL_VOID(glGetVertexAttribPointerv, (GLuint index, GLenum pname, GLvoid** pointer), (index, pname, pointer), 3, "GLuint", index, "GLenum", pname, "GLvoid**", pointer)
+TRACE_GL_VOID(glGetVertexAttribfv, (GLuint index, GLenum pname, GLfloat* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLfloat*", params)
+TRACE_GL_VOID(glGetVertexAttribiv, (GLuint index, GLenum pname, GLint* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glHint, (GLenum target, GLenum mode), (target, mode), 2, "GLenum", target, "GLenum", mode)
+TRACE_GL(GLboolean, glIsBuffer, (GLuint buffer), (buffer), 1, "GLuint", buffer)
+TRACE_GL(GLboolean, glIsEnabled, (GLenum cap), (cap), 1, "GLenum", cap)
+TRACE_GL(GLboolean, glIsFenceNV, (GLuint fence), (fence), 1, "GLuint", fence)
+TRACE_GL(GLboolean, glIsFramebuffer, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer)
+TRACE_GL(GLboolean, glIsFramebufferOES, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer)
+TRACE_GL(GLboolean, glIsProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL(GLboolean, glIsRenderbuffer, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer)
+TRACE_GL(GLboolean, glIsRenderbufferOES, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer)
+TRACE_GL(GLboolean, glIsShader, (GLuint shader), (shader), 1, "GLuint", shader)
+TRACE_GL(GLboolean, glIsTexture, (GLuint texture), (texture), 1, "GLuint", texture)
+TRACE_GL(GLboolean, glIsVertexArrayOES, (GLuint array), (array), 1, "GLuint", array)
+TRACE_GL_VOID(glLightModelf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glLightModelfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glLightModelx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightModelxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightModelxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLightModelxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLightf, (GLenum light, GLenum pname, GLfloat param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glLightfv, (GLenum light, GLenum pname, const GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glLightx, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightxOES, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glLightxv, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLightxvOES, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glLineWidth, (GLfloat width), (width), 1, "GLfloat", width)
+TRACE_GL_VOID(glLineWidthx, (GLfixed width), (width), 1, "GLfixed", width)
+TRACE_GL_VOID(glLineWidthxOES, (GLfixed width), (width), 1, "GLfixed", width)
+TRACE_GL_VOID(glLinkProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glLoadIdentity, (void), (), 0)
+TRACE_GL_VOID(glLoadMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m)
+TRACE_GL_VOID(glLoadMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glLoadMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glLoadPaletteFromModelViewMatrixOES, (void), (), 0)
+TRACE_GL_VOID(glLogicOp, (GLenum opcode), (opcode), 1, "GLenum", opcode)
+TRACE_GL(void*, glMapBufferOES, (GLenum target, GLenum access), (target, access), 2, "GLenum", target, "GLenum", access)
+TRACE_GL_VOID(glMaterialf, (GLenum face, GLenum pname, GLfloat param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glMaterialfv, (GLenum face, GLenum pname, const GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glMaterialx, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glMaterialxOES, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glMaterialxv, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glMaterialxvOES, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glMatrixIndexPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glMatrixMode, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glMultMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m)
+TRACE_GL_VOID(glMultMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glMultMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m)
+TRACE_GL_VOID(glMultiDrawArraysEXT, (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount), (mode, first, count, primcount), 4, "GLenum", mode, "GLint *", first, "GLsizei *", count, "GLsizei", primcount)
+TRACE_GL_VOID(glMultiDrawElementsEXT, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount), (mode, count, type, indices, primcount), 5, "GLenum", mode, "const GLsizei *", count, "GLenum", type, "const GLvoid* *", indices, "GLsizei", primcount)
+TRACE_GL_VOID(glMultiTexCoord4f, (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q), (target, s, t, r, q), 5, "GLenum", target, "GLfloat", s, "GLfloat", t, "GLfloat", r, "GLfloat", q)
+TRACE_GL_VOID(glMultiTexCoord4x, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q)
+TRACE_GL_VOID(glMultiTexCoord4xOES, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q)
+TRACE_GL_VOID(glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz), (nx, ny, nz), 3, "GLfloat", nx, "GLfloat", ny, "GLfloat", nz)
+TRACE_GL_VOID(glNormal3x, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz)
+TRACE_GL_VOID(glNormal3xOES, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz)
+TRACE_GL_VOID(glNormalPointer, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glOrthof, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glOrthofOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar)
+TRACE_GL_VOID(glOrthox, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glOrthoxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar)
+TRACE_GL_VOID(glPixelStorei, (GLenum pname, GLint param), (pname, param), 2, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glPointParameterf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glPointParameterfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glPointParameterx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glPointParameterxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glPointParameterxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glPointParameterxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glPointSize, (GLfloat size), (size), 1, "GLfloat", size)
+TRACE_GL_VOID(glPointSizePointerOES, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glPointSizex, (GLfixed size), (size), 1, "GLfixed", size)
+TRACE_GL_VOID(glPointSizexOES, (GLfixed size), (size), 1, "GLfixed", size)
+TRACE_GL_VOID(glPolygonOffset, (GLfloat factor, GLfloat units), (factor, units), 2, "GLfloat", factor, "GLfloat", units)
+TRACE_GL_VOID(glPolygonOffsetx, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units)
+TRACE_GL_VOID(glPolygonOffsetxOES, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units)
+TRACE_GL_VOID(glPopMatrix, (void), (), 0)
+TRACE_GL_VOID(glProgramBinaryOES, (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length), (program, binaryFormat, binary, length), 4, "GLuint", program, "GLenum", binaryFormat, "const GLvoid *", binary, "GLint", length)
+TRACE_GL_VOID(glPushMatrix, (void), (), 0)
+TRACE_GL(GLbitfield, glQueryMatrixxOES, (GLfixed mantissa[16], GLint exponent[16]), (mantissa, exponent), 2, "GLfixed", mantissa, "GLint", exponent)
+TRACE_GL_VOID(glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels), (x, y, width, height, format, type, pixels), 7, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "GLvoid *", pixels)
+TRACE_GL_VOID(glReleaseShaderCompiler, (void), (), 0)
+TRACE_GL_VOID(glRenderbufferStorage, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRenderbufferStorageMultisampleIMG, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRenderbufferStorageOES, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z), (angle, x, y, z), 4, "GLfloat", angle, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glRotatex, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glRotatexOES, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glSampleCoverage, (GLclampf value, GLboolean invert), (value, invert), 2, "GLclampf", value, "GLboolean", invert)
+TRACE_GL_VOID(glSampleCoveragex, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert)
+TRACE_GL_VOID(glSampleCoveragexOES, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert)
+TRACE_GL_VOID(glScalef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glScalex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glScalexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glScissor, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height), 4, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glSelectPerfMonitorCountersAMD, (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList), (monitor, enable, group, numCounters, countersList), 5, "GLuint", monitor, "GLboolean", enable, "GLuint", group, "GLint", numCounters, "GLuint *", countersList)
+TRACE_GL_VOID(glSetFenceNV, (GLuint fence, GLenum condition), (fence, condition), 2, "GLuint", fence, "GLenum", condition)
+TRACE_GL_VOID(glShadeModel, (GLenum mode), (mode), 1, "GLenum", mode)
+TRACE_GL_VOID(glShaderBinary, (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length), (n, shaders, binaryformat, binary, length), 5, "GLsizei", n, "const GLuint*", shaders, "GLenum", binaryformat, "const GLvoid*", binary, "GLsizei", length)
+TRACE_GL_VOID(glShaderSource, (GLuint shader, GLsizei count, const GLchar** string, const GLint* length), (shader, count, string, length), 4, "GLuint", shader, "GLsizei", count, "const GLchar**", string, "const GLint*", length)
+TRACE_GL_VOID(glStartTilingQCOM, (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask), (x, y, width, height, preserveMask), 5, "GLuint", x, "GLuint", y, "GLuint", width, "GLuint", height, "GLbitfield", preserveMask)
+TRACE_GL_VOID(glStencilFunc, (GLenum func, GLint ref, GLuint mask), (func, ref, mask), 3, "GLenum", func, "GLint", ref, "GLuint", mask)
+TRACE_GL_VOID(glStencilFuncSeparate, (GLenum face, GLenum func, GLint ref, GLuint mask), (face, func, ref, mask), 4, "GLenum", face, "GLenum", func, "GLint", ref, "GLuint", mask)
+TRACE_GL_VOID(glStencilMask, (GLuint mask), (mask), 1, "GLuint", mask)
+TRACE_GL_VOID(glStencilMaskSeparate, (GLenum face, GLuint mask), (face, mask), 2, "GLenum", face, "GLuint", mask)
+TRACE_GL_VOID(glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass), (fail, zfail, zpass), 3, "GLenum", fail, "GLenum", zfail, "GLenum", zpass)
+TRACE_GL_VOID(glStencilOpSeparate, (GLenum face, GLenum fail, GLenum zfail, GLenum zpass), (face, fail, zfail, zpass), 4, "GLenum", face, "GLenum", fail, "GLenum", zfail, "GLenum", zpass)
+TRACE_GL(GLboolean, glTestFenceNV, (GLuint fence), (fence), 1, "GLuint", fence)
+TRACE_GL_VOID(glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glTexEnvf, (GLenum target, GLenum pname, GLfloat param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glTexEnvfv, (GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glTexEnvi, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glTexEnviv, (GLenum target, GLenum pname, const GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLint *", params)
+TRACE_GL_VOID(glTexEnvx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexEnvxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexEnvxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexEnvxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexGenfOES, (GLenum coord, GLenum pname, GLfloat param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glTexGenfvOES, (GLenum coord, GLenum pname, const GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glTexGeniOES, (GLenum coord, GLenum pname, GLint param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glTexGenivOES, (GLenum coord, GLenum pname, const GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLint *", params)
+TRACE_GL_VOID(glTexGenxOES, (GLenum coord, GLenum pname, GLfixed param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexGenxvOES, (GLenum coord, GLenum pname, const GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels), (target, level, internalformat, width, height, border, format, type, pixels), 9, "GLenum", target, "GLint", level, "GLint", internalformat, "GLsizei", width, "GLsizei", height, "GLint", border, "GLenum", format, "GLenum", type, "const GLvoid *", pixels)
+TRACE_GL_VOID(glTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels), (target, level, internalformat, width, height, depth, border, format, type, pixels), 10, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLenum", format, "GLenum", type, "const GLvoid*", pixels)
+TRACE_GL_VOID(glTexParameterf, (GLenum target, GLenum pname, GLfloat param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfloat", param)
+TRACE_GL_VOID(glTexParameterfv, (GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfloat *", params)
+TRACE_GL_VOID(glTexParameteri, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param)
+TRACE_GL_VOID(glTexParameteriv, (GLenum target, GLenum pname, const GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLint *", params)
+TRACE_GL_VOID(glTexParameterx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexParameterxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
+TRACE_GL_VOID(glTexParameterxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexParameterxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels), (target, level, xoffset, yoffset, width, height, format, type, pixels), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "const GLvoid *", pixels)
+TRACE_GL_VOID(glTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "const GLvoid*", pixels)
+TRACE_GL_VOID(glTranslatef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glTranslatex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glTranslatexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
+TRACE_GL_VOID(glUniform1f, (GLint location, GLfloat x), (location, x), 2, "GLint", location, "GLfloat", x)
+TRACE_GL_VOID(glUniform1fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v)
+TRACE_GL_VOID(glUniform1i, (GLint location, GLint x), (location, x), 2, "GLint", location, "GLint", x)
+TRACE_GL_VOID(glUniform1iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v)
+TRACE_GL_VOID(glUniform2f, (GLint location, GLfloat x, GLfloat y), (location, x, y), 3, "GLint", location, "GLfloat", x, "GLfloat", y)
+TRACE_GL_VOID(glUniform2fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v)
+TRACE_GL_VOID(glUniform2i, (GLint location, GLint x, GLint y), (location, x, y), 3, "GLint", location, "GLint", x, "GLint", y)
+TRACE_GL_VOID(glUniform2iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v)
+TRACE_GL_VOID(glUniform3f, (GLint location, GLfloat x, GLfloat y, GLfloat z), (location, x, y, z), 4, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glUniform3fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v)
+TRACE_GL_VOID(glUniform3i, (GLint location, GLint x, GLint y, GLint z), (location, x, y, z), 4, "GLint", location, "GLint", x, "GLint", y, "GLint", z)
+TRACE_GL_VOID(glUniform3iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v)
+TRACE_GL_VOID(glUniform4f, (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w), (location, x, y, z, w), 5, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", w)
+TRACE_GL_VOID(glUniform4fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v)
+TRACE_GL_VOID(glUniform4i, (GLint location, GLint x, GLint y, GLint z, GLint w), (location, x, y, z, w), 5, "GLint", location, "GLint", x, "GLint", y, "GLint", z, "GLint", w)
+TRACE_GL_VOID(glUniform4iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v)
+TRACE_GL_VOID(glUniformMatrix2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value)
+TRACE_GL_VOID(glUniformMatrix3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value)
+TRACE_GL_VOID(glUniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value)
+TRACE_GL(GLboolean, glUnmapBufferOES, (GLenum target), (target), 1, "GLenum", target)
+TRACE_GL_VOID(glUseProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glValidateProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glVertexAttrib1f, (GLuint indx, GLfloat x), (indx, x), 2, "GLuint", indx, "GLfloat", x)
+TRACE_GL_VOID(glVertexAttrib1fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values)
+TRACE_GL_VOID(glVertexAttrib2f, (GLuint indx, GLfloat x, GLfloat y), (indx, x, y), 3, "GLuint", indx, "GLfloat", x, "GLfloat", y)
+TRACE_GL_VOID(glVertexAttrib2fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values)
+TRACE_GL_VOID(glVertexAttrib3f, (GLuint indx, GLfloat x, GLfloat y, GLfloat z), (indx, x, y, z), 4, "GLuint", indx, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glVertexAttrib3fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values)
+TRACE_GL_VOID(glVertexAttrib4f, (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w), (indx, x, y, z, w), 5, "GLuint", indx, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", w)
+TRACE_GL_VOID(glVertexAttrib4fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values)
+TRACE_GL_VOID(glVertexAttribPointer, (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr), (indx, size, type, normalized, stride, ptr), 6, "GLuint", indx, "GLint", size, "GLenum", type, "GLboolean", normalized, "GLsizei", stride, "const GLvoid*", ptr)
+TRACE_GL_VOID(glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
+TRACE_GL_VOID(glViewport, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height), 4, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glWeightPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer)
diff --git a/opengl/tests/gl2_java/AndroidManifest.xml b/opengl/tests/gl2_java/AndroidManifest.xml
index 585b63f..8bb6840 100644
--- a/opengl/tests/gl2_java/AndroidManifest.xml
+++ b/opengl/tests/gl2_java/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl2_java/res/values/strings.xml b/opengl/tests/gl2_java/res/values/strings.xml
index d718b1d..06bd23c 100644
--- a/opengl/tests/gl2_java/res/values/strings.xml
+++ b/opengl/tests/gl2_java/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, 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.
-*/
+<!-- Copyright (C) 2006 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.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl2_jni/AndroidManifest.xml b/opengl/tests/gl2_jni/AndroidManifest.xml
index a72a6a5..1827e5f 100644
--- a/opengl/tests/gl2_jni/AndroidManifest.xml
+++ b/opengl/tests/gl2_jni/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl2_jni/res/values/strings.xml b/opengl/tests/gl2_jni/res/values/strings.xml
index e3f7331..a29c74b 100644
--- a/opengl/tests/gl2_jni/res/values/strings.xml
+++ b/opengl/tests/gl2_jni/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, 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.
-*/
+<!-- Copyright (C) 2006 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.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl2_yuvtex/Android.mk b/opengl/tests/gl2_yuvtex/Android.mk
new file mode 100644
index 0000000..6304700
--- /dev/null
+++ b/opengl/tests/gl2_yuvtex/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	gl2_yuvtex.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv2 \
+    libui
+
+LOCAL_MODULE:= test-opengl-gl2_yuvtex
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
new file mode 100644
index 0000000..f0b8d12
--- /dev/null
+++ b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
@@ -0,0 +1,427 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sched.h>
+#include <sys/resource.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <utils/Timers.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+using namespace android;
+
+static void printGLString(const char *name, GLenum s) {
+    // fprintf(stderr, "printGLString %s, %d\n", name, s);
+    const char *v = (const char *) glGetString(s);
+    // int error = glGetError();
+    // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+    //        (unsigned int) v);
+    // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+    //    fprintf(stderr, "GL %s = %s\n", name, v);
+    // else
+    //    fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+    fprintf(stderr, "GL %s = %s\n", name, v);
+}
+
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    if (returnVal != EGL_TRUE) {
+        fprintf(stderr, "%s() returned %d\n", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
+                error);
+    }
+}
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+    "varying vec2 yuvTexCoords;\n"
+    "void main() {\n"
+    "  yuvTexCoords = vPosition.xy + vec2(0.5, 0.5);\n"
+    "  gl_Position = vPosition;\n"
+    "}\n";
+
+static const char gFragmentShader[] = "#extension GL_OES_EGL_image_external : require\n"
+    "precision mediump float;\n"
+    "uniform samplerExternalOES yuvTexSampler;\n"
+    "varying vec2 yuvTexCoords;\n"
+    "void main() {\n"
+    "  gl_FragColor = texture2D(yuvTexSampler, yuvTexCoords);\n"
+    "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    fprintf(stderr, "Could not compile shader %d:\n%s\n",
+                            shaderType, buf);
+                    free(buf);
+                }
+            } else {
+                fprintf(stderr, "Guessing at GL_INFO_LOG_LENGTH size\n");
+                char* buf = (char*) malloc(0x1000);
+                if (buf) {
+                    glGetShaderInfoLog(shader, 0x1000, NULL, buf);
+                    fprintf(stderr, "Could not compile shader %d:\n%s\n",
+                            shaderType, buf);
+                    free(buf);
+                }
+            }
+            glDeleteShader(shader);
+            shader = 0;
+        }
+    }
+    return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
+
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+    if (!pixelShader) {
+        return 0;
+    }
+
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        checkGlError("glAttachShader");
+        glAttachShader(program, pixelShader);
+        checkGlError("glAttachShader");
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    fprintf(stderr, "Could not link program:\n%s\n", buf);
+                    free(buf);
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    return program;
+}
+
+GLuint gProgram;
+GLint gvPositionHandle;
+GLint gYuvTexSamplerHandle;
+
+bool setupGraphics(int w, int h) {
+    gProgram = createProgram(gVertexShader, gFragmentShader);
+    if (!gProgram) {
+        return false;
+    }
+    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+    checkGlError("glGetAttribLocation");
+    fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n",
+            gvPositionHandle);
+    gYuvTexSamplerHandle = glGetUniformLocation(gProgram, "yuvTexSampler");
+    checkGlError("glGetUniformLocation");
+    fprintf(stderr, "glGetUniformLocation(\"yuvTexSampler\") = %d\n",
+            gYuvTexSamplerHandle);
+
+    glViewport(0, 0, w, h);
+    checkGlError("glViewport");
+    return true;
+}
+
+int align(int x, int a) {
+    return (x + (a-1)) & (~(a-1));
+}
+
+const int yuvTexWidth = 608;
+const int yuvTexHeight = 480;
+const int yuvTexUsage = GraphicBuffer::USAGE_HW_TEXTURE |
+        GraphicBuffer::USAGE_SW_WRITE_RARELY;
+const int yuvTexFormat = HAL_PIXEL_FORMAT_YV12;
+const int yuvTexOffsetY = 0;
+const bool yuvTexSameUV = false;
+static sp<GraphicBuffer> yuvTexBuffer;
+static GLuint yuvTex;
+
+bool setupYuvTexSurface(EGLDisplay dpy, EGLContext context) {
+    int blockWidth = yuvTexWidth > 16 ? yuvTexWidth / 16 : 1;
+    int blockHeight = yuvTexHeight > 16 ? yuvTexHeight / 16 : 1;
+    yuvTexBuffer = new GraphicBuffer(yuvTexWidth, yuvTexHeight, yuvTexFormat,
+            yuvTexUsage);
+    int yuvTexStrideY = yuvTexBuffer->getStride();
+    int yuvTexOffsetV = yuvTexStrideY * yuvTexHeight;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * yuvTexHeight/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    char* buf = NULL;
+    status_t err = yuvTexBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
+    if (err != 0) {
+        fprintf(stderr, "yuvTexBuffer->lock(...) failed: %d\n", err);
+        return false;
+    }
+    for (int x = 0; x < yuvTexWidth; x++) {
+        for (int y = 0; y < yuvTexHeight; y++) {
+            int parityX = (x / blockWidth) & 1;
+            int parityY = (y / blockHeight) & 1;
+            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+            if (x < yuvTexWidth / 2 && y < yuvTexHeight / 2) {
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+                if (yuvTexSameUV) {
+                    buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = intensity;
+                } else if (x < yuvTexWidth / 4 && y < yuvTexHeight / 4) {
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = intensity;
+                }
+            }
+        }
+    }
+
+    err = yuvTexBuffer->unlock();
+    if (err != 0) {
+        fprintf(stderr, "yuvTexBuffer->unlock() failed: %d\n", err);
+        return false;
+    }
+
+    EGLClientBuffer clientBuffer = (EGLClientBuffer)yuvTexBuffer->getNativeBuffer();
+    EGLImageKHR img = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+            clientBuffer, 0);
+    checkEglError("eglCreateImageKHR");
+    if (img == EGL_NO_IMAGE_KHR) {
+        return false;
+    }
+
+    glGenTextures(1, &yuvTex);
+    checkGlError("glGenTextures");
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex);
+    checkGlError("glBindTexture");
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img);
+    checkGlError("glEGLImageTargetTexture2DOES");
+
+    return true;
+}
+
+const GLfloat gTriangleVertices[] = {
+    -0.5f, 0.5f,
+    -0.5f, -0.5f,
+    0.5f, -0.5f,
+    0.5f, 0.5f,
+};
+
+void renderFrame() {
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    checkGlError("glClearColor");
+    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    checkGlError("glClear");
+
+    glUseProgram(gProgram);
+    checkGlError("glUseProgram");
+
+    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+    checkGlError("glVertexAttribPointer");
+    glEnableVertexAttribArray(gvPositionHandle);
+    checkGlError("glEnableVertexAttribArray");
+
+    glUniform1i(gYuvTexSamplerHandle, 0);
+    checkGlError("glUniform1i");
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex);
+    checkGlError("glBindTexture");
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    checkGlError("glDrawArrays");
+}
+
+void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            printf(" %s: ", names[j].name);
+            printf("%d (0x%x)", value, value);
+        }
+    }
+    printf("\n");
+}
+
+int main(int argc, char** argv) {
+    EGLBoolean returnValue;
+    EGLConfig myConfig = {0};
+
+    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint s_configAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_NONE };
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLSurface surface;
+    EGLint w, h;
+
+    EGLDisplay dpy;
+
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+        return 0;
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    if (returnValue != EGL_TRUE) {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    EGLNativeWindowType window = android_createDisplaySurface();
+    returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
+    if (returnValue) {
+        printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
+        return 1;
+    }
+
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
+
+    printf("Chose this configuration:\n");
+    printEGLConfiguration(dpy, myConfig);
+
+    surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        printf("gelCreateWindowSurface failed.\n");
+        return 1;
+    }
+
+    context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
+        printf("eglCreateContext failed\n");
+        return 1;
+    }
+    returnValue = eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent", returnValue);
+    if (returnValue != EGL_TRUE) {
+        return 1;
+    }
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+    checkEglError("eglQuerySurface");
+    GLint dim = w < h ? w : h;
+
+    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
+
+    if(!setupYuvTexSurface(dpy, context)) {
+        fprintf(stderr, "Could not set up texture surface.\n");
+        return 1;
+    }
+
+    if(!setupGraphics(w, h)) {
+        fprintf(stderr, "Could not set up graphics.\n");
+        return 1;
+    }
+
+    for (;;) {
+        renderFrame();
+        eglSwapBuffers(dpy, surface);
+        checkEglError("eglSwapBuffers");
+    }
+
+    return 0;
+}
diff --git a/opengl/tests/gl_jni/AndroidManifest.xml b/opengl/tests/gl_jni/AndroidManifest.xml
index 64bd6bf..5d0ec96 100644
--- a/opengl/tests/gl_jni/AndroidManifest.xml
+++ b/opengl/tests/gl_jni/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gl_jni/res/values/strings.xml b/opengl/tests/gl_jni/res/values/strings.xml
index 880f5c9..aee9fa0 100644
--- a/opengl/tests/gl_jni/res/values/strings.xml
+++ b/opengl/tests/gl_jni/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, 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.
-*/
+<!-- Copyright (C) 2006 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.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/gl_perf/Android.mk b/opengl/tests/gl_perf/Android.mk
new file mode 100644
index 0000000..37647ca
--- /dev/null
+++ b/opengl/tests/gl_perf/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	gl2_perf.cpp \
+	filltest.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv2 \
+    libui
+
+LOCAL_MODULE:= test-opengl-gl2_perf
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/gl_perf/fill_common.cpp b/opengl/tests/gl_perf/fill_common.cpp
new file mode 100644
index 0000000..a069f67
--- /dev/null
+++ b/opengl/tests/gl_perf/fill_common.cpp
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2007 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 "fragment_shaders.cpp"
+
+FILE * fOut = NULL;
+void ptSwap();
+
+static char gCurrentTestName[1024];
+static uint32_t gWidth = 0;
+static uint32_t gHeight = 0;
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        LOGE("after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    LOGE("Could not compile shader %d:\n%s\n", shaderType, buf);
+                    free(buf);
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+    }
+    return shader;
+}
+
+enum {
+    A_POS,
+    A_COLOR,
+    A_TEX0,
+    A_TEX1
+};
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
+
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+    if (!pixelShader) {
+        return 0;
+    }
+
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        checkGlError("glAttachShader v");
+        glAttachShader(program, pixelShader);
+        checkGlError("glAttachShader p");
+
+        glBindAttribLocation(program, A_POS, "a_pos");
+        glBindAttribLocation(program, A_COLOR, "a_color");
+        glBindAttribLocation(program, A_TEX0, "a_tex0");
+        glBindAttribLocation(program, A_TEX1, "a_tex1");
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    LOGE("Could not link program:\n%s\n", buf);
+                    free(buf);
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    checkGlError("createProgram");
+    glUseProgram(program);
+    return program;
+}
+
+uint64_t getTime() {
+    struct timespec t;
+    clock_gettime(CLOCK_MONOTONIC, &t);
+    return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
+}
+
+uint64_t gTime;
+void startTimer() {
+    gTime = getTime();
+}
+
+
+static void endTimer(int count) {
+    uint64_t t2 = getTime();
+    double delta = ((double)(t2 - gTime)) / 1000000000;
+    double pixels = (gWidth * gHeight) * count;
+    double mpps = pixels / delta / 1000000;
+    double dc60 = ((double)count) / delta / 60;
+
+    if (fOut) {
+        fprintf(fOut, "%s, %f, %f\r\n", gCurrentTestName, mpps, dc60);
+        fflush(fOut);
+    } else {
+        printf("%s, %f, %f\n", gCurrentTestName, mpps, dc60);
+    }
+    LOGI("%s, %f, %f\r\n", gCurrentTestName, mpps, dc60);
+}
+
+
+static const char gVertexShader[] =
+    "attribute vec4 a_pos;\n"
+    "attribute vec4 a_color;\n"
+    "attribute vec2 a_tex0;\n"
+    "attribute vec2 a_tex1;\n"
+    "varying vec4 v_color;\n"
+    "varying vec2 v_tex0;\n"
+    "varying vec2 v_tex1;\n"
+    "uniform vec2 u_texOff;\n"
+
+    "void main() {\n"
+    "    v_color = a_color;\n"
+    "    v_tex0 = a_tex0;\n"
+    "    v_tex1 = a_tex1;\n"
+    "    v_tex0.x += u_texOff.x;\n"
+    "    v_tex1.y += u_texOff.y;\n"
+    "    gl_Position = a_pos;\n"
+    "}\n";
+
+static void setupVA() {
+    static const float vtx[] = {
+        -1.0f,-1.0f,
+         1.0f,-1.0f,
+        -1.0f, 1.0f,
+         1.0f, 1.0f };
+    static const float color[] = {
+        1.0f,0.0f,1.0f,1.0f,
+        0.0f,0.0f,1.0f,1.0f,
+        1.0f,1.0f,0.0f,1.0f,
+        1.0f,1.0f,1.0f,1.0f };
+    static const float tex0[] = {
+        0.0f,0.0f,
+        1.0f,0.0f,
+        0.0f,1.0f,
+        1.0f,1.0f };
+    static const float tex1[] = {
+        1.0f,0.0f,
+        1.0f,1.0f,
+        0.0f,1.0f,
+        0.0f,0.0f };
+
+    glEnableVertexAttribArray(A_POS);
+    glEnableVertexAttribArray(A_COLOR);
+    glEnableVertexAttribArray(A_TEX0);
+    glEnableVertexAttribArray(A_TEX1);
+
+    glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx);
+    glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color);
+    glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0);
+    glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1);
+}
+
+static void randUniform(int pgm, const char *var) {
+    int loc = glGetUniformLocation(pgm, var);
+    if (loc >= 0) {
+        float x = ((float)rand()) / RAND_MAX;
+        float y = ((float)rand()) / RAND_MAX;
+        float z = ((float)rand()) / RAND_MAX;
+        float w = ((float)rand()) / RAND_MAX;
+        glUniform4f(loc, x, y, z, w);
+    }
+}
+
+static void doLoop(bool warmup, int pgm, uint32_t passCount) {
+    if (warmup) {
+        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+        ptSwap();
+        glFinish();
+        return;
+    }
+
+    startTimer();
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    for (uint32_t ct=0; ct < passCount; ct++) {
+        int loc = glGetUniformLocation(pgm, "u_texOff");
+        glUniform2f(loc, ((float)ct) / passCount, ((float)ct) / 2.f / passCount);
+
+        randUniform(pgm, "u_color");
+        randUniform(pgm, "u_0");
+        randUniform(pgm, "u_1");
+        randUniform(pgm, "u_2");
+        randUniform(pgm, "u_3");
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    }
+    ptSwap();
+    glFinish();
+    endTimer(passCount);
+}
+
+
+static uint32_t rgb(uint32_t r, uint32_t g, uint32_t b)
+{
+    uint32_t ret = 0xff000000;
+    ret |= r & 0xff;
+    ret |= (g & 0xff) << 8;
+    ret |= (b & 0xff) << 16;
+    return ret;
+}
+
+void genTextures() {
+    uint32_t *m = (uint32_t *)malloc(1024*1024*4);
+    for (int y=0; y < 1024; y++){
+        for (int x=0; x < 1024; x++){
+            m[y*1024 + x] = rgb(x, (((x+y) & 0xff) == 0x7f) * 0xff, y);
+        }
+    }
+    glBindTexture(GL_TEXTURE_2D, 1);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+    for (int y=0; y < 16; y++){
+        for (int x=0; x < 16; x++){
+            m[y*16 + x] = rgb(x << 4, (((x+y) & 0xf) == 0x7) * 0xff, y << 4);
+        }
+    }
+    glBindTexture(GL_TEXTURE_2D, 2);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    free(m);
+}
+
+static void doSingleTest(uint32_t pgmNum, int tex) {
+    const char *pgmTxt = gFragmentTests[pgmNum]->txt;
+    int pgm = createProgram(gVertexShader, pgmTxt);
+    if (!pgm) {
+        printf("error running test\n");
+        return;
+    }
+    int loc = glGetUniformLocation(pgm, "u_tex0");
+    if (loc >= 0) glUniform1i(loc, 0);
+    loc = glGetUniformLocation(pgm, "u_tex1");
+    if (loc >= 0) glUniform1i(loc, 1);
+
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glActiveTexture(GL_TEXTURE1);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glActiveTexture(GL_TEXTURE0);
+
+    glBlendFunc(GL_ONE, GL_ONE);
+    glDisable(GL_BLEND);
+    //sprintf(str2, "%i, %i, %i, %i, %i, 0",
+            //useVarColor, texCount, modulateFirstTex, extraMath, tex0);
+    //doLoop(true, pgm, w, h, str2);
+    //doLoop(false, pgm, w, h, str2);
+
+    glEnable(GL_BLEND);
+    sprintf(gCurrentTestName, "%s, %i, %i, 1", gFragmentTests[pgmNum]->name, pgmNum, tex);
+    doLoop(true, pgm, 100);
+    doLoop(false, pgm, 100);
+}
+
diff --git a/opengl/tests/gl_perf/filltest.cpp b/opengl/tests/gl_perf/filltest.cpp
new file mode 100644
index 0000000..3f8faca
--- /dev/null
+++ b/opengl/tests/gl_perf/filltest.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 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 <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sched.h>
+#include <sys/resource.h>
+#include <string.h>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <utils/Timers.h>
+#include <EGL/egl.h>
+#include <utils/Log.h>
+
+
+using namespace android;
+
+
+#include "fill_common.cpp"
+
+
+bool doTest(uint32_t w, uint32_t h) {
+    gWidth = w;
+    gHeight = h;
+    setupVA();
+    genTextures();
+
+    printf("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n");
+
+    for (uint32_t num = 0; num < gFragmentTestCount; num++) {
+        doSingleTest(num, 2);
+        if (gFragmentTests[num]->texCount) {
+            doSingleTest(num, 1);
+        }
+    }
+
+    exit(0);
+    return true;
+}
diff --git a/opengl/tests/gl_perf/fragment_shaders.cpp b/opengl/tests/gl_perf/fragment_shaders.cpp
new file mode 100644
index 0000000..79d5ead
--- /dev/null
+++ b/opengl/tests/gl_perf/fragment_shaders.cpp
@@ -0,0 +1,139 @@
+
+typedef struct FragmentTestRec {
+	const char * name;
+	uint32_t texCount;
+	const char * txt;
+} FragmentTest;
+
+static FragmentTest fpFill = {
+	"Solid color", 0,
+
+    "precision mediump float;\n"
+    "uniform vec4 u_color;\n"
+    "void main() {\n"
+    "  gl_FragColor = u_color;\n"
+    "}\n"
+};
+
+static FragmentTest fpGradient = {
+	"Solid gradient", 0,
+
+    "precision mediump float;\n"
+    "varying lowp vec4 v_color;\n"
+    "void main() {\n"
+    "  gl_FragColor = v_color;\n"
+    "}\n"
+};
+
+static FragmentTest fpCopyTex = {
+	"Texture copy", 1,
+
+    "precision mediump float;\n"
+    "varying vec2 v_tex0;\n"
+    "uniform sampler2D u_tex0;\n"
+    "void main() {\n"
+    "  gl_FragColor = texture2D(u_tex0, v_tex0);\n"
+    "}\n"
+};
+
+static FragmentTest fpCopyTexGamma = {
+	"Texture copy with gamma", 1,
+
+    "precision mediump float;\n"
+    "varying vec2 v_tex0;\n"
+    "uniform sampler2D u_tex0;\n"
+    "void main() {\n"
+    "  vec4 t = texture2D(u_tex0, v_tex0);\n"
+    "  t.rgb = pow(t.rgb, vec3(1.4, 1.4, 1.4));\n"
+    "  gl_FragColor = t;\n"
+    "}\n"
+};
+
+static FragmentTest fpTexSpec = {
+	"Texture spec", 1,
+
+    "precision mediump float;\n"
+    "varying vec2 v_tex0;\n"
+    "uniform sampler2D u_tex0;\n"
+    "void main() {\n"
+    "  vec4 t = texture2D(u_tex0, v_tex0);\n"
+    "  float simSpec = dot(gl_FragCoord.xyz, gl_FragCoord.xyz);\n"
+    "  simSpec = pow(clamp(simSpec, 0.1, 1.0), 40.0);\n"
+    "  gl_FragColor = t + vec4(simSpec, simSpec, simSpec, simSpec);\n"
+    "}\n"
+};
+
+static FragmentTest fpDepTex = {
+	"Dependent Lookup", 1,
+
+    "precision mediump float;\n"
+    "varying vec2 v_tex0;\n"
+    "uniform sampler2D u_tex0;\n"
+    "void main() {\n"
+    "  vec4 t = texture2D(u_tex0, v_tex0);\n"
+    "  t += texture2D(u_tex0, t.xy);\n"
+    "  gl_FragColor = t;\n"
+    "}\n"
+};
+
+static FragmentTest fpModulateConstantTex = {
+	"Texture modulate constant", 1,
+
+    "precision mediump float;\n"
+    "varying vec2 v_tex0;\n"
+    "uniform sampler2D u_tex0;\n"
+    "uniform vec4 u_color;\n"
+
+    "void main() {\n"
+    "  lowp vec4 c = texture2D(u_tex0, v_tex0);\n"
+	"  c *= u_color;\n"
+    "  gl_FragColor = c;\n"
+    "}\n"
+};
+
+static FragmentTest fpModulateVaryingTex = {
+	"Texture modulate gradient", 1,
+
+    "precision mediump float;\n"
+    "varying vec2 v_tex0;\n"
+    "varying lowp vec4 v_color;\n"
+    "uniform sampler2D u_tex0;\n"
+
+    "void main() {\n"
+    "  lowp vec4 c = texture2D(u_tex0, v_tex0);\n"
+	"  c *= v_color;\n"
+    "  gl_FragColor = c;\n"
+    "}\n"
+};
+
+static FragmentTest fpModulateVaryingConstantTex = {
+	"Texture modulate gradient constant", 1,
+
+    "precision mediump float;\n"
+    "varying vec2 v_tex0;\n"
+    "varying lowp vec4 v_color;\n"
+    "uniform sampler2D u_tex0;\n"
+    "uniform vec4 u_color;\n"
+
+    "void main() {\n"
+    "  lowp vec4 c = texture2D(u_tex0, v_tex0);\n"
+	"  c *= v_color;\n"
+	"  c *= u_color;\n"
+    "  gl_FragColor = c;\n"
+    "}\n"
+};
+
+static FragmentTest *gFragmentTests[] = {
+	&fpFill,
+	&fpGradient,
+	&fpCopyTex,
+	&fpCopyTexGamma,
+   &fpTexSpec,
+   &fpDepTex,
+	&fpModulateConstantTex,
+	&fpModulateVaryingTex,
+	&fpModulateVaryingConstantTex,
+
+};
+
+static const size_t gFragmentTestCount = sizeof(gFragmentTests) / sizeof(gFragmentTests[0]);
diff --git a/opengl/tests/gl_perf/gl2_perf.cpp b/opengl/tests/gl_perf/gl2_perf.cpp
new file mode 100644
index 0000000..9dfcf1c
--- /dev/null
+++ b/opengl/tests/gl_perf/gl2_perf.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2007 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 <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sched.h>
+#include <sys/resource.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <utils/Timers.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
+
+using namespace android;
+
+
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    if (returnVal != EGL_TRUE) {
+        fprintf(stderr, "%s() returned %d\n", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
+                error);
+    }
+}
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+bool doTest(uint32_t w, uint32_t h);
+
+static EGLDisplay dpy;
+static EGLSurface surface;
+
+int main(int argc, char** argv) {
+    EGLBoolean returnValue;
+    EGLConfig myConfig = {0};
+
+    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint s_configAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_NONE };
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLint w, h;
+
+
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+        return 0;
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    if (returnValue != EGL_TRUE) {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    EGLNativeWindowType window = android_createDisplaySurface();
+    returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
+    if (returnValue) {
+        printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
+        return 0;
+    }
+
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
+
+    surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        printf("gelCreateWindowSurface failed.\n");
+        return 0;
+    }
+
+    context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
+        printf("eglCreateContext failed\n");
+        return 0;
+    }
+    returnValue = eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent", returnValue);
+    if (returnValue != EGL_TRUE) {
+        return 0;
+    }
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+    checkEglError("eglQuerySurface");
+    GLint dim = w < h ? w : h;
+
+    glViewport(0, 0, w, h);
+
+    for (;;) {
+        doTest(w, h);
+        eglSwapBuffers(dpy, surface);
+        checkEglError("eglSwapBuffers");
+    }
+
+    return 0;
+}
+
+void ptSwap() {
+    eglSwapBuffers(dpy, surface);
+}
+
diff --git a/opengl/tests/gl_perfapp/Android.mk b/opengl/tests/gl_perfapp/Android.mk
new file mode 100644
index 0000000..dd75a74
--- /dev/null
+++ b/opengl/tests/gl_perfapp/Android.mk
@@ -0,0 +1,54 @@
+#########################################################################
+# OpenGL ES Perf App
+# This makefile builds both an activity and a shared library.
+#########################################################################
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GLPerf
+
+LOCAL_JNI_SHARED_LIBRARIES := libglperf
+
+# Run on Eclair
+LOCAL_SDK_VERSION := 7
+
+include $(BUILD_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+# Optional tag would mean it doesn't get installed by default
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -Werror
+
+LOCAL_SRC_FILES:= \
+  gl_code.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libEGL \
+	libGLESv2
+
+LOCAL_MODULE := libglperf
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # TARGET_SIMULATOR
diff --git a/opengl/tests/gl_perfapp/AndroidManifest.xml b/opengl/tests/gl_perfapp/AndroidManifest.xml
new file mode 100644
index 0000000..ee4bd98
--- /dev/null
+++ b/opengl/tests/gl_perfapp/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.glperf"
+    android:versionName="1.0.0" android:versionCode="10000" >
+    <uses-sdk android:targetSdkVersion="7" android:minSdkVersion="7" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <application
+            android:label="@string/glperf_activity">
+        <activity android:name="GLPerfActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            	android:launchMode="singleTask"
+            	android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/gl_perfapp/jni/gl_code.cpp b/opengl/tests/gl_perfapp/jni/gl_code.cpp
new file mode 100644
index 0000000..f993371
--- /dev/null
+++ b/opengl/tests/gl_perfapp/jni/gl_code.cpp
@@ -0,0 +1,103 @@
+// OpenGL ES 2.0 code
+
+#include <nativehelper/jni.h>
+#define LOG_TAG "GLPerf gl_code.cpp"
+#include <utils/Log.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <utils/Timers.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "../../gl_perf/fill_common.cpp"
+
+
+//////////////////////////
+
+// Width and height of the screen
+
+uint32_t w;
+uint32_t h;
+
+// The stateClock starts at zero and increments by 1 every time we draw a frame. It is used to control which phase of the test we are in.
+
+int stateClock;
+const int doLoopStates = 2;
+const int doSingleTestStates = 2;
+bool done;
+
+// Saves the parameters of the test (so we can print them out when we finish the timing.)
+
+
+int pgm;
+
+void ptSwap() {
+}
+
+void doTest() {
+    uint32_t testNum = stateClock >> 2;
+    int texSize = ((stateClock >> 1) & 0x1) + 1;
+
+    if (testNum >= gFragmentTestCount) {
+       LOGI("done\n");
+       if (fOut) {
+           fclose(fOut);
+           fOut = NULL;
+       }
+       done = true;
+       return;
+    }
+
+    // LOGI("doTest %d %d %d\n", texCount, extraMath, testSubState);
+
+//        for (uint32_t num = 0; num < gFragmentTestCount; num++) {
+    doSingleTest(testNum, texSize);
+}
+
+extern "C" {
+    JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_init(JNIEnv * env, jobject obj,  jint width, jint height);
+    JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_step(JNIEnv * env, jobject obj);
+};
+
+JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_init(JNIEnv * env, jobject obj,  jint width, jint height)
+{
+    gWidth = width;
+    gHeight = height;
+    if (!done) {
+            stateClock = 0;
+            done = false;
+            setupVA();
+            genTextures();
+            const char* fileName = "/sdcard/glperf.csv";
+            if (fOut != NULL) {
+                 LOGI("Closing partially written output.n");
+                 fclose(fOut);
+                 fOut = NULL;
+            }
+            LOGI("Writing to: %s\n",fileName);
+            fOut = fopen(fileName, "w");
+            if (fOut == NULL) {
+                LOGE("Could not open: %s\n", fileName);
+            }
+
+            LOGI("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n");
+            if (fOut) fprintf(fOut,"varColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\r\n");
+    }
+}
+
+JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_step(JNIEnv * env, jobject obj)
+{
+    if (! done) {
+        if (stateClock > 0 && ((stateClock & 1) == 0)) {
+            //endTimer(100);
+        }
+        doTest();
+        stateClock++;
+    } else {
+            glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    }
+}
diff --git a/opengl/tests/gl_perfapp/res/values/strings.xml b/opengl/tests/gl_perfapp/res/values/strings.xml
new file mode 100644
index 0000000..52cd961
--- /dev/null
+++ b/opengl/tests/gl_perfapp/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="glperf_activity">GLPerf</string>
+
+</resources>
+
diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java
new file mode 100644
index 0000000..e3f3abf
--- /dev/null
+++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 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.glperf;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GLPerfActivity extends Activity {
+
+    GLPerfView mView;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+	getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        mView = new GLPerfView(getApplication());
+	setContentView(mView);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java
new file mode 100644
index 0000000..89a0e54
--- /dev/null
+++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 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.glperf;
+
+// Wrapper for native library
+
+public class GLPerfLib {
+
+     static {
+         System.loadLibrary("glperf");
+     }
+
+    /**
+     * @param width the current view width
+     * @param height the current view height
+     */
+     public static native void init(int width, int height);
+     public static native void step();
+}
diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java
new file mode 100644
index 0000000..4ce4a4d
--- /dev/null
+++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java
@@ -0,0 +1,296 @@
+/*
+ * 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.
+ */
+
+package com.android.glperf;
+/*
+ * Copyright (C) 2008 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.
+ */
+
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation.  This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class GLPerfView extends GLSurfaceView {
+    private static String TAG = "GLPerfView";
+
+    public GLPerfView(Context context) {
+        super(context);
+        init(false, 0, 0);
+    }
+
+    public GLPerfView(Context context, boolean translucent, int depth, int stencil) {
+        super(context);
+        init(translucent, depth, stencil);
+    }
+
+    private void init(boolean translucent, int depth, int stencil) {
+        setEGLContextFactory(new ContextFactory());
+        setEGLConfigChooser( translucent ?
+              new ConfigChooser(8,8,8,8, depth, stencil) :
+              new ConfigChooser(5,6,5,0, depth, stencil));
+        setRenderer(new Renderer());
+    }
+
+    private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
+        private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+            Log.w(TAG, "creating OpenGL ES 2.0 context");
+            checkEglError("Before eglCreateContext", egl);
+            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+            EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
+            checkEglError("After eglCreateContext", egl);
+            return context;
+        }
+
+        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+            egl.eglDestroyContext(display, context);
+        }
+    }
+
+    private static void checkEglError(String prompt, EGL10 egl) {
+        int error;
+        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
+            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+        }
+    }
+
+    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
+        private static int EGL_OPENGL_ES2_BIT = 4;
+        private static int[] s_configAttribs2 =
+        {
+            EGL10.EGL_RED_SIZE, 4,
+            EGL10.EGL_GREEN_SIZE, 4,
+            EGL10.EGL_BLUE_SIZE, 4,
+            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL10.EGL_NONE
+        };
+
+        public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
+            mRedSize = r;
+            mGreenSize = g;
+            mBlueSize = b;
+            mAlphaSize = a;
+            mDepthSize = depth;
+            mStencilSize = stencil;
+        }
+
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+
+            int[] num_config = new int[1];
+            egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
+
+            int numConfigs = num_config[0];
+
+            if (numConfigs <= 0) {
+                throw new IllegalArgumentException("No configs match configSpec");
+            }
+            EGLConfig[] configs = new EGLConfig[numConfigs];
+            egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
+            // printConfigs(egl, display, configs);
+            return chooseConfig(egl, display, configs);
+        }
+
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
+                EGLConfig[] configs) {
+            EGLConfig closestConfig = null;
+            int closestDistance = 1000;
+            for(EGLConfig config : configs) {
+                int d = findConfigAttrib(egl, display, config,
+                        EGL10.EGL_DEPTH_SIZE, 0);
+                int s = findConfigAttrib(egl, display, config,
+                        EGL10.EGL_STENCIL_SIZE, 0);
+                if (d >= mDepthSize && s>= mStencilSize) {
+                    int r = findConfigAttrib(egl, display, config,
+                            EGL10.EGL_RED_SIZE, 0);
+                    int g = findConfigAttrib(egl, display, config,
+                             EGL10.EGL_GREEN_SIZE, 0);
+                    int b = findConfigAttrib(egl, display, config,
+                              EGL10.EGL_BLUE_SIZE, 0);
+                    int a = findConfigAttrib(egl, display, config,
+                            EGL10.EGL_ALPHA_SIZE, 0);
+                    int distance = Math.abs(r - mRedSize)
+                                + Math.abs(g - mGreenSize)
+                                + Math.abs(b - mBlueSize)
+                                + Math.abs(a - mAlphaSize);
+                    if (distance < closestDistance) {
+                        closestDistance = distance;
+                        closestConfig = config;
+                    }
+                }
+            }
+            return closestConfig;
+        }
+
+        private int findConfigAttrib(EGL10 egl, EGLDisplay display,
+                EGLConfig config, int attribute, int defaultValue) {
+
+            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
+                return mValue[0];
+            }
+            return defaultValue;
+        }
+
+        private void printConfigs(EGL10 egl, EGLDisplay display,
+            EGLConfig[] configs) {
+            int numConfigs = configs.length;
+            Log.w(TAG, String.format("%d configurations", numConfigs));
+            for (int i = 0; i < numConfigs; i++) {
+                Log.w(TAG, String.format("Configuration %d:\n", i));
+                printConfig(egl, display, configs[i]);
+            }
+        }
+
+        private void printConfig(EGL10 egl, EGLDisplay display,
+                EGLConfig config) {
+            int[] attributes = {
+                    EGL10.EGL_BUFFER_SIZE,
+                    EGL10.EGL_ALPHA_SIZE,
+                    EGL10.EGL_BLUE_SIZE,
+                    EGL10.EGL_GREEN_SIZE,
+                    EGL10.EGL_RED_SIZE,
+                    EGL10.EGL_DEPTH_SIZE,
+                    EGL10.EGL_STENCIL_SIZE,
+                    EGL10.EGL_CONFIG_CAVEAT,
+                    EGL10.EGL_CONFIG_ID,
+                    EGL10.EGL_LEVEL,
+                    EGL10.EGL_MAX_PBUFFER_HEIGHT,
+                    EGL10.EGL_MAX_PBUFFER_PIXELS,
+                    EGL10.EGL_MAX_PBUFFER_WIDTH,
+                    EGL10.EGL_NATIVE_RENDERABLE,
+                    EGL10.EGL_NATIVE_VISUAL_ID,
+                    EGL10.EGL_NATIVE_VISUAL_TYPE,
+                    0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
+                    EGL10.EGL_SAMPLES,
+                    EGL10.EGL_SAMPLE_BUFFERS,
+                    EGL10.EGL_SURFACE_TYPE,
+                    EGL10.EGL_TRANSPARENT_TYPE,
+                    EGL10.EGL_TRANSPARENT_RED_VALUE,
+                    EGL10.EGL_TRANSPARENT_GREEN_VALUE,
+                    EGL10.EGL_TRANSPARENT_BLUE_VALUE,
+                    0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
+                    0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
+                    0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
+                    0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
+                    EGL10.EGL_LUMINANCE_SIZE,
+                    EGL10.EGL_ALPHA_MASK_SIZE,
+                    EGL10.EGL_COLOR_BUFFER_TYPE,
+                    EGL10.EGL_RENDERABLE_TYPE,
+                    0x3042 // EGL10.EGL_CONFORMANT
+            };
+            String[] names = {
+                    "EGL_BUFFER_SIZE",
+                    "EGL_ALPHA_SIZE",
+                    "EGL_BLUE_SIZE",
+                    "EGL_GREEN_SIZE",
+                    "EGL_RED_SIZE",
+                    "EGL_DEPTH_SIZE",
+                    "EGL_STENCIL_SIZE",
+                    "EGL_CONFIG_CAVEAT",
+                    "EGL_CONFIG_ID",
+                    "EGL_LEVEL",
+                    "EGL_MAX_PBUFFER_HEIGHT",
+                    "EGL_MAX_PBUFFER_PIXELS",
+                    "EGL_MAX_PBUFFER_WIDTH",
+                    "EGL_NATIVE_RENDERABLE",
+                    "EGL_NATIVE_VISUAL_ID",
+                    "EGL_NATIVE_VISUAL_TYPE",
+                    "EGL_PRESERVED_RESOURCES",
+                    "EGL_SAMPLES",
+                    "EGL_SAMPLE_BUFFERS",
+                    "EGL_SURFACE_TYPE",
+                    "EGL_TRANSPARENT_TYPE",
+                    "EGL_TRANSPARENT_RED_VALUE",
+                    "EGL_TRANSPARENT_GREEN_VALUE",
+                    "EGL_TRANSPARENT_BLUE_VALUE",
+                    "EGL_BIND_TO_TEXTURE_RGB",
+                    "EGL_BIND_TO_TEXTURE_RGBA",
+                    "EGL_MIN_SWAP_INTERVAL",
+                    "EGL_MAX_SWAP_INTERVAL",
+                    "EGL_LUMINANCE_SIZE",
+                    "EGL_ALPHA_MASK_SIZE",
+                    "EGL_COLOR_BUFFER_TYPE",
+                    "EGL_RENDERABLE_TYPE",
+                    "EGL_CONFORMANT"
+            };
+            int[] value = new int[1];
+            for (int i = 0; i < attributes.length; i++) {
+                int attribute = attributes[i];
+                String name = names[i];
+                if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
+                    Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
+                } else {
+                    // Log.w(TAG, String.format("  %s: failed\n", name));
+                    while (egl.eglGetError() != EGL10.EGL_SUCCESS);
+                }
+            }
+        }
+
+        // Subclasses can adjust these values:
+        protected int mRedSize;
+        protected int mGreenSize;
+        protected int mBlueSize;
+        protected int mAlphaSize;
+        protected int mDepthSize;
+        protected int mStencilSize;
+        private int[] mValue = new int[1];
+    }
+
+    private static class Renderer implements GLSurfaceView.Renderer {
+        public void onDrawFrame(GL10 gl) {
+            GLPerfLib.step();
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            GLPerfLib.init(width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            // Do nothing.
+        }
+    }
+}
+
diff --git a/opengl/tests/gl_yuvtex/Android.mk b/opengl/tests/gl_yuvtex/Android.mk
new file mode 100644
index 0000000..a78db25
--- /dev/null
+++ b/opengl/tests/gl_yuvtex/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	gl_yuvtex.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv1_CM \
+    libui
+
+LOCAL_MODULE:= test-opengl-gl_yuvtex
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
new file mode 100644
index 0000000..fbe65f1
--- /dev/null
+++ b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sched.h>
+#include <sys/resource.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <utils/Timers.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+using namespace android;
+
+static void printGLString(const char *name, GLenum s) {
+    // fprintf(stderr, "printGLString %s, %d\n", name, s);
+    const char *v = (const char *) glGetString(s);
+    // int error = glGetError();
+    // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+    //        (unsigned int) v);
+    // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+    //    fprintf(stderr, "GL %s = %s\n", name, v);
+    // else
+    //    fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+    fprintf(stderr, "GL %s = %s\n", name, v);
+}
+
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    if (returnVal != EGL_TRUE) {
+        fprintf(stderr, "%s() returned %d\n", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
+                error);
+    }
+}
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+bool setupGraphics(int w, int h) {
+    glViewport(0, 0, w, h);
+    checkGlError("glViewport");
+    return true;
+}
+
+int align(int x, int a) {
+    return (x + (a-1)) & (~(a-1));
+}
+
+const int yuvTexWidth = 600;
+const int yuvTexHeight = 480;
+const int yuvTexUsage = GraphicBuffer::USAGE_HW_TEXTURE |
+        GraphicBuffer::USAGE_SW_WRITE_RARELY;
+const int yuvTexFormat = HAL_PIXEL_FORMAT_YV12;
+const int yuvTexOffsetY = 0;
+const int yuvTexStrideY = (yuvTexWidth + 0xf) & ~0xf;
+const int yuvTexOffsetV = yuvTexStrideY * yuvTexHeight;
+const int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 
+const int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * yuvTexHeight/2;
+const int yuvTexStrideU = yuvTexStrideV;
+const bool yuvTexSameUV = false;
+static sp<GraphicBuffer> yuvTexBuffer;
+static GLuint yuvTex;
+
+bool setupYuvTexSurface(EGLDisplay dpy, EGLContext context) {
+    int blockWidth = yuvTexWidth > 16 ? yuvTexWidth / 16 : 1;
+    int blockHeight = yuvTexHeight > 16 ? yuvTexHeight / 16 : 1;
+    yuvTexBuffer = new GraphicBuffer(yuvTexWidth, yuvTexHeight, yuvTexFormat,
+            yuvTexUsage);
+    char* buf = NULL;
+    status_t err = yuvTexBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
+    if (err != 0) {
+        fprintf(stderr, "yuvTexBuffer->lock(...) failed: %d\n", err);
+        return false;
+    }
+    for (int x = 0; x < yuvTexWidth; x++) {
+        for (int y = 0; y < yuvTexHeight; y++) {
+            int parityX = (x / blockWidth) & 1;
+            int parityY = (y / blockHeight) & 1;
+            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+            if (x < yuvTexWidth / 2 && y < yuvTexHeight / 2) {
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+                if (yuvTexSameUV) {
+                    buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = intensity;
+                } else if (x < yuvTexWidth / 4 && y < yuvTexHeight / 4) {
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = intensity;
+                }
+            }
+        }
+    }
+
+    err = yuvTexBuffer->unlock();
+    if (err != 0) {
+        fprintf(stderr, "yuvTexBuffer->unlock() failed: %d\n", err);
+        return false;
+    }
+
+    EGLClientBuffer clientBuffer = (EGLClientBuffer)yuvTexBuffer->getNativeBuffer();
+    EGLImageKHR img = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+            clientBuffer, 0);
+    checkEglError("eglCreateImageKHR");
+    if (img == EGL_NO_IMAGE_KHR) {
+        return false;
+    }
+
+    glGenTextures(1, &yuvTex);
+    checkGlError("glGenTextures");
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex);
+    checkGlError("glBindTexture");
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img);
+    checkGlError("glEGLImageTargetTexture2DOES");
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    checkGlError("glTexParameteri");
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    checkGlError("glTexParameteri");
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    checkGlError("glTexEnvx");
+
+    GLint crop[4] = { 0, 0, yuvTexWidth, yuvTexHeight };
+    glTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_CROP_RECT_OES, crop);
+    checkGlError("glTexParameteriv");
+
+    return true;
+}
+
+void renderFrame(int w, int h) {
+    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+    checkGlError("glClearColor");
+    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    checkGlError("glClear");
+    
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex);
+    checkGlError("glBindTexture");
+    glEnable(GL_TEXTURE_EXTERNAL_OES);
+    checkGlError("glEnable");
+
+    glDrawTexiOES(0, 0, 0, w, h);
+    checkGlError("glDrawTexiOES");
+}
+
+void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            printf(" %s: ", names[j].name);
+            printf("%d (0x%x)", value, value);
+        }
+    }
+    printf("\n");
+}
+
+int main(int argc, char** argv) {
+    EGLBoolean returnValue;
+    EGLConfig myConfig = {0};
+
+    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE };
+    EGLint s_configAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+            EGL_NONE };
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLSurface surface;
+    EGLint w, h;
+
+    EGLDisplay dpy;
+
+    checkEglError("<init>");
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (dpy == EGL_NO_DISPLAY) {
+        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+        return 0;
+    }
+
+    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+    if (returnValue != EGL_TRUE) {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    EGLNativeWindowType window = android_createDisplaySurface();
+    returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
+    if (returnValue) {
+        printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
+        return 1;
+    }
+
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
+
+    printf("Chose this configuration:\n");
+    printEGLConfiguration(dpy, myConfig);
+
+    surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (surface == EGL_NO_SURFACE) {
+        printf("gelCreateWindowSurface failed.\n");
+        return 1;
+    }
+
+    context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
+        printf("eglCreateContext failed\n");
+        return 1;
+    }
+    returnValue = eglMakeCurrent(dpy, surface, surface, context);
+    checkEglError("eglMakeCurrent", returnValue);
+    if (returnValue != EGL_TRUE) {
+        return 1;
+    }
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+    checkEglError("eglQuerySurface");
+    GLint dim = w < h ? w : h;
+
+    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
+
+    if(!setupYuvTexSurface(dpy, context)) {
+        fprintf(stderr, "Could not set up texture surface.\n");
+        return 1;
+    }
+
+    if(!setupGraphics(w, h)) {
+        fprintf(stderr, "Could not set up graphics.\n");
+        return 1;
+    }
+
+    for (;;) {
+        static int dir = -1;
+
+        renderFrame(w, h);
+        eglSwapBuffers(dpy, surface);
+        checkEglError("eglSwapBuffers");
+
+        if (w <= 10 || h <= 10)
+        {
+            dir = -dir;
+        }
+
+        if (w >= 1300 || h >= 900)
+        {
+            dir = -dir;
+        }
+
+
+        w += dir;
+        h += dir;
+    }
+
+    return 0;
+}
diff --git a/opengl/tests/gldual/AndroidManifest.xml b/opengl/tests/gldual/AndroidManifest.xml
index 06f4c4d..a36f4f7 100644
--- a/opengl/tests/gldual/AndroidManifest.xml
+++ b/opengl/tests/gldual/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/gldual/res/values/strings.xml b/opengl/tests/gldual/res/values/strings.xml
index 4267dff..b1f535d 100644
--- a/opengl/tests/gldual/res/values/strings.xml
+++ b/opengl/tests/gldual/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, 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.
-*/
+<!-- Copyright (C) 2006 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.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk
new file mode 100644
index 0000000..6312970
--- /dev/null
+++ b/opengl/tests/hwc/Android.mk
@@ -0,0 +1,156 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE:= libhwcTest
+LOCAL_SRC_FILES:= hwcTestLib.cpp
+LOCAL_C_INCLUDES += system/extras/tests/include \
+    bionic \
+    bionic/libstdc++/include \
+    external/stlport/stlport \
+    frameworks/base/opengl/tests \
+    frameworks/base/opengl/tests/include \
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+LOCAL_SHARED_LIBRARIES += libcutils libutils libstlport
+LOCAL_STATIC_LIBRARIES += libglTest
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:= hwcStress.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libEGL \
+    libGLESv2 \
+    libui \
+    libhardware \
+
+LOCAL_STATIC_LIBRARIES := \
+    libtestUtil \
+    libglTest \
+    libhwcTest \
+
+LOCAL_C_INCLUDES += \
+    system/extras/tests/include \
+    hardware/libhardware/include \
+    frameworks/base/opengl/tests \
+    frameworks/base/opengl/tests/include \
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+LOCAL_MODULE:= hwcStress
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativestresstest
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:= hwcRects.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libEGL \
+    libGLESv2 \
+    libui \
+    libhardware \
+
+LOCAL_STATIC_LIBRARIES := \
+    libtestUtil \
+    libglTest \
+    libhwcTest \
+
+LOCAL_C_INCLUDES += \
+    system/extras/tests/include \
+    hardware/libhardware/include \
+    frameworks/base/opengl/tests \
+    frameworks/base/opengl/tests/include \
+
+LOCAL_MODULE:= hwcRects
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:= hwcColorEquiv.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libEGL \
+    libGLESv2 \
+    libui \
+    libhardware \
+
+LOCAL_STATIC_LIBRARIES := \
+    libtestUtil \
+    libglTest \
+    libhwcTest \
+
+LOCAL_C_INCLUDES += \
+    system/extras/tests/include \
+    hardware/libhardware/include \
+    frameworks/base/opengl/tests \
+    frameworks/base/opengl/tests/include \
+
+LOCAL_MODULE:= hwcColorEquiv
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:= hwcCommit.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libEGL \
+    libGLESv2 \
+    libui \
+    libhardware \
+
+LOCAL_STATIC_LIBRARIES := \
+    libtestUtil \
+    libglTest \
+    libhwcTest \
+
+LOCAL_C_INCLUDES += \
+    system/extras/tests/include \
+    hardware/libhardware/include \
+    frameworks/base/opengl/tests \
+    frameworks/base/opengl/tests/include \
+
+LOCAL_MODULE:= hwcCommit
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativebenchmark
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+include $(BUILD_NATIVE_TEST)
diff --git a/opengl/tests/hwc/hwcColorEquiv.cpp b/opengl/tests/hwc/hwcColorEquiv.cpp
new file mode 100644
index 0000000..1d03948
--- /dev/null
+++ b/opengl/tests/hwc/hwcColorEquiv.cpp
@@ -0,0 +1,438 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Hardware Composer Color Equivalence
+ *
+ * Synopsis
+ *   hwc_colorequiv [options] eFmt
+ *
+ *     options:
+         -v - verbose
+ *       -s <0.##, 0.##, 0.##> - Start color (default: <0.0, 0.0, 0.0>
+ *       -e <0.##, 0.##, 0.##> - Ending color (default: <1.0, 1.0, 1.0>
+ *       -r fmt - reference graphic format
+ *       -D #.## - End of test delay
+ *
+ *     graphic formats:
+ *       RGBA8888 (reference frame default)
+ *       RGBX8888
+ *       RGB888
+ *       RGB565
+ *       BGRA8888
+ *       RGBA5551
+ *       RGBA4444
+ *       YV12
+ *
+ * Description
+ *   Renders a horizontal blend in two frames.  The first frame is rendered
+ *   in the upper third of the display and is called the reference frame.
+ *   The second frame is displayed in the middle third and is called the
+ *   equivalence frame.  The primary purpose of this utility is to verify
+ *   that the colors produced in the reference and equivalence frames are
+ *   the same.  The colors are the same when the colors are the same
+ *   vertically between the reference and equivalence frames.
+ *
+ *   By default the reference frame is rendered through the use of the
+ *   RGBA8888 graphic format.  The -r option can be used to specify a
+ *   non-default reference frame graphic format.  The graphic format of
+ *   the equivalence frame is determined by a single required positional
+ *   parameter.  Intentionally there is no default for the graphic format
+ *   of the equivalence frame.
+ *
+ *   The horizontal blend in the reference frame is produced from a linear
+ *   interpolation from a start color (default: <0.0, 0.0, 0.0> on the left
+ *   side to an end color (default <1.0, 1.0, 1.0> on the right side.  Where
+ *   possible the equivalence frame is rendered with the equivalent color
+ *   from the reference frame.  A color of black is used in the equivalence
+ *   frame for cases where an equivalent color does not exist.
+ */
+
+#include <algorithm>
+#include <assert.h>
+#include <cerrno>
+#include <cmath>
+#include <cstdlib>
+#include <ctime>
+#include <libgen.h>
+#include <sched.h>
+#include <sstream>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <vector>
+
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+#define LOG_TAG "hwcColorEquivTest"
+#include <utils/Log.h>
+#include <testUtil.h>
+
+#include <hardware/hwcomposer.h>
+
+#include "hwcTestLib.h"
+
+using namespace std;
+using namespace android;
+
+// Defaults for command-line options
+const bool defaultVerbose = false;
+const ColorFract defaultStartColor(0.0, 0.0, 0.0);
+const ColorFract defaultEndColor(1.0, 1.0, 1.0);
+const char *defaultRefFormat = "RGBA8888";
+const float defaultEndDelay = 2.0; // Default delay after rendering graphics
+
+// Defines
+#define MAXSTR               100
+#define MAXCMD               200
+#define BITSPERBYTE            8 // TODO: Obtain from <values.h>, once
+                                 // it has been added
+
+#define CMD_STOP_FRAMEWORK   "stop 2>&1"
+#define CMD_START_FRAMEWORK  "start 2>&1"
+
+// Macros
+#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
+#define MEMCLR(addr, size) do { \
+        memset((addr), 0, (size)); \
+    } while (0)
+
+// Globals
+static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
+        GraphicBuffer::USAGE_SW_WRITE_RARELY;
+static hwc_composer_device_t *hwcDevice;
+static EGLDisplay dpy;
+static EGLSurface surface;
+static EGLint width, height;
+
+// Functions prototypes
+void init(void);
+void printSyntax(const char *cmd);
+
+// Command-line option settings
+static bool verbose = defaultVerbose;
+static ColorFract startRefColor = defaultStartColor;
+static ColorFract endRefColor = defaultEndColor;
+static float endDelay = defaultEndDelay;
+static const struct hwcTestGraphicFormat *refFormat
+    = hwcTestGraphicFormatLookup(defaultRefFormat);
+static const struct hwcTestGraphicFormat *equivFormat;
+
+/*
+ * Main
+ *
+ * Performs the following high-level sequence of operations:
+ *
+ *   1. Command-line parsing
+ *
+ *   2. Stop framework
+ *
+ *   3. Initialization
+ *
+ *   4. Create Hardware Composer description of reference and equivalence frames
+ *
+ *   5. Have Hardware Composer render the reference and equivalence frames
+ *
+ *   6. Delay for amount of time given by endDelay
+ *
+ *   7. Start framework
+ */
+int
+main(int argc, char *argv[])
+{
+    int rv, opt;
+    bool error;
+    char *chptr;
+    unsigned int pass;
+    char cmd[MAXCMD];
+    string str;
+
+    testSetLogCatTag(LOG_TAG);
+
+    assert(refFormat != NULL);
+
+    testSetLogCatTag(LOG_TAG);
+
+    // Parse command line arguments
+    while ((opt = getopt(argc, argv, "vs:e:r:D:?h")) != -1) {
+        switch (opt) {
+          case 'D': // End of test delay
+                    // Delay between completion of final pass and restart
+                    // of framework
+            endDelay = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (endDelay < 0.0)) {
+                testPrintE("Invalid command-line specified end of test delay "
+                           "of: %s", optarg);
+                exit(1);
+            }
+            break;
+
+          case 's': // Starting reference color
+            str = optarg;
+            while (optind < argc) {
+                if (*argv[optind] == '-') { break; }
+                char endChar = (str.length() > 1) ? str[str.length() - 1] : 0;
+                if ((endChar == '>') || (endChar == ']')) { break; }
+                str += " " + string(argv[optind++]);
+            }
+            {
+                istringstream in(str);
+                startRefColor = hwcTestParseColor(in, error);
+                // Any parse error or characters not used by parser
+                if (error
+                    || (((unsigned int) in.tellg() != in.str().length())
+                        && (in.tellg() != (streampos) -1))) {
+                    testPrintE("Invalid command-line specified start "
+                               "reference color of: %s", str.c_str());
+                    exit(2);
+                }
+            }
+            break;
+
+          case 'e': // Ending reference color
+            str = optarg;
+            while (optind < argc) {
+                if (*argv[optind] == '-') { break; }
+                char endChar = (str.length() > 1) ? str[str.length() - 1] : 0;
+                if ((endChar == '>') || (endChar == ']')) { break; }
+                str += " " + string(argv[optind++]);
+            }
+            {
+                istringstream in(str);
+                endRefColor = hwcTestParseColor(in, error);
+                // Any parse error or characters not used by parser
+                if (error
+                    || (((unsigned int) in.tellg() != in.str().length())
+                        && (in.tellg() != (streampos) -1))) {
+                    testPrintE("Invalid command-line specified end "
+                               "reference color of: %s", str.c_str());
+                    exit(3);
+                }
+            }
+            break;
+
+          case 'r': // Reference graphic format
+            refFormat = hwcTestGraphicFormatLookup(optarg);
+            if (refFormat == NULL) {
+                testPrintE("Unkown command-line specified reference graphic "
+                           "format of: %s", optarg);
+                printSyntax(basename(argv[0]));
+                exit(4);
+            }
+            break;
+
+          case 'v': // Verbose
+            verbose = true;
+            break;
+
+          case 'h': // Help
+          case '?':
+          default:
+            printSyntax(basename(argv[0]));
+            exit(((optopt == 0) || (optopt == '?')) ? 0 : 5);
+        }
+    }
+
+    // Expect a single positional parameter, which specifies the
+    // equivalence graphic format.
+    if (argc != (optind + 1)) {
+        testPrintE("Expected a single command-line postional parameter");
+        printSyntax(basename(argv[0]));
+        exit(6);
+    }
+    equivFormat = hwcTestGraphicFormatLookup(argv[optind]);
+    if (equivFormat == NULL) {
+        testPrintE("Unkown command-line specified equivalence graphic "
+                   "format of: %s", argv[optind]);
+        printSyntax(basename(argv[0]));
+        exit(7);
+    }
+
+    testPrintI("refFormat: %u %s", refFormat->format, refFormat->desc);
+    testPrintI("equivFormat: %u %s", equivFormat->format, equivFormat->desc);
+    testPrintI("startRefColor: %s", ((string) startRefColor).c_str());
+    testPrintI("endRefColor: %s", ((string) endRefColor).c_str());
+    testPrintI("endDelay: %f", endDelay);
+
+    // Stop framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
+        exit(8);
+    }
+    testExecCmd(cmd);
+    testDelay(1.0); // TODO - needs means to query whether asynchronous stop
+                    // framework operation has completed.  For now, just wait
+                    // a long time.
+
+    init();
+
+    // Use the upper third of the display for the reference frame and
+    // the middle third for the equivalence frame.
+    unsigned int refHeight = height / 3;
+    unsigned int refPosY = 0; // Reference frame Y position
+    unsigned int refPosX = 0; // Reference frame X position
+    unsigned int refWidth = width - refPosX;
+    if ((refWidth & refFormat->wMod) != 0) {
+        refWidth += refFormat->wMod - (refWidth % refFormat->wMod);
+    }
+    unsigned int equivHeight = height / 3;
+    unsigned int equivPosY = refHeight; // Equivalence frame Y position
+    unsigned int equivPosX = 0;         // Equivalence frame X position
+    unsigned int equivWidth = width - equivPosX;
+    if ((equivWidth & equivFormat->wMod) != 0) {
+        equivWidth += equivFormat->wMod - (equivWidth % equivFormat->wMod);
+    }
+
+    // Create reference and equivalence graphic buffers
+    const unsigned int numFrames = 2;
+    sp<GraphicBuffer> refFrame;
+    refFrame = new GraphicBuffer(refWidth, refHeight,
+                                 refFormat->format, texUsage);
+    if ((rv = refFrame->initCheck()) != NO_ERROR) {
+        testPrintE("refFrame initCheck failed, rv: %i", rv);
+        testPrintE("  width %u height: %u format: %u %s", refWidth, refHeight,
+                   refFormat->format,
+                   hwcTestGraphicFormat2str(refFormat->format));
+        exit(9);
+    }
+    testPrintI("refFrame width: %u height: %u format: %u %s",
+               refWidth, refHeight, refFormat->format,
+               hwcTestGraphicFormat2str(refFormat->format));
+
+    sp<GraphicBuffer> equivFrame;
+    equivFrame = new GraphicBuffer(equivWidth, equivHeight,
+                                   equivFormat->format, texUsage);
+    if ((rv = refFrame->initCheck()) != NO_ERROR) {
+        testPrintE("refFrame initCheck failed, rv: %i", rv);
+        testPrintE("  width %u height: %u format: %u %s", refWidth, refHeight,
+                   refFormat->format,
+                   hwcTestGraphicFormat2str(refFormat->format));
+        exit(10);
+    }
+    testPrintI("equivFrame width: %u height: %u format: %u %s",
+               equivWidth, equivHeight, equivFormat->format,
+               hwcTestGraphicFormat2str(equivFormat->format));
+
+    // Fill the frames with a horizontal blend
+    hwcTestFillColorHBlend(refFrame.get(), refFormat->format,
+                           startRefColor, endRefColor);
+    hwcTestFillColorHBlend(equivFrame.get(), refFormat->format,
+                           startRefColor, endRefColor);
+
+    hwc_layer_list_t *list;
+    size_t size = sizeof(hwc_layer_list) + numFrames * sizeof(hwc_layer_t);
+    if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) {
+        testPrintE("Allocate list failed");
+        exit(11);
+    }
+    list->flags = HWC_GEOMETRY_CHANGED;
+    list->numHwLayers = numFrames;
+
+    hwc_layer_t *layer = &list->hwLayers[0];
+    layer->handle = refFrame->handle;
+    layer->blending = HWC_BLENDING_NONE;
+    layer->sourceCrop.left = 0;
+    layer->sourceCrop.top = 0;
+    layer->sourceCrop.right = width;
+    layer->sourceCrop.bottom = refHeight;
+    layer->displayFrame.left = 0;
+    layer->displayFrame.top = 0;
+    layer->displayFrame.right = width;
+    layer->displayFrame.bottom = refHeight;
+    layer->visibleRegionScreen.numRects = 1;
+    layer->visibleRegionScreen.rects = &layer->displayFrame;
+
+    layer++;
+    layer->handle = equivFrame->handle;
+    layer->blending = HWC_BLENDING_NONE;
+    layer->sourceCrop.left = 0;
+    layer->sourceCrop.top = 0;
+    layer->sourceCrop.right = width;
+    layer->sourceCrop.bottom = equivHeight;
+    layer->displayFrame.left = 0;
+    layer->displayFrame.top = refHeight;
+    layer->displayFrame.right = width;
+    layer->displayFrame.bottom = layer->displayFrame.top + equivHeight;
+    layer->visibleRegionScreen.numRects = 1;
+    layer->visibleRegionScreen.rects = &layer->displayFrame;
+
+    // Perform prepare operation
+    if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); }
+    hwcDevice->prepare(hwcDevice, list);
+    if (verbose) {
+        testPrintI("Post Prepare:");
+        hwcTestDisplayListPrepareModifiable(list);
+    }
+
+    // Turn off the geometry changed flag
+    list->flags &= ~HWC_GEOMETRY_CHANGED;
+
+    if (verbose) {hwcTestDisplayListHandles(list); }
+    hwcDevice->set(hwcDevice, dpy, surface, list);
+
+    testDelay(endDelay);
+
+    // Start framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
+        exit(12);
+    }
+    testExecCmd(cmd);
+
+    return 0;
+}
+
+void init(void)
+{
+    // Seed pseudo random number generator
+    // Seeding causes fill horizontal blend to fill the pad area with
+    // a deterministic set of values.
+    srand48(0);
+
+    hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
+
+    hwcTestOpenHwc(&hwcDevice);
+}
+
+void printSyntax(const char *cmd)
+{
+    testPrintE("  %s [options] graphicFormat", cmd);
+    testPrintE("    options:");
+    testPrintE("      -s <0.##, 0.##, 0.##> - Starting reference color");
+    testPrintE("      -e <0.##, 0.##, 0.##> - Ending reference color");
+    testPrintE("      -r format - Reference graphic format");
+    testPrintE("      -D #.## - End of test delay");
+    testPrintE("      -v Verbose");
+    testPrintE("");
+    testPrintE("    graphic formats:");
+    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
+        testPrintE("      %s", hwcTestGraphicFormat[n1].desc);
+    }
+}
diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp
new file mode 100644
index 0000000..66ccdae
--- /dev/null
+++ b/opengl/tests/hwc/hwcCommit.cpp
@@ -0,0 +1,1562 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Hardware Composer Commit Points
+ *
+ * Synopsis
+ *   hwcCommit [options] graphicFormat ...
+ *     options:
+ *       -s [width, height] - Starting dimension
+ *       -v - Verbose
+ *
+ *      graphic formats:
+ *        RGBA8888 (reference frame default)
+ *        RGBX8888
+ *        RGB888
+ *        RGB565
+ *        BGRA8888
+ *        RGBA5551
+ *        RGBA4444
+ *        YV12
+ *
+ * Description
+ *   The Hardware Composer (HWC) Commit test is a benchmark that
+ *   discovers the points at which the HWC will commit to rendering an
+ *   overlay(s).  Before rendering a set of overlays, the HWC is shown
+ *   the list through a prepare call.  During the prepare call the HWC
+ *   is able to examine the list and specify which overlays it is able
+ *   to handle.  The overlays that it can't handle are typically composited
+ *   by a higher level (e.g. Surface Flinger) and then the original list
+ *   plus a composit of what HWC passed on are provided back to the HWC
+ *   for rendering.
+ *
+ *   Once an implementation of the HWC has been shipped, a regression would
+ *   likely occur if a latter implementation started passing on conditions
+ *   that it used to commit to.  The primary purpose of this benchmark
+ *   is the automated discovery of the commit points, where an implementation
+ *   is on the edge between committing and not committing.  These are commonly
+ *   referred to as commit points.  Between implementations changes to the
+ *   commit points are allowed, as long as they improve what the HWC commits
+ *   to.  Once an implementation of the HWC is shipped, the commit points are
+ *   not allowed to regress in future implementations.
+ *
+ *   This benchmark takes a sampling and then adjusts until it finds a
+ *   commit point.  It doesn't exhaustively check all possible conditions,
+ *   which do to the number of combinations would be impossible.  Instead
+ *   it starts its search from a starting dimension, that can be changed
+ *   via the -s option.  The search is also bounded by a set of search
+ *   limits, that are hard-coded into a structure of constants named
+ *   searchLimits.  Results that happen to reach a searchLimit are prefixed
+ *   with >=, so that it is known that the value could possibly be larger.
+ *
+ *   Measurements are made for each of the graphic formats specified as
+ *   positional parameters on the command-line.  If no graphic formats
+ *   are specified on the command line, then by default measurements are
+ *   made and reported for each of the known graphic format.
+ */
+
+#include <algorithm>
+#include <assert.h>
+#include <cerrno>
+#include <cmath>
+#include <cstdlib>
+#include <ctime>
+#include <iomanip>
+#include <istream>
+#include <libgen.h>
+#include <list>
+#include <sched.h>
+#include <sstream>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <vector>
+
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+#define LOG_TAG "hwcCommitTest"
+#include <utils/Log.h>
+#include <testUtil.h>
+
+#include <hardware/hwcomposer.h>
+
+#include <glTestLib.h>
+#include <hwc/hwcTestLib.h>
+
+using namespace std;
+using namespace android;
+
+// Defaults
+const HwcTestDim defaultStartDim = HwcTestDim(100, 100);
+const bool defaultVerbose = false;
+
+const uint32_t   defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+const int32_t    defaultTransform = 0;
+const uint32_t   defaultBlend = HWC_BLENDING_NONE;
+const ColorFract defaultColor(0.5, 0.5, 0.5);
+const float      defaultAlpha = 1.0; // Opaque
+const HwcTestDim defaultSourceDim(1, 1);
+const struct hwc_rect defaultSourceCrop = {0, 0, 1, 1};
+const struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100};
+
+// Global Constants
+const uint32_t printFieldWidth = 2;
+const struct searchLimits {
+    uint32_t   numOverlays;
+    HwcTestDim sourceCrop;
+} searchLimits = {
+    10,
+    HwcTestDim(3000, 2000),
+};
+const struct transformType {
+    const char *desc;
+    uint32_t id;
+} transformType[] = {
+    {"fliph",  HWC_TRANSFORM_FLIP_H},
+    {"flipv",  HWC_TRANSFORM_FLIP_V},
+    {"rot90",  HWC_TRANSFORM_ROT_90},
+    {"rot180", HWC_TRANSFORM_ROT_180},
+    {"rot270", HWC_TRANSFORM_ROT_270},
+};
+const struct blendType {
+    const char *desc;
+    uint32_t id;
+} blendType[] = {
+    {"none", HWC_BLENDING_NONE},
+    {"premult", HWC_BLENDING_PREMULT},
+    {"coverage", HWC_BLENDING_COVERAGE},
+};
+
+// Defines
+#define MAXCMD               200
+#define CMD_STOP_FRAMEWORK   "stop 2>&1"
+#define CMD_START_FRAMEWORK  "start 2>&1"
+
+// Macros
+#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
+
+// Local types
+class Rectangle {
+public:
+    Rectangle(uint32_t graphicFormat = defaultFormat,
+              HwcTestDim dfDim = HwcTestDim(1, 1),
+              HwcTestDim sDim = HwcTestDim(1, 1));
+    void setSourceDim(HwcTestDim dim);
+
+    uint32_t     format;
+    uint32_t     transform;
+    int32_t      blend;
+    ColorFract   color;
+    float        alpha;
+    HwcTestDim   sourceDim;
+    struct hwc_rect   sourceCrop;
+    struct hwc_rect   displayFrame;
+};
+
+class Range {
+public:
+    Range(void) : _l(0), _u(0) {}
+    Range(uint32_t lower, uint32_t upper) : _l(lower), _u(upper) {}
+    uint32_t lower(void) { return _l; }
+    uint32_t upper(void) { return _u; }
+
+    operator string();
+
+private:
+    uint32_t _l; // lower
+    uint32_t _u; // upper
+};
+
+Range::operator string()
+{
+    ostringstream out;
+
+    out << '[' << _l << ", " << _u << ']';
+
+    return out.str();
+}
+
+class Rational {
+public:
+    Rational(void) : _n(0), _d(1) {}
+    Rational(uint32_t n, uint32_t d) : _n(n), _d(d) {}
+    uint32_t numerator(void) { return _n; }
+    uint32_t denominator(void) { return _d; }
+    void setNumerator(uint32_t numerator) { _n = numerator; }
+
+    bool operator==(const Rational& other) const;
+    bool operator!=(const Rational& other) const { return !(*this == other); }
+    bool operator<(const Rational& other) const;
+    bool operator>(const Rational& other) const {
+        return (!(*this == other) && !(*this < other));
+    }
+    static void double2Rational(double f, Range nRange, Range dRange,
+                               Rational& lower, Rational& upper);
+        
+    operator string() const;
+    operator double() const { return (double) _n / (double) _d; }
+
+
+private:
+    uint32_t _n;
+    uint32_t _d;
+};
+
+// Globals
+static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
+        GraphicBuffer::USAGE_SW_WRITE_RARELY;
+static hwc_composer_device_t *hwcDevice;
+static EGLDisplay dpy;
+static EGLSurface surface;
+static EGLint width, height;
+static size_t maxHeadingLen;
+static vector<string> formats;
+
+// Measurements
+struct meas {
+    uint32_t format;
+    uint32_t startDimOverlays;
+    uint32_t maxNonOverlapping;
+    uint32_t maxOverlapping;
+    list<uint32_t> transforms;
+    list<uint32_t> blends;
+    struct displayFrame {
+        uint32_t minWidth;
+        uint32_t minHeight;
+        HwcTestDim minDim;
+        uint32_t maxWidth;
+        uint32_t maxHeight;
+        HwcTestDim maxDim;
+    } df;
+    struct sourceCrop {
+        uint32_t minWidth;
+        uint32_t minHeight;
+        HwcTestDim minDim;
+        uint32_t maxWidth;
+        uint32_t maxHeight;
+        HwcTestDim maxDim;
+        Rational hScale;
+        HwcTestDim hScaleBestDf;
+        HwcTestDim hScaleBestSc;
+        Rational vScale;
+        HwcTestDim vScaleBestDf;
+        HwcTestDim vScaleBestSc;
+    } sc;
+    vector<uint32_t> overlapBlendNone;
+    vector<uint32_t> overlapBlendPremult;
+    vector<uint32_t> overlapBlendCoverage;
+};
+vector<meas> measurements;
+
+// Function prototypes
+uint32_t numOverlays(list<Rectangle>& rectList);
+uint32_t maxOverlays(uint32_t format, bool allowOverlap);
+list<uint32_t> supportedTransforms(uint32_t format);
+list<uint32_t> supportedBlends(uint32_t format);
+uint32_t dfMinWidth(uint32_t format);
+uint32_t dfMinHeight(uint32_t format);
+uint32_t dfMaxWidth(uint32_t format);
+uint32_t dfMaxHeight(uint32_t format);
+HwcTestDim dfMinDim(uint32_t format);
+HwcTestDim dfMaxDim(uint32_t format);
+uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim);
+uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim);
+uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim);
+uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim);
+HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim);
+HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim);
+Rational scHScale(uint32_t format,
+                  const HwcTestDim& dfMin, const HwcTestDim& dfMax,
+                  const HwcTestDim& scMin, const HwcTestDim& scMax,
+                  HwcTestDim& outBestDf, HwcTestDim& outBestSc);
+Rational scVScale(uint32_t format,
+                  const HwcTestDim& dfMin, const HwcTestDim& dfMax,
+                  const HwcTestDim& scMin, const HwcTestDim& scMax,
+                  HwcTestDim& outBestDf, HwcTestDim& outBestSc);
+uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat,
+                        uint32_t backgroundBlend, uint32_t foregroundBlend);
+string transformList2str(const list<uint32_t>& transformList);
+string blendList2str(const list<uint32_t>& blendList);
+void init(void);
+void printFormatHeadings(size_t indent);
+void printOverlapLine(size_t indent, const string formatStr,
+                      const vector<uint32_t>& results);
+void printSyntax(const char *cmd);
+
+// Command-line option settings
+static bool verbose = defaultVerbose;
+static HwcTestDim startDim = defaultStartDim;
+
+/*
+ * Main
+ *
+ * Performs the following high-level sequence of operations:
+ *
+ *   1. Command-line parsing
+ *
+ *   2. Form a list of command-line specified graphic formats.  If
+ *      no formats are specified, then form a list of all known formats.
+ *
+ *   3. Stop framework
+ *      Only one user at a time is allowed to use the HWC.  Surface
+ *      Flinger uses the HWC and is part of the framework.  Need to
+ *      stop the framework so that Surface Flinger will stop using
+ *      the HWC.
+ *   
+ *   4. Initialization
+ *
+ *   5. For each graphic format in the previously formed list perform
+ *      measurements on that format and report the results.
+ *
+ *   6. Start framework
+ */
+int
+main(int argc, char *argv[])
+{
+    int     rv, opt;
+    char   *chptr;
+    bool    error;
+    string  str;
+    char cmd[MAXCMD];
+    list<Rectangle> rectList;
+
+    testSetLogCatTag(LOG_TAG);
+
+    // Parse command line arguments
+    while ((opt = getopt(argc, argv, "s:v?h")) != -1) {
+        switch (opt) {
+
+          case 's': // Start Dimension
+            // Use arguments until next starts with a dash
+            // or current ends with a > or ]
+            str = optarg;
+            while (optind < argc) {
+                if (*argv[optind] == '-') { break; }
+                char endChar = (str.length() > 1) ? str[str.length() - 1] : 0;
+                if ((endChar == '>') || (endChar == ']')) { break; }
+                str += " " + string(argv[optind++]);
+            }
+            {
+                istringstream in(str);
+                startDim = hwcTestParseDim(in, error);
+                // Any parse error or characters not used by parser
+                if (error
+                    || (((unsigned int) in.tellg() != in.str().length())
+                        && (in.tellg() != (streampos) -1))) {
+                    testPrintE("Invalid command-line specified start "
+                               "dimension of: %s", str.c_str());
+                    exit(8);
+                }
+            }
+            break;
+
+          case 'v': // Verbose
+            verbose = true;
+            break;
+
+          case 'h': // Help
+          case '?':
+          default:
+            printSyntax(basename(argv[0]));
+            exit(((optopt == 0) || (optopt == '?')) ? 0 : 11);
+        }
+    }
+
+    // Positional parameters
+    // Positional parameters provide the names of graphic formats that
+    // measurements are to be made on.  Measurements are made on all
+    // known graphic formats when no positional parameters are provided.
+    if (optind == argc) {
+        // No command-line specified graphic formats
+        // Add all graphic formats to the list of formats to be measured
+        for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
+            formats.push_back(hwcTestGraphicFormat[n1].desc);
+        }
+    } else {
+        // Add names of command-line specified graphic formats to the
+        // list of formats to be tested
+        for (; argv[optind] != NULL; optind++) {
+            formats.push_back(argv[optind]);
+        }
+    }
+
+    // Determine length of longest specified graphic format.
+    // This value is used for output formating
+    for (vector<string>::iterator it = formats.begin();
+         it != formats.end(); ++it) {
+         maxHeadingLen = max(maxHeadingLen, it->length());
+    }
+
+    // Stop framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
+        exit(14);
+    }
+    testExecCmd(cmd);
+    testDelay(1.0); // TODO - needs means to query whether asynchronous stop
+                    // framework operation has completed.  For now, just wait
+                    // a long time.
+
+    testPrintI("startDim: %s", ((string) startDim).c_str());
+
+    init();
+
+    // For each of the graphic formats
+    for (vector<string>::iterator itFormat = formats.begin();
+         itFormat != formats.end(); ++itFormat) {
+
+        // Locate hwcTestLib structure that describes this format
+        const struct hwcTestGraphicFormat *format;
+        format = hwcTestGraphicFormatLookup((*itFormat).c_str());
+        if (format == NULL) {
+            testPrintE("Unknown graphic format of: %s", (*itFormat).c_str());
+            exit(1);
+        }
+
+        // Display format header
+        testPrintI("format: %s", format->desc);
+
+        // Create area to hold the measurements
+        struct meas meas;
+        struct meas *measPtr;
+        meas.format = format->format;
+        measurements.push_back(meas);
+        measPtr = &measurements[measurements.size() - 1];
+
+        // Start dimension num overlays
+        Rectangle rect(format->format, startDim);
+        rectList.clear();
+        rectList.push_back(rect);
+        measPtr->startDimOverlays = numOverlays(rectList);
+        testPrintI("  startDimOverlays: %u", measPtr->startDimOverlays);
+
+        // Skip the rest of the measurements, when the start dimension
+        // doesn't produce an overlay
+        if (measPtr->startDimOverlays == 0) { continue; }
+
+        // Max Overlays
+        measPtr->maxNonOverlapping = maxOverlays(format->format, false);
+        testPrintI("  max nonOverlapping overlays: %s%u",
+                   (measPtr->maxNonOverlapping == searchLimits.numOverlays)
+                       ? ">= " : "",
+                   measPtr->maxNonOverlapping);
+        measPtr->maxOverlapping = maxOverlays(format->format, true);
+        testPrintI("  max Overlapping overlays: %s%u",
+                   (measPtr->maxOverlapping == searchLimits.numOverlays)
+                       ? ">= " : "",
+                   measPtr->maxOverlapping);
+
+        // Transforms and blends
+        measPtr->transforms = supportedTransforms(format->format);
+        testPrintI("  transforms: %s",
+                   transformList2str(measPtr->transforms).c_str());
+        measPtr->blends = supportedBlends(format->format);
+        testPrintI("  blends: %s",
+                   blendList2str(measPtr->blends).c_str());
+
+        // Display frame measurements
+        measPtr->df.minWidth = dfMinWidth(format->format);
+        testPrintI("  dfMinWidth: %u", measPtr->df.minWidth);
+
+        measPtr->df.minHeight = dfMinHeight(format->format);
+        testPrintI("  dfMinHeight: %u", measPtr->df.minHeight);
+
+        measPtr->df.maxWidth = dfMaxWidth(format->format);
+        testPrintI("  dfMaxWidth: %u", measPtr->df.maxWidth);
+
+        measPtr->df.maxHeight = dfMaxHeight(format->format);
+        testPrintI("  dfMaxHeight: %u", measPtr->df.maxHeight);
+
+        measPtr->df.minDim = dfMinDim(format->format);
+        testPrintI("  dfMinDim: %s", ((string) measPtr->df.minDim).c_str());
+
+        measPtr->df.maxDim = dfMaxDim(format->format);
+        testPrintI("  dfMaxDim: %s", ((string) measPtr->df.maxDim).c_str());
+
+        // Source crop measurements
+        measPtr->sc.minWidth = scMinWidth(format->format, measPtr->df.minDim);
+        testPrintI("  scMinWidth: %u", measPtr->sc.minWidth);
+
+        measPtr->sc.minHeight = scMinHeight(format->format, measPtr->df.minDim);
+        testPrintI("  scMinHeight: %u", measPtr->sc.minHeight);
+
+        measPtr->sc.maxWidth = scMaxWidth(format->format, measPtr->df.maxDim);
+        testPrintI("  scMaxWidth: %s%u", (measPtr->sc.maxWidth
+                   == searchLimits.sourceCrop.width()) ? ">= " : "",
+                   measPtr->sc.maxWidth);
+
+        measPtr->sc.maxHeight = scMaxHeight(format->format, measPtr->df.maxDim);
+        testPrintI("  scMaxHeight: %s%u", (measPtr->sc.maxHeight
+                   == searchLimits.sourceCrop.height()) ? ">= " : "",
+                   measPtr->sc.maxHeight);
+
+        measPtr->sc.minDim = scMinDim(format->format, measPtr->df.minDim);
+        testPrintI("  scMinDim: %s", ((string) measPtr->sc.minDim).c_str());
+
+        measPtr->sc.maxDim = scMaxDim(format->format, measPtr->df.maxDim);
+        testPrintI("  scMaxDim: %s%s", ((measPtr->sc.maxDim.width()
+                         >= searchLimits.sourceCrop.width())
+                         || (measPtr->sc.maxDim.width() >=
+                         searchLimits.sourceCrop.height())) ? ">= " : "",
+                   ((string) measPtr->sc.maxDim).c_str());
+
+        measPtr->sc.hScale = scHScale(format->format,
+                                      measPtr->df.minDim, measPtr->df.maxDim,
+                                      measPtr->sc.minDim, measPtr->sc.maxDim,
+                                      measPtr->sc.hScaleBestDf,
+                                      measPtr->sc.hScaleBestSc);
+        testPrintI("  scHScale: %s%f",
+                   (measPtr->sc.hScale
+                       >= Rational(searchLimits.sourceCrop.width(),
+                                   measPtr->df.minDim.width())) ? ">= " : "",
+                   (double) measPtr->sc.hScale);
+        testPrintI("    HScale Best Display Frame: %s",
+                   ((string) measPtr->sc.hScaleBestDf).c_str());
+        testPrintI("    HScale Best Source Crop: %s",
+                   ((string) measPtr->sc.hScaleBestSc).c_str());
+
+        measPtr->sc.vScale = scVScale(format->format,
+                                      measPtr->df.minDim, measPtr->df.maxDim,
+                                      measPtr->sc.minDim, measPtr->sc.maxDim,
+                                      measPtr->sc.vScaleBestDf,
+                                      measPtr->sc.vScaleBestSc);
+        testPrintI("  scVScale: %s%f",
+                   (measPtr->sc.vScale
+                       >= Rational(searchLimits.sourceCrop.height(),
+                                   measPtr->df.minDim.height())) ? ">= " : "",
+                   (double) measPtr->sc.vScale);
+        testPrintI("    VScale Best Display Frame: %s",
+                   ((string) measPtr->sc.vScaleBestDf).c_str());
+        testPrintI("    VScale Best Source Crop: %s",
+                   ((string) measPtr->sc.vScaleBestSc).c_str());
+
+        // Overlap two graphic formats and different blends
+        // Results displayed after all overlap measurments with
+        // current format in the foreground
+        // TODO: make measurments with background blend other than
+        //       none.  All of these measurements are done with a
+        //       background blend of HWC_BLENDING_NONE, with the
+        //       blend type of the foregound being varied.
+        uint32_t foregroundFormat = format->format;
+        for (vector<string>::iterator it = formats.begin();
+             it != formats.end(); ++it) {
+            uint32_t num;
+
+            const struct hwcTestGraphicFormat *backgroundFormatPtr
+                = hwcTestGraphicFormatLookup((*it).c_str());
+            uint32_t backgroundFormat = backgroundFormatPtr->format;
+
+            num = numOverlapping(backgroundFormat, foregroundFormat,
+                                 HWC_BLENDING_NONE, HWC_BLENDING_NONE);
+            measPtr->overlapBlendNone.push_back(num);
+
+            num = numOverlapping(backgroundFormat, foregroundFormat,
+                                 HWC_BLENDING_NONE, HWC_BLENDING_PREMULT);
+            measPtr->overlapBlendPremult.push_back(num);
+
+            num = numOverlapping(backgroundFormat, foregroundFormat,
+                                 HWC_BLENDING_NONE, HWC_BLENDING_COVERAGE);
+            measPtr->overlapBlendCoverage.push_back(num);
+        }
+
+    }
+
+    // Display overlap results
+    size_t indent = 2;
+    testPrintI("overlapping blend: none");
+    printFormatHeadings(indent);
+    for (vector<string>::iterator it = formats.begin();
+         it != formats.end(); ++it) {
+        printOverlapLine(indent, *it, measurements[it
+                         - formats.begin()].overlapBlendNone);
+    }
+    testPrintI("");
+
+    testPrintI("overlapping blend: premult");
+    printFormatHeadings(indent);
+    for (vector<string>::iterator it = formats.begin();
+         it != formats.end(); ++it) {
+        printOverlapLine(indent, *it, measurements[it
+                         - formats.begin()].overlapBlendPremult);
+    }
+    testPrintI("");
+
+    testPrintI("overlapping blend: coverage");
+    printFormatHeadings(indent);
+    for (vector<string>::iterator it = formats.begin();
+         it != formats.end(); ++it) {
+        printOverlapLine(indent, *it, measurements[it
+                         - formats.begin()].overlapBlendCoverage);
+    }
+    testPrintI("");
+
+    // Start framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
+        exit(21);
+    }
+    testExecCmd(cmd);
+
+    return 0;
+}
+
+// Determine the maximum number of overlays that are all of the same format
+// that the HWC will commit to.  If allowOverlap is true, then the rectangles
+// are laid out on a diagonal starting from the upper left corner.  With
+// each rectangle adjust one pixel to the right and one pixel down.
+// When allowOverlap is false, the rectangles are tiled in column major
+// order.  Note, column major ordering is used so that the initial rectangles
+// are all on different horizontal scan rows.  It is common that hardware
+// has limits on the number of objects it can handle on any single row.
+uint32_t maxOverlays(uint32_t format, bool allowOverlap)
+{
+    unsigned int max = 0;
+
+    for (unsigned int numRects = 1; numRects <= searchLimits.numOverlays;
+         numRects++) {
+        list<Rectangle> rectList;
+
+        for (unsigned int x = 0;
+             (x + startDim.width()) < (unsigned int) width;
+             x += (allowOverlap) ? 1 : startDim.width()) {
+            for (unsigned int y = 0;
+                 (y + startDim.height()) < (unsigned int) height;
+                 y += (allowOverlap) ? 1 : startDim.height()) {
+                Rectangle rect(format, startDim, startDim);
+                rect.displayFrame.left = x;
+                rect.displayFrame.top = y;
+                rect.displayFrame.right = x + startDim.width();
+                rect.displayFrame.bottom = y + startDim.height();
+
+                rectList.push_back(rect);
+
+                if (rectList.size() >= numRects) { break; }
+            }
+            if (rectList.size() >= numRects) { break; }
+        }
+
+        uint32_t num = numOverlays(rectList);
+        if (num > max) { max = num; }
+    }
+
+    return max;
+}
+
+// Measures what transforms (i.e. flip horizontal, rotate 180) are
+// supported by the specified format
+list<uint32_t> supportedTransforms(uint32_t format)
+{
+    list<uint32_t> rv;
+    list<Rectangle> rectList;
+    Rectangle rect(format, startDim);
+
+    // For each of the transform types
+    for (unsigned int idx = 0; idx < NUMA(transformType); idx++) {
+        unsigned int id = transformType[idx].id;
+
+        rect.transform = id;
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+
+        if (num == 1) {
+            rv.push_back(id);
+        }
+    }
+
+    return rv;
+}
+
+// Determines which types of blends (i.e. none, premult, coverage) are
+// supported by the specified format
+list<uint32_t> supportedBlends(uint32_t format)
+{
+    list<uint32_t> rv;
+    list<Rectangle> rectList;
+    Rectangle rect(format, startDim);
+
+    // For each of the blend types
+    for (unsigned int idx = 0; idx < NUMA(blendType); idx++) {
+        unsigned int id = blendType[idx].id;
+
+        rect.blend = id;
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+
+        if (num == 1) {
+            rv.push_back(id);
+        }
+    }
+
+    return rv;
+}
+
+// Determines the minimum width of any display frame of the given format
+// that the HWC will commit to.
+uint32_t dfMinWidth(uint32_t format)
+{
+    uint32_t w;
+    list<Rectangle> rectList;
+
+    for (w = 1; w <= startDim.width(); w++) {
+        HwcTestDim dim(w, startDim.height());
+        Rectangle rect(format, dim);
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return w;
+        }
+    }
+    if (w > startDim.width()) {
+        testPrintE("Failed to locate display frame min width");
+        exit(33);
+    }
+
+    return w;
+}
+
+// Display frame minimum height
+uint32_t dfMinHeight(uint32_t format)
+{
+    uint32_t h;
+    list<Rectangle> rectList;
+
+    for (h = 1; h <= startDim.height(); h++) {
+        HwcTestDim dim(startDim.width(), h);
+        Rectangle rect(format, dim);
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return h;
+        }
+    }
+    if (h > startDim.height()) {
+        testPrintE("Failed to locate display frame min height");
+        exit(34);
+    }
+
+    return h;
+}
+
+// Display frame maximum width
+uint32_t dfMaxWidth(uint32_t format)
+{
+    uint32_t w;
+    list<Rectangle> rectList;
+
+    for (w = width; w >= startDim.width(); w--) {
+        HwcTestDim dim(w, startDim.height());
+        Rectangle rect(format, dim);
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return w;
+        }
+    }
+    if (w < startDim.width()) {
+        testPrintE("Failed to locate display frame max width");
+        exit(35);
+    }
+
+    return w;
+}
+
+// Display frame maximum height
+uint32_t dfMaxHeight(uint32_t format)
+{
+    uint32_t h;
+
+    for (h = height; h >= startDim.height(); h--) {
+        HwcTestDim dim(startDim.width(), h);
+        Rectangle rect(format, dim);
+        list<Rectangle> rectList;
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return h;
+        }
+    }
+    if (h < startDim.height()) {
+        testPrintE("Failed to locate display frame max height");
+        exit(36);
+    }
+
+    return h;
+}
+
+// Determine the minimum number of pixels that the HWC will ever commit to.
+// Note, this might be different that dfMinWidth * dfMinHeight, in that this
+// function adjusts both the width and height from the starting dimension.
+HwcTestDim dfMinDim(uint32_t format)
+{
+    uint64_t bestMinPixels = 0;
+    HwcTestDim bestDim;
+    bool bestSet = false; // True when value has been assigned to
+                          // bestMinPixels and bestDim
+
+    bool origVerbose = verbose;  // Temporarily turn off verbose
+    verbose = false;
+    for (uint32_t w = 1; w <= startDim.width(); w++) {
+        for (uint32_t h = 1; h <= startDim.height(); h++) {
+            if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) {
+                break;
+            }
+
+            HwcTestDim dim(w, h);
+            Rectangle rect(format, dim);
+            list<Rectangle> rectList;
+            rectList.push_back(rect);
+            uint32_t num = numOverlays(rectList);
+            if (num > 0) {
+                uint64_t pixels = dim.width() * dim.height();
+                if (!bestSet || (pixels < bestMinPixels)) {
+                    bestMinPixels = pixels;
+                    bestDim = dim;
+                    bestSet = true;
+                }
+            }
+        }
+    }
+    verbose = origVerbose;
+
+    if (!bestSet) {
+        testPrintE("Unable to locate display frame min dimension");
+        exit(20);
+    }
+
+    return bestDim;
+}
+
+// Display frame maximum dimension
+HwcTestDim dfMaxDim(uint32_t format)
+{
+    uint64_t bestMaxPixels = 0;
+    HwcTestDim bestDim;
+    bool bestSet = false; // True when value has been assigned to
+                          // bestMaxPixels and bestDim;
+
+    // Potentially increase benchmark performance by first checking
+    // for the common case of supporting a full display frame.
+    HwcTestDim dim(width, height);
+    Rectangle rect(format, dim);
+    list<Rectangle> rectList;
+    rectList.push_back(rect);
+    uint32_t num = numOverlays(rectList);
+    if (num == 1) { return dim; }
+
+    // TODO: Use a binary search
+    bool origVerbose = verbose;  // Temporarily turn off verbose
+    verbose = false;
+    for (uint32_t w = startDim.width(); w <= (uint32_t) width; w++) {
+        for (uint32_t h = startDim.height(); h <= (uint32_t) height; h++) {
+            if (bestSet && ((w * h) <= bestMaxPixels)) { continue; }
+
+            HwcTestDim dim(w, h);
+            Rectangle rect(format, dim);
+            list<Rectangle> rectList;
+            rectList.push_back(rect);
+            uint32_t num = numOverlays(rectList);
+            if (num > 0) {
+                uint64_t pixels = dim.width() * dim.height();
+                if (!bestSet || (pixels > bestMaxPixels)) {
+                    bestMaxPixels = pixels;
+                    bestDim = dim;
+                    bestSet = true;
+                }
+            }
+        }
+    }
+    verbose = origVerbose;
+
+    if (!bestSet) {
+        testPrintE("Unable to locate display frame max dimension");
+        exit(21);
+    }
+
+    return bestDim;
+}
+
+// Source crop minimum width
+uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim)
+{
+    uint32_t w;
+    list<Rectangle> rectList;
+
+    // Source crop frame min width
+    for (w = 1; w <= dfDim.width(); w++) {
+        Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height()));
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return w;
+        }
+    }
+    testPrintE("Failed to locate source crop min width");
+    exit(35);
+}
+
+// Source crop minimum height
+uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim)
+{
+    uint32_t h;
+    list<Rectangle> rectList;
+
+    for (h = 1; h <= dfDim.height(); h++) {
+        Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h));
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return h;
+        }
+    }
+    testPrintE("Failed to locate source crop min height");
+    exit(36);
+}
+
+// Source crop maximum width
+uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim)
+{
+    uint32_t w;
+    list<Rectangle> rectList;
+
+    for (w = searchLimits.sourceCrop.width(); w >= dfDim.width(); w--) {
+        Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height()));
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return w;
+        }
+    }
+    testPrintE("Failed to locate source crop max width");
+    exit(35);
+}
+
+// Source crop maximum height
+uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim)
+{
+    uint32_t h;
+    list<Rectangle> rectList;
+
+    for (h = searchLimits.sourceCrop.height(); h >= dfDim.height(); h--) {
+        Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h));
+        rectList.clear();
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+        if (num > 0) {
+            return h;
+        }
+    }
+    testPrintE("Failed to locate source crop max height");
+    exit(36);
+}
+
+// Source crop minimum dimension
+// Discovers the source crop with the least number of pixels that the
+// HWC will commit to.  Note, this may be different from scMinWidth
+// * scMinHeight, in that this function searches for a combination of
+// width and height.  While the other routines always keep one of the
+// dimensions equal to the corresponding start dimension.
+HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim)
+{
+    uint64_t bestMinPixels = 0;
+    HwcTestDim bestDim;
+    bool bestSet = false; // True when value has been assigned to
+                          // bestMinPixels and bestDim
+
+    bool origVerbose = verbose;  // Temporarily turn off verbose
+    verbose = false;
+    for (uint32_t w = 1; w <= dfDim.width(); w++) {
+        for (uint32_t h = 1; h <= dfDim.height(); h++) {
+            if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) {
+                break;
+            }
+
+            HwcTestDim dim(w, h);
+            Rectangle rect(format, dfDim, HwcTestDim(w, h));
+            list<Rectangle> rectList;
+            rectList.push_back(rect);
+            uint32_t num = numOverlays(rectList);
+            if (num > 0) {
+                uint64_t pixels = dim.width() * dim.height();
+                if (!bestSet || (pixels < bestMinPixels)) {
+                    bestMinPixels = pixels;
+                    bestDim = dim;
+                    bestSet = true;
+                }
+            }
+        }
+    }
+    verbose = origVerbose;
+
+    if (!bestSet) {
+        testPrintE("Unable to locate source crop min dimension");
+        exit(20);
+    }
+
+    return bestDim;
+}
+
+// Source crop maximum dimension
+HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim)
+{
+    uint64_t bestMaxPixels = 0;
+    HwcTestDim bestDim;
+    bool bestSet = false; // True when value has been assigned to
+                          // bestMaxPixels and bestDim;
+
+    // Potentially increase benchmark performance by first checking
+    // for the common case of supporting the maximum checked source size
+    HwcTestDim dim = searchLimits.sourceCrop;
+    Rectangle rect(format, dfDim, searchLimits.sourceCrop);
+    list<Rectangle> rectList;
+    rectList.push_back(rect);
+    uint32_t num = numOverlays(rectList);
+    if (num == 1) { return dim; }
+
+    // TODO: Use a binary search
+    bool origVerbose = verbose;  // Temporarily turn off verbose
+    verbose = false;
+    for (uint32_t w = dfDim.width();
+         w <= searchLimits.sourceCrop.width(); w++) {
+        for (uint32_t h = dfDim.height();
+             h <= searchLimits.sourceCrop.height(); h++) {
+            if (bestSet && ((w * h) <= bestMaxPixels)) { continue; }
+
+            HwcTestDim dim(w, h);
+            Rectangle rect(format, dfDim, dim);
+            list<Rectangle> rectList;
+            rectList.push_back(rect);
+            uint32_t num = numOverlays(rectList);
+            if (num > 0) {
+                uint64_t pixels = dim.width() * dim.height();
+                if (!bestSet || (pixels > bestMaxPixels)) {
+                    bestMaxPixels = pixels;
+                    bestDim = dim;
+                    bestSet = true;
+                }
+            }
+        }
+    }
+    verbose = origVerbose;
+
+    if (!bestSet) {
+        testPrintE("Unable to locate source crop max dimension");
+        exit(21);
+    }
+
+    return bestDim;
+}
+
+// Source crop horizontal scale
+// Determines the maximum factor by which the source crop can be larger
+// that the display frame.  The commit point is discovered through a
+// binary search of rational numbers.  The numerator in each of the
+// rational numbers contains the dimension for the source crop, while
+// the denominator specifies the dimension for the display frame.  On
+// each pass of the binary search the mid-point between the greatest
+// point committed to (best) and the smallest point in which a commit
+// has failed is calculated.  This mid-point is then passed to a function
+// named double2Rational, which determines the closest rational numbers
+// just below and above the mid-point.  By default the lower rational
+// number is used for the scale factor on the next pass of the binary
+// search.  The upper value is only used when best is already equal
+// to the lower value.  This only occurs when the lower value has already
+// been tried.
+Rational scHScale(uint32_t format,
+                      const HwcTestDim& dfMin, const HwcTestDim& dfMax,
+                      const HwcTestDim& scMin, const HwcTestDim& scMax,
+                      HwcTestDim& outBestDf, HwcTestDim& outBestSc)
+{
+    HwcTestDim scDim, dfDim; // Source crop and display frame dimension
+    Rational best(0, 1), minBad;  // Current bounds for a binary search
+                                  // MinGood is set below the lowest
+                                  // possible scale.  The value of minBad,
+                                  // will be set by the first pass
+                                  // of the binary search.
+
+    // Perform the passes of the binary search
+    bool firstPass = true;
+    do {
+        // On first pass try the maximum scale within the search limits
+        if (firstPass) {
+            // Try the maximum possible scale, within the search limits
+            scDim = HwcTestDim(searchLimits.sourceCrop.width(), scMin.height());
+            dfDim = dfMin;
+        } else {
+            // Subsequent pass
+            // Halve the difference between best and minBad.
+            Rational lower, upper, selected;
+
+            // Try the closest ratio halfway between minBood and minBad;
+            // TODO: Avoid rounding issue by using Rational type for
+            //       midpoint.  For now will use double, which should
+            //       have more than sufficient resolution.
+            double mid = (double) best
+                         + ((double) minBad - (double) best) / 2.0;
+            Rational::double2Rational(mid,
+                            Range(scMin.width(), scMax.width()),
+                            Range(dfMin.width(), dfMax.width()),
+                            lower, upper);
+            if (((lower == best) && (upper == minBad))) {
+                return best;
+            }
+
+            // Use lower value unless its already been tried
+            selected = (lower != best) ? lower : upper;
+
+            // Assign the size of the source crop and display frame
+            // from the selected ratio of source crop to display frame.
+            scDim = HwcTestDim(selected.numerator(), scMin.height());
+            dfDim = HwcTestDim(selected.denominator(), dfMin.height());
+        }
+
+        // See if the HWC will commit to this combination
+        Rectangle rect(format, dfDim, scDim);
+        list<Rectangle> rectList;
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+
+        if (verbose) {
+            testPrintI("  scHscale num: %u scale: %f dfDim: %s scDim: %s",
+                       num, (float) Rational(scDim.width(), dfDim.width()),
+                       ((string) dfDim).c_str(), ((string) scDim).c_str());
+        }
+        if (num == 1) {
+            // HWC committed to the combination
+            // This is the best scale factor seen so far.  Report the
+            // dimensions to the caller, in case nothing better is seen.
+            outBestDf = dfDim;
+            outBestSc = scDim;
+
+            // Success on the first pass means the largest possible scale
+            // is supported, in which case no need to search any further.
+            if (firstPass) { return Rational(scDim.width(), dfDim.width()); }
+
+            // Update the lower bound of the binary search
+            best = Rational(scDim.width(), dfDim.width());
+        } else {
+            // HWC didn't commit to this combination, so update the
+            // upper bound of the binary search.
+            minBad = Rational(scDim.width(), dfDim.width());
+        }
+
+        firstPass = false;
+    } while (best != minBad);
+
+    return best;
+}
+
+// Source crop vertical scale
+// Determines the maximum factor by which the source crop can be larger
+// that the display frame.  The commit point is discovered through a
+// binary search of rational numbers.  The numerator in each of the
+// rational numbers contains the dimension for the source crop, while
+// the denominator specifies the dimension for the display frame.  On
+// each pass of the binary search the mid-point between the greatest
+// point committed to (best) and the smallest point in which a commit
+// has failed is calculated.  This mid-point is then passed to a function
+// named double2Rational, which determines the closest rational numbers
+// just below and above the mid-point.  By default the lower rational
+// number is used for the scale factor on the next pass of the binary
+// search.  The upper value is only used when best is already equal
+// to the lower value.  This only occurs when the lower value has already
+// been tried.
+Rational scVScale(uint32_t format,
+                      const HwcTestDim& dfMin, const HwcTestDim& dfMax,
+                      const HwcTestDim& scMin, const HwcTestDim& scMax,
+                      HwcTestDim& outBestDf, HwcTestDim& outBestSc)
+{
+    HwcTestDim scDim, dfDim; // Source crop and display frame dimension
+    Rational best(0, 1), minBad;  // Current bounds for a binary search
+                                  // MinGood is set below the lowest
+                                  // possible scale.  The value of minBad,
+                                  // will be set by the first pass
+                                  // of the binary search.
+
+    // Perform the passes of the binary search
+    bool firstPass = true;
+    do {
+        // On first pass try the maximum scale within the search limits
+        if (firstPass) {
+            // Try the maximum possible scale, within the search limits
+            scDim = HwcTestDim(scMin.width(), searchLimits.sourceCrop.height());
+            dfDim = dfMin;
+        } else {
+            // Subsequent pass
+            // Halve the difference between best and minBad.
+            Rational lower, upper, selected;
+
+            // Try the closest ratio halfway between minBood and minBad;
+            // TODO: Avoid rounding issue by using Rational type for
+            //       midpoint.  For now will use double, which should
+            //       have more than sufficient resolution.
+            double mid = (double) best
+                         + ((double) minBad - (double) best) / 2.0;
+            Rational::double2Rational(mid,
+                            Range(scMin.height(), scMax.height()),
+                            Range(dfMin.height(), dfMax.height()),
+                            lower, upper);
+            if (((lower == best) && (upper == minBad))) {
+                return best;
+            }
+
+            // Use lower value unless its already been tried
+            selected = (lower != best) ? lower : upper;
+
+            // Assign the size of the source crop and display frame
+            // from the selected ratio of source crop to display frame.
+            scDim = HwcTestDim(scMin.width(), selected.numerator());
+            dfDim = HwcTestDim(dfMin.width(), selected.denominator());
+        }
+
+        // See if the HWC will commit to this combination
+        Rectangle rect(format, dfDim, scDim);
+        list<Rectangle> rectList;
+        rectList.push_back(rect);
+        uint32_t num = numOverlays(rectList);
+
+        if (verbose) {
+            testPrintI("  scHscale num: %u scale: %f dfDim: %s scDim: %s",
+                       num, (float) Rational(scDim.height(), dfDim.height()),
+                       ((string) dfDim).c_str(), ((string) scDim).c_str());
+        }
+        if (num == 1) {
+            // HWC committed to the combination
+            // This is the best scale factor seen so far.  Report the
+            // dimensions to the caller, in case nothing better is seen.
+            outBestDf = dfDim;
+            outBestSc = scDim;
+
+            // Success on the first pass means the largest possible scale
+            // is supported, in which case no need to search any further.
+            if (firstPass) { return Rational(scDim.height(), dfDim.height()); }
+
+            // Update the lower bound of the binary search
+            best = Rational(scDim.height(), dfDim.height());
+        } else {
+            // HWC didn't commit to this combination, so update the
+            // upper bound of the binary search.
+            minBad = Rational(scDim.height(), dfDim.height());
+        }
+
+        firstPass = false;
+    } while (best != minBad);
+
+    return best;
+}
+
+uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat,
+                        uint32_t backgroundBlend, uint32_t foregroundBlend)
+{
+    list<Rectangle> rectList;
+
+    Rectangle background(backgroundFormat, startDim, startDim);
+    background.blend = backgroundBlend;
+    rectList.push_back(background);
+
+    // TODO: Handle cases where startDim is so small that adding 5
+    //       causes frames not to overlap.
+    // TODO: Handle cases where startDim is so large that adding 5
+    //       cause a portion or all of the foreground displayFrame
+    //       to be off the display.
+    Rectangle foreground(foregroundFormat, startDim, startDim);
+    foreground.displayFrame.left += 5;
+    foreground.displayFrame.top += 5;
+    foreground.displayFrame.right += 5;
+    foreground.displayFrame.bottom += 5;
+    background.blend = foregroundBlend;
+    rectList.push_back(foreground);
+
+    uint32_t num = numOverlays(rectList);
+
+    return num;
+}
+
+Rectangle::Rectangle(uint32_t graphicFormat, HwcTestDim dfDim,
+                     HwcTestDim sDim) :
+    format(graphicFormat), transform(defaultTransform),
+    blend(defaultBlend), color(defaultColor), alpha(defaultAlpha),
+    sourceCrop(sDim), displayFrame(dfDim)
+{
+    // Set source dimension
+    // Can't use a base initializer, because the setting of format
+    // must be done before setting the sourceDimension.
+    setSourceDim(sDim);
+}
+
+void Rectangle::setSourceDim(HwcTestDim dim)
+{
+    this->sourceDim = dim;
+
+    const struct hwcTestGraphicFormat *attrib;
+    attrib = hwcTestGraphicFormatLookup(this->format);
+    if (attrib != NULL) {
+        if (sourceDim.width() % attrib->wMod) {
+            sourceDim.setWidth(sourceDim.width() + attrib->wMod
+            - (sourceDim.width() % attrib->wMod));
+        }
+        if (sourceDim.height() % attrib->hMod) {
+            sourceDim.setHeight(sourceDim.height() + attrib->hMod
+            - (sourceDim.height() % attrib->hMod));
+        }
+    }
+}
+
+// Rational member functions
+bool Rational::operator==(const Rational& other) const
+{
+    if (((uint64_t) _n * other._d)
+        == ((uint64_t) _d * other._n)) { return true; }
+
+    return false;
+}
+
+bool Rational::operator<(const Rational& other) const
+{
+    if (((uint64_t) _n * other._d)
+        < ((uint64_t) _d * other._n)) { return true; }
+
+    return false;
+}
+
+Rational::operator string() const
+{
+    ostringstream out;
+
+    out << _n << '/' << _d;
+
+    return out.str();
+}
+
+void Rational::double2Rational(double f, Range nRange, Range dRange,
+                    Rational& lower, Rational& upper)
+{
+    Rational bestLower(nRange.lower(), dRange.upper());
+    Rational bestUpper(nRange.upper(), dRange.lower());
+
+    // Search for a better solution
+    for (uint32_t d = dRange.lower(); d <= dRange.upper(); d++) {
+        Rational val(d * f, d);  // Lower, because double to int cast truncates
+
+        if ((val.numerator() < nRange.lower())
+            || (val.numerator() > nRange.upper())) { continue; }
+
+        if (((double) val > (double) bestLower) && ((double) val <= f)) {
+            bestLower = val;
+        } 
+
+        val.setNumerator(val.numerator() + 1);
+        if (val.numerator() > nRange.upper()) { continue; }
+
+        if (((double) val < (double) bestUpper) && ((double) val >= f)) {
+            bestUpper = val;
+        }
+    }
+
+    lower = bestLower;
+    upper = bestUpper;
+}
+
+// Local functions
+
+// Num Overlays
+// Given a list of rectangles, determine how many HWC will commit to render
+uint32_t numOverlays(list<Rectangle>& rectList)
+{
+    hwc_layer_list_t *hwcList;
+    list<sp<GraphicBuffer> > buffers;
+
+    hwcList = hwcTestCreateLayerList(rectList.size());
+    if (hwcList == NULL) {
+        testPrintE("numOverlays create hwcList failed");
+        exit(30);
+    }
+
+    hwc_layer_t *layer = &hwcList->hwLayers[0];
+    for (std::list<Rectangle>::iterator it = rectList.begin();
+         it != rectList.end(); ++it, ++layer) {
+        // Allocate the texture for the source frame
+        // and push it onto the buffers list, so that it
+        // stays in scope until a return from this function.
+        sp<GraphicBuffer> texture;
+        texture  = new GraphicBuffer(it->sourceDim.width(),
+                                     it->sourceDim.height(),
+                                     it->format, texUsage);
+        buffers.push_back(texture);
+
+        layer->handle = texture->handle;
+        layer->blending = it->blend;
+        layer->transform = it->transform;
+        layer->sourceCrop = it->sourceCrop;
+        layer->displayFrame = it->displayFrame;
+
+        layer->visibleRegionScreen.numRects = 1;
+        layer->visibleRegionScreen.rects = &layer->displayFrame;
+    }
+
+    // Perform prepare operation
+    if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(hwcList); }
+    hwcDevice->prepare(hwcDevice, hwcList);
+    if (verbose) {
+        testPrintI("Post Prepare:");
+        hwcTestDisplayListPrepareModifiable(hwcList);
+    }
+
+    // Count the number of overlays
+    uint32_t total = 0;
+    for (unsigned int n1 = 0; n1 < hwcList->numHwLayers; n1++) {
+        if (hwcList->hwLayers[n1].compositionType == HWC_OVERLAY) {
+            total++;
+        }
+    }
+
+    // Free the layer list and graphic buffers
+    hwcTestFreeLayerList(hwcList);
+
+    return total;
+}
+
+string transformList2str(const list<uint32_t>& transformList)
+{
+    ostringstream out;
+
+    for (list<uint32_t>::const_iterator it = transformList.begin();
+         it != transformList.end(); ++it) {
+        uint32_t id = *it;
+
+        if (it != transformList.begin()) {
+            out << ", ";
+        }
+        out << id;
+
+        for (unsigned int idx = 0; idx < NUMA(transformType); idx++) {
+            if (id == transformType[idx].id) {
+                out << " (" << transformType[idx].desc << ')';
+                break;
+            }
+        }
+    }
+
+    return out.str();
+}
+
+string blendList2str(const list<uint32_t>& blendList)
+{
+    ostringstream out;
+
+    for (list<uint32_t>::const_iterator it = blendList.begin();
+         it != blendList.end(); ++it) {
+        uint32_t id = *it;
+
+        if (it != blendList.begin()) {
+            out << ", ";
+        }
+        out << id;
+
+        for (unsigned int idx = 0; idx < NUMA(blendType); idx++) {
+            if (id == blendType[idx].id) {
+                out << " (" << blendType[idx].desc << ')';
+                break;
+            }
+        }
+    }
+
+    return out.str();
+}
+
+void init(void)
+{
+    srand48(0);
+
+    hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
+
+    hwcTestOpenHwc(&hwcDevice);
+}
+
+void printFormatHeadings(size_t indent)
+{
+    for (size_t row = 0; row <= maxHeadingLen; row++) {
+        ostringstream line;
+        for(vector<string>::iterator it = formats.begin();
+            it != formats.end(); ++it) {
+            if ((maxHeadingLen - row) <= it->length()) {
+                if (row != maxHeadingLen) {
+                    char ch = (*it)[it->length() - (maxHeadingLen - row)];
+                    line << ' ' << setw(printFieldWidth) << ch;
+                } else {
+                    line << ' ' << string(printFieldWidth, '-');
+                }
+            } else {
+               line << ' ' << setw(printFieldWidth) << "";
+            }
+        }
+        testPrintI("%*s%s", indent + maxHeadingLen, "",
+                   line.str().c_str());
+    }
+}
+
+void printOverlapLine(size_t indent, const string formatStr,
+                        const vector<uint32_t>& results)
+{
+    ostringstream line;
+
+    line << setw(indent + maxHeadingLen - formatStr.length()) << "";
+
+    line << formatStr;
+
+    for (vector<uint32_t>::const_iterator it = results.begin();
+         it != results.end(); ++it) {
+        line << ' ' << setw(printFieldWidth) << *it;
+    }
+
+    testPrintI("%s", line.str().c_str());
+}
+
+void printSyntax(const char *cmd)
+{
+    testPrintE("  %s [options] [graphicFormat] ...",
+               cmd);
+    testPrintE("    options:");
+    testPrintE("      -s [width, height] - start dimension");
+    testPrintE("      -v - Verbose");
+    testPrintE("");
+    testPrintE("    graphic formats:");
+    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
+        testPrintE("      %s", hwcTestGraphicFormat[n1].desc);
+    }
+}
diff --git a/opengl/tests/hwc/hwcRects.cpp b/opengl/tests/hwc/hwcRects.cpp
new file mode 100644
index 0000000..523e3de
--- /dev/null
+++ b/opengl/tests/hwc/hwcRects.cpp
@@ -0,0 +1,577 @@
+/*
+ * 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.
+ */
+
+/*
+ * Hardware Composer Rectangles
+ *
+ * Synopsis
+ *   hwcRects [options] (graphicFormat displayFrame [attributes],)...
+ *     options:
+ *       -D #.## - End of test delay
+ *       -v - Verbose
+ *
+ *      graphic formats:
+ *        RGBA8888 (reference frame default)
+ *        RGBX8888
+ *        RGB888
+ *        RGB565
+ *        BGRA8888
+ *        RGBA5551
+ *        RGBA4444
+ *        YV12
+ *
+ *      displayFrame
+ *        [left, top, right, bottom]
+ *
+ *      attributes:
+ *        transform: none | fliph | flipv | rot90 | rot180 | rot270
+ *        blend: none | premult | coverage
+ *        color: [0.##, 0.##, 0.##]
+ *        alpha: 0.##
+ *        sourceDim: [width, height]
+ *        sourceCrop: [left, top, right, bottom]
+ *
+ *      Example:
+ *        # White YV12 rectangle, with overlapping turquoise
+ *        #  RGBA8888 rectangle at 30%% (alpha: 0.7) transparency
+ *        hwcRects -v -D 30.0 \
+ *          YV12 [50, 80, 200, 300] transform: none \
+ *            color: [1.0, 0.5, 0.5], \
+ *          RGBA8888 [100, 150, 300, 400] blend: coverage \
+ *            color: [0.251, 0.878, 0.816] alpha: 0.7 \
+ *            sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]
+ *
+ * Description
+ *   Constructs a Hardware Composer (HWC) list of frames from
+ *   command-line specified parameters.  Then sends it to the HWC
+ *   be rendered.  The intended purpose of this tool is as a means to
+ *   reproduce and succinctly specify an observed HWC operation, with
+ *   no need to modify/compile a program.
+ *
+ *   The command-line syntax consists of a few standard command-line
+ *   options and then a description of one or more frames.  The frame
+ *   descriptions are separated from one another via a comma.  The
+ *   beginning of a frame description requires the specification
+ *   of the graphic format and then the display frame rectangle where
+ *   the frame will be displayed.  The display frame rectangle is
+ *   specified as follows, with the right and bottom coordinates being
+ *   exclusive values:
+ *
+ *     [left, top, right, bottom]
+ *    
+ *   After these two required parameters each frame description can
+ *   specify 1 or more optional attributes.  The name of each optional
+ *   attribute is preceded by a colon.  The current implementation
+ *   then requires white space after the colon and then the value of
+ *   the attribute is specified.  See the synopsis section above for
+ *   a list of attributes and the format of their expected value.
+ */
+
+#include <algorithm>
+#include <assert.h>
+#include <cerrno>
+#include <cmath>
+#include <cstdlib>
+#include <ctime>
+#include <istream>
+#include <libgen.h>
+#include <list>
+#include <sched.h>
+#include <sstream>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+#define LOG_TAG "hwcRectsTest"
+#include <utils/Log.h>
+#include <testUtil.h>
+
+#include <hardware/hwcomposer.h>
+
+#include <glTestLib.h>
+#include <hwc/hwcTestLib.h>
+
+using namespace std;
+using namespace android;
+
+// Defaults
+const bool defaultVerbose = false;
+const float defaultEndDelay = 2.0; // Default delay after rendering graphics
+
+const uint32_t   defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+const int32_t    defaultTransform = 0;
+const uint32_t   defaultBlend = HWC_BLENDING_NONE;
+const ColorFract defaultColor(0.5, 0.5, 0.5);
+const float      defaultAlpha = 1.0; // Opaque
+const HwcTestDim defaultSourceDim(1, 1);
+const struct hwc_rect defaultSourceCrop = {0, 0, 1, 1};
+const struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100};
+
+// Defines
+#define MAXCMD               200
+#define CMD_STOP_FRAMEWORK   "stop 2>&1"
+#define CMD_START_FRAMEWORK  "start 2>&1"
+
+// Macros
+#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
+
+// Local types
+class Rectangle {
+public:
+    Rectangle() : format(defaultFormat), transform(defaultTransform),
+                  blend(defaultBlend), color(defaultColor),
+                  alpha(defaultAlpha), sourceDim(defaultSourceDim),
+                  sourceCrop(defaultSourceCrop),
+                  displayFrame(defaultDisplayFrame) {};
+
+    uint32_t     format;
+    uint32_t     transform;
+    int32_t      blend;
+    ColorFract   color;
+    float        alpha;
+    HwcTestDim   sourceDim;
+    struct hwc_rect   sourceCrop;
+    struct hwc_rect   displayFrame;
+
+    sp<GraphicBuffer> texture;
+};
+
+// Globals
+list<Rectangle> rectangle;
+static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
+        GraphicBuffer::USAGE_SW_WRITE_RARELY;
+static hwc_composer_device_t *hwcDevice;
+static EGLDisplay dpy;
+static EGLSurface surface;
+static EGLint width, height;
+
+// Function prototypes
+static Rectangle parseRect(string rectStr);
+void init(void);
+void printSyntax(const char *cmd);
+
+// Command-line option settings
+static bool verbose = defaultVerbose;
+static float endDelay = defaultEndDelay;
+
+/*
+ * Main
+ *
+ * Performs the following high-level sequence of operations:
+ *
+ *   1. Parse command-line options
+ *
+ *   2. Stop framework
+ *
+ *   3. Initialization
+ *
+ *   4. Parse frame descriptions
+ *
+ *   5. Create HWC list from frame descriptions
+ *
+ *   6. Have HWC render the list description of the frames
+ *
+ *   7. Delay for amount of time given by endDelay
+ *
+ *   8. Start framework
+ */
+int
+main(int argc, char *argv[])
+{
+    int     rv, opt;
+    char   *chptr;
+    bool    error;
+    string  str;
+    char cmd[MAXCMD];
+
+    testSetLogCatTag(LOG_TAG);
+
+    // Parse command line arguments
+    while ((opt = getopt(argc, argv, "D:v?h")) != -1) {
+        switch (opt) {
+          case 'D': // End of test delay
+            endDelay = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (endDelay < 0.0)) {
+                testPrintE("Invalid command-line specified end of test delay "
+                           "of: %s", optarg);
+                exit(1);
+            }
+            break;
+
+          case 'v': // Verbose
+            verbose = true;
+            break;
+
+          case 'h': // Help
+          case '?':
+          default:
+            printSyntax(basename(argv[0]));
+            exit(((optopt == 0) || (optopt == '?')) ? 0 : 2);
+        }
+    }
+
+    // Stop framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
+        exit(3);
+    }
+    testExecCmd(cmd);
+    testDelay(1.0); // TODO - needs means to query whether asyncronous stop
+                    // framework operation has completed.  For now, just wait
+                    // a long time.
+
+    init();
+
+    // Parse rectangle descriptions
+    int numOpen = 0; // Current number of unmatched <[
+    string rectDesc(""); // String description of a single rectangle
+    while (optind < argc) {
+        string argNext = string(argv[optind++]);
+
+        if (rectDesc.length()) { rectDesc += ' '; }
+        rectDesc += argNext;
+
+        // Count number of opening <[ and matching >]
+        // At this point not worried about an opening character being
+        // matched by it's corresponding closing character.  For example,
+        // "<1.0, 2.0]" is incorrect because the opening < should be matched
+        // with a closing >, instead of the closing ].  Such errors are
+        // detected when the actual value is parsed.
+        for (unsigned int n1 = 0; n1 < argNext.length(); n1++) {
+            switch(argNext[n1]) {
+              case '[':
+              case '<':
+                numOpen++;
+                break;
+
+              case ']':
+              case '>':
+                numOpen--;
+                break;
+            }
+
+            // Error anytime there is more closing then opening characters
+            if (numOpen < 0) {
+                testPrintI("Mismatched number of opening <[ with "
+                           "closing >] in: %s", rectDesc.c_str());
+                exit(4);
+            }
+        }
+
+        // Description of a rectangle is complete when all opening
+        // <[ are closed with >] and the string ends with a comma or
+        // there are no more args.
+        if ((numOpen == 0) && rectDesc.length()
+            && ((rectDesc[rectDesc.length() - 1] == ',')
+                || (optind == argc))) {
+            // Remove trailing comma if it is present
+            if (rectDesc[rectDesc.length() - 1] == ',') {
+                rectDesc.erase(rectDesc.length() - 1);
+            }
+
+            // Parse string description of rectangle
+            Rectangle rect = parseRect(rectDesc);
+
+            // Add to the list of rectangles
+            rectangle.push_back(rect);
+
+            // Prepare for description of another rectangle
+            rectDesc = string("");
+        }
+    }
+
+    // Create list of frames
+    hwc_layer_list_t *list;
+    list = hwcTestCreateLayerList(rectangle.size());
+    if (list == NULL) {
+        testPrintE("hwcTestCreateLayerList failed");
+        exit(5);
+    }
+
+    hwc_layer_t *layer = &list->hwLayers[0];
+    for (std::list<Rectangle>::iterator it = rectangle.begin();
+         it != rectangle.end(); ++it, ++layer) {
+        layer->handle = it->texture->handle;
+        layer->blending = it->blend;
+        layer->transform = it->transform;
+        layer->sourceCrop = it->sourceCrop;
+        layer->displayFrame = it->displayFrame;
+
+        layer->visibleRegionScreen.numRects = 1;
+        layer->visibleRegionScreen.rects = &layer->displayFrame;
+    }
+
+    // Perform prepare operation
+    if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); }
+    hwcDevice->prepare(hwcDevice, list);
+    if (verbose) {
+        testPrintI("Post Prepare:");
+        hwcTestDisplayListPrepareModifiable(list);
+    }
+
+    // Turn off the geometry changed flag
+    list->flags &= ~HWC_GEOMETRY_CHANGED;
+
+    // Perform the set operation(s)
+    if (verbose) {testPrintI("Set:"); }
+    if (verbose) { hwcTestDisplayListHandles(list); }
+    hwcDevice->set(hwcDevice, dpy, surface, list);
+
+    testDelay(endDelay);
+
+    // Start framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
+        exit(6);
+    }
+    testExecCmd(cmd);
+
+    return 0;
+}
+
+// Parse string description of rectangle and add it to list of rectangles
+// to be rendered.
+static Rectangle parseRect(string rectStr)
+{
+    int rv;
+    string str;
+    bool   error;
+    istringstream in(rectStr);
+    const struct hwcTestGraphicFormat *format;
+    Rectangle rect;
+    struct hwc_rect hwcRect;
+
+    // Graphic Format
+    in >> str;
+    if (!in) {
+        testPrintE("Error parsing format from: %s", rectStr.c_str());
+        exit(20);
+    }
+    format = hwcTestGraphicFormatLookup(str.c_str());
+    if (format == NULL) {
+        testPrintE("Unknown graphic format in: %s", rectStr.c_str());
+        exit(21);
+    }
+    rect.format = format->format;
+
+    // Display Frame
+    rect.displayFrame = hwcTestParseHwcRect(in, error);
+    if (error) {
+        testPrintE("Invalid display frame in: %s", rectStr.c_str());
+        exit(22);
+    }
+
+    // Set default sourceDim and sourceCrop based on size of display frame.
+    // Default is source size equal to the size of the display frame, with
+    // the source crop being the entire size of the source frame.
+    rect.sourceDim = HwcTestDim(rect.displayFrame.right
+                                     - rect.displayFrame.left,
+                                 rect.displayFrame.bottom
+                                     - rect.displayFrame.top);
+    rect.sourceCrop.left = 0;
+    rect.sourceCrop.top = 0;
+    rect.sourceCrop.right = rect.sourceDim.width();
+    rect.sourceCrop.bottom = rect.sourceDim.height();
+
+    // Optional settings
+    while ((in.tellg() < (streampos) in.str().length())
+           && (in.tellg() != (streampos) -1)) {
+        string attrName;
+
+        in >> attrName;
+        if (in.eof()) { break; }
+        if (!in) {
+            testPrintE("Error reading attribute name in: %s",
+                       rectStr.c_str());
+            exit(23);
+        }
+
+        // Transform
+        if (attrName == "transform:") { // Transform
+            string str;
+
+            in >> str;
+            if (str == "none") {
+                rect.transform = 0;
+            } else if (str == "fliph") {
+                rect.transform = HWC_TRANSFORM_FLIP_H;
+            } else if (str == "flipv") {
+                rect.transform = HWC_TRANSFORM_FLIP_V;
+            } else if (str == "rot90") {
+                rect.transform = HWC_TRANSFORM_ROT_90;
+            } else if (str == "rot180") {
+                rect.transform = HWC_TRANSFORM_ROT_180;
+            } else if (str == "rot270") {
+                rect.transform = HWC_TRANSFORM_ROT_270;
+            } else {
+                testPrintE("Unknown transform of \"%s\" in: %s", str.c_str(),
+                           rectStr.c_str());
+                exit(24);
+            }
+        } else if (attrName == "blend:") { // Blend
+            string str;
+
+            in >> str;
+            if (str == string("none")) {
+                rect.blend = HWC_BLENDING_NONE;
+            } else if (str == "premult") {
+                rect.blend = HWC_BLENDING_PREMULT;
+            } else if (str == "coverage") {
+                rect.blend = HWC_BLENDING_COVERAGE;
+            } else {
+                testPrintE("Unknown blend of \"%s\" in: %s", str.c_str(),
+                           rectStr.c_str());
+                exit(25);
+            }
+        } else if (attrName == "color:") { // Color
+            rect.color = hwcTestParseColor(in, error);
+            if (error) {
+                testPrintE("Error parsing color in: %s", rectStr.c_str());
+                exit(26);
+            }
+        } else if (attrName == "alpha:") { // Alpha
+            in >> rect.alpha;
+            if (!in) {
+                testPrintE("Error parsing value for alpha attribute in: %s",
+                           rectStr.c_str());
+                exit(27);
+            }
+        } else if (attrName == "sourceDim:") { // Source Dimension
+           rect.sourceDim = hwcTestParseDim(in, error);
+            if (error) {
+                testPrintE("Error parsing source dimenision in: %s",
+                           rectStr.c_str());
+                exit(28);
+            }
+        } else if (attrName == "sourceCrop:") { // Source Crop
+            rect.sourceCrop = hwcTestParseHwcRect(in, error);
+            if (error) {
+                testPrintE("Error parsing source crop in: %s",
+                           rectStr.c_str());
+                exit(29);
+            }
+        } else { // Unknown attribute
+            testPrintE("Unknown attribute of \"%s\" in: %s", attrName.c_str(),
+                       rectStr.c_str());
+            exit(30);
+        }
+    }
+
+    // Validate
+    if (((uint32_t) rect.sourceCrop.left >= rect.sourceDim.width())
+        || ((uint32_t) rect.sourceCrop.right > rect.sourceDim.width())
+        || ((uint32_t) rect.sourceCrop.top >= rect.sourceDim.height())
+        || ((uint32_t) rect.sourceCrop.bottom > rect.sourceDim.height())) {
+        testPrintE("Invalid source crop in: %s", rectStr.c_str());
+        exit(31);
+    }
+    if ((rect.displayFrame.left >= width)
+        || (rect.displayFrame.right > width)
+        || (rect.displayFrame.top >= height)
+        || (rect.displayFrame.bottom > height)) {
+        testPrintE("Invalid display frame in: %s", rectStr.c_str());
+        exit(32);
+    }
+    if ((rect.alpha < 0.0) || (rect.alpha > 1.0)) {
+        testPrintE("Invalid alpha in: %s", rectStr.c_str());
+        exit(33);
+    }
+
+    // Create source texture
+    rect.texture = new GraphicBuffer(rect.sourceDim.width(),
+                                     rect.sourceDim.height(),
+                                     rect.format, texUsage);
+    if ((rv = rect.texture->initCheck()) != NO_ERROR) {
+        testPrintE("source texture initCheck failed, rv: %i", rv);
+        testPrintE("  %s", rectStr.c_str());
+
+    }
+
+    // Fill with uniform color
+    hwcTestFillColor(rect.texture.get(), rect.color, rect.alpha);
+    if (verbose) {
+        testPrintI("    buf: %p handle: %p format: %s width: %u height: %u "
+                   "color: %s alpha: %f",
+                   rect.texture.get(), rect.texture->handle, format->desc,
+                   rect.sourceDim.width(), rect.sourceDim.height(),
+                   string(rect.color).c_str(), rect.alpha);
+    }
+
+    return rect;
+}
+
+void init(void)
+{
+    // Seed pseudo random number generator
+    // Needed so that the pad areas of frames are filled with a deterministic
+    // pseudo random value.
+    srand48(0);
+
+    hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
+
+    hwcTestOpenHwc(&hwcDevice);
+}
+
+void printSyntax(const char *cmd)
+{
+    testPrintE("  %s [options] (graphicFormat displayFrame [attributes],)...",
+               cmd);
+    testPrintE("    options:");
+    testPrintE("      -D End of test delay");
+    testPrintE("      -v Verbose");
+    testPrintE("");
+    testPrintE("    graphic formats:");
+    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
+        testPrintE("      %s", hwcTestGraphicFormat[n1].desc);
+    }
+    testPrintE("");
+    testPrintE("    displayFrame");
+    testPrintE("      [left, top, right, bottom]");
+    testPrintE("");
+    testPrintE("    attributes:");
+    testPrintE("      transform: none | fliph | flipv | rot90 | rot180 "
+               " | rot270");
+    testPrintE("      blend: none | premult | coverage");
+    testPrintE("      color: [0.##, 0.##, 0.##]");
+    testPrintE("      alpha: 0.##");
+    testPrintE("      sourceDim: [width, height]");
+    testPrintE("      sourceCrop: [left, top, right, bottom]");
+    testPrintE("");
+    testPrintE("    Example:");
+    testPrintE("      # White YV12 rectangle, with overlapping turquoise ");
+    testPrintE("      #  RGBA8888 rectangle at 30%% (alpha: 0.7) transparency");
+    testPrintE("      %s -v -D 30.0 \\", cmd);
+    testPrintE("        YV12 [50, 80, 200, 300] transform: none \\");
+    testPrintE("          color: [1.0, 0.5, 0.5], \\");
+    testPrintE("        RGBA8888 [100, 150, 300, 400] blend: coverage \\");
+    testPrintE("          color: [0.251, 0.878, 0.816] alpha: 0.7 \\");
+    testPrintE("          sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]");
+}
diff --git a/opengl/tests/hwc/hwcStress.cpp b/opengl/tests/hwc/hwcStress.cpp
new file mode 100644
index 0000000..1cefb4b
--- /dev/null
+++ b/opengl/tests/hwc/hwcStress.cpp
@@ -0,0 +1,645 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Hardware Composer stress test
+ *
+ * Performs a pseudo-random (prandom) sequence of operations to the
+ * Hardware Composer (HWC), for a specified number of passes or for
+ * a specified period of time.  By default the period of time is FLT_MAX,
+ * so that the number of passes will take precedence.
+ *
+ * The passes are grouped together, where (pass / passesPerGroup) specifies
+ * which group a particular pass is in.  This causes every passesPerGroup
+ * worth of sequential passes to be within the same group.  Computationally
+ * intensive operations are performed just once at the beginning of a group
+ * of passes and then used by all the passes in that group.  This is done
+ * so as to increase both the average and peak rate of graphic operations,
+ * by moving computationally intensive operations to the beginning of a group.
+ * In particular, at the start of each group of passes a set of
+ * graphic buffers are created, then used by the first and remaining
+ * passes of that group of passes.
+ *
+ * The per-group initialization of the graphic buffers is performed
+ * by a function called initFrames.  This function creates an array
+ * of smart pointers to the graphic buffers, in the form of a vector
+ * of vectors.  The array is accessed in row major order, so each
+ * row is a vector of smart pointers.  All the pointers of a single
+ * row point to graphic buffers which use the same pixel format and
+ * have the same dimension, although it is likely that each one is
+ * filled with a different color.  This is done so that after doing
+ * the first HWC prepare then set call, subsequent set calls can
+ * be made with each of the layer handles changed to a different
+ * graphic buffer within the same row.  Since the graphic buffers
+ * in a particular row have the same pixel format and dimension,
+ * additional HWC set calls can be made, without having to perform
+ * an HWC prepare call.
+ *
+ * This test supports the following command-line options:
+ *
+ *   -v        Verbose
+ *   -s num    Starting pass
+ *   -e num    Ending pass
+ *   -p num    Execute the single pass specified by num
+ *   -n num    Number of set operations to perform after each prepare operation
+ *   -t float  Maximum time in seconds to execute the test
+ *   -d float  Delay in seconds performed after each set operation
+ *   -D float  Delay in seconds performed after the last pass is executed
+ *
+ * Typically the test is executed for a large range of passes.  By default
+ * passes 0 through 99999 (100,000 passes) are executed.  Although this test
+ * does not validate the generated image, at times it is useful to reexecute
+ * a particular pass and leave the displayed image on the screen for an
+ * extended period of time.  This can be done either by setting the -s
+ * and -e options to the desired pass, along with a large value for -D.
+ * This can also be done via the -p option, again with a large value for
+ * the -D options.
+ *
+ * So far this test only contains code to create graphic buffers with
+ * a continuous solid color.  Although this test is unable to validate the
+ * image produced, any image that contains other than rectangles of a solid
+ * color are incorrect.  Note that the rectangles may use a transparent
+ * color and have a blending operation that causes the color in overlapping
+ * rectangles to be mixed.  In such cases the overlapping portions may have
+ * a different color from the rest of the rectangle.
+ */
+
+#include <algorithm>
+#include <assert.h>
+#include <cerrno>
+#include <cmath>
+#include <cstdlib>
+#include <ctime>
+#include <libgen.h>
+#include <sched.h>
+#include <sstream>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <vector>
+
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+#define LOG_TAG "hwcStressTest"
+#include <utils/Log.h>
+#include <testUtil.h>
+
+#include <hardware/hwcomposer.h>
+
+#include <glTestLib.h>
+#include <hwc/hwcTestLib.h>
+
+using namespace std;
+using namespace android;
+
+const float maxSizeRatio = 1.3;  // Graphic buffers can be upto this munch
+                                 // larger than the default screen size
+const unsigned int passesPerGroup = 10; // A group of passes all use the same
+                                        // graphic buffers
+
+// Ratios at which rare and frequent conditions should be produced
+const float rareRatio = 0.1;
+const float freqRatio = 0.9;
+
+// Defaults for command-line options
+const bool defaultVerbose = false;
+const unsigned int defaultStartPass = 0;
+const unsigned int defaultEndPass = 99999;
+const unsigned int defaultPerPassNumSet = 10;
+const float defaultPerSetDelay = 0.0; // Default delay after each set
+                                      // operation.  Default delay of
+                                      // zero used so as to perform the
+                                      // the set operations as quickly
+                                      // as possible.
+const float defaultEndDelay = 2.0; // Default delay between completion of
+                                   // final pass and restart of framework
+const float defaultDuration = FLT_MAX; // A fairly long time, so that
+                                       // range of passes will have
+                                       // precedence
+
+// Command-line option settings
+static bool verbose = defaultVerbose;
+static unsigned int startPass = defaultStartPass;
+static unsigned int endPass = defaultEndPass;
+static unsigned int numSet = defaultPerPassNumSet;
+static float perSetDelay = defaultPerSetDelay;
+static float endDelay = defaultEndDelay;
+static float duration = defaultDuration;
+
+// Command-line mutual exclusion detection flags.
+// Corresponding flag set true once an option is used.
+bool eFlag, sFlag, pFlag;
+
+#define MAXSTR               100
+#define MAXCMD               200
+#define BITSPERBYTE            8 // TODO: Obtain from <values.h>, once
+                                 // it has been added
+
+#define CMD_STOP_FRAMEWORK   "stop 2>&1"
+#define CMD_START_FRAMEWORK  "start 2>&1"
+
+#define NUMA(a) (sizeof(a) / sizeof(a [0]))
+#define MEMCLR(addr, size) do { \
+        memset((addr), 0, (size)); \
+    } while (0)
+
+// File scope constants
+const unsigned int blendingOps[] = {
+    HWC_BLENDING_NONE,
+    HWC_BLENDING_PREMULT,
+    HWC_BLENDING_COVERAGE,
+};
+const unsigned int layerFlags[] = {
+    HWC_SKIP_LAYER,
+};
+const vector<unsigned int> vecLayerFlags(layerFlags,
+    layerFlags + NUMA(layerFlags));
+
+const unsigned int transformFlags[] = {
+    HWC_TRANSFORM_FLIP_H,
+    HWC_TRANSFORM_FLIP_V,
+    HWC_TRANSFORM_ROT_90,
+    // ROT_180 & ROT_270 intentionally not listed, because they
+    // they are formed from combinations of the flags already listed.
+};
+const vector<unsigned int> vecTransformFlags(transformFlags,
+    transformFlags + NUMA(transformFlags));
+
+// File scope globals
+static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
+        GraphicBuffer::USAGE_SW_WRITE_RARELY;
+static hwc_composer_device_t *hwcDevice;
+static EGLDisplay dpy;
+static EGLSurface surface;
+static EGLint width, height;
+static vector <vector <sp<GraphicBuffer> > > frames;
+
+// File scope prototypes
+void init(void);
+void initFrames(unsigned int seed);
+template <class T> vector<T> vectorRandSelect(const vector<T>& vec, size_t num);
+template <class T> T vectorOr(const vector<T>& vec);
+
+/*
+ * Main
+ *
+ * Performs the following high-level sequence of operations:
+ *
+ *   1. Command-line parsing
+ *
+ *   2. Initialization
+ *
+ *   3. For each pass:
+ *
+ *        a. If pass is first pass or in a different group from the
+ *           previous pass, initialize the array of graphic buffers.
+ *
+ *        b. Create a HWC list with room to specify a prandomly
+ *           selected number of layers.
+ *
+ *        c. Select a subset of the rows from the graphic buffer array,
+ *           such that there is a unique row to be used for each
+ *           of the layers in the HWC list.
+ *
+ *        d. Prandomly fill in the HWC list with handles
+ *           selected from any of the columns of the selected row.
+ *
+ *        e. Pass the populated list to the HWC prepare call.
+ *
+ *        f. Pass the populated list to the HWC set call.
+ *
+ *        g. If additional set calls are to be made, then for each
+ *           additional set call, select a new set of handles and
+ *           perform the set call.
+ */
+int
+main(int argc, char *argv[])
+{
+    int rv, opt;
+    char *chptr;
+    unsigned int pass;
+    char cmd[MAXCMD];
+    struct timeval startTime, currentTime, delta;
+
+    testSetLogCatTag(LOG_TAG);
+
+    // Parse command line arguments
+    while ((opt = getopt(argc, argv, "vp:d:D:n:s:e:t:?h")) != -1) {
+        switch (opt) {
+          case 'd': // Delay after each set operation
+            perSetDelay = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (perSetDelay < 0.0)) {
+                testPrintE("Invalid command-line specified per pass delay of: "
+                           "%s", optarg);
+                exit(1);
+            }
+            break;
+
+          case 'D': // End of test delay
+                    // Delay between completion of final pass and restart
+                    // of framework
+            endDelay = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (endDelay < 0.0)) {
+                testPrintE("Invalid command-line specified end of test delay "
+                           "of: %s", optarg);
+                exit(2);
+            }
+            break;
+
+          case 't': // Duration
+            duration = strtod(optarg, &chptr);
+            if ((*chptr != '\0') || (duration < 0.0)) {
+                testPrintE("Invalid command-line specified duration of: %s",
+                           optarg);
+                exit(3);
+            }
+            break;
+
+          case 'n': // Num set operations per pass
+            numSet = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified num set per pass "
+                           "of: %s", optarg);
+                exit(4);
+            }
+            break;
+
+          case 's': // Starting Pass
+            sFlag = true;
+            if (pFlag) {
+                testPrintE("Invalid combination of command-line options.");
+                testPrintE("  The -p option is mutually exclusive from the");
+                testPrintE("  -s and -e options.");
+                exit(5);
+            }
+            startPass = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified starting pass "
+                           "of: %s", optarg);
+                exit(6);
+            }
+            break;
+
+          case 'e': // Ending Pass
+            eFlag = true;
+            if (pFlag) {
+                testPrintE("Invalid combination of command-line options.");
+                testPrintE("  The -p option is mutually exclusive from the");
+                testPrintE("  -s and -e options.");
+                exit(7);
+            }
+            endPass = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified ending pass "
+                           "of: %s", optarg);
+                exit(8);
+            }
+            break;
+
+          case 'p': // Run a single specified pass
+            pFlag = true;
+            if (sFlag || eFlag) {
+                testPrintE("Invalid combination of command-line options.");
+                testPrintE("  The -p option is mutually exclusive from the");
+                testPrintE("  -s and -e options.");
+                exit(9);
+            }
+            startPass = endPass = strtoul(optarg, &chptr, 10);
+            if (*chptr != '\0') {
+                testPrintE("Invalid command-line specified pass of: %s",
+                           optarg);
+                exit(10);
+            }
+            break;
+
+          case 'v': // Verbose
+            verbose = true;
+            break;
+
+          case 'h': // Help
+          case '?':
+          default:
+            testPrintE("  %s [options]", basename(argv[0]));
+            testPrintE("    options:");
+            testPrintE("      -p Execute specified pass");
+            testPrintE("      -s Starting pass");
+            testPrintE("      -e Ending pass");
+            testPrintE("      -t Duration");
+            testPrintE("      -d Delay after each set operation");
+            testPrintE("      -D End of test delay");
+            testPrintE("      -n Num set operations per pass");
+            testPrintE("      -v Verbose");
+            exit(((optopt == 0) || (optopt == '?')) ? 0 : 11);
+        }
+    }
+    if (endPass < startPass) {
+        testPrintE("Unexpected ending pass before starting pass");
+        testPrintE("  startPass: %u endPass: %u", startPass, endPass);
+        exit(12);
+    }
+    if (argc != optind) {
+        testPrintE("Unexpected command-line postional argument");
+        testPrintE("  %s [-s start_pass] [-e end_pass] [-t duration]",
+            basename(argv[0]));
+        exit(13);
+    }
+    testPrintI("duration: %g", duration);
+    testPrintI("startPass: %u", startPass);
+    testPrintI("endPass: %u", endPass);
+    testPrintI("numSet: %u", numSet);
+
+    // Stop framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
+        exit(14);
+    }
+    testExecCmd(cmd);
+    testDelay(1.0); // TODO - need means to query whether asyncronous stop
+                    // framework operation has completed.  For now, just wait
+                    // a long time.
+
+    init();
+
+    // For each pass
+    gettimeofday(&startTime, NULL);
+    for (pass = startPass; pass <= endPass; pass++) {
+        // Stop if duration of work has already been performed
+        gettimeofday(&currentTime, NULL);
+        delta = tvDelta(&startTime, &currentTime);
+        if (tv2double(&delta) > duration) { break; }
+
+        // Regenerate a new set of test frames when this pass is
+        // either the first pass or is in a different group then
+        // the previous pass.  A group of passes are passes that
+        // all have the same quotient when their pass number is
+        // divided by passesPerGroup.
+        if ((pass == startPass)
+            || ((pass / passesPerGroup) != ((pass - 1) / passesPerGroup))) {
+            initFrames(pass / passesPerGroup);
+        }
+
+        testPrintI("==== Starting pass: %u", pass);
+
+        // Cause deterministic sequence of prandom numbers to be
+        // generated for this pass.
+        srand48(pass);
+
+        hwc_layer_list_t *list;
+        list = hwcTestCreateLayerList(testRandMod(frames.size()) + 1);
+        if (list == NULL) {
+            testPrintE("hwcTestCreateLayerList failed");
+            exit(20);
+        }
+
+        // Prandomly select a subset of frames to be used by this pass.
+        vector <vector <sp<GraphicBuffer> > > selectedFrames;
+        selectedFrames = vectorRandSelect(frames, list->numHwLayers);
+
+        // Any transform tends to create a layer that the hardware
+        // composer is unable to support and thus has to leave for
+        // SurfaceFlinger.  Place heavy bias on specifying no transforms.
+        bool noTransform = testRandFract() > rareRatio;
+
+        for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
+            unsigned int idx = testRandMod(selectedFrames[n1].size());
+            sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
+            hwc_layer_t *layer = &list->hwLayers[n1];
+            layer->handle = gBuf->handle;
+
+            layer->blending = blendingOps[testRandMod(NUMA(blendingOps))];
+            layer->flags = (testRandFract() > rareRatio) ? 0
+                : vectorOr(vectorRandSelect(vecLayerFlags,
+                           testRandMod(vecLayerFlags.size() + 1)));
+            layer->transform = (noTransform || testRandFract() > rareRatio) ? 0
+                : vectorOr(vectorRandSelect(vecTransformFlags,
+                           testRandMod(vecTransformFlags.size() + 1)));
+            layer->sourceCrop.left = testRandMod(gBuf->getWidth());
+            layer->sourceCrop.top = testRandMod(gBuf->getHeight());
+            layer->sourceCrop.right = layer->sourceCrop.left
+                + testRandMod(gBuf->getWidth() - layer->sourceCrop.left) + 1;
+            layer->sourceCrop.bottom = layer->sourceCrop.top
+                + testRandMod(gBuf->getHeight() - layer->sourceCrop.top) + 1;
+            layer->displayFrame.left = testRandMod(width);
+            layer->displayFrame.top = testRandMod(height);
+            layer->displayFrame.right = layer->displayFrame.left
+                + testRandMod(width - layer->displayFrame.left) + 1;
+            layer->displayFrame.bottom = layer->displayFrame.top
+                + testRandMod(height - layer->displayFrame.top) + 1;
+
+            // Increase the frequency that a scale factor of 1.0 from
+            // the sourceCrop to displayFrame occurs.  This is the
+            // most common scale factor used by applications and would
+            // be rarely produced by this stress test without this
+            // logic.
+            if (testRandFract() <= freqRatio) {
+                // Only change to scale factor to 1.0 if both the
+                // width and height will fit.
+                int sourceWidth = layer->sourceCrop.right
+                                  - layer->sourceCrop.left;
+                int sourceHeight = layer->sourceCrop.bottom
+                                   - layer->sourceCrop.top;
+                if (((layer->displayFrame.left + sourceWidth) <= width)
+                    && ((layer->displayFrame.top + sourceHeight) <= height)) {
+                    layer->displayFrame.right = layer->displayFrame.left
+                                                + sourceWidth;
+                    layer->displayFrame.bottom = layer->displayFrame.top
+                                                 + sourceHeight;
+                }
+            }
+
+            layer->visibleRegionScreen.numRects = 1;
+            layer->visibleRegionScreen.rects = &layer->displayFrame;
+        }
+
+        // Perform prepare operation
+        if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); }
+        hwcDevice->prepare(hwcDevice, list);
+        if (verbose) {
+            testPrintI("Post Prepare:");
+            hwcTestDisplayListPrepareModifiable(list);
+        }
+
+        // Turn off the geometry changed flag
+        list->flags &= ~HWC_GEOMETRY_CHANGED;
+
+        // Perform the set operation(s)
+        if (verbose) {testPrintI("Set:"); }
+        for (unsigned int n1 = 0; n1 < numSet; n1++) {
+            if (verbose) { hwcTestDisplayListHandles(list); }
+            hwcDevice->set(hwcDevice, dpy, surface, list);
+
+            // Prandomly select a new set of handles
+            for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
+                unsigned int idx = testRandMod(selectedFrames[n1].size());
+                sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
+                hwc_layer_t *layer = &list->hwLayers[n1];
+                layer->handle = (native_handle_t *) gBuf->handle;
+            }
+
+            testDelay(perSetDelay);
+        }
+
+        hwcTestFreeLayerList(list);
+        testPrintI("==== Completed pass: %u", pass);
+    }
+
+    testDelay(endDelay);
+
+    // Start framework
+    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
+    if (rv >= (signed) sizeof(cmd) - 1) {
+        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
+        exit(21);
+    }
+    testExecCmd(cmd);
+
+    testPrintI("Successfully completed %u passes", pass - startPass);
+
+    return 0;
+}
+
+void init(void)
+{
+    srand48(0); // Defensively set pseudo random number generator.
+                // Should not need to set this, because a stress test
+                // sets the seed on each pass.  Defensively set it here
+                // so that future code that uses pseudo random numbers
+                // before the first pass will be deterministic.
+
+    hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
+
+    hwcTestOpenHwc(&hwcDevice);
+}
+
+/*
+ * Initialize Frames
+ *
+ * Creates an array of graphic buffers, within the global variable
+ * named frames.  The graphic buffers are contained within a vector of
+ * vectors.  All the graphic buffers in a particular row are of the same
+ * format and dimension.  Each graphic buffer is uniformly filled with a
+ * prandomly selected color.  It is likely that each buffer, even
+ * in the same row, will be filled with a unique color.
+ */
+void initFrames(unsigned int seed)
+{
+    int rv;
+    const size_t maxRows = 5;
+    const size_t minCols = 2;  // Need at least double buffering
+    const size_t maxCols = 4;  // One more than triple buffering
+
+    if (verbose) { testPrintI("initFrames seed: %u", seed); }
+    srand48(seed);
+    size_t rows = testRandMod(maxRows) + 1;
+
+    frames.clear();
+    frames.resize(rows);
+
+    for (unsigned int row = 0; row < rows; row++) {
+        // All frames within a row have to have the same format and
+        // dimensions.  Width and height need to be >= 1.
+        unsigned int formatIdx = testRandMod(NUMA(hwcTestGraphicFormat));
+        const struct hwcTestGraphicFormat *formatPtr
+            = &hwcTestGraphicFormat[formatIdx];
+        int format = formatPtr->format;
+
+        // Pick width and height, which must be >= 1 and the size
+        // mod the wMod/hMod value must be equal to 0.
+        size_t w = (width * maxSizeRatio) * testRandFract();
+        size_t h = (height * maxSizeRatio) * testRandFract();
+        w = max(1u, w);
+        h = max(1u, h);
+        if ((w % formatPtr->wMod) != 0) {
+            w += formatPtr->wMod - (w % formatPtr->wMod);
+        }
+        if ((h % formatPtr->hMod) != 0) {
+            h += formatPtr->hMod - (h % formatPtr->hMod);
+        }
+        if (verbose) {
+            testPrintI("  frame %u width: %u height: %u format: %u %s",
+                       row, w, h, format, hwcTestGraphicFormat2str(format));
+        }
+
+        size_t cols = testRandMod((maxCols + 1) - minCols) + minCols;
+        frames[row].resize(cols);
+        for (unsigned int col = 0; col < cols; col++) {
+            ColorFract color(testRandFract(), testRandFract(), testRandFract());
+            float alpha = testRandFract();
+
+            frames[row][col] = new GraphicBuffer(w, h, format, texUsage);
+            if ((rv = frames[row][col]->initCheck()) != NO_ERROR) {
+                testPrintE("GraphicBuffer initCheck failed, rv: %i", rv);
+                testPrintE("  frame %u width: %u height: %u format: %u %s",
+                           row, w, h, format, hwcTestGraphicFormat2str(format));
+                exit(80);
+            }
+
+            hwcTestFillColor(frames[row][col].get(), color, alpha);
+            if (verbose) {
+                testPrintI("    buf: %p handle: %p color: %s alpha: %f",
+                           frames[row][col].get(), frames[row][col]->handle,
+                           string(color).c_str(), alpha);
+            }
+        }
+    }
+}
+
+/*
+ * Vector Random Select
+ *
+ * Prandomly selects and returns num elements from vec.
+ */
+template <class T>
+vector<T> vectorRandSelect(const vector<T>& vec, size_t num)
+{
+    vector<T> rv = vec;
+
+    while (rv.size() > num) {
+        rv.erase(rv.begin() + testRandMod(rv.size()));
+    }
+
+    return rv;
+}
+
+/*
+ * Vector Or
+ *
+ * Or's togethen the values of each element of vec and returns the result.
+ */
+template <class T>
+T vectorOr(const vector<T>& vec)
+{
+    T rv = 0;
+
+    for (size_t n1 = 0; n1 < vec.size(); n1++) {
+        rv |= vec[n1];
+    }
+
+    return rv;
+}
diff --git a/opengl/tests/hwc/hwcTestLib.cpp b/opengl/tests/hwc/hwcTestLib.cpp
new file mode 100644
index 0000000..925405e
--- /dev/null
+++ b/opengl/tests/hwc/hwcTestLib.cpp
@@ -0,0 +1,1028 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Hardware Composer Test Library
+ * Utility library functions for use by the Hardware Composer test cases
+ */
+
+#include <sstream>
+#include <string>
+
+#include <arpa/inet.h> // For ntohl() and htonl()
+
+#include <hwc/hwcTestLib.h>
+
+// Defines
+#define NUMA(a) (sizeof(a) / sizeof(a [0]))
+
+// Function Prototypes
+static void printGLString(const char *name, GLenum s);
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
+static void checkGlError(const char* op);
+static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config);
+
+using namespace std;
+using namespace android;
+
+
+#define BITSPERBYTE            8 // TODO: Obtain from <values.h>, once
+                                 // it has been added
+
+// Initialize Display
+void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface,
+    EGLint *width, EGLint *height)
+{
+    static EGLContext context;
+
+    int rv;
+
+    EGLBoolean returnValue;
+    EGLConfig myConfig = {0};
+    EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+    EGLint sConfigAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_NONE };
+    EGLint majorVersion, minorVersion;
+
+    checkEglError("<init>");
+    *dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    checkEglError("eglGetDisplay");
+    if (*dpy == EGL_NO_DISPLAY) {
+        testPrintE("eglGetDisplay returned EGL_NO_DISPLAY");
+        exit(70);
+    }
+
+    returnValue = eglInitialize(*dpy, &majorVersion, &minorVersion);
+    checkEglError("eglInitialize", returnValue);
+    if (verbose) {
+        testPrintI("EGL version %d.%d", majorVersion, minorVersion);
+    }
+    if (returnValue != EGL_TRUE) {
+        testPrintE("eglInitialize failed");
+        exit(71);
+    }
+
+    EGLNativeWindowType window = android_createDisplaySurface();
+    if (window == NULL) {
+        testPrintE("android_createDisplaySurface failed");
+        exit(72);
+    }
+    returnValue = EGLUtils::selectConfigForNativeWindow(*dpy,
+        sConfigAttribs, window, &myConfig);
+    if (returnValue) {
+        testPrintE("EGLUtils::selectConfigForNativeWindow() returned %d",
+            returnValue);
+        exit(73);
+    }
+    checkEglError("EGLUtils::selectConfigForNativeWindow");
+
+    if (verbose) {
+        testPrintI("Chose this configuration:");
+        printEGLConfiguration(*dpy, myConfig);
+    }
+
+    *surface = eglCreateWindowSurface(*dpy, myConfig, window, NULL);
+    checkEglError("eglCreateWindowSurface");
+    if (*surface == EGL_NO_SURFACE) {
+        testPrintE("gelCreateWindowSurface failed.");
+        exit(74);
+    }
+
+    context = eglCreateContext(*dpy, myConfig, EGL_NO_CONTEXT, contextAttribs);
+    checkEglError("eglCreateContext");
+    if (context == EGL_NO_CONTEXT) {
+        testPrintE("eglCreateContext failed");
+        exit(75);
+    }
+    returnValue = eglMakeCurrent(*dpy, *surface, *surface, context);
+    checkEglError("eglMakeCurrent", returnValue);
+    if (returnValue != EGL_TRUE) {
+        testPrintE("eglMakeCurrent failed");
+        exit(76);
+    }
+    eglQuerySurface(*dpy, *surface, EGL_WIDTH, width);
+    checkEglError("eglQuerySurface");
+    eglQuerySurface(*dpy, *surface, EGL_HEIGHT, height);
+    checkEglError("eglQuerySurface");
+
+    if (verbose) {
+        testPrintI("Window dimensions: %d x %d", *width, *height);
+
+        printGLString("Version", GL_VERSION);
+        printGLString("Vendor", GL_VENDOR);
+        printGLString("Renderer", GL_RENDERER);
+        printGLString("Extensions", GL_EXTENSIONS);
+    }
+}
+
+// Open Hardware Composer Device
+void hwcTestOpenHwc(hwc_composer_device_t **hwcDevicePtr)
+{
+    int rv;
+    hw_module_t const *hwcModule;
+
+    if ((rv = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwcModule)) != 0) {
+        testPrintE("hw_get_module failed, rv: %i", rv);
+        errno = -rv;
+        perror(NULL);
+        exit(77);
+    }
+    if ((rv = hwc_open(hwcModule, hwcDevicePtr)) != 0) {
+        testPrintE("hwc_open failed, rv: %i", rv);
+        errno = -rv;
+        perror(NULL);
+        exit(78);
+    }
+}
+
+// Color fraction class to string conversion
+ColorFract::operator string()
+{
+    ostringstream out;
+
+    out << '[' << this->c1() << ", "
+        << this->c2() << ", "
+        << this->c3() << ']';
+
+    return out.str();
+}
+
+// Dimension class to string conversion
+HwcTestDim::operator string()
+{
+    ostringstream out;
+
+    out << '[' << this->width() << ", "
+        << this->height() << ']';
+
+    return out.str();
+}
+
+// Dimension class to hwc_rect conversion
+HwcTestDim::operator hwc_rect() const
+{
+    hwc_rect rect;
+
+    rect.left = rect.top = 0;
+
+    rect.right = this->_w;
+    rect.bottom = this->_h;
+
+    return rect;
+}
+
+// Hardware Composer rectangle to string conversion
+string hwcTestRect2str(const struct hwc_rect& rect)
+{
+    ostringstream out;
+
+    out << '[';
+    out << rect.left << ", ";
+    out << rect.top << ", ";
+    out << rect.right << ", ";
+    out << rect.bottom;
+    out << ']';
+
+    return out.str();
+}
+
+// Parse HWC rectangle description of form [left, top, right, bottom]
+struct hwc_rect hwcTestParseHwcRect(istringstream& in, bool& error)
+{
+    struct hwc_rect rect;
+    char chStart, ch;
+
+    // Defensively specify that an error occurred.  Will clear
+    // error flag if all of parsing succeeds.
+    error = true;
+
+    // First character should be a [ or <
+    in >> chStart;
+    if (!in || ((chStart != '<') && (chStart != '['))) { return rect; }
+
+    // Left
+    in >> rect.left;
+    if (!in) { return rect; }
+    in >> ch;
+    if (!in || (ch != ',')) { return rect; }
+
+    // Top
+    in >> rect.top;
+    if (!in) { return rect; }
+    in >> ch;
+    if (!in || (ch != ',')) { return rect; }
+
+    // Right
+    in >> rect.right;
+    if (!in) { return rect; }
+    in >> ch;
+    if (!in || (ch != ',')) { return rect; }
+
+    // Bottom
+    in >> rect.bottom;
+    if (!in) { return rect; }
+
+    // Closing > or ]
+    in >> ch;
+    if (!in) { return rect; }
+    if (((chStart == '<') && (ch != '>'))
+        || ((chStart == '[') && (ch != ']'))) { return rect; }
+
+    // Validate right and bottom are greater than left and top
+    if ((rect.right <= rect.left) || (rect.bottom <= rect.top)) { return rect; }
+
+    // Made It, clear error indicator
+    error = false;
+
+    return rect;
+}
+
+// Parse dimension of form [width, height]
+HwcTestDim hwcTestParseDim(istringstream& in, bool& error)
+{
+    HwcTestDim dim;
+    char chStart, ch;
+    uint32_t val;
+
+    // Defensively specify that an error occurred.  Will clear
+    // error flag if all of parsing succeeds.
+    error = true;
+
+    // First character should be a [ or <
+    in >> chStart;
+    if (!in || ((chStart != '<') && (chStart != '['))) { return dim; }
+
+    // Width
+    in >> val;
+    if (!in) { return dim; }
+    dim.setWidth(val);
+    in >> ch;
+    if (!in || (ch != ',')) { return dim; }
+
+    // Height
+    in >> val;
+    if (!in) { return dim; }
+    dim.setHeight(val);
+
+    // Closing > or ]
+    in >> ch;
+    if (!in) { return dim; }
+    if (((chStart == '<') && (ch != '>'))
+        || ((chStart == '[') && (ch != ']'))) { return dim; }
+
+    // Validate width and height greater than 0
+    if ((dim.width() <= 0) || (dim.height() <= 0)) { return dim; }
+
+    // Made It, clear error indicator
+    error = false;
+    return dim;
+}
+
+// Parse fractional color of form [0.##, 0.##, 0.##]
+// Fractional values can be from 0.0 to 1.0 inclusive.  Note, integer
+// values of 0.0 and 1.0, which are non-fractional, are considered valid.
+// They are an exception, all other valid inputs are fractions.
+ColorFract hwcTestParseColor(istringstream& in, bool& error)
+{
+    ColorFract color;
+    char chStart, ch;
+    float c1, c2, c3;
+
+    // Defensively specify that an error occurred.  Will clear
+    // error flag if all of parsing succeeds.
+    error = true;
+
+    // First character should be a [ or <
+    in >> chStart;
+    if (!in || ((chStart != '<') && (chStart != '['))) { return color; }
+
+    // 1st Component
+    in >> c1;
+    if (!in) { return color; }
+    if ((c1 < 0.0) || (c1 > 1.0)) { return color; }
+    in >> ch;
+    if (!in || (ch != ',')) { return color; }
+
+    // 2nd Component
+    in >> c2;
+    if (!in) { return color; }
+    if ((c2 < 0.0) || (c2 > 1.0)) { return color; }
+    in >> ch;
+    if (!in || (ch != ',')) { return color; }
+
+    // 3rd Component
+    in >> c3;
+    if (!in) { return color; }
+    if ((c3 < 0.0) || (c3 > 1.0)) { return color; }
+
+    // Closing > or ]
+    in >> ch;
+    if (!in) { return color; }
+    if (((chStart == '<') && (ch != '>'))
+        || ((chStart == '[') && (ch != ']'))) { return color; }
+
+    // Are all the components fractional
+    if ((c1 < 0.0) || (c1 > 1.0)
+        || (c2 < 0.0) || (c2 > 1.0)
+        || (c3 < 0.0) || (c3 > 1.0)) { return color; }
+
+    // Made It, clear error indicator
+    error = false;
+
+    return ColorFract(c1, c2, c3);
+}
+
+// Look up and return pointer to structure with the characteristics
+// of the graphic format named by the desc parameter.  Search failure
+// indicated by the return of NULL.
+const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc)
+{
+    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
+        if (string(desc) == string(hwcTestGraphicFormat[n1].desc)) {
+            return &hwcTestGraphicFormat[n1];
+        }
+    }
+
+    return NULL;
+}
+
+// Look up and return pointer to structure with the characteristics
+// of the graphic format specified by the id parameter.  Search failure
+// indicated by the return of NULL.
+const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id)
+{
+    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
+        if (id == hwcTestGraphicFormat[n1].format) {
+            return &hwcTestGraphicFormat[n1];
+        }
+    }
+
+    return NULL;
+}
+
+
+// Given the integer ID of a graphic format, return a pointer to
+// a string that describes the format.
+const char *hwcTestGraphicFormat2str(uint32_t format)
+{
+    const static char *unknown = "unknown";
+
+    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
+        if (format == hwcTestGraphicFormat[n1].format) {
+            return hwcTestGraphicFormat[n1].desc;
+        }
+    }
+
+    return unknown;
+}
+
+/*
+ * hwcTestCreateLayerList
+ * Dynamically creates layer list with numLayers worth
+ * of hwLayers entries.
+ */
+hwc_layer_list_t *hwcTestCreateLayerList(size_t numLayers)
+{
+    hwc_layer_list_t *list;
+
+    size_t size = sizeof(hwc_layer_list) + numLayers * sizeof(hwc_layer_t);
+    if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) {
+        return NULL;
+    }
+    list->flags = HWC_GEOMETRY_CHANGED;
+    list->numHwLayers = numLayers;
+
+    return list;
+}
+
+/*
+ * hwcTestFreeLayerList
+ * Frees memory previous allocated via hwcTestCreateLayerList().
+ */
+void hwcTestFreeLayerList(hwc_layer_list_t *list)
+{
+    free(list);
+}
+
+// Display the settings of the layer list pointed to by list
+void hwcTestDisplayList(hwc_layer_list_t *list)
+{
+    testPrintI("  flags: %#x%s", list->flags,
+               (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : "");
+    testPrintI("  numHwLayers: %u", list->numHwLayers);
+
+    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
+        testPrintI("    layer %u compositionType: %#x%s%s", layer,
+                   list->hwLayers[layer].compositionType,
+                   (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
+                       ? " FRAMEBUFFER" : "",
+                   (list->hwLayers[layer].compositionType == HWC_OVERLAY)
+                       ? " OVERLAY" : "");
+
+        testPrintI("      hints: %#x",
+                   list->hwLayers[layer].hints,
+                   (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
+                       ? " TRIPLE_BUFFER" : "",
+                   (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
+                       ? " CLEAR_FB" : "");
+
+        testPrintI("      flags: %#x%s",
+                   list->hwLayers[layer].flags,
+                   (list->hwLayers[layer].flags & HWC_SKIP_LAYER)
+                       ? " SKIP_LAYER" : "");
+
+        testPrintI("      handle: %p",
+                   list->hwLayers[layer].handle);
+
+        // Intentionally skipped display of ROT_180 & ROT_270,
+        // which are formed from combinations of the other flags.
+        testPrintI("      transform: %#x%s%s%s",
+                   list->hwLayers[layer].transform,
+                   (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_H)
+                       ? " FLIP_H" : "",
+                   (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_V)
+                       ? " FLIP_V" : "",
+                   (list->hwLayers[layer].transform & HWC_TRANSFORM_ROT_90)
+                       ? " ROT_90" : "");
+
+        testPrintI("      blending: %#x%s%s%s",
+                   list->hwLayers[layer].blending,
+                   (list->hwLayers[layer].blending == HWC_BLENDING_NONE)
+                       ? " NONE" : "",
+                   (list->hwLayers[layer].blending == HWC_BLENDING_PREMULT)
+                       ? " PREMULT" : "",
+                   (list->hwLayers[layer].blending == HWC_BLENDING_COVERAGE)
+                       ? " COVERAGE" : "");
+
+        testPrintI("      sourceCrop: %s",
+                   hwcTestRect2str(list->hwLayers[layer].sourceCrop).c_str());
+        testPrintI("      displayFrame: %s",
+                   hwcTestRect2str(list->hwLayers[layer].displayFrame).c_str());
+        testPrintI("      scaleFactor: [%f, %f]",
+                   (float) (list->hwLayers[layer].sourceCrop.right
+                            - list->hwLayers[layer].sourceCrop.left)
+                       / (float) (list->hwLayers[layer].displayFrame.right
+                            - list->hwLayers[layer].displayFrame.left),
+                   (float) (list->hwLayers[layer].sourceCrop.bottom
+                            - list->hwLayers[layer].sourceCrop.top)
+                       / (float) (list->hwLayers[layer].displayFrame.bottom
+                            - list->hwLayers[layer].displayFrame.top));
+    }
+}
+
+/*
+ * Display List Prepare Modifiable
+ *
+ * Displays the portions of a list that are meant to be modified by
+ * a prepare call.
+ */
+void hwcTestDisplayListPrepareModifiable(hwc_layer_list_t *list)
+{
+    uint32_t numOverlays = 0;
+    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
+        if (list->hwLayers[layer].compositionType == HWC_OVERLAY) {
+            numOverlays++;
+        }
+        testPrintI("    layer %u compositionType: %#x%s%s", layer,
+                   list->hwLayers[layer].compositionType,
+                   (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
+                       ? " FRAMEBUFFER" : "",
+                   (list->hwLayers[layer].compositionType == HWC_OVERLAY)
+                       ? " OVERLAY" : "");
+        testPrintI("      hints: %#x%s%s",
+                   list->hwLayers[layer].hints,
+                   (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
+                       ? " TRIPLE_BUFFER" : "",
+                   (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
+                       ? " CLEAR_FB" : "");
+    }
+    testPrintI("    numOverlays: %u", numOverlays);
+}
+
+/*
+ * Display List Handles
+ *
+ * Displays the handles of all the graphic buffers in the list.
+ */
+void hwcTestDisplayListHandles(hwc_layer_list_t *list)
+{
+    const unsigned int maxLayersPerLine = 6;
+
+    ostringstream str("  layers:");
+    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
+        str << ' ' << list->hwLayers[layer].handle;
+        if (((layer % maxLayersPerLine) == (maxLayersPerLine - 1))
+            && (layer != list->numHwLayers - 1)) {
+            testPrintI("%s", str.str().c_str());
+            str.str("    ");
+        }
+    }
+    testPrintI("%s", str.str().c_str());
+}
+
+// Returns a uint32_t that contains a format specific representation of a
+// single pixel of the given color and alpha values.
+uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha)
+{
+    const struct attrib {
+        uint32_t format;
+        bool   hostByteOrder;
+        size_t bytes;
+        size_t c1Offset;
+        size_t c1Size;
+        size_t c2Offset;
+        size_t c2Size;
+        size_t c3Offset;
+        size_t c3Size;
+        size_t aOffset;
+        size_t aSize;
+    } attributes[] = {
+        {HAL_PIXEL_FORMAT_RGBA_8888, false, 4,  0, 8,  8, 8, 16, 8, 24, 8},
+        {HAL_PIXEL_FORMAT_RGBX_8888, false, 4,  0, 8,  8, 8, 16, 8,  0, 0},
+        {HAL_PIXEL_FORMAT_RGB_888,   false, 3,  0, 8,  8, 8, 16, 8,  0, 0},
+        {HAL_PIXEL_FORMAT_RGB_565,   true,  2,  0, 5,  5, 6, 11, 5,  0, 0},
+        {HAL_PIXEL_FORMAT_BGRA_8888, false, 4, 16, 8,  8, 8,  0, 8, 24, 8},
+        {HAL_PIXEL_FORMAT_RGBA_5551, true , 2,  0, 5,  5, 5, 10, 5, 15, 1},
+        {HAL_PIXEL_FORMAT_RGBA_4444, false, 2, 12, 4,  0, 4,  4, 4,  8, 4},
+        {HAL_PIXEL_FORMAT_YV12,      true,  3, 16, 8,  8, 8,  0, 8,  0, 0},  
+    };
+
+    const struct attrib *attrib;
+    for (attrib = attributes; attrib < attributes + NUMA(attributes);
+         attrib++) {
+        if (attrib->format == format) { break; }
+    }
+    if (attrib >= attributes + NUMA(attributes)) {
+        testPrintE("colorFract2Pixel unsupported format of: %u", format);
+        exit(80);
+    }
+
+    uint32_t pixel;
+    pixel = htonl((uint32_t) round((((1 << attrib->c1Size) - 1) * color.c1()))
+         << ((sizeof(pixel) * BITSPERBYTE)
+             - (attrib->c1Offset + attrib->c1Size)));
+    pixel |= htonl((uint32_t) round((((1 << attrib->c2Size) - 1) * color.c2()))
+         << ((sizeof(pixel) * BITSPERBYTE)
+             - (attrib->c2Offset + attrib->c2Size)));
+    pixel |= htonl((uint32_t) round((((1 << attrib->c3Size) - 1) * color.c3()))
+         << ((sizeof(pixel) * BITSPERBYTE)
+             - (attrib->c3Offset + attrib->c3Size)));
+    if (attrib->aSize) {
+        pixel |= htonl((uint32_t) round((((1 << attrib->aSize) - 1) * alpha))
+             << ((sizeof(pixel) * BITSPERBYTE)
+                 - (attrib->aOffset + attrib->aSize)));
+    }
+    if (attrib->hostByteOrder) {
+        pixel = ntohl(pixel);
+        pixel >>= sizeof(pixel) * BITSPERBYTE - attrib->bytes * BITSPERBYTE;
+    }
+
+    return pixel;
+}
+
+// Sets the pixel at the given x and y coordinates to the color and alpha
+// value given by pixel.  The contents of pixel is format specific.  It's
+// value should come from a call to hwcTestColor2Pixel().
+void hwcTestSetPixel(GraphicBuffer *gBuf, unsigned char *buf,
+              uint32_t x, uint32_t y, uint32_t pixel)
+{
+
+    const struct attrib {
+        int format;
+        size_t bytes;
+    } attributes[] = {
+        {HAL_PIXEL_FORMAT_RGBA_8888,  4},
+        {HAL_PIXEL_FORMAT_RGBX_8888,  4},
+        {HAL_PIXEL_FORMAT_RGB_888,    3},
+        {HAL_PIXEL_FORMAT_RGB_565,    2},
+        {HAL_PIXEL_FORMAT_BGRA_8888,  4},
+        {HAL_PIXEL_FORMAT_RGBA_5551,  2},
+        {HAL_PIXEL_FORMAT_RGBA_4444,  2},
+    };
+
+    if (gBuf->getPixelFormat() == HAL_PIXEL_FORMAT_YV12) {
+        uint32_t yPlaneOffset, uPlaneOffset, vPlaneOffset;
+        uint32_t yPlaneStride = gBuf->getStride();
+        uint32_t uPlaneStride = ((gBuf->getStride() / 2) + 0xf) & ~0xf;
+        uint32_t vPlaneStride = uPlaneStride;
+        yPlaneOffset = 0;
+        vPlaneOffset = yPlaneOffset + yPlaneStride * gBuf->getHeight();
+        uPlaneOffset = vPlaneOffset
+                       + vPlaneStride * (gBuf->getHeight() / 2);
+        *(buf + yPlaneOffset + y * yPlaneStride + x) = pixel & 0xff;
+        *(buf + uPlaneOffset + (y / 2) * uPlaneStride + (x / 2))
+            = (pixel & 0xff00) >> 8;
+        *(buf + vPlaneOffset + (y / 2) * vPlaneStride + (x / 2))
+            = (pixel & 0xff0000) >> 16;
+
+        return;
+    }
+
+    const struct attrib *attrib;
+    for (attrib = attributes; attrib < attributes + NUMA(attributes);
+         attrib++) {
+        if (attrib->format == gBuf->getPixelFormat()) { break; }
+    }
+    if (attrib >= attributes + NUMA(attributes)) {
+        testPrintE("setPixel unsupported format of: %u",
+                   gBuf->getPixelFormat());
+        exit(90);
+    }
+
+    memmove(buf + ((gBuf->getStride() * attrib->bytes) * y)
+            + (attrib->bytes * x), &pixel, attrib->bytes);
+}
+
+// Fill a given graphic buffer with a uniform color and alpha
+void hwcTestFillColor(GraphicBuffer *gBuf, ColorFract color, float alpha)
+{
+    unsigned char* buf = NULL;
+    status_t err;
+    uint32_t pixel;
+
+    pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, alpha);
+
+    err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
+    if (err != 0) {
+        testPrintE("hwcTestFillColor lock failed: %d", err);
+        exit(100);
+    }
+
+    for (unsigned int x = 0; x < gBuf->getStride(); x++) {
+        for (unsigned int y = 0; y < gBuf->getHeight(); y++) {
+            uint32_t val = pixel;
+            hwcTestSetPixel(gBuf, buf, x, y, (x < gBuf->getWidth())
+                            ? pixel : testRand());
+        }
+    }
+
+    err = gBuf->unlock();
+    if (err != 0) {
+        testPrintE("hwcTestFillColor unlock failed: %d", err);
+        exit(101);
+    }
+}
+
+// Fill the given buffer with a horizontal blend of colors, with the left
+// side color given by startColor and the right side color given by
+// endColor.  The startColor and endColor values are specified in the format
+// given by colorFormat, which might be different from the format of the
+// graphic buffer.  When different, a color conversion is done when possible
+// to the graphic format of the graphic buffer.  A color of black is
+// produced for cases where the conversion is impossible (e.g. out of gamut
+// values).
+void hwcTestFillColorHBlend(GraphicBuffer *gBuf, uint32_t colorFormat,
+                            ColorFract startColor, ColorFract endColor)
+{
+    status_t err;
+    unsigned char* buf = NULL;
+    const uint32_t width = gBuf->getWidth();
+    const uint32_t height = gBuf->getHeight();
+    const uint32_t stride = gBuf->getStride();
+
+    err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
+    if (err != 0) {
+        testPrintE("hwcTestFillColorHBlend lock failed: %d", err);
+        exit(110);
+    }
+
+    for (unsigned int x = 0; x < stride; x++) {
+        uint32_t pixel;
+        if (x < width) {
+            ColorFract color(startColor.c1() + (endColor.c1() - startColor.c1())
+                                 * ((float) x / (float) (width - 1)),
+                             startColor.c2() + (endColor.c2() - startColor.c2())
+                                 * ((float) x / (float) (width - 1)),
+                             startColor.c3() + (endColor.c3() - startColor.c3())
+                                 * ((float) x / (float) (width - 1)));
+
+            // When formats differ, convert colors.
+            // Important to not convert when formats are the same, since
+            // out of gamut colors are always converted to black.
+            if (colorFormat != (uint32_t) gBuf->getPixelFormat()) {
+                hwcTestColorConvert(colorFormat, gBuf->getPixelFormat(), color);
+            }
+            pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, 1.0);
+        } else {
+            // Fill pad with random values
+            pixel = testRand();
+        }
+
+        for (unsigned int y = 0; y < height; y++) {
+            hwcTestSetPixel(gBuf, buf, x, y, pixel);
+        }
+    }
+
+    err = gBuf->unlock();
+    if (err != 0) {
+        testPrintE("hwcTestFillColorHBlend unlock failed: %d", err);
+        exit(111);
+    }
+}
+
+/*
+ * When possible, converts color specified as a full range value in
+ * the fromFormat, into an equivalent full range color in the toFormat.
+ * When conversion is impossible (e.g. out of gamut color) a color
+ * or black in the full range output format is produced.  The input
+ * color is given as a fractional color in the parameter named color.
+ * The produced color is written over the same parameter used to
+ * provide the input color.
+ *
+ * Each graphic format has 3 color components and each of these
+ * components has both a full and in gamut range.  This function uses
+ * a table that provides the full and in gamut ranges of each of the
+ * supported graphic formats.  The full range is given by members named
+ * c[123]Min to c[123]Max, while the in gamut range is given by members
+ * named c[123]Low to c[123]High.  In most cases the full and in gamut
+ * ranges are equivalent.  This occurs when the c[123]Min == c[123]Low and
+ * c[123]High == c[123]Max.
+ *
+ * The input and produced colors are both specified as a fractional amount
+ * of the full range.  The diagram below provides an overview of the
+ * conversion process.  The main steps are:
+ *
+ *   1. Produce black if the input color is out of gamut.
+ *
+ *   2. Convert the in gamut color into the fraction of the fromFromat
+ *      in gamut range.
+ *
+ *   3. Convert from the fraction of the in gamut from format range to
+ *      the fraction of the in gamut to format range.  Produce black
+ *      if an equivalent color does not exists.
+ *
+ *   4. Covert from the fraction of the in gamut to format to the
+ *      fraction of the full range to format.
+ *
+ *       From Format                 To Format
+ *    max           high            high        max
+ *    ----+                 +-----------+
+ *    high \               /             \      high
+ *    ------\-------------+               +-------->
+ *           \
+ *            \                   +--- black --+
+ *             \                 /              \
+ *              \               /                +-->
+ *    low        \             /                  low
+ *    -------- ---+-- black --+
+ *    min             low           low           min
+ *     ^               ^      ^      ^             ^
+ *     |               |      |      |             |
+ *     |               |      |      |             +-- fraction of full range
+ *     |               |      |      +-- fraction of valid range
+ *     |               |      +-- fromFormat to toFormat color conversion
+ *     |               +-- fraction of valid range
+ *     +-- fraction of full range
+ */
+void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat,
+                  ColorFract& color)
+{
+    const struct attrib {
+        uint32_t     format;
+        bool         rgb;
+        bool         yuv;
+        int          c1Min, c1Low, c1High, c1Max;
+        int          c2Min, c2Low, c2High, c2Max;
+        int          c3Min, c3Low, c3High, c3Max;
+    } attributes[] = {
+        {HAL_PIXEL_FORMAT_RGBA_8888, true,  false,
+         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
+        {HAL_PIXEL_FORMAT_RGBX_8888, true,  false,
+         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
+        {HAL_PIXEL_FORMAT_RGB_888,   true,  false,
+         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
+        {HAL_PIXEL_FORMAT_RGB_565,   true,  false,
+         0, 0, 31, 31, 0, 0, 63, 63, 0, 0, 31, 31},
+        {HAL_PIXEL_FORMAT_BGRA_8888, true,  false,
+         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
+        {HAL_PIXEL_FORMAT_RGBA_5551, true,  false,
+         0, 0, 31, 31, 0, 0, 31, 31, 0, 0, 31, 31},
+        {HAL_PIXEL_FORMAT_RGBA_4444, true,  false,
+         0, 0, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15},
+        {HAL_PIXEL_FORMAT_YV12,      false, true,
+         0, 16, 235, 255, 0, 16, 240, 255, 0, 16, 240, 255},
+    };
+
+    const struct attrib *fromAttrib;
+    for (fromAttrib = attributes; fromAttrib < attributes + NUMA(attributes);
+         fromAttrib++) {
+        if (fromAttrib->format == fromFormat) { break; }
+    }
+    if (fromAttrib >= attributes + NUMA(attributes)) {
+        testPrintE("hwcTestColorConvert unsupported from format of: %u",
+                   fromFormat);
+        exit(120);
+    }
+
+    const struct attrib *toAttrib;
+    for (toAttrib = attributes; toAttrib < attributes + NUMA(attributes);
+         toAttrib++) {
+        if (toAttrib->format == toFormat) { break; }
+    }
+    if (toAttrib >= attributes + NUMA(attributes)) {
+        testPrintE("hwcTestColorConvert unsupported to format of: %u",
+                   toFormat);
+        exit(121);
+    }
+
+    // Produce black if any of the from components are outside the
+    // valid color range
+    float c1Val = fromAttrib->c1Min
+        + ((float) (fromAttrib->c1Max - fromAttrib->c1Min) * color.c1());
+    float c2Val = fromAttrib->c2Min
+        + ((float) (fromAttrib->c2Max - fromAttrib->c2Min) * color.c2());
+    float c3Val = fromAttrib->c3Min
+        + ((float) (fromAttrib->c3Max - fromAttrib->c3Min) * color.c3());
+    if ((c1Val < fromAttrib->c1Low) || (c1Val > fromAttrib->c1High)
+        || (c2Val < fromAttrib->c2Low) || (c2Val > fromAttrib->c2High)
+        || (c3Val < fromAttrib->c3Low) || (c3Val > fromAttrib->c3High)) {
+
+        // Return black
+        // Will use representation of black from RGBA8888 graphic format
+        // and recursively convert it to the requested graphic format.
+        color = ColorFract(0.0, 0.0, 0.0);
+        hwcTestColorConvert(HAL_PIXEL_FORMAT_RGBA_8888, toFormat, color);
+        return;
+    }
+
+    // Within from format, convert from fraction of full range
+    // to fraction of valid range
+    color = ColorFract((c1Val - fromAttrib->c1Low)
+                           / (fromAttrib->c1High - fromAttrib->c1Low),
+                       (c2Val - fromAttrib->c2Low)
+                           / (fromAttrib->c2High - fromAttrib->c2Low),
+                       (c3Val - fromAttrib->c3Low)
+                           / (fromAttrib->c3High - fromAttrib->c3Low));
+
+    // If needed perform RGB to YUV conversion
+    float wr = 0.2126, wg = 0.7152, wb = 0.0722; // ITU709 recommended constants
+    if (fromAttrib->rgb && toAttrib->yuv) {
+        float r = color.c1(), g = color.c2(), b = color.c3();
+        float y = wr * r + wg * g + wb * b;
+        float u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5;
+        float v = 0.5 * ((r - y) / (1.0 - wr)) + 0.5;
+
+        // Produce black if color is outside the YUV gamut
+        if ((y < 0.0) || (y > 1.0)
+            || (u < 0.0) || (u > 1.0)
+            || (v < 0.0) || (v > 1.0)) {
+            y = 0.0;
+            u = v = 0.5;
+        }
+
+        color = ColorFract(y, u, v);
+    }
+
+    // If needed perform YUV to RGB conversion
+    // Equations determined from the ITU709 equations for RGB to YUV
+    // conversion, plus the following algebra:
+    //
+    //   u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5
+    //   0.5 * ((b - y) / (1.0 - wb)) = u - 0.5
+    //   (b - y) / (1.0 - wb) = 2 * (u - 0.5)
+    //   b - y = 2 * (u - 0.5) * (1.0 - wb)
+    //   b = 2 * (u - 0.5) * (1.0 - wb) + y
+    //
+    //   v = 0.5 * ((r -y) / (1.0 - wr)) + 0.5
+    //   0.5 * ((r - y) / (1.0 - wr)) = v - 0.5
+    //   (r - y) / (1.0 - wr) = 2 * (v - 0.5)
+    //   r - y = 2 * (v - 0.5) * (1.0 - wr)
+    //   r = 2 * (v - 0.5) * (1.0 - wr) + y
+    //
+    //   y = wr * r + wg * g + wb * b
+    //   wr * r + wg * g + wb * b = y
+    //   wg * g = y - wr * r - wb * b
+    //   g = (y - wr * r - wb * b) / wg
+    if (fromAttrib->yuv && toAttrib->rgb) {
+        float y = color.c1(), u = color.c2(), v = color.c3();
+        float r = 2.0 * (v - 0.5) * (1.0 - wr) + y;
+        float b = 2.0 * (u - 0.5) * (1.0 - wb) + y;
+        float g = (y - wr * r - wb * b) / wg;
+
+        // Produce black if color is outside the RGB gamut
+        if ((r < 0.0) || (r > 1.0)
+            || (g < 0.0) || (g > 1.0)
+            || (b < 0.0) || (b > 1.0)) {
+            r = g = b = 0.0;
+        }
+
+        color = ColorFract(r, g, b);
+    }
+
+    // Within to format, convert from fraction of valid range
+    // to fraction of full range
+    c1Val = (toAttrib->c1Low
+        + (float) (toAttrib->c1High - toAttrib->c1Low) * color.c1());
+    c2Val = (toAttrib->c1Low
+        + (float) (toAttrib->c2High - toAttrib->c2Low) * color.c2());
+    c3Val = (toAttrib->c1Low
+        + (float) (toAttrib->c3High - toAttrib->c3Low) * color.c3());
+    color = ColorFract((float) (c1Val - toAttrib->c1Min)
+                           / (float) (toAttrib->c1Max - toAttrib->c1Min),
+                       (float) (c2Val - toAttrib->c2Min)
+                           / (float) (toAttrib->c2Max - toAttrib->c2Min),
+                       (float) (c3Val - toAttrib->c3Min)
+                           / (float) (toAttrib->c3Max - toAttrib->c3Min));
+}
+
+// TODO: Use PrintGLString, CechckGlError, and PrintEGLConfiguration
+//       from libglTest
+static void printGLString(const char *name, GLenum s)
+{
+    const char *v = (const char *) glGetString(s);
+
+    if (v == NULL) {
+        testPrintI("GL %s unknown", name);
+    } else {
+        testPrintI("GL %s = %s", name, v);
+    }
+}
+
+static void checkEglError(const char* op, EGLBoolean returnVal)
+{
+    if (returnVal != EGL_TRUE) {
+        testPrintE("%s() returned %d", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        testPrintE("after %s() eglError %s (0x%x)",
+                   op, EGLUtils::strerror(error), error);
+    }
+}
+
+static void checkGlError(const char* op)
+{
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        testPrintE("after %s() glError (0x%x)", op, error);
+    }
+}
+
+static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config)
+{
+
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute,
+                                              &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            testPrintI(" %s: %d (%#x)", names[j].name, value, value);
+        }
+    }
+    testPrintI("");
+}
diff --git a/opengl/tests/hwc/hwcTestLib.h b/opengl/tests/hwc/hwcTestLib.h
new file mode 100644
index 0000000..99ee608
--- /dev/null
+++ b/opengl/tests/hwc/hwcTestLib.h
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Hardware Composer Test Library Header
+ */
+
+#include <sstream>
+#include <string>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+#include <utils/Log.h>
+#include <testUtil.h>
+
+#include <hardware/hwcomposer.h>
+
+// Characteristics of known graphic formats
+const struct hwcTestGraphicFormat {
+    uint32_t format;
+    const char *desc;
+    uint32_t wMod, hMod; // Width/height mod this value must equal zero
+} hwcTestGraphicFormat[] = {
+    {HAL_PIXEL_FORMAT_RGBA_8888, "RGBA8888", 1, 1},
+    {HAL_PIXEL_FORMAT_RGBX_8888, "RGBX8888", 1, 1},
+    {HAL_PIXEL_FORMAT_RGB_888,   "RGB888",   1, 1},
+    {HAL_PIXEL_FORMAT_RGB_565,   "RGB565",   1, 1},
+    {HAL_PIXEL_FORMAT_BGRA_8888, "BGRA8888", 1, 1},
+    {HAL_PIXEL_FORMAT_RGBA_5551, "RGBA5551", 1, 1},
+    {HAL_PIXEL_FORMAT_RGBA_4444, "RGBA4444", 1, 1},
+    {HAL_PIXEL_FORMAT_YV12,      "YV12",     2, 2},
+};
+
+// Represent RGB color as fraction of color components.
+// Each of the color components are expected in the range [0.0, 1.0]
+class ColorFract {
+  public:
+    ColorFract(): _c1(0.0), _c2(0.0), _c3(0.0) {};
+    ColorFract(float c1, float c2, float c3): _c1(c1), _c2(c2), _c3(c3) {};
+    float c1(void) const { return _c1; }
+    float c2(void) const { return _c2; }
+    float c3(void) const { return _c3; }
+
+    operator std::string();
+
+  private:
+    float _c1;
+    float _c2;
+    float _c3;
+};
+
+// Represent RGB color as fraction of color components.
+// Each of the color components are expected in the range [0.0, 1.0]
+class ColorRGB {
+  public:
+    ColorRGB(): _r(0.0), _g(0.0), _b(0.0) {};
+    ColorRGB(float f): _r(f), _g(f), _b(f) {}; // Gray
+    ColorRGB(float r, float g, float b): _r(r), _g(g), _b(b) {};
+    float r(void) const { return _r; }
+    float g(void) const { return _g; }
+    float b(void) const { return _b; }
+
+  private:
+    float _r;
+    float _g;
+    float _b;
+};
+
+// Dimension - width and height of a rectanguler area
+class HwcTestDim {
+  public:
+    HwcTestDim(): _w(0), _h(0) {};
+    HwcTestDim(uint32_t w, uint32_t h) : _w(w), _h(h) {}
+    uint32_t width(void) const { return _w; }
+    uint32_t height(void) const { return _h; }
+    void setWidth(uint32_t w) { _w = w; }
+    void setHeight(uint32_t h) { _h = h; }
+
+    operator std::string();
+    operator hwc_rect() const;
+
+  private:
+    uint32_t _w;
+    uint32_t _h;
+};
+
+// Function Prototypes
+void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface,
+    EGLint *width, EGLint *height);
+void hwcTestOpenHwc(hwc_composer_device_t **hwcDevicePtr);
+const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc);
+const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id);
+const char *hwcTestGraphicFormat2str(uint32_t format);
+std::string hwcTestRect2str(const struct hwc_rect& rect);
+
+hwc_layer_list_t *hwcTestCreateLayerList(size_t numLayers);
+void hwcTestFreeLayerList(hwc_layer_list_t *list);
+void hwcTestDisplayList(hwc_layer_list_t *list);
+void hwcTestDisplayListPrepareModifiable(hwc_layer_list_t *list);
+void hwcTestDisplayListHandles(hwc_layer_list_t *list);
+
+uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha);
+void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat,
+                  ColorFract& color);
+void hwcTestSetPixel(android::GraphicBuffer *gBuf, unsigned char *buf,
+                     uint32_t x, uint32_t y, uint32_t pixel);
+void hwcTestFillColor(android::GraphicBuffer *gBuf, ColorFract color,
+                      float alpha);
+void hwcTestFillColorHBlend(android::GraphicBuffer *gBuf,
+                            uint32_t colorFormat,
+                            ColorFract startColor, ColorFract endColor);
+ColorFract hwcTestParseColor(std::istringstream& in, bool& error);
+struct hwc_rect hwcTestParseHwcRect(std::istringstream& in, bool& error);
+HwcTestDim hwcTestParseDim(std::istringstream& in, bool& error);
diff --git a/opengl/tests/include/glTestLib.h b/opengl/tests/include/glTestLib.h
new file mode 100644
index 0000000..06fbf5d
--- /dev/null
+++ b/opengl/tests/include/glTestLib.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Graphics Test Library Header
+ */
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+//#include <ui/FramebufferNativeWindow.h>
+//#include <ui/GraphicBuffer.h>
+#include <ui/EGLUtils.h>
+
+void glTestPrintGLString(const char *name, GLenum s);
+void glTestCheckEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
+void glTestCheckGlError(const char* op);
+void glTestPrintEGLConfiguration(EGLDisplay dpy, EGLConfig config);
diff --git a/opengl/tests/lib/Android.mk b/opengl/tests/lib/Android.mk
new file mode 100644
index 0000000..7542ac4
--- /dev/null
+++ b/opengl/tests/lib/Android.mk
@@ -0,0 +1,32 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE:= libglTest
+LOCAL_SRC_FILES:= glTestLib.cpp
+LOCAL_C_INCLUDES += system/extras/tests/include \
+    bionic \
+    bionic/libstdc++/include \
+    external/stlport/stlport \
+    frameworks/base/opengl/tests/include \
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+LOCAL_SHARED_LIBRARIES += libcutils libutils libstlport
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/opengl/tests/lib/glTestLib.cpp b/opengl/tests/lib/glTestLib.cpp
new file mode 100644
index 0000000..052cbd7
--- /dev/null
+++ b/opengl/tests/lib/glTestLib.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Graphics Test Library
+ */
+
+#include <glTestLib.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/EGLUtils.h>
+
+#include <utils/Log.h>
+#include <testUtil.h>
+
+using namespace std;
+using namespace android;
+
+void glTestPrintGLString(const char *name, GLenum s)
+{
+    const char *v = (const char *) glGetString(s);
+
+    if (v == NULL) {
+        testPrintI("GL %s unknown", name);
+    } else {
+        testPrintI("GL %s = %s", name, v);
+    }
+}
+
+void glTestCheckEglError(const char* op, EGLBoolean returnVal)
+{
+    if (returnVal != EGL_TRUE) {
+        testPrintE("%s() returned %d", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        testPrintE("after %s() eglError %s (0x%x)",
+                   op, EGLUtils::strerror(error), error);
+    }
+}
+
+void glTestCheckGlError(const char* op)
+{
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        testPrintE("after %s() glError (0x%x)", op, error);
+    }
+}
+
+void glTestPrintEGLConfiguration(EGLDisplay dpy, EGLConfig config)
+{
+
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute,
+                                              &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            testPrintI(" %s: %d (%#x)", names[j].name, value, value);
+        }
+    }
+    testPrintI("");
+}
diff --git a/opengl/tests/testFramerate/Android.mk b/opengl/tests/testFramerate/Android.mk
new file mode 100644
index 0000000..500abf3
--- /dev/null
+++ b/opengl/tests/testFramerate/Android.mk
@@ -0,0 +1,19 @@
+#########################################################################
+# Test framerate and look for hiccups
+#########################################################################
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := TestFramerate
+
+include $(BUILD_PACKAGE)
diff --git a/opengl/tests/testFramerate/AndroidManifest.xml b/opengl/tests/testFramerate/AndroidManifest.xml
new file mode 100644
index 0000000..85617f4
--- /dev/null
+++ b/opengl/tests/testFramerate/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.testframerate">
+    <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" />
+
+    <application
+            android:label="@string/testFramerate_activity">
+        <activity android:name="TestFramerateActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+                android:launchMode="singleTask"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/testFramerate/res/values/strings.xml b/opengl/tests/testFramerate/res/values/strings.xml
new file mode 100644
index 0000000..baadf0e
--- /dev/null
+++ b/opengl/tests/testFramerate/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="testFramerate_activity">TestFramerate</string>
+
+</resources>
+
diff --git a/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java
new file mode 100644
index 0000000..cbe279b
--- /dev/null
+++ b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 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.testframerate;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class TestFramerateActivity extends Activity {
+
+    TestFramerateView mView;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mView = new TestFramerateView(getApplication());
+        setContentView(mView);
+        mView.setFocusableInTouchMode(true);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java
new file mode 100644
index 0000000..f3fb5de
--- /dev/null
+++ b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+package com.android.testframerate;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.SystemProperties;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+class TestFramerateView extends GLSurfaceView {
+    private static String TAG = "TestFramerateView";
+
+    public TestFramerateView(Context context) {
+        super(context);
+        setEGLContextClientVersion(2);
+        setRenderer(new Renderer());
+    }
+
+    private long mLastTime_us = 0;
+    private long mNumShortFramesElapsed = 0;
+    private void registerTime(long now_us) {
+        long longFrameTime_ms = Integer.parseInt(SystemProperties.get("debug.longframe_ms", "16"));
+        long elapsedTime_us = now_us - mLastTime_us;
+        float fps = 1000000.f / elapsedTime_us;
+        if (mLastTime_us > 0 && elapsedTime_us > longFrameTime_ms*1000) {
+          Log.v(TAG, "Long frame: " + elapsedTime_us/1000.f + " ms (" + fps + " fps)");
+          if (mNumShortFramesElapsed > 0) {
+            Log.v(TAG, "  Short frames since last long frame: " + mNumShortFramesElapsed);
+            mNumShortFramesElapsed = 0;
+          }
+        } else {
+            ++mNumShortFramesElapsed;
+        }
+
+        mLastTime_us = now_us;
+    }
+
+    private class Renderer implements GLSurfaceView.Renderer {
+        public Renderer() {
+        }
+
+
+        public void onDrawFrame(GL10 gl) {
+            long now_us = System.nanoTime() / 1000;
+            registerTime(now_us);
+
+            float red = (now_us % 1000000) / 1000000.f;
+            float green = (now_us % 2000000) / 2000000.f;
+            float blue = (now_us % 3000000) / 3000000.f;
+            GLES20.glClearColor(red, green, blue, 1.0f);
+            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            GLES20.glViewport(0, 0, width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        }
+
+    }
+}
diff --git a/opengl/tests/testLatency/Android.mk b/opengl/tests/testLatency/Android.mk
new file mode 100644
index 0000000..96417c7
--- /dev/null
+++ b/opengl/tests/testLatency/Android.mk
@@ -0,0 +1,20 @@
+#########################################################################
+# Test end-to-end latency.
+#########################################################################
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SDK_VERSION := 8
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := TestLatency
+
+include $(BUILD_PACKAGE)
diff --git a/opengl/tests/testLatency/AndroidManifest.xml b/opengl/tests/testLatency/AndroidManifest.xml
new file mode 100644
index 0000000..59f2643
--- /dev/null
+++ b/opengl/tests/testLatency/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.testlatency">
+    <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" />
+
+    <application
+            android:label="@string/testLatency_activity">
+        <activity android:name="TestLatencyActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+                android:launchMode="singleTask"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/testLatency/res/values/strings.xml b/opengl/tests/testLatency/res/values/strings.xml
new file mode 100644
index 0000000..d80b77c
--- /dev/null
+++ b/opengl/tests/testLatency/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="testLatency_activity">TestLatency</string>
+
+</resources>
+
diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java
new file mode 100644
index 0000000..ed993cb
--- /dev/null
+++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 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.testlatency;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class TestLatencyActivity extends Activity {
+
+    TestLatencyView mView;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mView = new TestLatencyView(getApplication());
+        setContentView(mView);
+        mView.setFocusableInTouchMode(true);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java
new file mode 100644
index 0000000..d62bf17
--- /dev/null
+++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+
+package com.android.testlatency;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation.  This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class TestLatencyView extends GLSurfaceView {
+    private static String TAG = "TestLatencyiew";
+    private float mX;
+    private float mY;
+    private float mDX;
+    private float mDY;
+    private long  mT;
+    private long  mDT;
+
+    public TestLatencyView(Context context) {
+        super(context);
+        setEGLContextClientVersion(2);
+        setRenderer(new Renderer());
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        switch (event.getAction()) {
+        case MotionEvent.ACTION_MOVE:
+            float x = event.getX();
+            float y = event.getY();
+            long  t = event.getEventTime();
+            synchronized(this) {
+                mDT = t - mT;
+                mT = t;
+                mDX = x - mX;
+                mX = x;
+                mDY = y - mY;
+                mY = y;
+            }
+            break;
+        default:
+            break;
+        }
+        return true;
+    }
+
+    private class Renderer implements GLSurfaceView.Renderer {
+        private float mScaleX, mScaleY, mOffsetX, mOffsetY;
+        private final float MS_PER_FRAME = 1000 / 60;
+        public Renderer() {
+            mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4)
+                .order(ByteOrder.nativeOrder()).asFloatBuffer();
+        }
+
+
+        public void onDrawFrame(GL10 gl) {
+            GLES20.glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
+            GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+            GLES20.glUseProgram(mProgram);
+            checkGlError("glUseProgram");
+
+            float x, y, dx, dy;
+            long t, dt;
+            synchronized(TestLatencyView.this) {
+                x = mX;
+                y = mY;
+                dx = mDX;
+                dy = mDY;
+                dt = mDT;
+            }
+
+            if (dt > 0) {
+                dx = dx * MS_PER_FRAME / dt;
+                dy = dy * MS_PER_FRAME / dt;
+            }
+
+            GLES20.glEnableVertexAttribArray(mvPositionHandle);
+            checkGlError("glEnableVertexAttribArray");
+            GLES20.glEnableVertexAttribArray(mvColorHandle);
+            checkGlError("glEnableVertexAttribArray");
+            for(int step = 0; step < 8; step++) {
+                float sx = (x + dx * step) * mScaleX + mOffsetX;
+                float sy = (y + dy * step) * mScaleY + mOffsetY;
+                int cbase = step * 4;
+
+                for (int i = 0; i < mTriangleVerticesData.length; i += 6) {
+                    mTriangleVerticesData2[i] = sx + mTriangleVerticesData[i];
+                    mTriangleVerticesData2[i+1] = -sy + mTriangleVerticesData[i+1];
+                    mTriangleVerticesData2[i+2] = mColors[cbase];
+                    mTriangleVerticesData2[i+3] = mColors[cbase+1];
+                    mTriangleVerticesData2[i+4] = mColors[cbase+2];
+                    mTriangleVerticesData2[i+5] = mColors[cbase+3];
+                }
+                mTriangleVertices.position(0);
+                mTriangleVertices.put(mTriangleVerticesData2).position(0);
+
+                GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices);
+                checkGlError("glVertexAttribPointer mvPosition");
+                mTriangleVertices.put(mTriangleVerticesData2).position(2);
+                GLES20.glVertexAttribPointer(mvColorHandle, 4, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices);
+                checkGlError("glVertexAttribPointer mvColor");
+                GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
+                checkGlError("glDrawArrays");
+            }
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            GLES20.glViewport(0, 0, width, height);
+            mScaleX = 2.0f / width;
+            mScaleY = 2.0f / height;
+            mOffsetX = -1f;
+            mOffsetY = -1f;
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            mProgram = createProgram(mVertexShader, mFragmentShader);
+            if (mProgram == 0) {
+                return;
+            }
+            mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
+            checkGlError("glGetAttribLocation");
+            if (mvPositionHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for vPosition");
+            }
+            mvColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
+            checkGlError("glGetAttribLocation");
+            if (mvColorHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for vColor");
+            }
+        }
+
+        private int loadShader(int shaderType, String source) {
+            int shader = GLES20.glCreateShader(shaderType);
+            if (shader != 0) {
+                GLES20.glShaderSource(shader, source);
+                GLES20.glCompileShader(shader);
+                int[] compiled = new int[1];
+                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+                if (compiled[0] == 0) {
+                    Log.e(TAG, "Could not compile shader " + shaderType + ":");
+                    Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+                    GLES20.glDeleteShader(shader);
+                    shader = 0;
+                }
+            }
+            return shader;
+        }
+
+        private int createProgram(String vertexSource, String fragmentSource) {
+            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+            if (vertexShader == 0) {
+                return 0;
+            }
+
+            int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+            if (pixelShader == 0) {
+                return 0;
+            }
+
+            int program = GLES20.glCreateProgram();
+            if (program != 0) {
+                GLES20.glAttachShader(program, vertexShader);
+                checkGlError("glAttachShader vertexShader");
+                GLES20.glAttachShader(program, pixelShader);
+                checkGlError("glAttachShader pixelShader");
+                GLES20.glLinkProgram(program);
+                int[] linkStatus = new int[1];
+                GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+                if (linkStatus[0] != GLES20.GL_TRUE) {
+                    Log.e(TAG, "Could not link program: ");
+                    Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+                    GLES20.glDeleteProgram(program);
+                    program = 0;
+                }
+            }
+            return program;
+        }
+
+        private void checkGlError(String op) {
+            int error;
+            while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+                Log.e(TAG, op + ": glError " + error);
+                throw new RuntimeException(op + ": glError " + error);
+            }
+        }
+
+        // X, Y, R G B A
+        private final float[] mTriangleVerticesData = {
+                -0.025f, 0.3f, 0.0f, 1.0f, 0.0f, 1.0f,
+                 0.0f  , 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
+                 0.025f, 0.3f, 1.0f, 1.0f, 255.0f, 1.0f
+                };
+
+        // Color cascade:
+        private final float[] mColors = {
+                0.0f, 0.0f, 0.0f, 1.0f,
+                0.5f, 0.0f, 0.0f, 1.0f,
+                0.0f, 0.5f, 0.0f, 1.0f,
+                0.5f, 0.5f, 0.0f, 1.0f,
+
+                0.0f, 0.0f, 0.5f, 1.0f,
+                1.0f, 0.0f, 0.0f, 1.0f,
+                1.0f, 1.0f, 1.0f, 1.0f,
+                0.0f, 1.0f, 0.0f, 1.0f
+        };
+
+        private float[] mTriangleVerticesData2 = new float[mTriangleVerticesData.length];
+        private FloatBuffer mTriangleVertices;
+
+        private final String mVertexShader = "attribute vec4 aPosition;\n"
+            + "attribute vec4 aColor;\n"
+            + "varying vec4 vColor;\n"
+            + "void main() {\n"
+            + "  gl_Position = aPosition;\n"
+            + "  vColor = aColor;\n"
+            + "}\n";
+
+        private final String mFragmentShader = "precision mediump float;\n"
+            + "varying vec4 vColor;\n"
+            + "void main() {\n"
+            + "  gl_FragColor = vColor;\n"
+            + "}\n";
+
+        private int mProgram;
+        private int mvPositionHandle;
+        private int mvColorHandle;
+
+    }
+}
+
diff --git a/opengl/tests/testPauseResume/AndroidManifest.xml b/opengl/tests/testPauseResume/AndroidManifest.xml
index 3e8e7e7..1879bc3 100644
--- a/opengl/tests/testPauseResume/AndroidManifest.xml
+++ b/opengl/tests/testPauseResume/AndroidManifest.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
+<!-- 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.
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/opengl/tests/testPauseResume/res/values/strings.xml b/opengl/tests/testPauseResume/res/values/strings.xml
index 208fe15..b4c98fe 100644
--- a/opengl/tests/testPauseResume/res/values/strings.xml
+++ b/opengl/tests/testPauseResume/res/values/strings.xml
@@ -1,21 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2006, 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.
-*/
+<!-- Copyright (C) 2006 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.
 -->
 
 <!-- This file contains resource definitions for displayed strings, allowing
diff --git a/opengl/tests/testViewport/Android.mk b/opengl/tests/testViewport/Android.mk
new file mode 100644
index 0000000..ab37809
--- /dev/null
+++ b/opengl/tests/testViewport/Android.mk
@@ -0,0 +1,26 @@
+#########################################################################
+# OpenGL ES JNI sample
+# This makefile builds both an activity and a shared library.
+#########################################################################
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := TestViewport
+
+# Set a specific SDK version so we can run on Froyo.
+
+LOCAL_SDK_VERSION := 8
+
+include $(BUILD_PACKAGE)
+
+endif # TARGET_SIMULATOR
diff --git a/opengl/tests/testViewport/AndroidManifest.xml b/opengl/tests/testViewport/AndroidManifest.xml
new file mode 100644
index 0000000..ba178bb
--- /dev/null
+++ b/opengl/tests/testViewport/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.test">
+    <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <application
+            android:label="@string/test_activity">
+        <activity android:name="TestActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            	android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/testViewport/README b/opengl/tests/testViewport/README
new file mode 100644
index 0000000..c06abc9
--- /dev/null
+++ b/opengl/tests/testViewport/README
@@ -0,0 +1,28 @@
+Repro steps:
+
+build, install and run the attached test program TestViewport.apk
+
+Run on Sapphire with Froyo.
+
+The program clears the screen to blue, then draws a full screen white quad that
+is alligned to the screen.
+(Therefore the whole screen should appear to be white.)
+
+
+Note that screen is all white.
+
+Rotate screen 90 degrees.
+
+Expected: screen is still all white.
+
+Actual: screen is blue with offset white rectangle.
+
+This bug only happens on Sapphire, it works correctly on Passion.
+
+What happens:
+
+I think the bug is that the gl.glViewport() call in onSurfaceChanged() is
+being ignored by the OpenGL driver.
+
+NOTE: If a gl.glViewport call is added at the beginning of the onDrawFrame()
+call (which means it is called before every draw), the program runs correctly.
diff --git a/opengl/tests/testViewport/res/values/strings.xml b/opengl/tests/testViewport/res/values/strings.xml
new file mode 100644
index 0000000..c037a7c
--- /dev/null
+++ b/opengl/tests/testViewport/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="test_activity">Test Viewport</string>
+
+</resources>
+
diff --git a/opengl/tests/testViewport/src/com/android/test/TestActivity.java b/opengl/tests/testViewport/src/com/android/test/TestActivity.java
new file mode 100644
index 0000000..cc7e450
--- /dev/null
+++ b/opengl/tests/testViewport/src/com/android/test/TestActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 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;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+public class TestActivity extends Activity {
+    private final static String TAG = "TestActivity";
+    TestView mView;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mView = new TestView(getApplication());
+	    mView.setFocusableInTouchMode(true);
+	    setContentView(mView);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/opengl/tests/testViewport/src/com/android/test/TestView.java b/opengl/tests/testViewport/src/com/android/test/TestView.java
new file mode 100644
index 0000000..23cc37d
--- /dev/null
+++ b/opengl/tests/testViewport/src/com/android/test/TestView.java
@@ -0,0 +1,262 @@
+/*
+ * 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.
+ */
+
+package com.android.test;
+/*
+ * Copyright (C) 2008 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.
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.FloatBuffer;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation.  This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class TestView extends GLSurfaceView {
+    TestView(Context context) {
+        super(context);
+        init();
+    }
+
+    public TestView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        setRenderer(new Renderer());
+        setRenderMode(RENDERMODE_WHEN_DIRTY);
+    }
+    
+        /** A grid is a topologically rectangular array of vertices.
+    *
+    * The vertex and index data are held in VBO objects because on most
+    * GPUs VBO objects are the fastest way of rendering static vertex
+    * and index data.
+    *
+    */
+
+   private static class Grid {
+       // Size of vertex data elements in bytes:
+       final static int FLOAT_SIZE = 4;
+       final static int CHAR_SIZE = 2;
+
+       // Vertex structure:
+       // float x, y, z;
+
+       final static int VERTEX_SIZE = 3 * FLOAT_SIZE;
+
+       private int mVertexBufferObjectId;
+       private int mElementBufferObjectId;
+
+       // These buffers are used to hold the vertex and index data while
+       // constructing the grid. Once createBufferObjects() is called
+       // the buffers are nulled out to save memory.
+
+       private ByteBuffer mVertexByteBuffer;
+       private FloatBuffer mVertexBuffer;
+       private CharBuffer mIndexBuffer;
+
+       private int mW;
+       private int mH;
+       private int mIndexCount;
+
+       public Grid(int w, int h) {
+           if (w < 0 || w >= 65536) {
+               throw new IllegalArgumentException("w");
+           }
+           if (h < 0 || h >= 65536) {
+               throw new IllegalArgumentException("h");
+           }
+           if (w * h >= 65536) {
+               throw new IllegalArgumentException("w * h >= 65536");
+           }
+
+           mW = w;
+           mH = h;
+           int size = w * h;
+
+           mVertexByteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * size)
+               .order(ByteOrder.nativeOrder());
+           mVertexBuffer = mVertexByteBuffer.asFloatBuffer();
+
+           int quadW = mW - 1;
+           int quadH = mH - 1;
+           int quadCount = quadW * quadH;
+           int indexCount = quadCount * 6;
+           mIndexCount = indexCount;
+           mIndexBuffer = ByteBuffer.allocateDirect(CHAR_SIZE * indexCount)
+               .order(ByteOrder.nativeOrder()).asCharBuffer();
+
+           /*
+            * Initialize triangle list mesh.
+            *
+            *     [0]-----[  1] ...
+            *      |    /   |
+            *      |   /    |
+            *      |  /     |
+            *     [w]-----[w+1] ...
+            *      |       |
+            *
+            */
+
+           {
+               int i = 0;
+               for (int y = 0; y < quadH; y++) {
+                   for (int x = 0; x < quadW; x++) {
+                       char a = (char) (y * mW + x);
+                       char b = (char) (y * mW + x + 1);
+                       char c = (char) ((y + 1) * mW + x);
+                       char d = (char) ((y + 1) * mW + x + 1);
+
+                       mIndexBuffer.put(i++, a);
+                       mIndexBuffer.put(i++, c);
+                       mIndexBuffer.put(i++, b);
+
+                       mIndexBuffer.put(i++, b);
+                       mIndexBuffer.put(i++, c);
+                       mIndexBuffer.put(i++, d);
+                   }
+               }
+           }
+
+       }
+
+       public void set(int i, int j, float x, float y, float z) {
+           if (i < 0 || i >= mW) {
+               throw new IllegalArgumentException("i");
+           }
+           if (j < 0 || j >= mH) {
+               throw new IllegalArgumentException("j");
+           }
+
+           int index = mW * j + i;
+
+           mVertexBuffer.position(index * VERTEX_SIZE / FLOAT_SIZE);
+           mVertexBuffer.put(x);
+           mVertexBuffer.put(y);
+           mVertexBuffer.put(z);
+       }
+
+       public void createBufferObjects(GL gl) {
+           // Generate a the vertex and element buffer IDs
+           int[] vboIds = new int[2];
+           GL11 gl11 = (GL11) gl;
+           gl11.glGenBuffers(2, vboIds, 0);
+           mVertexBufferObjectId = vboIds[0];
+           mElementBufferObjectId = vboIds[1];
+
+           // Upload the vertex data
+           gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId);
+           mVertexByteBuffer.position(0);
+           gl11.glBufferData(GL11.GL_ARRAY_BUFFER, mVertexByteBuffer.capacity(), mVertexByteBuffer, GL11.GL_STATIC_DRAW);
+
+           gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId);
+           mIndexBuffer.position(0);
+           gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer.capacity() * CHAR_SIZE, mIndexBuffer, GL11.GL_STATIC_DRAW);
+
+           // We don't need the in-memory data any more
+           mVertexBuffer = null;
+           mVertexByteBuffer = null;
+           mIndexBuffer = null;
+       }
+
+       public void draw(GL10 gl) {
+           GL11 gl11 = (GL11) gl;
+
+           gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+
+           gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId);
+           gl11.glVertexPointer(3, GL10.GL_FLOAT, VERTEX_SIZE, 0);
+           
+           gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId);
+           gl11.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, 0);
+           gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
+           gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
+           gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
+       }
+   }
+
+
+    private class Renderer implements GLSurfaceView.Renderer {
+        private static final String TAG = "Renderer";
+        private Grid mGrid;
+        
+        public void onDrawFrame(GL10 gl) {
+			gl.glClearColor(0,0,1,1);
+			gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
+            mGrid.draw(gl);
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            gl.glViewport(0, 0, width, height);
+			gl.glMatrixMode(GL11.GL_PROJECTION);
+			gl.glLoadIdentity();
+			gl.glOrthof(0, width, height, 0, -1, 1);
+			gl.glMatrixMode(GL11.GL_MODELVIEW);
+            createGrid(gl, width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        }
+        
+        private void createGrid(GL10 gl, float w, float h) {
+        mGrid = new Grid(2, 2);
+			for (int j = 0; j < 2; j++) {
+				for (int i = 0; i < 2; i++) {
+					float x = w * i;
+					float y = h * j;
+					float z = 0.0f;
+					mGrid.set(i,j, x, y, z);
+				}
+			}
+			mGrid.createBufferObjects(gl);
+		}
+    }
+}
+
diff --git a/opengl/tools/glgen/stubs/gles11/glGetString.java b/opengl/tools/glgen/stubs/gles11/glGetString.java
index d44a6dd..b02a0d1 100644
--- a/opengl/tools/glgen/stubs/gles11/glGetString.java
+++ b/opengl/tools/glgen/stubs/gles11/glGetString.java
@@ -1,21 +1,21 @@
-/*
- * 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.
- */
-
-    // C function const GLubyte * glGetString ( GLenum name )
-
-    public static native String glGetString(
-        int name
-    );
+/*
+ * 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.
+ */
+
+    // C function const GLubyte * glGetString ( GLenum name )
+
+    public static native String glGetString(
+        int name
+    );
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index c5bdaa1..8a00a2e 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -5,12 +5,10 @@
     clz.cpp.arm \
     DisplayHardware/DisplayHardware.cpp \
     DisplayHardware/DisplayHardwareBase.cpp \
-    BlurFilter.cpp.arm \
+    DisplayHardware/HWComposer.cpp \
     GLExtensions.cpp \
     Layer.cpp \
     LayerBase.cpp \
-    LayerBuffer.cpp \
-    LayerBlur.cpp \
     LayerDim.cpp \
     MessageQueue.cpp \
     SurfaceFlinger.cpp \
diff --git a/services/surfaceflinger/BlurFilter.cpp b/services/surfaceflinger/BlurFilter.cpp
deleted file mode 100644
index 1ffbd5b..0000000
--- a/services/surfaceflinger/BlurFilter.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-/* 
-**
-** Copyright 2006, 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <utils/Errors.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "clz.h"
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-namespace android {
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
-    return v;
-}
-inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
-    return v;
-}
-#else
-inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
-    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
-}
-inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
-    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
-}
-#endif
-
-const int BLUR_DITHER_BITS = 6;  // dither weights stored on 6 bits
-const int BLUR_DITHER_ORDER_SHIFT= 3;
-const int BLUR_DITHER_ORDER      = (1<<BLUR_DITHER_ORDER_SHIFT);
-const int BLUR_DITHER_SIZE       = BLUR_DITHER_ORDER * BLUR_DITHER_ORDER;
-const int BLUR_DITHER_MASK       = BLUR_DITHER_ORDER-1;
-
-static const uint8_t gDitherMatrix[BLUR_DITHER_SIZE] = {
-     0, 32,  8, 40,  2, 34, 10, 42,
-    48, 16, 56, 24, 50, 18, 58, 26,
-    12, 44,  4, 36, 14, 46,  6, 38,
-    60, 28, 52, 20, 62, 30, 54, 22,
-     3, 35, 11, 43,  1, 33,  9, 41,
-    51, 19, 59, 27, 49, 17, 57, 25,
-    15, 47,  7, 39, 13, 45,  5, 37,
-    63, 31, 55, 23, 61, 29, 53, 21
-};
-
-
-template <int FACTOR = 0>
-struct BlurColor565
-{
-    typedef uint16_t type;
-    int r, g, b;    
-    inline BlurColor565() { }
-    inline BlurColor565(uint16_t v) {
-        r = v >> 11;
-        g = (v >> 5) & 0x3E;
-        b = v & 0x1F;
-    }
-    inline void clear() { r=g=b=0; }
-    inline uint16_t to(int shift, int last, int dither) const {
-        int R = r;
-        int G = g;
-        int B = b;
-        if  (UNLIKELY(last)) {
-            if (FACTOR>0) {
-                int L = (R+G+B)>>1;
-                R += (((L>>1) - R) * FACTOR) >> 8;
-                G += (((L   ) - G) * FACTOR) >> 8;
-                B += (((L>>1) - B) * FACTOR) >> 8;
-            }
-            R += (dither << shift) >> BLUR_DITHER_BITS;
-            G += (dither << shift) >> BLUR_DITHER_BITS;
-            B += (dither << shift) >> BLUR_DITHER_BITS;
-        }
-        R >>= shift;
-        G >>= shift;
-        B >>= shift;
-        return (R<<11) | (G<<5) | B;
-    }    
-    inline BlurColor565& operator += (const BlurColor565& rhs) {
-        r += rhs.r;
-        g += rhs.g;
-        b += rhs.b;
-        return *this;
-    }
-    inline BlurColor565& operator -= (const BlurColor565& rhs) {
-        r -= rhs.r;
-        g -= rhs.g;
-        b -= rhs.b;
-        return *this;
-    }
-};
-
-template <int FACTOR = 0>
-struct BlurColor888X
-{
-    typedef uint32_t type;
-    int r, g, b;    
-    inline BlurColor888X() { }
-    inline BlurColor888X(uint32_t v) {
-        v = BLUR_RGBA_TO_HOST(v);
-        r = v & 0xFF;
-        g = (v >>  8) & 0xFF;
-        b = (v >> 16) & 0xFF;
-    }
-    inline void clear() { r=g=b=0; }
-    inline uint32_t to(int shift, int last, int dither) const {
-        int R = r;
-        int G = g;
-        int B = b;
-        if  (UNLIKELY(last)) {
-            if (FACTOR>0) {
-                int L = (R+G+G+B)>>2;
-                R += ((L - R) * FACTOR) >> 8;
-                G += ((L - G) * FACTOR) >> 8;
-                B += ((L - B) * FACTOR) >> 8;
-            }
-        }
-        R >>= shift;
-        G >>= shift;
-        B >>= shift;
-        return BLUR_HOST_TO_RGBA((0xFF<<24) | (B<<16) | (G<<8) | R);
-    }    
-    inline BlurColor888X& operator += (const BlurColor888X& rhs) {
-        r += rhs.r;
-        g += rhs.g;
-        b += rhs.b;
-        return *this;
-    }
-    inline BlurColor888X& operator -= (const BlurColor888X& rhs) {
-        r -= rhs.r;
-        g -= rhs.g;
-        b -= rhs.b;
-        return *this;
-    }
-};
-
-struct BlurGray565
-{
-    typedef uint16_t type;
-    int l;    
-    inline BlurGray565() { }
-    inline BlurGray565(uint16_t v) {
-        int r = v >> 11;
-        int g = (v >> 5) & 0x3F;
-        int b = v & 0x1F;
-        l = (r + g + b + 1)>>1;
-    }
-    inline void clear() { l=0; }
-    inline uint16_t to(int shift, int last, int dither) const {
-        int L = l;
-        if  (UNLIKELY(last)) {
-            L += (dither << shift) >> BLUR_DITHER_BITS;
-        }
-        L >>= shift;
-        return ((L>>1)<<11) | (L<<5) | (L>>1);
-    }
-    inline BlurGray565& operator += (const BlurGray565& rhs) {
-        l += rhs.l;
-        return *this;
-    }
-    inline BlurGray565& operator -= (const BlurGray565& rhs) {
-        l -= rhs.l;
-        return *this;
-    }
-};
-
-struct BlurGray8888
-{
-    typedef uint32_t type;
-    int l, a;    
-    inline BlurGray8888() { }
-    inline BlurGray8888(uint32_t v) {
-        v = BLUR_RGBA_TO_HOST(v);
-        int r = v & 0xFF;
-        int g = (v >>  8) & 0xFF;
-        int b = (v >> 16) & 0xFF;
-        a = v >> 24;
-        l = r + g + g + b;
-    }    
-    inline void clear() { l=a=0; }
-    inline uint32_t to(int shift, int last, int dither) const {
-        int L = l;
-        int A = a;
-        if  (UNLIKELY(last)) {
-            L += (dither << (shift+2)) >> BLUR_DITHER_BITS;
-            A += (dither << shift) >> BLUR_DITHER_BITS;
-        }
-        L >>= (shift+2);
-        A >>= shift;
-        return BLUR_HOST_TO_RGBA((A<<24) | (L<<16) | (L<<8) | L);
-    }
-    inline BlurGray8888& operator += (const BlurGray8888& rhs) {
-        l += rhs.l;
-        a += rhs.a;
-        return *this;
-    }
-    inline BlurGray8888& operator -= (const BlurGray8888& rhs) {
-        l -= rhs.l;
-        a -= rhs.a;
-        return *this;
-    }
-};
-
-
-template<typename PIXEL>
-static status_t blurFilter(
-        GGLSurface const* dst,
-        GGLSurface const* src,
-        int kernelSizeUser,
-        int repeat)
-{
-    typedef typename PIXEL::type TYPE;
-
-    const int shift             = 31 - clz(kernelSizeUser);
-    const int areaShift         = shift*2;
-    const int kernelSize        = 1<<shift;
-    const int kernelHalfSize    = kernelSize/2;
-    const int mask              = kernelSize-1;
-    const int w                 = src->width;
-    const int h                 = src->height;
-    const uint8_t* ditherMatrix = gDitherMatrix;
-
-    // we need a temporary buffer to store one line of blurred columns
-    // as well as kernelSize lines of source pixels organized as a ring buffer.
-    void* const temporary_buffer = malloc(
-            (w + kernelSize) * sizeof(PIXEL) +
-            (src->stride * kernelSize) * sizeof(TYPE));
-    if (!temporary_buffer)
-        return NO_MEMORY;
-
-    PIXEL* const sums = (PIXEL*)temporary_buffer;
-    TYPE* const scratch = (TYPE*)(sums + w + kernelSize);
-
-    // Apply the blur 'repeat' times, this is used to approximate
-    // gaussian blurs. 3 times gives good results.
-    for (int k=0 ; k<repeat ; k++) {
-
-        // Clear the columns sums for this round
-        memset(sums, 0, (w + kernelSize) * sizeof(PIXEL));
-        TYPE* head;
-        TYPE pixel;
-        PIXEL current;
-
-        // Since we're going to override the source data we need
-        // to copy it in a temporary buffer. Only kernelSize lines are
-        // required. But since we start in the center of the kernel,
-        // we only copy half of the data, and fill the rest with zeros
-        // (assuming black/transparent pixels).
-        memcpy( scratch + src->stride*kernelHalfSize,
-                src->data,
-                src->stride*kernelHalfSize*sizeof(TYPE));
-
-        // sum half of each column, because we assume the first half is
-        // zeros (black/transparent).
-        for (int y=0 ; y<kernelHalfSize ; y++) {
-            head = (TYPE*)src->data + y*src->stride;
-            for (int x=0 ; x<w ; x++)
-                sums[x] += PIXEL( *head++ );
-        }
-
-        for (int y=0 ; y<h ; y++) {
-            TYPE* fb = (TYPE*)dst->data + y*dst->stride;
-
-            // compute the dither matrix line
-            uint8_t const * ditherY = ditherMatrix
-                    + (y & BLUR_DITHER_MASK)*BLUR_DITHER_ORDER;
-
-            // Horizontal blur pass on the columns sums
-            int count, dither, x=0;
-            PIXEL const * out= sums;
-            PIXEL const * in = sums;
-            current.clear();
-
-            count = kernelHalfSize;
-            do {
-                current += *in;
-                in++;
-            } while (--count);
-            
-            count = kernelHalfSize;
-            do {
-                current += *in;
-                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
-                *fb++ = current.to(areaShift, k==repeat-1, dither);
-                in++;
-            } while (--count);
-
-            count = w-kernelSize;
-            do {
-                current += *in;
-                current -= *out;
-                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
-                *fb++ = current.to(areaShift, k==repeat-1, dither);
-                in++, out++;
-            } while (--count);
-
-            count = kernelHalfSize;
-            do {
-                current -= *out;
-                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
-                *fb++ = current.to(areaShift, k==repeat-1, dither);
-                out++;
-            } while (--count);
-
-            // vertical blur pass, subtract the oldest line from each columns
-            // and add a new line. Subtract or add zeros at the top
-            // and bottom edges.
-            TYPE* const tail = scratch + (y & mask) * src->stride;
-            if (y >= kernelHalfSize) {
-                for (int x=0 ; x<w ; x++)
-                    sums[x] -= PIXEL( tail[x] );
-            }
-            if (y < h-kernelSize) {
-                memcpy( tail,
-                        (TYPE*)src->data + (y+kernelHalfSize)*src->stride,
-                        src->stride*sizeof(TYPE));
-                for (int x=0 ; x<w ; x++)
-                    sums[x] += PIXEL( tail[x] );
-            }
-        }
-
-        // The subsequent passes are always done in-place.
-        src = dst;
-    }
-    
-    free(temporary_buffer);
-
-    return NO_ERROR;
-}
-
-template status_t blurFilter< BlurColor565<0x80> >(
-        GGLSurface const* dst,
-        GGLSurface const* src,
-        int kernelSizeUser,
-        int repeat);
-
-status_t blurFilter(
-        GGLSurface const* image,
-        int kernelSizeUser,
-        int repeat)
-{
-    status_t err = BAD_VALUE;
-    if (image->format == GGL_PIXEL_FORMAT_RGB_565) {
-        err = blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
-    } else if (image->format == GGL_PIXEL_FORMAT_RGBX_8888) {
-        err = blurFilter< BlurColor888X<0x80> >(image, image, kernelSizeUser, repeat);
-    }
-    return err;
-}
-
-} // namespace android
-
-//err = blur< BlurColor565<0x80> >(dst, src, kernelSizeUser, repeat);
-//err = blur<BlurGray565>(dst, src, kernelSizeUser, repeat);
-//err = blur<BlurGray8888>(dst, src, kernelSizeUser, repeat);
diff --git a/services/surfaceflinger/BlurFilter.h b/services/surfaceflinger/BlurFilter.h
deleted file mode 100644
index 294db43..0000000
--- a/services/surfaceflinger/BlurFilter.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* 
-**
-** Copyright 2006, 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_BLUR_FILTER_H
-#define ANDROID_BLUR_FILTER_H
-
-#include <stdint.h>
-#include <utils/Errors.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-namespace android {
-
-status_t blurFilter(
-        GGLSurface const* image,
-        int kernelSizeUser,
-        int repeat);
-
-} // namespace android
-
-#endif // ANDROID_BLUR_FILTER_H
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 818774d..64cff96 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -36,11 +36,10 @@
 
 #include "DisplayHardware/DisplayHardware.h"
 
-#include <hardware/copybit.h>
-#include <hardware/overlay.h>
 #include <hardware/gralloc.h>
 
 #include "GLExtensions.h"
+#include "HWComposer.h"
 
 using namespace android;
 
@@ -76,7 +75,7 @@
         const sp<SurfaceFlinger>& flinger,
         uint32_t dpy)
     : DisplayHardwareBase(flinger, dpy),
-      mFlags(0)
+      mFlags(0), mHwc(0)
 {
     init(dpy);
 }
@@ -104,12 +103,6 @@
     mDpiY = mNativeWindow->ydpi;
     mRefreshRate = fbDev->fps;
 
-    mOverlayEngine = NULL;
-    hw_module_t const* module;
-    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
-        overlay_control_open(module, &mOverlayEngine);
-    }
-
     EGLint w, h, dummy;
     EGLint numConfigs=0;
     EGLSurface surface;
@@ -272,6 +265,17 @@
 
     // Unbind the context from this thread
     eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+
+    // initialize the H/W composer
+    mHwc = new HWComposer();
+    if (mHwc->initCheck() == NO_ERROR) {
+        mHwc->setFrameBuffer(mDisplay, mSurface);
+    }
+}
+
+HWComposer& DisplayHardware::getHwComposer() const {
+    return *mHwc;
 }
 
 /*
@@ -285,12 +289,14 @@
 {
     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglTerminate(mDisplay);
-    overlay_control_close(mOverlayEngine);
 }
 
 void DisplayHardware::releaseScreen() const
 {
     DisplayHardwareBase::releaseScreen();
+    if (mHwc->initCheck() == NO_ERROR) {
+        mHwc->release();
+    }
 }
 
 void DisplayHardware::acquireScreen() const
@@ -331,7 +337,12 @@
     }
     
     mPageFlipCount++;
-    eglSwapBuffers(dpy, surface);
+
+    if (mHwc->initCheck() == NO_ERROR) {
+        mHwc->commit();
+    } else {
+        eglSwapBuffers(dpy, surface);
+    }
     checkEGLErrors("eglSwapBuffers");
 
     // for debugging
@@ -339,12 +350,6 @@
     //glClear(GL_COLOR_BUFFER_BIT);
 }
 
-status_t DisplayHardware::postBypassBuffer(const native_handle_t* handle) const
-{
-   framebuffer_device_t *fbDev = (framebuffer_device_t *)mNativeWindow->getDevice();
-   return fbDev->post(fbDev, handle);
-}
-
 uint32_t DisplayHardware::getFlags() const
 {
     return mFlags;
@@ -354,3 +359,8 @@
 {
     eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
 }
+
+void DisplayHardware::dump(String8& res) const
+{
+    mNativeWindow->dump(res);
+}
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 79ef2a7..ee7a2af 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -33,13 +33,10 @@
 
 #include "DisplayHardware/DisplayHardwareBase.h"
 
-struct overlay_control_device_t;
-struct framebuffer_device_t;
-struct copybit_image_t;
-
 namespace android {
 
 class FramebufferNativeWindow;
+class HWComposer;
 
 class DisplayHardware : public DisplayHardwareBase
 {
@@ -64,7 +61,6 @@
     // Flip the front and back buffers if the back buffer is "dirty".  Might
     // be instantaneous, might involve copying the frame buffer around.
     void flip(const Region& dirty) const;
-    status_t postBypassBuffer(const native_handle_t* handle) const;
 
     float       getDpiX() const;
     float       getDpiY() const;
@@ -80,7 +76,11 @@
 
     uint32_t getPageFlipCount() const;
     EGLDisplay getEGLDisplay() const { return mDisplay; }
-    overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
+
+    void dump(String8& res) const;
+
+    // Hardware Composer
+    HWComposer& getHwComposer() const;
     
     status_t compositionComplete() const;
     
@@ -111,8 +111,9 @@
     GLint           mMaxViewportDims;
     GLint           mMaxTextureSize;
     
+    HWComposer*     mHwc;
+
     sp<FramebufferNativeWindow> mNativeWindow;
-    overlay_control_device_t* mOverlayEngine;
 };
 
 }; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
new file mode 100644
index 0000000..4a3b20d
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+#include <hardware/hardware.h>
+
+#include <cutils/log.h>
+
+#include <EGL/egl.h>
+
+#include "HWComposer.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+HWComposer::HWComposer()
+    : mModule(0), mHwc(0), mList(0), mCapacity(0),
+      mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
+{
+    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
+    LOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
+    if (err == 0) {
+        err = hwc_open(mModule, &mHwc);
+        LOGE_IF(err, "%s device failed to initialize (%s)",
+                HWC_HARDWARE_COMPOSER, strerror(-err));
+    }
+}
+
+HWComposer::~HWComposer() {
+    free(mList);
+    if (mHwc) {
+        hwc_close(mHwc);
+    }
+}
+
+status_t HWComposer::initCheck() const {
+    return mHwc ? NO_ERROR : NO_INIT;
+}
+
+void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
+    mDpy = (hwc_display_t)dpy;
+    mSur = (hwc_surface_t)sur;
+}
+
+status_t HWComposer::createWorkList(size_t numLayers) {
+    if (mHwc) {
+        if (!mList || mCapacity < numLayers) {
+            free(mList);
+            size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
+            mList = (hwc_layer_list_t*)malloc(size);
+            mCapacity = numLayers;
+        }
+        mList->flags = HWC_GEOMETRY_CHANGED;
+        mList->numHwLayers = numLayers;
+    }
+    return NO_ERROR;
+}
+
+status_t HWComposer::prepare() const {
+    int err = mHwc->prepare(mHwc, mList);
+    return (status_t)err;
+}
+
+status_t HWComposer::commit() const {
+    int err = mHwc->set(mHwc, mDpy, mSur, mList);
+    if (mList) {
+        mList->flags &= ~HWC_GEOMETRY_CHANGED;
+    }
+    return (status_t)err;
+}
+
+status_t HWComposer::release() const {
+    int err = mHwc->set(mHwc, NULL, NULL, NULL);
+    return (status_t)err;
+}
+
+size_t HWComposer::getNumLayers() const {
+    return mList ? mList->numHwLayers : 0;
+}
+
+hwc_layer_t* HWComposer::getLayers() const {
+    return mList ? mList->hwLayers : 0;
+}
+
+void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
+    if (mHwc && mList) {
+        result.append("Hardware Composer state:\n");
+
+        snprintf(buffer, SIZE, "  numHwLayers=%u, flags=%08x\n",
+                mList->numHwLayers, mList->flags);
+        result.append(buffer);
+
+        for (size_t i=0 ; i<mList->numHwLayers ; i++) {
+            const hwc_layer_t& l(mList->hwLayers[i]);
+            snprintf(buffer, SIZE, "  %8s | %08x | %08x | %02x | %04x | [%5d,%5d,%5d,%5d] |  [%5d,%5d,%5d,%5d]\n",
+                    l.compositionType ? "OVERLAY" : "FB",
+                    l.hints, l.flags, l.transform, l.blending,
+                    l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
+                    l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom);
+            result.append(buffer);
+        }
+
+    }
+    if (mHwc && mHwc->common.version >= 1 && mHwc->dump) {
+        mHwc->dump(mHwc, buffer, SIZE);
+        result.append(buffer);
+    }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
new file mode 100644
index 0000000..5a9e9eb
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SF_HWCOMPOSER_H
+#define ANDROID_SF_HWCOMPOSER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+
+#include <hardware/hwcomposer.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class String8;
+
+class HWComposer
+{
+public:
+
+    HWComposer();
+    ~HWComposer();
+
+    status_t initCheck() const;
+
+    // tells the HAL what the framebuffer is
+    void setFrameBuffer(EGLDisplay dpy, EGLSurface sur);
+
+    // create a work list for numLayers layer
+    status_t createWorkList(size_t numLayers);
+
+    // Asks the HAL what it can do
+    status_t prepare() const;
+
+    // commits the list
+    status_t commit() const;
+
+    // release hardware resources
+    status_t release() const;
+
+    size_t getNumLayers() const;
+    hwc_layer_t* getLayers() const;
+
+    // for debugging
+    void dump(String8& out, char* scratch, size_t SIZE) const;
+
+private:
+    hw_module_t const*      mModule;
+    hwc_composer_device_t*  mHwc;
+    hwc_layer_list_t*       mList;
+    size_t                  mCapacity;
+    hwc_display_t           mDpy;
+    hwc_surface_t           mSur;
+};
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c9dcef3..517c335 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -35,6 +35,7 @@
 #include "Layer.h"
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
+#include "DisplayHardware/HWComposer.h"
 
 
 #define DEBUG_RESIZE    0
@@ -55,10 +56,10 @@
         mNeedsBlending(true),
         mNeedsDithering(false),
         mSecure(false),
+        mProtectedByApp(false),
         mTextureManager(),
         mBufferManager(mTextureManager),
-        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false),
-        mBypassState(false)
+        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false)
 {
 }
 
@@ -83,8 +84,28 @@
             sharedClient, token, mBufferManager.getDefaultBufferCount(),
             getIdentity());
 
-    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
 
+    sp<UserClient> ourClient(mUserClientRef.getClient());
+
+    /*
+     *  Here it is guaranteed that userClient != ourClient
+     *  (see UserClient::getTokenForSurface()).
+     *
+     *  We release the token used by this surface in ourClient below.
+     *  This should be safe to do so now, since this layer won't be attached
+     *  to this client, it should be okay to reuse that id.
+     *
+     *  If this causes problems, an other solution would be to keep a list
+     *  of all the {UserClient, token} ever used and release them when the
+     *  Layer is destroyed.
+     *
+     */
+
+    if (ourClient != 0) {
+        ourClient->detachLayer(this);
+    }
+
+    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
     LOGE_IF(err != NO_ERROR,
             "ClientRef::setToken(%p, %p, %u) failed",
             userClient.get(), lcblk.get(), token);
@@ -120,7 +141,8 @@
 
 sp<LayerBaseClient::Surface> Layer::createSurface() const
 {
-    return mSurface;
+    sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this)));
+    return sur;
 }
 
 status_t Layer::ditch()
@@ -130,10 +152,6 @@
     // the layer is not on screen anymore. free as much resources as possible
     mFreezeLock.clear();
 
-    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-    mBufferManager.destroy(dpy);
-    mSurface.clear();
-
     Mutex::Autolock _l(mLock);
     mWidth = mHeight = 0;
     return NO_ERROR;
@@ -171,17 +189,83 @@
     mReqHeight = h;
 
     mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
-    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+    mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
+    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
+            (flags & ISurfaceComposer::eOpaque) == 0;
 
     // we use the red index
     int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
     int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
     mNeedsDithering = layerRedsize > displayRedSize;
 
-    mSurface = new SurfaceLayer(mFlinger, this);
     return NO_ERROR;
 }
 
+void Layer::setGeometry(hwc_layer_t* hwcl)
+{
+    hwcl->compositionType = HWC_FRAMEBUFFER;
+    hwcl->hints = 0;
+    hwcl->flags = 0;
+    hwcl->transform = 0;
+    hwcl->blending = HWC_BLENDING_NONE;
+
+    // we can't do alpha-fade with the hwc HAL
+    const State& s(drawingState());
+    if (s.alpha < 0xFF) {
+        hwcl->flags = HWC_SKIP_LAYER;
+        return;
+    }
+
+    // we can only handle simple transformation
+    if (mOrientation & Transform::ROT_INVALID) {
+        hwcl->flags = HWC_SKIP_LAYER;
+        return;
+    }
+
+    Transform tr(Transform(mOrientation) * Transform(mBufferTransform));
+    hwcl->transform = tr.getOrientation();
+
+    if (needsBlending()) {
+        hwcl->blending = mPremultipliedAlpha ?
+                HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
+    }
+
+    hwcl->displayFrame.left   = mTransformedBounds.left;
+    hwcl->displayFrame.top    = mTransformedBounds.top;
+    hwcl->displayFrame.right  = mTransformedBounds.right;
+    hwcl->displayFrame.bottom = mTransformedBounds.bottom;
+
+    hwcl->visibleRegionScreen.rects =
+            reinterpret_cast<hwc_rect_t const *>(
+                    visibleRegionScreen.getArray(
+                            &hwcl->visibleRegionScreen.numRects));
+}
+
+void Layer::setPerFrameData(hwc_layer_t* hwcl) {
+    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
+    if (buffer == NULL) {
+        // this can happen if the client never drew into this layer yet,
+        // or if we ran out of memory. In that case, don't let
+        // HWC handle it.
+        hwcl->flags |= HWC_SKIP_LAYER;
+        hwcl->handle = NULL;
+        return;
+    }
+    hwcl->handle = buffer->handle;
+
+    if (!mBufferCrop.isEmpty()) {
+        hwcl->sourceCrop.left   = mBufferCrop.left;
+        hwcl->sourceCrop.top    = mBufferCrop.top;
+        hwcl->sourceCrop.right  = mBufferCrop.right;
+        hwcl->sourceCrop.bottom = mBufferCrop.bottom;
+    } else {
+        hwcl->sourceCrop.left   = 0;
+        hwcl->sourceCrop.top    = 0;
+        hwcl->sourceCrop.right  = buffer->width;
+        hwcl->sourceCrop.bottom = buffer->height;
+    }
+}
+
 void Layer::reloadTexture(const Region& dirty)
 {
     sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
@@ -252,32 +336,48 @@
         }
         return;
     }
-
-#ifdef USE_COMPOSITION_BYPASS
-    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
-    if ((buffer != NULL) && (buffer->transform)) {
-        // Here we have a "bypass" buffer, but we need to composite it
-        // most likely because it's not fullscreen anymore.
-        // Since the buffer may have a transformation applied by the client
-        // we need to inverse this transformation here.
-
-        // calculate the inverse of the buffer transform
-        const uint32_t mask = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_FLIP_H;
-        const uint32_t bufferTransformInverse = buffer->transform ^ mask;
-
-        // To accomplish the inverse transform, we use "mBufferTransform"
-        // which is not used by Layer.cpp
-        const_cast<Layer*>(this)->mBufferTransform = bufferTransformInverse;
-        drawWithOpenGL(clip, tex);
-        // reset to "no transfrom"
-        const_cast<Layer*>(this)->mBufferTransform = 0;
-        return;
-    }
-#endif
-
     drawWithOpenGL(clip, tex);
 }
 
+// As documented in libhardware header, formats in the range
+// 0x100 - 0x1FF are specific to the HAL implementation, and
+// are known to have no alpha channel
+// TODO: move definition for device-specific range into
+// hardware.h, instead of using hard-coded values here.
+#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
+
+bool Layer::needsBlending(const sp<GraphicBuffer>& buffer) const
+{
+    // If buffers where set with eOpaque flag, all buffers are known to
+    // be opaque without having to check their actual format
+    if (mNeedsBlending && buffer != NULL) {
+        PixelFormat format = buffer->getPixelFormat();
+
+        if (HARDWARE_IS_DEVICE_FORMAT(format)) {
+            return false;
+        }
+
+        PixelFormatInfo info;
+        status_t err = getPixelFormatInfo(format, &info);
+        if (!err && info.h_alpha <= info.l_alpha) {
+            return false;
+        }
+    }
+
+    // Return opacity as determined from flags and format options
+    // passed to setBuffers()
+    return mNeedsBlending;
+}
+
+bool Layer::needsBlending() const
+{
+    if (mBufferManager.hasActiveBuffer()) {
+        return needsBlending(mBufferManager.getActiveBuffer());
+    }
+
+    return mNeedsBlending;
+}
+
 bool Layer::needsFiltering() const
 {
     if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
@@ -290,6 +390,12 @@
     return LayerBase::needsFiltering();
 }
 
+bool Layer::isProtected() const
+{
+    sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer());
+    return (activeBuffer != 0) &&
+            (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+}
 
 status_t Layer::setBufferCount(int bufferCount)
 {
@@ -302,8 +408,10 @@
 
     // NOTE: lcblk->resize() is protected by an internal lock
     status_t err = lcblk->resize(bufferCount);
-    if (err == NO_ERROR)
-        mBufferManager.resize(bufferCount);
+    if (err == NO_ERROR) {
+        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+        mBufferManager.resize(bufferCount, mFlinger, dpy);
+    }
 
     return err;
 }
@@ -335,14 +443,13 @@
      * buffer 'index' as our front buffer.
      */
 
-    uint32_t w, h, f, bypass;
+    status_t err = NO_ERROR;
+    uint32_t w, h, f;
     { // scope for the lock
         Mutex::Autolock _l(mLock);
 
-        bypass = mBypassState;
-
         // zero means default
-        mFixedSize = reqWidth && reqHeight;
+        const bool fixedSize = reqWidth && reqHeight;
         if (!reqFormat) reqFormat = mFormat;
         if (!reqWidth)  reqWidth = mWidth;
         if (!reqHeight) reqHeight = mHeight;
@@ -356,6 +463,7 @@
             mReqWidth  = reqWidth;
             mReqHeight = reqHeight;
             mReqFormat = reqFormat;
+            mFixedSize = fixedSize;
             mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
 
             lcblk->reallocateAllExcept(index);
@@ -365,40 +473,9 @@
     // here we have to reallocate a new buffer because the buffer could be
     // used as the front buffer, or by a client in our process
     // (eg: status bar), and we can't release the handle under its feet.
-    uint32_t effectiveUsage = getEffectiveUsage(usage);
-
-    status_t err = NO_MEMORY;
-
-#ifdef USE_COMPOSITION_BYPASS
-    if (!mSecure && bypass && (effectiveUsage & GRALLOC_USAGE_HW_RENDER)) {
-        // always allocate a buffer matching the screen size. the size
-        // may be different from (w,h) if the buffer is rotated.
-        const DisplayHardware& hw(graphicPlane(0).displayHardware());
-        int32_t w = hw.getWidth();
-        int32_t h = hw.getHeight();
-        int32_t f = hw.getFormat();
-
-        buffer = new GraphicBuffer(w, h, f, effectiveUsage | GRALLOC_USAGE_HW_FB);
-        err = buffer->initCheck();
-        buffer->transform = uint8_t(getOrientation());
-
-        if (err != NO_ERROR) {
-            // allocation didn't succeed, probably because an older bypass
-            // window hasn't released all its resources yet.
-            ClientRef::Access sharedClient(mUserClientRef);
-            SharedBufferServer* lcblk(sharedClient.get());
-            if (lcblk) {
-                // all buffers need reallocation
-                lcblk->reallocateAll();
-            }
-        }
-    }
-#endif
-
-    if (err != NO_ERROR) {
-        buffer = new GraphicBuffer(w, h, f, effectiveUsage);
-        err = buffer->initCheck();
-    }
+    const uint32_t effectiveUsage = getEffectiveUsage(usage);
+    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
+    err = buffer->initCheck();
 
     if (err || buffer->handle == 0) {
         GraphicBuffer::dumpAllocationsToSystemLog();
@@ -442,42 +519,13 @@
         // request EGLImage for all buffers
         usage |= GraphicBuffer::USAGE_HW_TEXTURE;
     }
+    if (mProtectedByApp) {
+        // need a hardware-protected path to external video sink
+        usage |= GraphicBuffer::USAGE_PROTECTED;
+    }
     return usage;
 }
 
-bool Layer::setBypass(bool enable)
-{
-    Mutex::Autolock _l(mLock);
-
-    if (mNeedsScaling || mNeedsFiltering) {
-        return false;
-    }
-
-    if (mBypassState != enable) {
-        mBypassState = enable;
-        ClientRef::Access sharedClient(mUserClientRef);
-        SharedBufferServer* lcblk(sharedClient.get());
-        if (lcblk) {
-            // all buffers need reallocation
-            lcblk->reallocateAll();
-        }
-    }
-
-    return true;
-}
-
-void Layer::updateBuffersOrientation()
-{
-    sp<GraphicBuffer> buffer(getBypassBuffer());
-    if (buffer != NULL && mOrientation != buffer->transform) {
-        ClientRef::Access sharedClient(mUserClientRef);
-        SharedBufferServer* lcblk(sharedClient.get());
-        if (lcblk) { // all buffers need reallocation
-            lcblk->reallocateAll();
-        }
-    }
-}
-
 uint32_t Layer::doTransaction(uint32_t flags)
 {
     const Layer::State& front(drawingState());
@@ -581,14 +629,31 @@
     }
 
     // we retired a buffer, which becomes the new front buffer
+
+    const bool noActiveBuffer = !mBufferManager.hasActiveBuffer();
+    const bool activeBlending =
+            noActiveBuffer ? true : needsBlending(mBufferManager.getActiveBuffer());
+
     if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
         LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
         mPostedDirtyRegion.clear();
         return;
     }
 
+    if (noActiveBuffer) {
+        // we didn't have an active buffer, we need to recompute
+        // our visible region
+        recomputeVisibleRegions = true;
+    }
+
     sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
     if (newFrontBuffer != NULL) {
+        if (!noActiveBuffer && activeBlending != needsBlending(newFrontBuffer)) {
+            // new buffer has different opacity than previous active buffer, need
+            // to recompute visible regions accordingly
+            recomputeVisibleRegions = true;
+        }
+
         // get the dirty region
         // compute the posted region
         const Region dirty(lcblk->getDirtyRegion(buf));
@@ -712,9 +777,9 @@
     snprintf(buffer, SIZE,
             "      "
             "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
-            " freezeLock=%p, bypass=%d, dq-q-time=%u us\n",
+            " freezeLock=%p, dq-q-time=%u us\n",
             mFormat, w0, h0, s0, w1, h1, s1,
-            getFreezeLock().get(), mBypassState, totalTime);
+            getFreezeLock().get(), totalTime);
 
     result.append(buffer);
 }
@@ -744,7 +809,7 @@
 
     { // scope for strong mUserClient reference
         sp<UserClient> userClient(mUserClient.promote());
-        if (mUserClient != 0 && mControlBlock != 0) {
+        if (userClient != 0 && mControlBlock != 0) {
             mControlBlock->setStatus(NO_INIT);
         }
     }
@@ -779,7 +844,7 @@
 
 Layer::BufferManager::BufferManager(TextureManager& tm)
     : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
-      mActiveBuffer(-1), mFailover(false)
+      mActiveBufferIndex(-1), mFailover(false)
 {
 }
 
@@ -787,9 +852,54 @@
 {
 }
 
-status_t Layer::BufferManager::resize(size_t size)
+status_t Layer::BufferManager::resize(size_t size,
+        const sp<SurfaceFlinger>& flinger, EGLDisplay dpy)
 {
     Mutex::Autolock _l(mLock);
+
+    if (size < mNumBuffers) {
+        // If there is an active texture, move it into slot 0 if needed
+        if (mActiveBufferIndex > 0) {
+            BufferData activeBufferData = mBufferData[mActiveBufferIndex];
+            mBufferData[mActiveBufferIndex] = mBufferData[0];
+            mBufferData[0] = activeBufferData;
+            mActiveBufferIndex = 0;
+        }
+
+        // Free the buffers that are no longer needed.
+        for (size_t i = size; i < mNumBuffers; i++) {
+            mBufferData[i].buffer = 0;
+
+            // Create a message to destroy the textures on SurfaceFlinger's GL
+            // thread.
+            class MessageDestroyTexture : public MessageBase {
+                Image mTexture;
+                EGLDisplay mDpy;
+             public:
+                MessageDestroyTexture(const Image& texture, EGLDisplay dpy)
+                    : mTexture(texture), mDpy(dpy) { }
+                virtual bool handler() {
+                    status_t err = Layer::BufferManager::destroyTexture(
+                            &mTexture, mDpy);
+                    LOGE_IF(err<0, "error destroying texture: %d (%s)",
+                            mTexture.name, strerror(-err));
+                    return true; // XXX: err == 0;  ????
+                }
+            };
+
+            MessageDestroyTexture *msg = new MessageDestroyTexture(
+                    mBufferData[i].texture, dpy);
+
+            // Don't allow this texture to be cleaned up by
+            // BufferManager::destroy.
+            mBufferData[i].texture.name = -1U;
+            mBufferData[i].texture.image = EGL_NO_IMAGE_KHR;
+
+            // Post the message to the SurfaceFlinger object.
+            flinger->postMessageAsync(msg);
+        }
+    }
+
     mNumBuffers = size;
     return NO_ERROR;
 }
@@ -800,33 +910,33 @@
 }
 
 status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
-    mActiveBuffer = index;
+    BufferData const * const buffers = mBufferData;
+    Mutex::Autolock _l(mLock);
+    mActiveBuffer = buffers[index].buffer;
+    mActiveBufferIndex = index;
     return NO_ERROR;
 }
 
 size_t Layer::BufferManager::getActiveBufferIndex() const {
-    return mActiveBuffer;
+    return mActiveBufferIndex;
 }
 
 Texture Layer::BufferManager::getActiveTexture() const {
     Texture res;
-    if (mFailover || mActiveBuffer<0) {
+    if (mFailover || mActiveBufferIndex<0) {
         res = mFailoverTexture;
     } else {
-        static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
+        static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture;
     }
     return res;
 }
 
 sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
-    sp<GraphicBuffer> result;
-    const ssize_t activeBuffer = mActiveBuffer;
-    if (activeBuffer >= 0) {
-        BufferData const * const buffers = mBufferData;
-        Mutex::Autolock _l(mLock);
-        result = buffers[activeBuffer].buffer;
-    }
-    return result;
+    return mActiveBuffer;
+}
+
+bool Layer::BufferManager::hasActiveBuffer() const {
+    return mActiveBufferIndex >= 0;
 }
 
 sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
@@ -871,7 +981,7 @@
         const sp<GraphicBuffer>& buffer)
 {
     status_t err = NO_INIT;
-    ssize_t index = mActiveBuffer;
+    ssize_t index = mActiveBufferIndex;
     if (index >= 0) {
         if (!mFailover) {
             Image& texture(mBufferData[index].texture);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7bb207a..128f93d 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -68,24 +68,22 @@
     bool isFixedSize() const;
 
     // LayerBase interface
+    virtual void setGeometry(hwc_layer_t* hwcl);
+    virtual void setPerFrameData(hwc_layer_t* hwcl);
     virtual void drawForSreenShot() const;
     virtual void onDraw(const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t transactionFlags);
     virtual void lockPageFlip(bool& recomputeVisibleRegions);
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-    virtual bool needsBlending() const      { return mNeedsBlending; }
+    virtual bool needsBlending(const sp<GraphicBuffer>& buffer) const;
+    virtual bool needsBlending() const;
     virtual bool needsDithering() const     { return mNeedsDithering; }
     virtual bool needsFiltering() const;
     virtual bool isSecure() const           { return mSecure; }
+    virtual bool isProtected() const;
     virtual sp<Surface> createSurface() const;
     virtual status_t ditch();
     virtual void onRemoved();
-    virtual bool setBypass(bool enable);
-
-    void updateBuffersOrientation();
-
-    inline sp<GraphicBuffer> getBypassBuffer() const {
-        return mBufferManager.getActiveBuffer(); }
 
     // only for debugging
     inline sp<GraphicBuffer> getBuffer(int i) const {
@@ -167,7 +165,8 @@
         size_t              mNumBuffers;
         Texture             mFailoverTexture;
         TextureManager&     mTextureManager;
-        ssize_t             mActiveBuffer;
+        ssize_t             mActiveBufferIndex;
+        sp<GraphicBuffer>   mActiveBuffer;
         bool                mFailover;
         static status_t destroyTexture(Image* tex, EGLDisplay dpy);
 
@@ -180,7 +179,8 @@
         sp<GraphicBuffer> detachBuffer(size_t index);
         status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer);
         // resize the number of active buffers
-        status_t resize(size_t size);
+        status_t resize(size_t size, const sp<SurfaceFlinger>& flinger,
+                EGLDisplay dpy);
 
         // ----------------------------------------------
         // must be called from GL thread
@@ -190,6 +190,8 @@
         size_t getActiveBufferIndex() const;
         // return the active buffer
         sp<GraphicBuffer> getActiveBuffer() const;
+        // return wether we have an active buffer
+        bool hasActiveBuffer() const;
         // return the active texture (or fail-over)
         Texture getActiveTexture() const;
         // frees resources associated with all buffers
@@ -211,14 +213,14 @@
     ClientRef mUserClientRef;
 
     // constants
-    sp<Surface> mSurface;
     PixelFormat mFormat;
     const GLExtensions& mGLExtensions;
     bool mNeedsBlending;
     bool mNeedsDithering;
 
     // page-flip thread (currently main thread)
-    bool mSecure;
+    bool mSecure;         // no screenshots
+    bool mProtectedByApp; // application requires protected path to external sink
     Region mPostedDirtyRegion;
 
     // page-flip thread and transaction thread (currently main thread)
@@ -237,7 +239,6 @@
     uint32_t mReqFormat;
     bool mNeedsScaling;
     bool mFixedSize;
-    bool mBypassState;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 21c36e1..6025ed4 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -301,6 +301,15 @@
     }
 }
 
+void LayerBase::setGeometry(hwc_layer_t* hwcl) {
+    hwcl->flags |= HWC_SKIP_LAYER;
+}
+
+void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
+    hwcl->compositionType = HWC_FRAMEBUFFER;
+    hwcl->handle = NULL;
+}
+
 void LayerBase::draw(const Region& clip) const
 {
     // reset GL state
@@ -489,13 +498,17 @@
 }
 
 void LayerBase::setBufferCrop(const Rect& crop) {
-    if (!crop.isEmpty()) {
+    if (mBufferCrop != crop) {
         mBufferCrop = crop;
+        mFlinger->invalidateHwcGeometry();
     }
 }
 
 void LayerBase::setBufferTransform(uint32_t transform) {
-    mBufferTransform = transform;
+    if (mBufferTransform != transform) {
+        mBufferTransform = transform;
+        mFlinger->invalidateHwcGeometry();
+    }
 }
 
 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
@@ -515,13 +528,21 @@
     result.append(buffer);
 }
 
+void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
+{
+    LayerBase::dump(result, scratch, size);
+}
+
+
 // ---------------------------------------------------------------------------
 
 int32_t LayerBaseClient::sIdentity = 1;
 
 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client)
-    : LayerBase(flinger, display), mClientRef(client),
+    : LayerBase(flinger, display),
+      mHasSurface(false),
+      mClientRef(client),
       mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
 {
 }
@@ -538,14 +559,20 @@
 {
     sp<Surface> s;
     Mutex::Autolock _l(mLock);
-    s = mClientSurface.promote();
-    if (s == 0) {
-        s = createSurface();
-        mClientSurface = s;
-    }
+
+    LOG_ALWAYS_FATAL_IF(mHasSurface,
+            "LayerBaseClient::getSurface() has already been called");
+
+    mHasSurface = true;
+    s = createSurface();
+    mClientSurfaceBinder = s->asBinder();
     return s;
 }
 
+wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
+    return mClientSurfaceBinder;
+}
+
 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
 {
     return new Surface(mFlinger, mIdentity,
@@ -566,6 +593,12 @@
     result.append(buffer);
 }
 
+
+void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
+{
+    LayerBaseClient::dump(result, scratch, size);
+}
+
 // ---------------------------------------------------------------------------
 
 LayerBaseClient::Surface::Surface(
@@ -597,21 +630,6 @@
 status_t LayerBaseClient::Surface::onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
-    switch (code) {
-        case REGISTER_BUFFERS:
-        case UNREGISTER_BUFFERS:
-        case CREATE_OVERLAY:
-        {
-            if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
-                IPCThreadState* ipc = IPCThreadState::self();
-                const int pid = ipc->getCallingPid();
-                const int uid = ipc->getCallingUid();
-                LOGE("Permission Denial: "
-                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-                return PERMISSION_DENIED;
-            }
-        }
-    }
     return BnSurface::onTransact(code, data, reply, flags);
 }
 
@@ -626,26 +644,6 @@
     return INVALID_OPERATION;
 }
 
-status_t LayerBaseClient::Surface::registerBuffers(
-        const ISurface::BufferHeap& buffers) 
-{ 
-    return INVALID_OPERATION; 
-}
-
-void LayerBaseClient::Surface::postBuffer(ssize_t offset) 
-{
-}
-
-void LayerBaseClient::Surface::unregisterBuffers() 
-{
-}
-
-sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
-        uint32_t w, uint32_t h, int32_t format, int32_t orientation)
-{
-    return NULL;
-};
-
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index afc5ec8..7162e47 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -27,7 +27,6 @@
 #include <utils/RefBase.h>
 
 #include <ui/Region.h>
-#include <ui/Overlay.h>
 
 #include <surfaceflinger/ISurfaceComposerClient.h>
 #include <private/surfaceflinger/SharedBufferStack.h>
@@ -35,6 +34,8 @@
 
 #include <pixelflinger/pixelflinger.h>
 
+#include <hardware/hwcomposer.h>
+
 #include "DisplayHardware/DisplayHardware.h"
 #include "Transform.h"
 
@@ -109,6 +110,10 @@
 
     virtual const char* getTypeId() const { return "LayerBase"; }
 
+    virtual void setGeometry(hwc_layer_t* hwcl);
+
+    virtual void setPerFrameData(hwc_layer_t* hwcl);
+
     /**
      * draw - performs some global clipping optimizations
      * and calls onDraw().
@@ -119,11 +124,6 @@
     virtual void drawForSreenShot() const;
     
     /**
-     * bypass mode
-     */
-    virtual bool setBypass(bool enable) { return false; }
-
-    /**
      * onDraw - draws the surface.
      */
     virtual void onDraw(const Region& clip) const = 0;
@@ -196,6 +196,12 @@
      */
     virtual bool isSecure() const       { return false; }
 
+    /**
+     * isProtected - true if the layer may contain protected content in the
+     * GRALLOC_USAGE_PROTECTED sense.
+     */
+    virtual bool isProtected() const   { return false; }
+
     /** Called from the main thread, when the surface is removed from the
      * draw list */
     virtual status_t ditch() { return NO_ERROR; }
@@ -206,6 +212,7 @@
     
     /** always call base class first */
     virtual void dump(String8& result, char* scratch, size_t size) const;
+    virtual void shortDump(String8& result, char* scratch, size_t size) const;
 
 
     enum { // flags for doTransaction()
@@ -284,6 +291,7 @@
     virtual ~LayerBaseClient();
 
             sp<Surface> getSurface();
+            wp<IBinder> getSurfaceBinder() const;
     virtual sp<Surface> createSurface() const;
     virtual sp<LayerBaseClient> getLayerBaseClient() const {
         return const_cast<LayerBaseClient*>(this); }
@@ -308,12 +316,6 @@
                 uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
         virtual status_t setBufferCount(int bufferCount);
 
-        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); 
-        virtual void postBuffer(ssize_t offset);
-        virtual void unregisterBuffers();
-        virtual sp<OverlayRef> createOverlay(uint32_t w, uint32_t h,
-                int32_t format, int32_t orientation);
-
     protected:
         friend class LayerBaseClient;
         sp<SurfaceFlinger>  mFlinger;
@@ -325,10 +327,12 @@
 
 protected:
     virtual void dump(String8& result, char* scratch, size_t size) const;
+    virtual void shortDump(String8& result, char* scratch, size_t size) const;
 
 private:
     mutable Mutex mLock;
-    mutable wp<Surface> mClientSurface;
+    mutable bool mHasSurface;
+    wp<IBinder> mClientSurfaceBinder;
     const wp<Client> mClientRef;
     // only read
     const uint32_t mIdentity;
diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp
deleted file mode 100644
index 4cfcfe3..0000000
--- a/services/surfaceflinger/LayerBlur.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include "clz.h"
-#include "BlurFilter.h"
-#include "LayerBlur.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client)
-    : LayerBaseClient(flinger, display, client), mCacheDirty(true),
-          mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
-          mWidthScale(1.0f), mHeightScale(1.0f),
-          mBlurFormat(GGL_PIXEL_FORMAT_RGB_565)
-{
-}
-
-LayerBlur::~LayerBlur()
-{
-    if (mTextureName != -1U) {
-        glDeleteTextures(1, &mTextureName);
-    }
-}
-
-void LayerBlur::setVisibleRegion(const Region& visibleRegion)
-{
-    LayerBaseClient::setVisibleRegion(visibleRegion);
-    if (visibleRegionScreen.isEmpty()) {
-        if (mTextureName != -1U) {
-            // We're not visible, free the texture up.
-            glBindTexture(GL_TEXTURE_2D, 0);
-            glDeleteTextures(1, &mTextureName);
-            mTextureName = -1U;
-        }
-    }
-}
-
-uint32_t LayerBlur::doTransaction(uint32_t flags)
-{
-    // we're doing a transaction, refresh the cache!
-    if (!mFlinger->isFrozen()) {
-        mRefreshCache = true;
-        mCacheDirty = true;
-        flags |= eVisibleRegion;
-        this->contentDirty = true;
-    }
-    return LayerBase::doTransaction(flags);    
-}
-
-void LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion)
-{
-    // this code-path must be as tight as possible, it's called each time
-    // the screen is composited.
-    if (UNLIKELY(!visibleRegionScreen.isEmpty())) {
-        // if anything visible below us is invalidated, the cache becomes dirty
-        if (!mCacheDirty && 
-                !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) {
-            mCacheDirty = true;
-        }
-        if (mCacheDirty) {
-            if (!mFlinger->isFrozen()) {
-                // update everything below us that is visible
-                outDirtyRegion.orSelf(visibleRegionScreen);
-                nsecs_t now = systemTime();
-                if ((now - mCacheAge) >= ms2ns(500)) {
-                    mCacheAge = now;
-                    mRefreshCache = true;
-                    mCacheDirty = false;
-                } else {
-                    if (!mAutoRefreshPending) {
-                        mFlinger->postMessageAsync(
-                                new MessageBase(MessageQueue::INVALIDATE),
-                                ms2ns(500));
-                        mAutoRefreshPending = true;
-                    }
-                }
-            }
-        }
-    }
-    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
-}
-
-void LayerBlur::onDraw(const Region& clip) const
-{
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    const uint32_t fbHeight = hw.getHeight();
-    int x = mTransformedBounds.left;
-    int y = mTransformedBounds.top;
-    int w = mTransformedBounds.width();
-    int h = mTransformedBounds.height();
-    GLint X = x;
-    GLint Y = fbHeight - (y + h);
-    if (X < 0) {
-        w += X;
-        X = 0;
-    }
-    if (Y < 0) {
-        h += Y;
-        Y = 0;
-    }
-    if (w<0 || h<0) {
-        // we're outside of the framebuffer
-        return;
-    }
-
-    if (mTextureName == -1U) {
-        // create the texture name the first time
-        // can't do that in the ctor, because it runs in another thread.
-        glGenTextures(1, &mTextureName);
-        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat);
-        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType);
-        if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) {
-            mReadFormat = GL_RGBA;
-            mReadType = GL_UNSIGNED_BYTE;
-            mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888;
-        }
-    }
-
-    Region::const_iterator it = clip.begin();
-    Region::const_iterator const end = clip.end();
-    if (it != end) {
-#if defined(GL_OES_EGL_image_external)
-        if (GLExtensions::getInstance().haveTextureExternal()) {
-            glDisable(GL_TEXTURE_EXTERNAL_OES);
-        }
-#endif
-        glEnable(GL_TEXTURE_2D);
-        glBindTexture(GL_TEXTURE_2D, mTextureName);
-
-        if (mRefreshCache) {
-            mRefreshCache = false;
-            mAutoRefreshPending = false;
-
-            int32_t pixelSize = 4;
-            int32_t s = w;
-            if (mReadType == GL_UNSIGNED_SHORT_5_6_5) {
-                // allocate enough memory for 4-bytes (2 pixels) aligned data
-                s = (w + 1) & ~1;
-                pixelSize = 2;
-            }
-
-            uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize);
-
-            // This reads the frame-buffer, so a h/w GL would have to
-            // finish() its rendering first. we don't want to do that
-            // too often. Read data is 4-bytes aligned.
-            glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels);
-
-            // blur that texture.
-            GGLSurface bl;
-            bl.version = sizeof(GGLSurface);
-            bl.width = w;
-            bl.height = h;
-            bl.stride = s;
-            bl.format = mBlurFormat;
-            bl.data = (GGLubyte*)pixels;            
-            blurFilter(&bl, 8, 2);
-
-            if (GLExtensions::getInstance().haveNpot()) {
-                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0,
-                        mReadFormat, mReadType, pixels);
-                mWidthScale  = 1.0f / w;
-                mHeightScale =-1.0f / h;
-                mYOffset = 0;
-            } else {
-                GLuint tw = 1 << (31 - clz(w));
-                GLuint th = 1 << (31 - clz(h));
-                if (tw < GLuint(w)) tw <<= 1;
-                if (th < GLuint(h)) th <<= 1;
-                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0,
-                        mReadFormat, mReadType, NULL);
-                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, 
-                        mReadFormat, mReadType, pixels);
-                mWidthScale  = 1.0f / tw;
-                mHeightScale =-1.0f / th;
-                mYOffset = th-h;
-            }
-
-            free((void*)pixels);
-        }
-
-        const State& s = drawingState();
-        if (UNLIKELY(s.alpha < 0xFF)) {
-            const GLfloat alpha = s.alpha * (1.0f/255.0f);
-            glColor4f(0, 0, 0, alpha);
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-            glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        } else {
-            glDisable(GL_BLEND);
-        }
-
-        if (mFlags & DisplayHardware::SLOW_CONFIG) {
-            glDisable(GL_DITHER);
-        } else {
-            glEnable(GL_DITHER);
-        }
-
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-        glMatrixMode(GL_TEXTURE);
-        glLoadIdentity();
-        glScalef(mWidthScale, mHeightScale, 1);
-        glTranslatef(-x, mYOffset - y, 0);
-        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-        glVertexPointer(2, GL_FLOAT, 0, mVertices);
-        glTexCoordPointer(2, GL_FLOAT, 0, mVertices);
-        while (it != end) {
-            const Rect& r = *it++;
-            const GLint sy = fbHeight - (r.top + r.height());
-            glScissor(r.left, sy, r.width(), r.height());
-            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-        }
-        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-        glLoadIdentity();
-        glMatrixMode(GL_MODELVIEW);
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/surfaceflinger/LayerBlur.h b/services/surfaceflinger/LayerBlur.h
deleted file mode 100644
index 4c9ec64..0000000
--- a/services/surfaceflinger/LayerBlur.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007 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_LAYER_BLUR_H
-#define ANDROID_LAYER_BLUR_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/Region.h>
-
-#include "LayerBase.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class LayerBlur : public LayerBaseClient
-{
-public:    
-                LayerBlur(SurfaceFlinger* flinger, DisplayID display,
-                        const sp<Client>& client);
-        virtual ~LayerBlur();
-
-    virtual void onDraw(const Region& clip) const;
-    virtual bool needsBlending() const  { return true; }
-    virtual bool isSecure() const       { return false; }
-    virtual const char* getTypeId() const { return "LayerBlur"; }
-
-    virtual uint32_t doTransaction(uint32_t flags);
-    virtual void setVisibleRegion(const Region& visibleRegion);
-    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-
-private:
-            bool    mCacheDirty;
-    mutable bool    mRefreshCache;
-    mutable bool    mAutoRefreshPending;
-            nsecs_t mCacheAge;
-    mutable GLuint  mTextureName;
-    mutable GLfloat mWidthScale;
-    mutable GLfloat mHeightScale;
-    mutable GLfloat mYOffset;
-    mutable GLint   mReadFormat;
-    mutable GLint   mReadType;
-    mutable uint32_t mBlurFormat;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BLUR_H
diff --git a/services/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp
deleted file mode 100644
index 23506cf..0000000
--- a/services/surfaceflinger/LayerBuffer.cpp
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdlib.h>
-#include <stdint.h>
-#include <math.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-#include <ui/FramebufferNativeWindow.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-
-#include <hardware/copybit.h>
-
-#include "LayerBuffer.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client)
-    : LayerBaseClient(flinger, display, client),
-      mNeedsBlending(false), mBlitEngine(0)
-{
-}
-
-LayerBuffer::~LayerBuffer()
-{
-    if (mBlitEngine) {
-        copybit_close(mBlitEngine);
-    }
-}
-
-void LayerBuffer::onFirstRef()
-{
-    LayerBaseClient::onFirstRef();
-    mSurface = new SurfaceLayerBuffer(mFlinger, this);
-
-    hw_module_t const* module = (hw_module_t const*)sGrallocModule;
-    if (!module) {
-        // NOTE: technically there is a race here, but it shouldn't
-        // cause any problem since hw_get_module() always returns
-        // the same value.
-        if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
-            sGrallocModule = (gralloc_module_t const *)module;
-        }
-    }
-
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        copybit_open(module, &mBlitEngine);
-    }
-}
-
-sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
-{
-    return mSurface;
-}
-
-status_t LayerBuffer::ditch()
-{
-    mSurface.clear();
-    return NO_ERROR;
-}
-
-bool LayerBuffer::needsBlending() const {
-    return mNeedsBlending;
-}
-
-void LayerBuffer::setNeedsBlending(bool blending) {
-    mNeedsBlending = blending;
-}
-
-void LayerBuffer::postBuffer(ssize_t offset)
-{
-    sp<Source> source(getSource());
-    if (source != 0)
-        source->postBuffer(offset);
-}
-
-void LayerBuffer::unregisterBuffers()
-{
-    sp<Source> source(clearSource());
-    if (source != 0)
-        source->unregisterBuffers();
-}
-
-uint32_t LayerBuffer::doTransaction(uint32_t flags)
-{
-    sp<Source> source(getSource());
-    if (source != 0)
-        source->onTransaction(flags);
-    uint32_t res = LayerBase::doTransaction(flags);
-    // we always want filtering for these surfaces
-    mNeedsFiltering = !(mFlags & DisplayHardware::SLOW_CONFIG);
-    return res;
-}
-
-void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
-        Region& outDirtyRegion)
-{
-    // this code-path must be as tight as possible, it's called each time
-    // the screen is composited.
-    sp<Source> source(getSource());
-    if (source != 0)
-        source->onVisibilityResolved(planeTransform);
-    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);    
-}
-
-void LayerBuffer::validateVisibility(const Transform& globalTransform)
-{
-    sp<Source> source(getSource());
-    if (source != 0)
-        source->onvalidateVisibility(globalTransform);
-    LayerBase::validateVisibility(globalTransform);
-}
-
-void LayerBuffer::drawForSreenShot() const
-{
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    clearWithOpenGL( Region(hw.bounds()) );
-}
-
-void LayerBuffer::onDraw(const Region& clip) const
-{
-    sp<Source> source(getSource());
-    if (LIKELY(source != 0)) {
-        source->onDraw(clip);
-    } else {
-        clearWithOpenGL(clip);
-    }
-}
-
-void LayerBuffer::serverDestroy()
-{
-    sp<Source> source(clearSource());
-    if (source != 0) {
-        source->destroy();
-    }
-}
-
-/**
- * This creates a "buffer" source for this surface
- */
-status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
-{
-    Mutex::Autolock _l(mLock);
-    if (mSource != 0)
-        return INVALID_OPERATION;
-
-    sp<BufferSource> source = new BufferSource(*this, buffers);
-
-    status_t result = source->getStatus();
-    if (result == NO_ERROR) {
-        mSource = source;
-    }
-    return result;
-}    
-
-/**
- * This creates an "overlay" source for this surface
- */
-sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f,
-        int32_t orientation)
-{
-    sp<OverlayRef> result;
-    Mutex::Autolock _l(mLock);
-    if (mSource != 0)
-        return result;
-
-    sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f, orientation);
-    if (result != 0) {
-        mSource = source;
-    }
-    return result;
-}
-
-sp<LayerBuffer::Source> LayerBuffer::getSource() const {
-    Mutex::Autolock _l(mLock);
-    return mSource;
-}
-
-sp<LayerBuffer::Source> LayerBuffer::clearSource() {
-    sp<Source> source;
-    Mutex::Autolock _l(mLock);
-    source = mSource;
-    mSource.clear();
-    return source;
-}
-
-// ============================================================================
-// LayerBuffer::SurfaceLayerBuffer
-// ============================================================================
-
-LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(
-        const sp<SurfaceFlinger>& flinger, const sp<LayerBuffer>& owner)
-    : LayerBaseClient::Surface(flinger, owner->getIdentity(), owner)
-{
-}
-
-LayerBuffer::SurfaceLayerBuffer::~SurfaceLayerBuffer()
-{
-    unregisterBuffers();
-}
-
-status_t LayerBuffer::SurfaceLayerBuffer::registerBuffers(
-        const ISurface::BufferHeap& buffers)
-{
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        return owner->registerBuffers(buffers);
-    return NO_INIT;
-}
-
-void LayerBuffer::SurfaceLayerBuffer::postBuffer(ssize_t offset)
-{
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        owner->postBuffer(offset);
-}
-
-void LayerBuffer::SurfaceLayerBuffer::unregisterBuffers()
-{
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        owner->unregisterBuffers();
-}
-
-sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(
-        uint32_t w, uint32_t h, int32_t format, int32_t orientation) {
-    sp<OverlayRef> result;
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        result = owner->createOverlay(w, h, format, orientation);
-    return result;
-}
-
-// ============================================================================
-// LayerBuffer::Buffer
-// ============================================================================
-
-LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers,
-        ssize_t offset, size_t bufferSize)
-    : mBufferHeap(buffers), mSupportsCopybit(false)
-{
-    NativeBuffer& src(mNativeBuffer);
-    src.crop.l = 0;
-    src.crop.t = 0;
-    src.crop.r = buffers.w;
-    src.crop.b = buffers.h;
-
-    src.img.w       = buffers.hor_stride ?: buffers.w;
-    src.img.h       = buffers.ver_stride ?: buffers.h;
-    src.img.format  = buffers.format;
-    src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
-    src.img.handle  = 0;
-
-    gralloc_module_t const * module = LayerBuffer::getGrallocModule();
-    if (module && module->perform) {
-        int err = module->perform(module,
-                GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
-                buffers.heap->heapID(), bufferSize,
-                offset, buffers.heap->base(),
-                &src.img.handle);
-
-        // we can fail here is the passed buffer is purely software
-        mSupportsCopybit = (err == NO_ERROR);
-    }
- }
-
-LayerBuffer::Buffer::~Buffer()
-{
-    NativeBuffer& src(mNativeBuffer);
-    if (src.img.handle) {
-        native_handle_delete(src.img.handle);
-    }
-}
-
-// ============================================================================
-// LayerBuffer::Source
-// LayerBuffer::BufferSource
-// LayerBuffer::OverlaySource
-// ============================================================================
-
-LayerBuffer::Source::Source(LayerBuffer& layer)
-    : mLayer(layer)
-{    
-}
-LayerBuffer::Source::~Source() {    
-}
-void LayerBuffer::Source::onDraw(const Region& clip) const {
-}
-void LayerBuffer::Source::onTransaction(uint32_t flags) {
-}
-void LayerBuffer::Source::onVisibilityResolved(
-        const Transform& planeTransform) {
-}
-void LayerBuffer::Source::postBuffer(ssize_t offset) {
-}
-void LayerBuffer::Source::unregisterBuffers() {
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
-        const ISurface::BufferHeap& buffers)
-    : Source(layer), mStatus(NO_ERROR), mBufferSize(0)
-{
-    if (buffers.heap == NULL) {
-        // this is allowed, but in this case, it is illegal to receive
-        // postBuffer(). The surface just erases the framebuffer with
-        // fully transparent pixels.
-        mBufferHeap = buffers;
-        mLayer.setNeedsBlending(false);
-        return;
-    }
-
-    status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
-    if (err != NO_ERROR) {
-        LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
-        mStatus = err;
-        return;
-    }
-    
-    PixelFormatInfo info;
-    err = getPixelFormatInfo(buffers.format, &info);
-    if (err != NO_ERROR) {
-        LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
-                buffers.format, strerror(err));
-        mStatus = err;
-        return;
-    }
-
-    if (buffers.hor_stride<0 || buffers.ver_stride<0) {
-        LOGE("LayerBuffer::BufferSource: invalid parameters "
-             "(w=%d, h=%d, xs=%d, ys=%d)", 
-             buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
-        mStatus = BAD_VALUE;
-        return;
-    }
-
-    mBufferHeap = buffers;
-    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
-    mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
-    mLayer.forceVisibilityTransaction();
-}
-
-LayerBuffer::BufferSource::~BufferSource()
-{    
-    class MessageDestroyTexture : public MessageBase {
-        SurfaceFlinger* flinger;
-        GLuint name;
-    public:
-        MessageDestroyTexture(
-                SurfaceFlinger* flinger, GLuint name)
-            : flinger(flinger), name(name) { }
-        virtual bool handler() {
-            glDeleteTextures(1, &name);
-            return true;
-        }
-    };
-
-    if (mTexture.name != -1U) {
-        // GL textures can only be destroyed from the GL thread
-        getFlinger()->mEventQueue.postMessage(
-                new MessageDestroyTexture(getFlinger(), mTexture.name) );
-    }
-    if (mTexture.image != EGL_NO_IMAGE_KHR) {
-        EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
-        eglDestroyImageKHR(dpy, mTexture.image);
-    }
-}
-
-void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
-{    
-    ISurface::BufferHeap buffers;
-    { // scope for the lock
-        Mutex::Autolock _l(mBufferSourceLock);
-        buffers = mBufferHeap;
-        if (buffers.heap != 0) {
-            const size_t memorySize = buffers.heap->getSize();
-            if ((size_t(offset) + mBufferSize) > memorySize) {
-                LOGE("LayerBuffer::BufferSource::postBuffer() "
-                     "invalid buffer (offset=%d, size=%d, heap-size=%d",
-                     int(offset), int(mBufferSize), int(memorySize));
-                return;
-            }
-        }
-    }
-
-    sp<Buffer> buffer;
-    if (buffers.heap != 0) {
-        buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize);
-        if (buffer->getStatus() != NO_ERROR)
-            buffer.clear();
-        setBuffer(buffer);
-        mLayer.invalidate();
-    }
-}
-
-void LayerBuffer::BufferSource::unregisterBuffers()
-{
-    Mutex::Autolock _l(mBufferSourceLock);
-    mBufferHeap.heap.clear();
-    mBuffer.clear();
-    mLayer.invalidate();
-}
-
-sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
-{
-    Mutex::Autolock _l(mBufferSourceLock);
-    return mBuffer;
-}
-
-void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
-{
-    Mutex::Autolock _l(mBufferSourceLock);
-    mBuffer = buffer;
-}
-
-void LayerBuffer::BufferSource::onDraw(const Region& clip) const 
-{
-    sp<Buffer> ourBuffer(getBuffer());
-    if (UNLIKELY(ourBuffer == 0))  {
-        // nothing to do, we don't have a buffer
-        mLayer.clearWithOpenGL(clip);
-        return;
-    }
-
-    status_t err = NO_ERROR;
-    NativeBuffer src(ourBuffer->getBuffer());
-    const Rect transformedBounds(mLayer.getTransformedBounds());
-
-#if defined(EGL_ANDROID_image_native_buffer)
-    if (GLExtensions::getInstance().haveDirectTexture()) {
-        err = INVALID_OPERATION;
-        if (ourBuffer->supportsCopybit()) {
-            copybit_device_t* copybit = mLayer.mBlitEngine;
-            if (copybit && err != NO_ERROR) {
-                // create our EGLImageKHR the first time
-                err = initTempBuffer();
-                if (err == NO_ERROR) {
-                    // NOTE: Assume the buffer is allocated with the proper USAGE flags
-                    const NativeBuffer& dst(mTempBuffer);
-                    region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b)));
-                    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-                    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-                    copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-                    err = copybit->stretch(copybit, &dst.img, &src.img,
-                            &dst.crop, &src.crop, &clip);
-                    if (err != NO_ERROR) {
-                        clearTempBufferImage();
-                    }
-                }
-            }
-        }
-    }
-#endif
-    else {
-        err = INVALID_OPERATION;
-    }
-
-    if (err != NO_ERROR) {
-        // slower fallback
-        GGLSurface t;
-        t.version = sizeof(GGLSurface);
-        t.width  = src.crop.r;
-        t.height = src.crop.b;
-        t.stride = src.img.w;
-        t.vstride= src.img.h;
-        t.format = src.img.format;
-        t.data = (GGLubyte*)src.img.base;
-        const Region dirty(Rect(t.width, t.height));
-        mTextureManager.loadTexture(&mTexture, dirty, t);
-    }
-
-    mLayer.setBufferTransform(mBufferHeap.transform);
-    mLayer.drawWithOpenGL(clip, mTexture);
-}
-
-status_t LayerBuffer::BufferSource::initTempBuffer() const
-{
-    // figure out the size we need now
-    const ISurface::BufferHeap& buffers(mBufferHeap);
-    uint32_t w = mLayer.mTransformedBounds.width();
-    uint32_t h = mLayer.mTransformedBounds.height();
-    if (mLayer.getOrientation() & (Transform::ROT_90 | Transform::ROT_270)) {
-        int t = w; w = h; h = t;
-    }
-
-    // we're in the copybit case, so make sure we can handle this blit
-    // we don't have to keep the aspect ratio here
-    copybit_device_t* copybit = mLayer.mBlitEngine;
-    const int down = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
-    const int up = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
-    if (buffers.w > w*down)     w = buffers.w / down;
-    else if (w > buffers.w*up)  w = buffers.w*up;
-    if (buffers.h > h*down)     h = buffers.h / down;
-    else if (h > buffers.h*up)  h = buffers.h*up;
-
-    if (mTexture.image != EGL_NO_IMAGE_KHR) {
-        // we have an EGLImage, make sure the needed size didn't change
-        if (w!=mTexture.width || h!= mTexture.height) {
-            // delete the EGLImage and texture
-            clearTempBufferImage();
-        } else {
-            // we're good, we have an EGLImageKHR and it's (still) the
-            // right size
-            return NO_ERROR;
-        }
-    }
-
-    // figure out if we need linear filtering
-    if (buffers.w * h == buffers.h * w) {
-        // same pixel area, don't use filtering
-        mLayer.mNeedsFiltering = false;
-    }
-
-    // Allocate a temporary buffer and create the corresponding EGLImageKHR
-    // once the EGLImage has been created we don't need the
-    // graphic buffer reference anymore.
-    sp<GraphicBuffer> buffer = new GraphicBuffer(
-            w, h, HAL_PIXEL_FORMAT_RGB_565,
-            GraphicBuffer::USAGE_HW_TEXTURE |
-            GraphicBuffer::USAGE_HW_2D);
-
-    status_t err = buffer->initCheck();
-    if (err == NO_ERROR) {
-        NativeBuffer& dst(mTempBuffer);
-        dst.img.w = buffer->getStride();
-        dst.img.h = h;
-        dst.img.format = buffer->getPixelFormat();
-        dst.img.handle = (native_handle_t *)buffer->handle;
-        dst.img.base = 0;
-        dst.crop.l = 0;
-        dst.crop.t = 0;
-        dst.crop.r = w;
-        dst.crop.b = h;
-
-        EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
-        err = mTextureManager.initEglImage(&mTexture, dpy, buffer);
-    }
-
-    return err;
-}
-
-void LayerBuffer::BufferSource::clearTempBufferImage() const
-{
-    // delete the image
-    EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
-    eglDestroyImageKHR(dpy, mTexture.image);
-
-    // and the associated texture (recreate a name)
-    glDeleteTextures(1, &mTexture.name);
-    Texture defaultTexture;
-    mTexture = defaultTexture;
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
-        sp<OverlayRef>* overlayRef, 
-        uint32_t w, uint32_t h, int32_t format, int32_t orientation)
-    : Source(layer), mVisibilityChanged(false),
-    mOverlay(0), mOverlayHandle(0), mOverlayDevice(0), mOrientation(orientation)
-{
-    overlay_control_device_t* overlay_dev = getFlinger()->getOverlayEngine();
-    if (overlay_dev == NULL) {
-        // overlays not supported
-        return;
-    }
-
-    mOverlayDevice = overlay_dev;
-    overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
-    if (overlay == NULL) {
-        // couldn't create the overlay (no memory? no more overlays?)
-        return;
-    }
-
-    // enable dithering...
-    overlay_dev->setParameter(overlay_dev, overlay, 
-            OVERLAY_DITHER, OVERLAY_ENABLE);
-
-    mOverlay = overlay;
-    mWidth = overlay->w;
-    mHeight = overlay->h;
-    mFormat = overlay->format; 
-    mWidthStride = overlay->w_stride;
-    mHeightStride = overlay->h_stride;
-    mInitialized = false;
-
-    mOverlayHandle = overlay->getHandleRef(overlay);
-    
-    sp<OverlayChannel> channel = new OverlayChannel( &layer );
-
-    *overlayRef = new OverlayRef(mOverlayHandle, channel,
-            mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
-    getFlinger()->signalEvent();
-}
-
-LayerBuffer::OverlaySource::~OverlaySource()
-{
-    if (mOverlay && mOverlayDevice) {
-        overlay_control_device_t* overlay_dev = mOverlayDevice;
-        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
-    }
-}
-
-void LayerBuffer::OverlaySource::onDraw(const Region& clip) const
-{
-    // this would be where the color-key would be set, should we need it.
-    GLclampf red = 0;
-    GLclampf green = 0;
-    GLclampf blue = 0;
-    mLayer.clearWithOpenGL(clip, red, green, blue, 0);
-}
-
-void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
-{
-    const Layer::State& front(mLayer.drawingState());
-    const Layer::State& temp(mLayer.currentState());
-    if (temp.sequence != front.sequence) {
-        mVisibilityChanged = true;
-    }
-}
-
-void LayerBuffer::OverlaySource::onvalidateVisibility(const Transform&)
-{
-    mVisibilityChanged = true;
-}
-
-void LayerBuffer::OverlaySource::onVisibilityResolved(
-        const Transform& planeTransform)
-{
-    // this code-path must be as tight as possible, it's called each time
-    // the screen is composited.
-    if (UNLIKELY(mOverlay != 0)) {
-        if (mVisibilityChanged || !mInitialized) {
-            mVisibilityChanged = false;
-            mInitialized = true;
-            const Rect bounds(mLayer.getTransformedBounds());
-            int x = bounds.left;
-            int y = bounds.top;
-            int w = bounds.width();
-            int h = bounds.height();
-            
-            // we need a lock here to protect "destroy"
-            Mutex::Autolock _l(mOverlaySourceLock);
-            if (mOverlay) {
-                overlay_control_device_t* overlay_dev = mOverlayDevice;
-                overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
-                // we need to combine the layer orientation and the
-                // user-requested orientation.
-                Transform finalTransform(Transform(mLayer.getOrientation()) *
-                        Transform(mOrientation));
-                overlay_dev->setParameter(overlay_dev, mOverlay,
-                        OVERLAY_TRANSFORM, finalTransform.getOrientation());
-                overlay_dev->commit(overlay_dev, mOverlay);
-            }
-        }
-    }
-}
-
-void LayerBuffer::OverlaySource::destroy()
-{
-    // we need a lock here to protect "onVisibilityResolved"
-    Mutex::Autolock _l(mOverlaySourceLock);
-    if (mOverlay && mOverlayDevice) {
-        overlay_control_device_t* overlay_dev = mOverlayDevice;
-        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
-        mOverlay = 0;
-    }
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/services/surfaceflinger/LayerBuffer.h b/services/surfaceflinger/LayerBuffer.h
deleted file mode 100644
index a89d8fe..0000000
--- a/services/surfaceflinger/LayerBuffer.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2007 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_LAYER_BUFFER_H
-#define ANDROID_LAYER_BUFFER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "LayerBase.h"
-#include "TextureManager.h"
-
-struct copybit_device_t;
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class Buffer;
-class Region;
-class OverlayRef;
-
-// ---------------------------------------------------------------------------
-
-class LayerBuffer : public LayerBaseClient
-{
-    class Source : public LightRefBase<Source> {
-    public:
-        Source(LayerBuffer& layer);
-        virtual ~Source();
-        virtual void onDraw(const Region& clip) const;
-        virtual void onTransaction(uint32_t flags);
-        virtual void onVisibilityResolved(const Transform& planeTransform);
-        virtual void onvalidateVisibility(const Transform& globalTransform) { }
-        virtual void postBuffer(ssize_t offset);
-        virtual void unregisterBuffers();
-        virtual void destroy() { }
-        SurfaceFlinger* getFlinger() const { return mLayer.mFlinger.get(); }
-    protected:
-        LayerBuffer& mLayer;
-    };
-
-public:
-            LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
-                    const sp<Client>& client);
-        virtual ~LayerBuffer();
-
-    virtual void onFirstRef();
-    virtual bool needsBlending() const;
-    virtual const char* getTypeId() const { return "LayerBuffer"; }
-
-    virtual sp<LayerBaseClient::Surface> createSurface() const;
-    virtual status_t ditch();
-    virtual void onDraw(const Region& clip) const;
-    virtual void drawForSreenShot() const;
-    virtual uint32_t doTransaction(uint32_t flags);
-    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-    virtual void validateVisibility(const Transform& globalTransform);
-
-    status_t registerBuffers(const ISurface::BufferHeap& buffers);
-    void postBuffer(ssize_t offset);
-    void unregisterBuffers();
-    sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format,
-            int32_t orientation);
-    
-    sp<Source> getSource() const;
-    sp<Source> clearSource();
-    void setNeedsBlending(bool blending);
-    Rect getTransformedBounds() const {
-        return mTransformedBounds;
-    }
-
-    void serverDestroy();
-
-private:
-    struct NativeBuffer {
-        copybit_image_t   img;
-        copybit_rect_t    crop;
-    };
-
-    static gralloc_module_t const* sGrallocModule;
-    static gralloc_module_t const* getGrallocModule() {
-        return sGrallocModule;
-    }
-
-    class Buffer : public LightRefBase<Buffer> {
-    public:
-        Buffer(const ISurface::BufferHeap& buffers,
-                ssize_t offset, size_t bufferSize);
-        inline bool supportsCopybit() const {
-            return mSupportsCopybit;
-        }
-        inline status_t getStatus() const {
-            return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT;
-        }
-        inline const NativeBuffer& getBuffer() const {
-            return mNativeBuffer;
-        }
-    protected:
-        friend class LightRefBase<Buffer>;
-        Buffer& operator = (const Buffer& rhs);
-        Buffer(const Buffer& rhs);
-        ~Buffer();
-    private:
-        ISurface::BufferHeap    mBufferHeap;
-        NativeBuffer            mNativeBuffer;
-        bool                    mSupportsCopybit;
-    };
-
-    class BufferSource : public Source {
-    public:
-        BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers);
-        virtual ~BufferSource();
-
-        status_t getStatus() const { return mStatus; }
-        sp<Buffer> getBuffer() const;
-        void setBuffer(const sp<Buffer>& buffer);
-
-        virtual void onDraw(const Region& clip) const;
-        virtual void postBuffer(ssize_t offset);
-        virtual void unregisterBuffers();
-        virtual void destroy() { }
-    private:
-        status_t initTempBuffer() const;
-        void clearTempBufferImage() const;
-        mutable Mutex                   mBufferSourceLock;
-        sp<Buffer>                      mBuffer;
-        status_t                        mStatus;
-        ISurface::BufferHeap            mBufferHeap;
-        size_t                          mBufferSize;
-        mutable Texture                 mTexture;
-        mutable NativeBuffer            mTempBuffer;
-        mutable TextureManager          mTextureManager;
-    };
-    
-    class OverlaySource : public Source {
-    public:
-        OverlaySource(LayerBuffer& layer,
-                sp<OverlayRef>* overlayRef, 
-                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
-        virtual ~OverlaySource();
-        virtual void onDraw(const Region& clip) const;
-        virtual void onTransaction(uint32_t flags);
-        virtual void onVisibilityResolved(const Transform& planeTransform);
-        virtual void onvalidateVisibility(const Transform& globalTransform);
-        virtual void destroy();
-    private:
-
-        class OverlayChannel : public BnOverlay {
-            wp<LayerBuffer> mLayer;
-            virtual void destroy() {
-                sp<LayerBuffer> layer(mLayer.promote());
-                if (layer != 0) {
-                    layer->serverDestroy();
-                }
-            }
-        public:
-            OverlayChannel(const sp<LayerBuffer>& layer)
-                : mLayer(layer) {
-            }
-        };
-        
-        friend class OverlayChannel;
-        bool mVisibilityChanged;
-
-        overlay_t* mOverlay;        
-        overlay_handle_t mOverlayHandle;
-        overlay_control_device_t* mOverlayDevice;
-        uint32_t mWidth;
-        uint32_t mHeight;
-        int32_t mFormat;
-        int32_t mWidthStride;
-        int32_t mHeightStride;
-        int32_t mOrientation;
-        mutable Mutex mOverlaySourceLock;
-        bool mInitialized;
-    };
-
-
-    class SurfaceLayerBuffer : public LayerBaseClient::Surface
-    {
-    public:
-        SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
-                        const sp<LayerBuffer>& owner);
-        virtual ~SurfaceLayerBuffer();
-
-        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
-        virtual void postBuffer(ssize_t offset);
-        virtual void unregisterBuffers();
-        
-        virtual sp<OverlayRef> createOverlay(
-                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
-    private:
-        sp<LayerBuffer> getOwner() const {
-            return static_cast<LayerBuffer*>(Surface::getOwner().get());
-        }
-    };
-
-    mutable Mutex   mLock;
-    sp<Source>      mSource;
-    sp<Surface>     mSurface;
-    bool            mInvalidate;
-    bool            mNeedsBlending;
-    copybit_device_t* mBlitEngine;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BUFFER_H
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 80cc52c..f79166d 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -30,29 +30,12 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-bool LayerDim::sUseTexture;
-GLuint LayerDim::sTexId;
-EGLImageKHR LayerDim::sImage;
-int32_t LayerDim::sWidth;
-int32_t LayerDim::sHeight;
-
-// ---------------------------------------------------------------------------
-
 LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client)
     : LayerBaseClient(flinger, display, client)
 {
 }
 
-void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
-{
-    sTexId = -1;
-    sImage = EGL_NO_IMAGE_KHR;
-    sWidth = w;
-    sHeight = h;
-    sUseTexture = false;
-}
-
 LayerDim::~LayerDim()
 {
 }
@@ -67,8 +50,14 @@
         const GLfloat alpha = s.alpha/255.0f;
         const uint32_t fbHeight = hw.getHeight();
         glDisable(GL_DITHER);
-        glEnable(GL_BLEND);
-        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+        if (s.alpha == 0xFF) {
+            glDisable(GL_BLEND);
+        } else {
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+        }
+
         glColor4f(0, 0, 0, alpha);
 
 #if defined(GL_OES_EGL_image_external)
@@ -78,15 +67,7 @@
 #endif
         glDisable(GL_TEXTURE_2D);
 
-        GLshort w = sWidth;
-        GLshort h = sHeight;
-        const GLshort vertices[4][2] = {
-                { 0, 0 },
-                { 0, h },
-                { w, h },
-                { w, 0 }
-        };
-        glVertexPointer(2, GL_SHORT, 0, vertices);
+        glVertexPointer(2, GL_FLOAT, 0, mVertices);
 
         while (it != end) {
             const Rect& r = *it++;
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index f032314..75f9a89 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -31,22 +31,17 @@
 
 class LayerDim : public LayerBaseClient
 {
-    static bool sUseTexture;
-    static GLuint sTexId;
-    static EGLImageKHR sImage;
-    static int32_t sWidth;
-    static int32_t sHeight;
 public:    
                 LayerDim(SurfaceFlinger* flinger, DisplayID display,
                         const sp<Client>& client);
         virtual ~LayerDim();
 
     virtual void onDraw(const Region& clip) const;
-    virtual bool needsBlending() const  { return true; }
-    virtual bool isSecure() const       { return false; }
+    virtual bool needsBlending() const    { return true; }
+    virtual bool isSecure() const         { return false; }
+    virtual bool isProtectedByApp() const { return false; }
+    virtual bool isProtectedByDRM() const { return false; }
     virtual const char* getTypeId() const { return "LayerDim"; }
-
-    static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c08e2c9..a9fa1ef 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -47,12 +47,11 @@
 #include "clz.h"
 #include "GLExtensions.h"
 #include "Layer.h"
-#include "LayerBlur.h"
-#include "LayerBuffer.h"
 #include "LayerDim.h"
 #include "SurfaceFlinger.h"
 
 #include "DisplayHardware/DisplayHardware.h"
+#include "DisplayHardware/HWComposer.h"
 
 /* ideally AID_GRAPHICS would be in a semi-public header
  * or there would be a way to map a user/group name to its id
@@ -61,10 +60,6 @@
 #define AID_GRAPHICS 1003
 #endif
 
-#ifdef USE_COMPOSITION_BYPASS
-#warning "using COMPOSITION_BYPASS"
-#endif
-
 #define DISPLAY_COUNT       1
 
 namespace android {
@@ -82,6 +77,7 @@
         mReadFramebuffer("android.permission.READ_FRAME_BUFFER"),
         mDump("android.permission.DUMP"),
         mVisibleRegionsDirty(false),
+        mHwWorkListDirty(false),
         mDeferReleaseConsole(false),
         mFreezeDisplay(false),
         mElectronBeamAnimationMode(0),
@@ -89,6 +85,7 @@
         mFreezeDisplayTime(0),
         mDebugRegion(0),
         mDebugBackground(0),
+        mDebugDisableHWC(0),
         mDebugInSwapBuffers(0),
         mLastSwapBufferTime(0),
         mDebugInTransaction(0),
@@ -120,11 +117,6 @@
     glDeleteTextures(1, &mWormholeTexName);
 }
 
-overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
-{
-    return graphicPlane(0).displayHardware().getOverlayEngine();
-}
-
 sp<IMemoryHeap> SurfaceFlinger::getCblk() const
 {
     return mServerHeap;
@@ -152,6 +144,11 @@
     return bclient;
 }
 
+sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
+{
+    sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
+    return gba;
+}
 
 const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
 {
@@ -170,7 +167,7 @@
 {
     const nsecs_t now = systemTime();
     const nsecs_t duration = now - mBootTime;
-    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );  
+    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
     mBootFinished = true;
     property_set("ctl.stop", "bootanim");
 }
@@ -206,10 +203,10 @@
     mServerHeap = new MemoryHeapBase(4096,
             MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
     LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
-    
+
     mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
     LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
-    
+
     new(mServerCblk) surface_flinger_cblk_t;
 
     // initialize primary screen
@@ -238,7 +235,7 @@
 
     // Initialize OpenGL|ES
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-    glPixelStorei(GL_PACK_ALIGNMENT, 4); 
+    glPixelStorei(GL_PACK_ALIGNMENT, 4);
     glEnableClientState(GL_VERTEX_ARRAY);
     glEnable(GL_SCISSOR_TEST);
     glShadeModel(GL_FLAT);
@@ -262,8 +259,6 @@
     glLoadIdentity();
     glOrthof(0, w, h, 0, 0, 1);
 
-   LayerDim::initDimmer(this, w, h);
-
     mReadyToRunBarrier.open();
 
     /*
@@ -272,7 +267,7 @@
 
     // start boot animation
     property_set("ctl.start", "bootanim");
-    
+
     return NO_ERROR;
 }
 
@@ -332,6 +327,40 @@
     const_cast<SurfaceFlinger*>(this)->signalEvent();
 }
 
+bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
+    Mutex::Autolock _l(mStateLock);
+    sp<IBinder> surfBinder(surface->asBinder());
+
+    // Check the visible layer list for the ISurface
+    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+    size_t count = currentLayers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        const sp<LayerBase>& layer(currentLayers[i]);
+        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
+        if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
+            return true;
+        }
+    }
+
+    // Check the layers in the purgatory.  This check is here so that if a
+    // Surface gets destroyed before all the clients are done using it, the
+    // error will not be reported as "surface XYZ is not authenticated", but
+    // will instead fail later on when the client tries to use the surface,
+    // which should be reported as "surface XYZ returned an -ENODEV".  The
+    // purgatorized layers are no less authentic than the visible ones, so this
+    // should not cause any harm.
+    size_t purgatorySize =  mLayerPurgatory.size();
+    for (size_t i=0 ; i<purgatorySize ; i++) {
+        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
+        if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
         nsecs_t reltime, uint32_t flags)
 {
@@ -375,17 +404,15 @@
     // post surfaces (if needed)
     handlePageFlip();
 
+    if (UNLIKELY(mHwWorkListDirty)) {
+        // build the h/w work list
+        handleWorkList();
+    }
+
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     if (LIKELY(hw.canDraw() && !isFrozen())) {
-
-#ifdef USE_COMPOSITION_BYPASS
-        if (handleBypassLayer()) {
-            unlockClients();
-            return true;
-        }
-#endif
-
         // repaint the framebuffer (if needed)
+
         const int index = hw.getCurrentBufferIndex();
         GraphicLog& logger(GraphicLog::getInstance());
 
@@ -408,20 +435,6 @@
     return true;
 }
 
-bool SurfaceFlinger::handleBypassLayer()
-{
-    sp<Layer> bypassLayer(mBypassLayer.promote());
-    if (bypassLayer != 0) {
-        sp<GraphicBuffer> buffer(bypassLayer->getBypassBuffer());
-        if (buffer!=0 && (buffer->usage & GRALLOC_USAGE_HW_FB)) {
-            const DisplayHardware& hw(graphicPlane(0).displayHardware());
-            hw.postBypassBuffer(buffer->handle);
-            return true;
-        }
-    }
-    return false;
-}
-
 void SurfaceFlinger::postFramebuffer()
 {
     if (!mInvalidRegion.isEmpty()) {
@@ -480,6 +493,7 @@
         handleTransactionLocked(transactionFlags, ditchedLayers);
         mLastTransactionTime = systemTime() - now;
         mDebugInTransaction = 0;
+        invalidateHwcGeometry();
         // here the transaction has been committed
     }
 
@@ -487,6 +501,7 @@
      * Clean-up all layers that went away
      * (do this without the lock held)
      */
+
     const size_t count = ditchedLayers.size();
     for (size_t i=0 ; i<count ; i++) {
         if (ditchedLayers[i] != 0) {
@@ -690,7 +705,7 @@
 
         // Update aboveOpaqueLayers for next (lower) layer
         aboveOpaqueLayers.orSelf(opaqueRegion);
-        
+
         // Store the visible region is screen space
         layer->setVisibleRegion(visibleRegion);
         layer->setCoveredRegion(coveredRegion);
@@ -717,37 +732,11 @@
     mTransactionCV.broadcast();
 }
 
-void SurfaceFlinger::setBypassLayer(const sp<LayerBase>& layer)
-{
-    // if this layer is already the bypass layer, do nothing
-    sp<Layer> cur(mBypassLayer.promote());
-    if (mBypassLayer == layer) {
-        if (cur != NULL) {
-            cur->updateBuffersOrientation();
-        }
-        return;
-    }
-
-    // clear the current bypass layer
-    mBypassLayer.clear();
-    if (cur != 0) {
-        cur->setBypass(false);
-        cur.clear();
-    }
-
-    // set new bypass layer
-    if (layer != 0) {
-        if (layer->setBypass(true)) {
-            mBypassLayer = static_cast<Layer*>(layer.get());
-        }
-    }
-}
-
 void SurfaceFlinger::handlePageFlip()
 {
     bool visibleRegions = mVisibleRegionsDirty;
-    LayerVector& currentLayers = const_cast<LayerVector&>(
-            mDrawingState.layersSortedByZ);
+    LayerVector& currentLayers(
+            const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
     visibleRegions |= lockPageFlip(currentLayers);
 
         const DisplayHardware& hw = graphicPlane(0).displayHardware();
@@ -768,29 +757,20 @@
                     mVisibleLayersSortedByZ.add(currentLayers[i]);
             }
 
-#ifdef USE_COMPOSITION_BYPASS
-            sp<LayerBase> bypassLayer;
-            const size_t numVisibleLayers = mVisibleLayersSortedByZ.size();
-            if (numVisibleLayers == 1) {
-                const sp<LayerBase>& candidate(mVisibleLayersSortedByZ[0]);
-                const Region& visibleRegion(candidate->visibleRegionScreen);
-                const Region reminder(screenRegion.subtract(visibleRegion));
-                if (reminder.isEmpty()) {
-                    // fullscreen candidate!
-                    bypassLayer = candidate;
-                }
-            }
-            setBypassLayer(bypassLayer);
-#endif
-
             mWormholeRegion = screenRegion.subtract(opaqueRegion);
             mVisibleRegionsDirty = false;
+            invalidateHwcGeometry();
         }
 
     unlockPageFlip(currentLayers);
     mDirtyRegion.andSelf(screenRegion);
 }
 
+void SurfaceFlinger::invalidateHwcGeometry()
+{
+    mHwWorkListDirty = true;
+}
+
 bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
 {
     bool recomputeVisibleRegions = false;
@@ -815,15 +795,29 @@
     }
 }
 
+void SurfaceFlinger::handleWorkList()
+{
+    mHwWorkListDirty = false;
+    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
+    if (hwc.initCheck() == NO_ERROR) {
+        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
+        const size_t count = currentLayers.size();
+        hwc.createWorkList(count);
+        hwc_layer_t* const cur(hwc.getLayers());
+        for (size_t i=0 ; cur && i<count ; i++) {
+            currentLayers[i]->setGeometry(&cur[i]);
+            if (mDebugDisableHWC) {
+                cur[i].compositionType = HWC_FRAMEBUFFER;
+                cur[i].flags |= HWC_SKIP_LAYER;
+            }
+        }
+    }
+}
 
 void SurfaceFlinger::handleRepaint()
 {
     // compute the invalid region
     mInvalidRegion.orSelf(mDirtyRegion);
-    if (mInvalidRegion.isEmpty()) {
-        // nothing to do
-        return;
-    }
 
     if (UNLIKELY(mDebugRegion)) {
         debugFlashRegions();
@@ -835,8 +829,8 @@
     glLoadIdentity();
 
     uint32_t flags = hw.getFlags();
-    if ((flags & DisplayHardware::SWAP_RECTANGLE) || 
-        (flags & DisplayHardware::BUFFER_PRESERVED)) 
+    if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
+        (flags & DisplayHardware::BUFFER_PRESERVED))
     {
         // we can redraw only what's dirty, but since SWAP_RECTANGLE only
         // takes a rectangle, we must make sure to update that whole
@@ -879,9 +873,79 @@
         // draw something...
         drawWormhole();
     }
+
+    status_t err = NO_ERROR;
     const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
-    const size_t count = layers.size();
-    for (size_t i=0 ; i<count ; ++i) {
+    size_t count = layers.size();
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    HWComposer& hwc(hw.getHwComposer());
+    hwc_layer_t* const cur(hwc.getLayers());
+
+    LOGE_IF(cur && hwc.getNumLayers() != count,
+            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
+            hwc.getNumLayers(), count);
+
+    // just to be extra-safe, use the smallest count
+    if (hwc.initCheck() == NO_ERROR) {
+        count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
+    }
+
+    /*
+     *  update the per-frame h/w composer data for each layer
+     *  and build the transparent region of the FB
+     */
+    Region transparent;
+    if (cur) {
+        for (size_t i=0 ; i<count ; i++) {
+            const sp<LayerBase>& layer(layers[i]);
+            layer->setPerFrameData(&cur[i]);
+        }
+        err = hwc.prepare();
+        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
+
+        if (err == NO_ERROR) {
+            for (size_t i=0 ; i<count ; i++) {
+                if (cur[i].hints & HWC_HINT_CLEAR_FB) {
+                    const sp<LayerBase>& layer(layers[i]);
+                    if (!(layer->needsBlending())) {
+                        transparent.orSelf(layer->visibleRegionScreen);
+                    }
+                }
+            }
+
+            /*
+             *  clear the area of the FB that need to be transparent
+             */
+            transparent.andSelf(dirty);
+            if (!transparent.isEmpty()) {
+                glClearColor(0,0,0,0);
+                Region::const_iterator it = transparent.begin();
+                Region::const_iterator const end = transparent.end();
+                const int32_t height = hw.getHeight();
+                while (it != end) {
+                    const Rect& r(*it++);
+                    const GLint sy = height - (r.top + r.height());
+                    glScissor(r.left, sy, r.width(), r.height());
+                    glClear(GL_COLOR_BUFFER_BIT);
+                }
+            }
+        }
+    }
+
+
+    /*
+     * and then, render the layers targeted at the framebuffer
+     */
+    for (size_t i=0 ; i<count ; i++) {
+        if (cur) {
+            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
+                !(cur[i].flags & HWC_SKIP_LAYER)) {
+                // skip layers handled by the HAL
+                continue;
+            }
+        }
+
         const sp<LayerBase>& layer(layers[i]);
         const Region clip(dirty.intersect(layer->visibleRegionScreen));
         if (!clip.isEmpty()) {
@@ -993,6 +1057,8 @@
             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
         }
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        glLoadIdentity();
+        glMatrixMode(GL_MODELVIEW);
     }
 }
 
@@ -1054,7 +1120,7 @@
 {
     sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
     if (lbc != 0) {
-        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
+        mLayerMap.removeItem( lbc->getSurfaceBinder() );
     }
     ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
     if (index >= 0) {
@@ -1066,8 +1132,12 @@
 
 status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
 {
-    // remove the layer from the main list (through a transaction).
+    // First add the layer to the purgatory list, which makes sure it won't
+    // go away, then remove it from the main list (through a transaction).
     ssize_t err = removeLayer_l(layerBase);
+    if (err >= 0) {
+        mLayerPurgatory.add(layerBase);
+    }
 
     layerBase->onRemoved();
 
@@ -1109,7 +1179,7 @@
     if (android_atomic_dec(&mTransactionCount) == 1) {
         signalEvent();
 
-        // if there is a transaction with a resize, wait for it to 
+        // if there is a transaction with a resize, wait for it to
         // take effect before returning.
         Mutex::Autolock _l(mStateLock);
         while (mResizeTransationPending) {
@@ -1153,7 +1223,7 @@
     return NO_ERROR;
 }
 
-int SurfaceFlinger::setOrientation(DisplayID dpy, 
+int SurfaceFlinger::setOrientation(DisplayID dpy,
         int orientation, uint32_t flags)
 {
     if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
@@ -1186,21 +1256,17 @@
                 int(w), int(h));
         return surfaceHandle;
     }
-    
+
     //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
     sp<Layer> normalLayer;
     switch (flags & eFXSurfaceMask) {
         case eFXSurfaceNormal:
-            if (UNLIKELY(flags & ePushBuffers)) {
-                layer = createPushBuffersSurface(client, d, w, h, flags);
-            } else {
-                normalLayer = createNormalSurface(client, d, w, h, flags, format);
-                layer = normalLayer;
-            }
+            normalLayer = createNormalSurface(client, d, w, h, flags, format);
+            layer = normalLayer;
             break;
         case eFXSurfaceBlur:
-            layer = createBlurSurface(client, d, w, h, flags);
-            break;
+            // for now we treat Blur as Dim, until we can implement it
+            // efficiently.
         case eFXSurfaceDim:
             layer = createDimSurface(client, d, w, h, flags);
             break;
@@ -1212,7 +1278,7 @@
         ssize_t token = addClientLayer(client, layer);
 
         surfaceHandle = layer->getSurface();
-        if (surfaceHandle != 0) { 
+        if (surfaceHandle != 0) {
             params->token = token;
             params->identity = surfaceHandle->getIdentity();
             params->width = w;
@@ -1264,15 +1330,6 @@
     return layer;
 }
 
-sp<LayerBlur> SurfaceFlinger::createBlurSurface(
-        const sp<Client>& client, DisplayID display,
-        uint32_t w, uint32_t h, uint32_t flags)
-{
-    sp<LayerBlur> layer = new LayerBlur(this, display, client);
-    layer->initStates(w, h, flags);
-    return layer;
-}
-
 sp<LayerDim> SurfaceFlinger::createDimSurface(
         const sp<Client>& client, DisplayID display,
         uint32_t w, uint32_t h, uint32_t flags)
@@ -1282,21 +1339,12 @@
     return layer;
 }
 
-sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
-        const sp<Client>& client, DisplayID display,
-        uint32_t w, uint32_t h, uint32_t flags)
-{
-    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
-    layer->initStates(w, h, flags);
-    return layer;
-}
-
 status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
 {
     /*
      * called by the window manager, when a surface should be marked for
      * destruction.
-     * 
+     *
      * The surface is removed from the current and drawing lists, but placed
      * in the purgatory queue, so it's not destroyed right-away (we need
      * to wait for all client's references to go away first).
@@ -1317,7 +1365,7 @@
 status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
 {
     // called by ~ISurface() when all references are gone
-    
+
     class MessageDestroySurface : public MessageBase {
         SurfaceFlinger* flinger;
         sp<LayerBaseClient> layer;
@@ -1330,14 +1378,27 @@
             layer.clear(); // clear it outside of the lock;
             Mutex::Autolock _l(flinger->mStateLock);
             /*
-             * remove the layer from the current list -- chances are that it's 
-             * not in the list anyway, because it should have been removed 
-             * already upon request of the client (eg: window manager). 
+             * remove the layer from the current list -- chances are that it's
+             * not in the list anyway, because it should have been removed
+             * already upon request of the client (eg: window manager).
              * However, a buggy client could have not done that.
              * Since we know we don't have any more clients, we don't need
              * to use the purgatory.
              */
             status_t err = flinger->removeLayer_l(l);
+            if (err == NAME_NOT_FOUND) {
+                // The surface wasn't in the current list, which means it was
+                // removed already, which means it is in the purgatory,
+                // and need to be removed from there.
+                // This needs to happen from the main thread since its dtor
+                // must run from there (b/c of OpenGL ES). Additionally, we
+                // can't really acquire our internal lock from
+                // destroySurface() -- see postMessage() below.
+                ssize_t idx = flinger->mLayerPurgatory.remove(l);
+                LOGE_IF(idx < 0,
+                        "layer=%p is not in the purgatory list", l.get());
+            }
+
             LOGE_IF(err<0 && err != NAME_NOT_FOUND,
                     "error removing layer=%p (%s)", l.get(), strerror(-err));
             return true;
@@ -1420,7 +1481,7 @@
 
 status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
 {
-    const size_t SIZE = 1024;
+    const size_t SIZE = 4096;
     char buffer[SIZE];
     String8 result;
     if (!mDump.checkCalling()) {
@@ -1447,14 +1508,19 @@
         }
         const bool locked(retry >= 0);
         if (!locked) {
-            snprintf(buffer, SIZE, 
+            snprintf(buffer, SIZE,
                     "SurfaceFlinger appears to be unresponsive, "
                     "dumping anyways (no locks held)\n");
             result.append(buffer);
         }
 
+        /*
+         * Dump the visible layer list
+         */
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         const size_t count = currentLayers.size();
+        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+        result.append(buffer);
         for (size_t i=0 ; i<count ; i++) {
             const sp<LayerBase>& layer(currentLayers[i]);
             layer->dump(result, buffer, SIZE);
@@ -1464,12 +1530,30 @@
             layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
         }
 
+        /*
+         * Dump the layers in the purgatory
+         */
+
+        const size_t purgatorySize =  mLayerPurgatory.size();
+        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+        result.append(buffer);
+        for (size_t i=0 ; i<purgatorySize ; i++) {
+            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+            layer->shortDump(result, buffer, SIZE);
+        }
+
+        /*
+         * Dump SurfaceFlinger global state
+         */
+
+        snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+        result.append(buffer);
         mWormholeRegion.dump(result, "WormholeRegion");
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         snprintf(buffer, SIZE,
-                "  display frozen: %s, freezeCount=%d, orientation=%d, bypass=%p, canDraw=%d\n",
+                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
                 mFreezeDisplay?"yes":"no", mFreezeCount,
-                mCurrentState.orientation, mBypassLayer.unsafe_get(), hw.canDraw());
+                mCurrentState.orientation, hw.canDraw());
         result.append(buffer);
         snprintf(buffer, SIZE,
                 "  last eglSwapBuffers() time: %f us\n"
@@ -1489,8 +1573,22 @@
             result.append(buffer);
         }
 
+        /*
+         * Dump HWComposer state
+         */
+        HWComposer& hwc(hw.getHwComposer());
+        snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
+                hwc.initCheck()==NO_ERROR ? "present" : "not present",
+                mDebugDisableHWC ? "disabled" : "enabled");
+        result.append(buffer);
+        hwc.dump(result, buffer, SIZE);
+
+        /*
+         * Dump gralloc state
+         */
         const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
         alloc.dump(result);
+        hw.dump(result);
 
         if (locked) {
             mStateLock.unlock();
@@ -1564,6 +1662,11 @@
                 n = data.readInt32();
                 mDebugBackground = n ? 1 : 0;
                 return NO_ERROR;
+            case 1008:  // toggle use of hw composer
+                n = data.readInt32();
+                mDebugDisableHWC = n ? 1 : 0;
+                invalidateHwcGeometry();
+                // fall-through...
             case 1004:{ // repaint everything
                 Mutex::Autolock _l(mStateLock);
                 const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -2057,7 +2160,8 @@
 status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
         sp<IMemoryHeap>* heap,
         uint32_t* w, uint32_t* h, PixelFormat* f,
-        uint32_t sw, uint32_t sh)
+        uint32_t sw, uint32_t sh,
+        uint32_t minLayerZ, uint32_t maxLayerZ)
 {
     status_t result = PERMISSION_DENIED;
 
@@ -2065,6 +2169,19 @@
     if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
         return BAD_VALUE;
 
+    // make sure none of the layers are protected
+    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    const size_t count = layers.size();
+    for (size_t i=0 ; i<count ; ++i) {
+        const sp<LayerBase>& layer(layers[i]);
+        const uint32_t z = layer->drawingState().z;
+        if (z >= minLayerZ && z <= maxLayerZ) {
+            if (layer->isProtected()) {
+                return INVALID_OPERATION;
+            }
+        }
+    }
+
     if (!GLExtensions::getInstance().haveFramebufferObject())
         return INVALID_OPERATION;
 
@@ -2080,6 +2197,9 @@
     sh = (!sh) ? hw_h : sh;
     const size_t size = sw * sh * 4;
 
+    //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d",
+    //        sw, sh, minLayerZ, maxLayerZ);
+
     // make sure to clear all GL error flags
     while ( glGetError() != GL_NO_ERROR ) ;
 
@@ -2094,6 +2214,7 @@
             GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
 
     GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+
     if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
 
         // invert everything, b/c glReadPixel() below will invert the FB
@@ -2109,11 +2230,12 @@
         glClearColor(0,0,0,1);
         glClear(GL_COLOR_BUFFER_BIT);
 
-        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
-        const size_t count = layers.size();
         for (size_t i=0 ; i<count ; ++i) {
             const sp<LayerBase>& layer(layers[i]);
-            layer->drawForSreenShot();
+            const uint32_t z = layer->drawingState().z;
+            if (z >= minLayerZ && z <= maxLayerZ) {
+                layer->drawForSreenShot();
+            }
         }
 
         // XXX: this is needed on tegra
@@ -2148,8 +2270,6 @@
         glMatrixMode(GL_PROJECTION);
         glPopMatrix();
         glMatrixMode(GL_MODELVIEW);
-
-
     } else {
         result = BAD_VALUE;
     }
@@ -2161,6 +2281,8 @@
 
     hw.compositionComplete();
 
+    // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
+
     return result;
 }
 
@@ -2168,7 +2290,8 @@
 status_t SurfaceFlinger::captureScreen(DisplayID dpy,
         sp<IMemoryHeap>* heap,
         uint32_t* width, uint32_t* height, PixelFormat* format,
-        uint32_t sw, uint32_t sh)
+        uint32_t sw, uint32_t sh,
+        uint32_t minLayerZ, uint32_t maxLayerZ)
 {
     // only one display supported for now
     if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
@@ -2186,13 +2309,18 @@
         PixelFormat* f;
         uint32_t sw;
         uint32_t sh;
+        uint32_t minLayerZ;
+        uint32_t maxLayerZ;
         status_t result;
     public:
         MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
                 sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
-                uint32_t sw, uint32_t sh)
+                uint32_t sw, uint32_t sh,
+                uint32_t minLayerZ, uint32_t maxLayerZ)
             : flinger(flinger), dpy(dpy),
-              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), result(PERMISSION_DENIED)
+              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh),
+              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
+              result(PERMISSION_DENIED)
         {
         }
         status_t getResult() const {
@@ -2206,14 +2334,14 @@
                 return true;
 
             result = flinger->captureScreenImplLocked(dpy,
-                    heap, w, h, f, sw, sh);
+                    heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
 
             return true;
         }
     };
 
     sp<MessageBase> msg = new MessageCaptureScreen(this,
-            dpy, heap, width, height, format, sw, sh);
+            dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ);
     status_t res = postMessageSync(msg);
     if (res == NO_ERROR) {
         res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
@@ -2363,12 +2491,15 @@
 {
     int32_t name = NAME_NOT_FOUND;
     sp<Layer> layer(mFlinger->getLayer(sur));
-    if (layer == 0) return name;
+    if (layer == 0) {
+        return name;
+    }
 
     // if this layer already has a token, just return it
     name = layer->getToken();
-    if ((name >= 0) && (layer->getClient() == this))
+    if ((name >= 0) && (layer->getClient() == this)) {
         return name;
+    }
 
     name = 0;
     do {
@@ -2409,6 +2540,39 @@
 
 // ---------------------------------------------------------------------------
 
+GraphicBufferAlloc::GraphicBufferAlloc() {}
+
+GraphicBufferAlloc::~GraphicBufferAlloc() {}
+
+sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
+        PixelFormat format, uint32_t usage) {
+    sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
+    status_t err = graphicBuffer->initCheck();
+    if (err != 0) {
+        LOGE("createGraphicBuffer: init check failed: %d", err);
+        return 0;
+    } else if (graphicBuffer->handle == 0) {
+        LOGE("createGraphicBuffer: unable to create GraphicBuffer");
+        return 0;
+    }
+    Mutex::Autolock _l(mLock);
+    mBuffers.add(graphicBuffer);
+    return graphicBuffer;
+}
+
+void GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) {
+    Mutex::Autolock _l(mLock);
+    if (0 <= bufIdx && bufIdx < mBuffers.size()) {
+        sp<GraphicBuffer> b(mBuffers[bufIdx]);
+        mBuffers.clear();
+        mBuffers.add(b);
+    } else {
+        mBuffers.clear();
+    }
+}
+
+// ---------------------------------------------------------------------------
+
 GraphicPlane::GraphicPlane()
     : mHw(0)
 {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index df1ca48..9566819 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -34,6 +34,7 @@
 #include <ui/PixelFormat.h>
 #include <surfaceflinger/ISurfaceComposer.h>
 #include <surfaceflinger/ISurfaceComposerClient.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
 
 #include "Barrier.h"
 #include "Layer.h"
@@ -48,9 +49,7 @@
 class DisplayHardware;
 class FreezeLock;
 class Layer;
-class LayerBlur;
 class LayerDim;
-class LayerBuffer;
 
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
@@ -121,6 +120,21 @@
     sp<SurfaceFlinger> mFlinger;
 };
 
+class GraphicBufferAlloc : public BnGraphicBufferAlloc
+{
+public:
+    GraphicBufferAlloc();
+    virtual ~GraphicBufferAlloc();
+
+    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
+        PixelFormat format, uint32_t usage);
+    virtual void freeAllGraphicBuffersExcept(int bufIdx);
+
+private:
+    Vector<sp<GraphicBuffer> > mBuffers;
+    Mutex mLock;
+};
+
 // ---------------------------------------------------------------------------
 
 class GraphicPlane
@@ -186,6 +200,7 @@
     // ISurfaceComposer interface
     virtual sp<ISurfaceComposerClient>  createConnection();
     virtual sp<ISurfaceComposerClient>  createClientConnection();
+    virtual sp<IGraphicBufferAlloc>     createGraphicBufferAlloc();
     virtual sp<IMemoryHeap>             getCblk() const;
     virtual void                        bootFinished();
     virtual void                        openGlobalTransaction();
@@ -194,35 +209,33 @@
     virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
     virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
     virtual void                        signal() const;
-    virtual status_t                    captureScreen(DisplayID dpy,
-                                                      sp<IMemoryHeap>* heap,
-                                                      uint32_t* width,
-                                                      uint32_t* height,
-                                                      PixelFormat* format,
-                                                      uint32_t reqWidth,
-                                                      uint32_t reqHeight);
+    virtual bool                        authenticateSurface(const sp<ISurface>& surface) const;
+
+    virtual status_t captureScreen(DisplayID dpy,
+            sp<IMemoryHeap>* heap,
+            uint32_t* width, uint32_t* height,
+            PixelFormat* format, uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ);
+
     virtual status_t                    turnElectronBeamOff(int32_t mode);
     virtual status_t                    turnElectronBeamOn(int32_t mode);
 
             void                        screenReleased(DisplayID dpy);
             void                        screenAcquired(DisplayID dpy);
 
-            overlay_control_device_t* getOverlayEngine() const;
-
     status_t removeLayer(const sp<LayerBase>& layer);
     status_t addLayer(const sp<LayerBase>& layer);
     status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
+    void invalidateHwcGeometry();
 
     sp<Layer> getLayer(const sp<ISurface>& sur) const;
 
 private:
     friend class Client;
     friend class LayerBase;
-    friend class LayerBuffer;
     friend class LayerBaseClient;
     friend class LayerBaseClient::Surface;
     friend class Layer;
-    friend class LayerBlur;
     friend class LayerDim;
 
     sp<ISurface> createSurface(const sp<Client>& client,
@@ -236,18 +249,10 @@
             uint32_t w, uint32_t h, uint32_t flags,
             PixelFormat& format);
 
-    sp<LayerBlur> createBlurSurface(
-            const sp<Client>& client, DisplayID display,
-            uint32_t w, uint32_t h, uint32_t flags);
-
     sp<LayerDim> createDimSurface(
             const sp<Client>& client, DisplayID display,
             uint32_t w, uint32_t h, uint32_t flags);
 
-    sp<LayerBuffer> createPushBuffersSurface(
-            const sp<Client>& client, DisplayID display,
-            uint32_t w, uint32_t h, uint32_t flags);
-
     status_t removeSurface(const sp<Client>& client, SurfaceID sid);
     status_t destroySurface(const sp<LayerBaseClient>& layer);
     status_t setClientState(const sp<Client>& client,
@@ -306,8 +311,8 @@
             void        handlePageFlip();
             bool        lockPageFlip(const LayerVector& currentLayers);
             void        unlockPageFlip(const LayerVector& currentLayers);
+            void        handleWorkList();
             void        handleRepaint();
-            bool        handleBypassLayer();
             void        postFramebuffer();
             void        composeSurfaces(const Region& dirty);
 
@@ -322,12 +327,12 @@
             uint32_t    setTransactionFlags(uint32_t flags);
             void        commitTransaction();
 
-            void        setBypassLayer(const sp<LayerBase>& layer);
 
             status_t captureScreenImplLocked(DisplayID dpy,
                     sp<IMemoryHeap>* heap,
                     uint32_t* width, uint32_t* height, PixelFormat* format,
-                    uint32_t reqWidth = 0, uint32_t reqHeight = 0);
+                    uint32_t reqWidth, uint32_t reqHeight,
+                    uint32_t minLayerZ, uint32_t maxLayerZ);
 
             status_t turnElectronBeamOffImplLocked(int32_t mode);
             status_t turnElectronBeamOnImplLocked(int32_t mode);
@@ -370,6 +375,7 @@
     volatile    int32_t                 mTransactionFlags;
     volatile    int32_t                 mTransactionCount;
                 Condition               mTransactionCV;
+                SortedVector< sp<LayerBase> > mLayerPurgatory;
                 bool                    mResizeTransationPending;
 
                 // protected by mStateLock (but we could use another lock)
@@ -394,18 +400,19 @@
                 Region                      mInvalidRegion;
                 Region                      mWormholeRegion;
                 bool                        mVisibleRegionsDirty;
+                bool                        mHwWorkListDirty;
                 bool                        mDeferReleaseConsole;
                 bool                        mFreezeDisplay;
                 int32_t                     mElectronBeamAnimationMode;
                 int32_t                     mFreezeCount;
                 nsecs_t                     mFreezeDisplayTime;
                 Vector< sp<LayerBase> >     mVisibleLayersSortedByZ;
-                wp<Layer>                   mBypassLayer;
 
 
                 // don't use a lock for these, we don't care
                 int                         mDebugRegion;
                 int                         mDebugBackground;
+                int                         mDebugDisableHWC;
                 volatile nsecs_t            mDebugInSwapBuffers;
                 nsecs_t                     mLastSwapBufferTime;
                 volatile nsecs_t            mDebugInTransaction;
diff --git a/services/surfaceflinger/tests/overlays/Android.mk b/services/surfaceflinger/tests/overlays/Android.mk
deleted file mode 100644
index 592b601..0000000
--- a/services/surfaceflinger/tests/overlays/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	overlays.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-	libutils \
-    libui \
-    libsurfaceflinger_client
-
-LOCAL_MODULE:= test-overlays
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/overlays/overlays.cpp b/services/surfaceflinger/tests/overlays/overlays.cpp
deleted file mode 100644
index c248a615..0000000
--- a/services/surfaceflinger/tests/overlays/overlays.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-
-#include <ui/Overlay.h>
-
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
-using namespace android;
-
-namespace android {
-class Test {
-public:
-    static const sp<ISurface>& getISurface(const sp<Surface>& s) {
-        return s->getISurface();
-    }
-};
-};
-
-int main(int argc, char** argv)
-{
-    // set up the thread-pool
-    sp<ProcessState> proc(ProcessState::self());
-    ProcessState::self()->startThreadPool();
-
-    // create a client to surfaceflinger
-    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
-    
-    // create pushbuffer surface
-    sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240, 
-            PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);
-
-    // get to the isurface
-    sp<ISurface> isurface = Test::getISurface(surface);
-    printf("isurface = %p\n", isurface.get());
-    
-    // now request an overlay
-    sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
-    sp<Overlay> overlay = new Overlay(ref);
-    
-
-    /*
-     * here we can use the overlay API 
-     */
-    
-    overlay_buffer_t buffer; 
-    overlay->dequeueBuffer(&buffer);
-    printf("buffer = %p\n", buffer);
-    
-    void* address = overlay->getBufferAddress(buffer);
-    printf("address = %p\n", address);
-
-    overlay->queueBuffer(buffer);
-
-    return 0;
-}
diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
index 127cca3..0ccca77 100644
--- a/services/surfaceflinger/tests/resize/resize.cpp
+++ b/services/surfaceflinger/tests/resize/resize.cpp
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #include <cutils/memory.h>
 
 #include <utils/Log.h>
@@ -10,8 +26,6 @@
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
-#include <ui/Overlay.h>
-
 using namespace android;
 
 namespace android {
@@ -32,7 +46,6 @@
     // create a client to surfaceflinger
     sp<SurfaceComposerClient> client = new SurfaceComposerClient();
     
-    // create pushbuffer surface
     sp<Surface> surface = client->createSurface(getpid(), 0, 160, 240, 
             PIXEL_FORMAT_RGB_565);
 
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
index b4de4b4..67ecf7e 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #include <cutils/memory.h>
 
 #include <utils/Log.h>
@@ -10,8 +26,6 @@
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
-#include <ui/Overlay.h>
-
 using namespace android;
 
 int main(int argc, char** argv)
@@ -23,7 +37,6 @@
     // create a client to surfaceflinger
     sp<SurfaceComposerClient> client = new SurfaceComposerClient();
     
-    // create pushbuffer surface
     sp<SurfaceControl> surfaceControl = client->createSurface(
             getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565);
     client->openTransaction();
diff --git a/vpn/java/android/net/vpn/IVpnService.aidl b/vpn/java/android/net/vpn/IVpnService.aidl
index fedccb0..6bf3edd 100644
--- a/vpn/java/android/net/vpn/IVpnService.aidl
+++ b/vpn/java/android/net/vpn/IVpnService.aidl
@@ -24,10 +24,11 @@
  */
 interface IVpnService {
     /**
-     * Sets up the VPN connection.
+     * Sets up a VPN connection.
      * @param profile the profile object
      * @param username the username for authentication
      * @param password the corresponding password for authentication
+     * @return true if VPN is successfully connected
      */
     boolean connect(in VpnProfile profile, String username, String password);
 
@@ -37,7 +38,13 @@
     void disconnect();
 
     /**
-     * Makes the service broadcast the connectivity state.
+     * Gets the the current connection state.
      */
-    void checkStatus(in VpnProfile profile);
+    String getState(in VpnProfile profile);
+
+    /**
+     * Returns the idle state.
+     * @return true if the system is not connecting/connected to a VPN
+     */
+    boolean isIdle();
 }
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce40b5d..02486bb 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -16,17 +16,19 @@
 
 package android.net.vpn;
 
-import java.io.File;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
 import android.os.Environment;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.util.Log;
 
+import com.android.server.vpn.VpnServiceBinder;
+
 /**
  * The class provides interface to manage all VPN-related tasks, including:
  * <ul>
@@ -40,8 +42,6 @@
  * {@hide}
  */
 public class VpnManager {
-    // Action for broadcasting a connectivity state.
-    private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
     /** Key to the profile name of a connectivity broadcast event. */
     public static final String BROADCAST_PROFILE_NAME = "profile_name";
     /** Key to the connectivity state of a connectivity broadcast event. */
@@ -74,8 +74,10 @@
     private static final String PACKAGE_PREFIX =
             VpnManager.class.getPackage().getName() + ".";
 
-    // Action to start VPN service
-    private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE";
+    // Action for broadcasting a connectivity state.
+    private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
+
+    private static final String VPN_SERVICE_NAME = "vpn";
 
     // Action to start VPN settings
     private static final String ACTION_VPN_SETTINGS =
@@ -96,13 +98,76 @@
         return VpnType.values();
     }
 
+    public static void startVpnService(Context c) {
+        ServiceManager.addService(VPN_SERVICE_NAME, new VpnServiceBinder(c));
+    }
+
     private Context mContext;
+    private IVpnService mVpnService;
 
     /**
      * Creates a manager object with the specified context.
      */
     public VpnManager(Context c) {
         mContext = c;
+        createVpnServiceClient();
+    }
+
+    private void createVpnServiceClient() {
+        IBinder b = ServiceManager.getService(VPN_SERVICE_NAME);
+        mVpnService = IVpnService.Stub.asInterface(b);
+    }
+
+    /**
+     * Sets up a VPN connection.
+     * @param profile the profile object
+     * @param username the username for authentication
+     * @param password the corresponding password for authentication
+     * @return true if VPN is successfully connected
+     */
+    public boolean connect(VpnProfile p, String username, String password) {
+        try {
+            return mVpnService.connect(p, username, password);
+        } catch (RemoteException e) {
+            Log.e(TAG, "connect()", e);
+            return false;
+        }
+    }
+
+    /**
+     * Tears down the VPN connection.
+     */
+    public void disconnect() {
+        try {
+            mVpnService.disconnect();
+        } catch (RemoteException e) {
+            Log.e(TAG, "disconnect()", e);
+        }
+    }
+
+    /**
+     * Gets the the current connection state.
+     */
+    public VpnState getState(VpnProfile p) {
+        try {
+            return Enum.valueOf(VpnState.class, mVpnService.getState(p));
+        } catch (RemoteException e) {
+            Log.e(TAG, "getState()", e);
+            return VpnState.IDLE;
+        }
+    }
+
+    /**
+     * Returns the idle state.
+     * @return true if the system is not connecting/connected to a VPN
+     */
+    public boolean isIdle() {
+        try {
+            return mVpnService.isIdle();
+        } catch (RemoteException e) {
+            Log.e(TAG, "isIdle()", e);
+            return true;
+        }
     }
 
     /**
@@ -134,33 +199,6 @@
         }
     }
 
-    /**
-     * Starts the VPN service to establish VPN connection.
-     */
-    public void startVpnService() {
-        mContext.startService(new Intent(ACTION_VPN_SERVICE));
-    }
-
-    /**
-     * Stops the VPN service.
-     */
-    public void stopVpnService() {
-        mContext.stopService(new Intent(ACTION_VPN_SERVICE));
-    }
-
-    /**
-     * Binds the specified ServiceConnection with the VPN service.
-     */
-    public boolean bindVpnService(ServiceConnection c) {
-        if (!mContext.bindService(new Intent(ACTION_VPN_SERVICE), c, 0)) {
-            Log.w(TAG, "failed to connect to VPN service");
-            return false;
-        } else {
-            Log.d(TAG, "succeeded to connect to VPN service");
-            return true;
-        }
-    }
-
     /** Broadcasts the connectivity state of the specified profile. */
     public void broadcastConnectivity(String profileName, VpnState s) {
         broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR);
diff --git a/vpn/java/com/android/server/vpn/DaemonProxy.java b/vpn/java/com/android/server/vpn/DaemonProxy.java
new file mode 100644
index 0000000..289ee45
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/DaemonProxy.java
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.net.vpn.VpnManager;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * Proxy to start, stop and interact with a VPN daemon.
+ * The daemon is expected to accept connection through Unix domain socket.
+ * When the proxy successfully starts the daemon, it will establish a socket
+ * connection with the daemon, to both send commands to the daemon and receive
+ * response and connecting error code from the daemon.
+ */
+class DaemonProxy implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private static final boolean DBG = true;
+
+    private static final int WAITING_TIME = 15; // sec
+
+    private static final String SVC_STATE_CMD_PREFIX = "init.svc.";
+    private static final String SVC_START_CMD = "ctl.start";
+    private static final String SVC_STOP_CMD = "ctl.stop";
+    private static final String SVC_STATE_RUNNING = "running";
+    private static final String SVC_STATE_STOPPED = "stopped";
+
+    private static final int END_OF_ARGUMENTS = 255;
+
+    private String mName;
+    private String mTag;
+    private transient LocalSocket mControlSocket;
+
+    /**
+     * Creates a proxy of the specified daemon.
+     * @param daemonName name of the daemon
+     */
+    DaemonProxy(String daemonName) {
+        mName = daemonName;
+        mTag = "SProxy_" + daemonName;
+    }
+
+    String getName() {
+        return mName;
+    }
+
+    void start() throws IOException {
+        String svc = mName;
+
+        Log.i(mTag, "Start VPN daemon: " + svc);
+        SystemProperties.set(SVC_START_CMD, svc);
+
+        if (!blockUntil(SVC_STATE_RUNNING, WAITING_TIME)) {
+            throw new IOException("cannot start service: " + svc);
+        } else {
+            mControlSocket = createServiceSocket();
+        }
+    }
+
+    void sendCommand(String ...args) throws IOException {
+        OutputStream out = getControlSocketOutput();
+        for (String arg : args) outputString(out, arg);
+        out.write(END_OF_ARGUMENTS);
+        out.flush();
+
+        int result = getResultFromSocket(true);
+        if (result != args.length) {
+            throw new IOException("socket error, result from service: "
+                    + result);
+        }
+    }
+
+    // returns 0 if nothing is in the receive buffer
+    int getResultFromSocket() throws IOException {
+        return getResultFromSocket(false);
+    }
+
+    void closeControlSocket() {
+        if (mControlSocket == null) return;
+        try {
+            mControlSocket.close();
+        } catch (IOException e) {
+            Log.w(mTag, "close control socket", e);
+        } finally {
+            mControlSocket = null;
+        }
+    }
+
+    void stop() {
+        String svc = mName;
+        Log.i(mTag, "Stop VPN daemon: " + svc);
+        SystemProperties.set(SVC_STOP_CMD, svc);
+        boolean success = blockUntil(SVC_STATE_STOPPED, 5);
+        if (DBG) Log.d(mTag, "stopping " + svc + ", success? " + success);
+    }
+
+    boolean isStopped() {
+        String cmd = SVC_STATE_CMD_PREFIX + mName;
+        return SVC_STATE_STOPPED.equals(SystemProperties.get(cmd));
+    }
+
+    private int getResultFromSocket(boolean blocking) throws IOException {
+        LocalSocket s = mControlSocket;
+        if (s == null) return 0;
+        InputStream in = s.getInputStream();
+        if (!blocking && in.available() == 0) return 0;
+
+        int data = in.read();
+        Log.i(mTag, "got data from control socket: " + data);
+
+        return data;
+    }
+
+    private LocalSocket createServiceSocket() throws IOException {
+        LocalSocket s = new LocalSocket();
+        LocalSocketAddress a = new LocalSocketAddress(mName,
+                LocalSocketAddress.Namespace.RESERVED);
+
+        // try a few times in case the service has not listen()ed
+        IOException excp = null;
+        for (int i = 0; i < 10; i++) {
+            try {
+                s.connect(a);
+                return s;
+            } catch (IOException e) {
+                if (DBG) Log.d(mTag, "service not yet listen()ing; try again");
+                excp = e;
+                sleep(500);
+            }
+        }
+        throw excp;
+    }
+
+    private OutputStream getControlSocketOutput() throws IOException {
+        if (mControlSocket != null) {
+            return mControlSocket.getOutputStream();
+        } else {
+            throw new IOException("no control socket available");
+        }
+    }
+
+    /**
+     * Waits for the process to be in the expected state. The method returns
+     * false if after the specified duration (in seconds), the process is still
+     * not in the expected state.
+     */
+    private boolean blockUntil(String expectedState, int waitTime) {
+        String cmd = SVC_STATE_CMD_PREFIX + mName;
+        int sleepTime = 200; // ms
+        int n = waitTime * 1000 / sleepTime;
+        for (int i = 0; i < n; i++) {
+            if (expectedState.equals(SystemProperties.get(cmd))) {
+                if (DBG) {
+                    Log.d(mTag, mName + " is " + expectedState + " after "
+                            + (i * sleepTime) + " msec");
+                }
+                break;
+            }
+            sleep(sleepTime);
+        }
+        return expectedState.equals(SystemProperties.get(cmd));
+    }
+
+    private void outputString(OutputStream out, String s) throws IOException {
+        byte[] bytes = s.getBytes();
+        out.write(bytes.length);
+        out.write(bytes);
+        out.flush();
+    }
+
+    private void sleep(int msec) {
+        try {
+            Thread.currentThread().sleep(msec);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/L2tpIpsecPskService.java b/vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
new file mode 100644
index 0000000..50e0de1
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.net.vpn.L2tpIpsecPskProfile;
+
+import java.io.IOException;
+
+/**
+ * The service that manages the preshared key based L2TP-over-IPSec VPN
+ * connection.
+ */
+class L2tpIpsecPskService extends VpnService<L2tpIpsecPskProfile> {
+    private static final String IPSEC = "racoon";
+
+    @Override
+    protected void connect(String serverIp, String username, String password)
+            throws IOException {
+        L2tpIpsecPskProfile p = getProfile();
+        VpnDaemons daemons = getDaemons();
+
+        // IPSEC
+        daemons.startIpsecForL2tp(serverIp, p.getPresharedKey())
+                .closeControlSocket();
+
+        sleep(2000); // 2 seconds
+
+        // L2TP
+        daemons.startL2tp(serverIp,
+                (p.isSecretEnabled() ? p.getSecretString() : null),
+                username, password);
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/L2tpIpsecService.java b/vpn/java/com/android/server/vpn/L2tpIpsecService.java
new file mode 100644
index 0000000..663b0e8
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/L2tpIpsecService.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.net.vpn.L2tpIpsecProfile;
+import android.security.Credentials;
+
+import java.io.IOException;
+
+/**
+ * The service that manages the certificate based L2TP-over-IPSec VPN connection.
+ */
+class L2tpIpsecService extends VpnService<L2tpIpsecProfile> {
+    private static final String IPSEC = "racoon";
+
+    @Override
+    protected void connect(String serverIp, String username, String password)
+            throws IOException {
+        L2tpIpsecProfile p = getProfile();
+        VpnDaemons daemons = getDaemons();
+
+        // IPSEC
+        DaemonProxy ipsec = daemons.startIpsecForL2tp(serverIp,
+                Credentials.USER_PRIVATE_KEY + p.getUserCertificate(),
+                Credentials.USER_CERTIFICATE + p.getUserCertificate(),
+                Credentials.CA_CERTIFICATE + p.getCaCertificate());
+        ipsec.closeControlSocket();
+
+        sleep(2000); // 2 seconds
+
+        // L2TP
+        daemons.startL2tp(serverIp,
+                (p.isSecretEnabled() ? p.getSecretString() : null),
+                username, password);
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/L2tpService.java b/vpn/java/com/android/server/vpn/L2tpService.java
new file mode 100644
index 0000000..784a366
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/L2tpService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.net.vpn.L2tpProfile;
+
+import java.io.IOException;
+
+/**
+ * The service that manages the L2TP VPN connection.
+ */
+class L2tpService extends VpnService<L2tpProfile> {
+    @Override
+    protected void connect(String serverIp, String username, String password)
+            throws IOException {
+        L2tpProfile p = getProfile();
+        getDaemons().startL2tp(serverIp,
+                (p.isSecretEnabled() ? p.getSecretString() : null),
+                username, password);
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/PptpService.java b/vpn/java/com/android/server/vpn/PptpService.java
new file mode 100644
index 0000000..de12710
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/PptpService.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.net.vpn.PptpProfile;
+
+import java.io.IOException;
+
+/**
+ * The service that manages the PPTP VPN connection.
+ */
+class PptpService extends VpnService<PptpProfile> {
+    @Override
+    protected void connect(String serverIp, String username, String password)
+            throws IOException {
+        PptpProfile p = getProfile();
+        getDaemons().startPptp(serverIp, username, password,
+                p.isEncryptionEnabled());
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/VpnConnectingError.java b/vpn/java/com/android/server/vpn/VpnConnectingError.java
new file mode 100644
index 0000000..3c4ec7d
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/VpnConnectingError.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import java.io.IOException;
+
+/**
+ * Exception thrown when a connecting attempt fails.
+ */
+class VpnConnectingError extends IOException {
+    private int mErrorCode;
+
+    VpnConnectingError(int errorCode) {
+        super("Connecting error: " + errorCode);
+        mErrorCode = errorCode;
+    }
+
+    int getErrorCode() {
+        return mErrorCode;
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/VpnDaemons.java b/vpn/java/com/android/server/vpn/VpnDaemons.java
new file mode 100644
index 0000000..499195f
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/VpnDaemons.java
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A helper class for managing native VPN daemons.
+ */
+class VpnDaemons implements Serializable {
+    static final long serialVersionUID = 1L;
+    private final String TAG = VpnDaemons.class.getSimpleName();
+
+    private static final String MTPD = "mtpd";
+    private static final String IPSEC = "racoon";
+
+    private static final String L2TP = "l2tp";
+    private static final String L2TP_PORT = "1701";
+
+    private static final String PPTP = "pptp";
+    private static final String PPTP_PORT = "1723";
+
+    private static final String VPN_LINKNAME = "vpn";
+    private static final String PPP_ARGS_SEPARATOR = "";
+
+    private List<DaemonProxy> mDaemonList = new ArrayList<DaemonProxy>();
+
+    public DaemonProxy startL2tp(String serverIp, String secret,
+            String username, String password) throws IOException {
+        return startMtpd(L2TP, serverIp, L2TP_PORT, secret, username, password,
+                false);
+    }
+
+    public DaemonProxy startPptp(String serverIp, String username,
+            String password, boolean encryption) throws IOException {
+        return startMtpd(PPTP, serverIp, PPTP_PORT, null, username, password,
+                encryption);
+    }
+
+    public DaemonProxy startIpsecForL2tp(String serverIp, String pskKey)
+            throws IOException {
+        DaemonProxy ipsec = startDaemon(IPSEC);
+        ipsec.sendCommand(serverIp, L2TP_PORT, pskKey);
+        return ipsec;
+    }
+
+    public DaemonProxy startIpsecForL2tp(String serverIp, String userKeyKey,
+            String userCertKey, String caCertKey) throws IOException {
+        DaemonProxy ipsec = startDaemon(IPSEC);
+        ipsec.sendCommand(serverIp, L2TP_PORT, userKeyKey, userCertKey,
+                caCertKey);
+        return ipsec;
+    }
+
+    public synchronized void stopAll() {
+        new DaemonProxy(MTPD).stop();
+        new DaemonProxy(IPSEC).stop();
+    }
+
+    public synchronized void closeSockets() {
+        for (DaemonProxy s : mDaemonList) s.closeControlSocket();
+    }
+
+    public synchronized boolean anyDaemonStopped() {
+        for (DaemonProxy s : mDaemonList) {
+            if (s.isStopped()) {
+                Log.w(TAG, "    VPN daemon gone: " + s.getName());
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public synchronized int getSocketError() {
+        for (DaemonProxy s : mDaemonList) {
+            int errCode = getResultFromSocket(s);
+            if (errCode != 0) return errCode;
+        }
+        return 0;
+    }
+
+    private synchronized DaemonProxy startDaemon(String daemonName)
+            throws IOException {
+        DaemonProxy daemon = new DaemonProxy(daemonName);
+        mDaemonList.add(daemon);
+        daemon.start();
+        return daemon;
+    }
+
+    private int getResultFromSocket(DaemonProxy s) {
+        try {
+            return s.getResultFromSocket();
+        } catch (IOException e) {
+            return -1;
+        }
+    }
+
+    private DaemonProxy startMtpd(String protocol,
+            String serverIp, String port, String secret, String username,
+            String password, boolean encryption) throws IOException {
+        ArrayList<String> args = new ArrayList<String>();
+        args.addAll(Arrays.asList(protocol, serverIp, port));
+        if (secret != null) args.add(secret);
+        args.add(PPP_ARGS_SEPARATOR);
+        addPppArguments(args, serverIp, username, password, encryption);
+
+        DaemonProxy mtpd = startDaemon(MTPD);
+        mtpd.sendCommand(args.toArray(new String[args.size()]));
+        return mtpd;
+    }
+
+    private static void addPppArguments(ArrayList<String> args, String serverIp,
+            String username, String password, boolean encryption)
+            throws IOException {
+        args.addAll(Arrays.asList(
+                "linkname", VPN_LINKNAME,
+                "name", username,
+                "password", password,
+                "refuse-eap", "nodefaultroute", "usepeerdns",
+                "idle", "1800",
+                "mtu", "1400",
+                "mru", "1400"));
+        if (encryption) {
+            args.add("+mppe");
+        }
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/VpnService.java b/vpn/java/com/android/server/vpn/VpnService.java
new file mode 100644
index 0000000..4966c06
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/VpnService.java
@@ -0,0 +1,477 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+
+/**
+ * The service base class for managing a type of VPN connection.
+ */
+abstract class VpnService<E extends VpnProfile> {
+    private static final boolean DBG = true;
+    private static final int NOTIFICATION_ID = 1;
+
+    private static final String DNS1 = "net.dns1";
+    private static final String DNS2 = "net.dns2";
+    private static final String VPN_DNS1 = "vpn.dns1";
+    private static final String VPN_DNS2 = "vpn.dns2";
+    private static final String VPN_STATUS = "vpn.status";
+    private static final String VPN_IS_UP = "ok";
+    private static final String VPN_IS_DOWN = "down";
+
+    private static final String REMOTE_IP = "net.ipremote";
+    private static final String DNS_DOMAIN_SUFFICES = "net.dns.search";
+
+    private final String TAG = VpnService.class.getSimpleName();
+
+    E mProfile;
+    transient Context mContext;
+
+    private VpnState mState = VpnState.IDLE;
+    private Throwable mError;
+
+    // connection settings
+    private String mOriginalDns1;
+    private String mOriginalDns2;
+    private String mOriginalDomainSuffices;
+    private String mLocalIp;
+    private String mLocalIf;
+
+    private long mStartTime; // VPN connection start time
+
+    // for helping managing daemons
+    private VpnDaemons mDaemons = new VpnDaemons();
+
+    // for helping showing, updating notification
+    private transient NotificationHelper mNotification;
+
+    /**
+     * Establishes a VPN connection with the specified username and password.
+     */
+    protected abstract void connect(String serverIp, String username,
+            String password) throws IOException;
+
+    /**
+     * Returns the daemons management class for this service object.
+     */
+    protected VpnDaemons getDaemons() {
+        return mDaemons;
+    }
+
+    /**
+     * Returns the VPN profile associated with the connection.
+     */
+    protected E getProfile() {
+        return mProfile;
+    }
+
+    /**
+     * Returns the IP address of the specified host name.
+     */
+    protected String getIp(String hostName) throws IOException {
+        return InetAddress.getByName(hostName).getHostAddress();
+    }
+
+    void setContext(Context context, E profile) {
+        mProfile = profile;
+        mContext = context;
+        mNotification = new NotificationHelper();
+
+        if (VpnState.CONNECTED.equals(mState)) {
+            Log.i("VpnService", "     recovered: " + mProfile.getName());
+            startConnectivityMonitor();
+        }
+    }
+
+    VpnState getState() {
+        return mState;
+    }
+
+    boolean isIdle() {
+      return (mState == VpnState.IDLE);
+    }
+
+    synchronized boolean onConnect(String username, String password) {
+        try {
+            setState(VpnState.CONNECTING);
+
+            mDaemons.stopAll();
+            String serverIp = getIp(getProfile().getServerName());
+            saveLocalIpAndInterface(serverIp);
+            onBeforeConnect();
+            connect(serverIp, username, password);
+            waitUntilConnectedOrTimedout();
+            return true;
+        } catch (Throwable e) {
+            onError(e);
+            return false;
+        }
+    }
+
+    synchronized void onDisconnect() {
+        try {
+            Log.i(TAG, "disconnecting VPN...");
+            setState(VpnState.DISCONNECTING);
+            mNotification.showDisconnect();
+
+            mDaemons.stopAll();
+        } catch (Throwable e) {
+            Log.e(TAG, "onDisconnect()", e);
+        } finally {
+            onFinalCleanUp();
+        }
+    }
+
+    private void onError(Throwable error) {
+        // error may occur during or after connection setup
+        // and it may be due to one or all services gone
+        if (mError != null) {
+            Log.w(TAG, "   multiple errors occur, record the last one: "
+                    + error);
+        }
+        Log.e(TAG, "onError()", error);
+        mError = error;
+        onDisconnect();
+    }
+
+    private void onError(int errorCode) {
+        onError(new VpnConnectingError(errorCode));
+    }
+
+
+    private void onBeforeConnect() throws IOException {
+        mNotification.disableNotification();
+
+        SystemProperties.set(VPN_DNS1, "");
+        SystemProperties.set(VPN_DNS2, "");
+        SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
+        if (DBG) {
+            Log.d(TAG, "       VPN UP: " + SystemProperties.get(VPN_STATUS));
+        }
+    }
+
+    private void waitUntilConnectedOrTimedout() throws IOException {
+        sleep(2000); // 2 seconds
+        for (int i = 0; i < 80; i++) {
+            if (mState != VpnState.CONNECTING) {
+                break;
+            } else if (VPN_IS_UP.equals(
+                    SystemProperties.get(VPN_STATUS))) {
+                onConnected();
+                return;
+            } else {
+                int err = mDaemons.getSocketError();
+                if (err != 0) {
+                    onError(err);
+                    return;
+                }
+            }
+            sleep(500); // 0.5 second
+        }
+
+        if (mState == VpnState.CONNECTING) {
+            onError(new IOException("Connecting timed out"));
+        }
+    }
+
+    private synchronized void onConnected() throws IOException {
+        if (DBG) Log.d(TAG, "onConnected()");
+
+        mDaemons.closeSockets();
+        saveOriginalDns();
+        saveAndSetDomainSuffices();
+
+        mStartTime = System.currentTimeMillis();
+
+        setState(VpnState.CONNECTED);
+        setVpnDns();
+
+        startConnectivityMonitor();
+    }
+
+    private synchronized void onFinalCleanUp() {
+        if (DBG) Log.d(TAG, "onFinalCleanUp()");
+
+        if (mState == VpnState.IDLE) return;
+
+        // keep the notification when error occurs
+        if (!anyError()) mNotification.disableNotification();
+
+        restoreOriginalDns();
+        restoreOriginalDomainSuffices();
+        setState(VpnState.IDLE);
+
+        SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
+    }
+
+    private boolean anyError() {
+        return (mError != null);
+    }
+
+    private void restoreOriginalDns() {
+        // restore only if they are not overridden
+        String vpnDns1 = SystemProperties.get(VPN_DNS1);
+        if (vpnDns1.equals(SystemProperties.get(DNS1))) {
+            Log.i(TAG, String.format("restore original dns prop: %s --> %s",
+                    SystemProperties.get(DNS1), mOriginalDns1));
+            Log.i(TAG, String.format("restore original dns prop: %s --> %s",
+                    SystemProperties.get(DNS2), mOriginalDns2));
+            SystemProperties.set(DNS1, mOriginalDns1);
+            SystemProperties.set(DNS2, mOriginalDns2);
+        }
+    }
+
+    private void saveOriginalDns() {
+        mOriginalDns1 = SystemProperties.get(DNS1);
+        mOriginalDns2 = SystemProperties.get(DNS2);
+        Log.i(TAG, String.format("save original dns prop: %s, %s",
+                mOriginalDns1, mOriginalDns2));
+    }
+
+    private void setVpnDns() {
+        String vpnDns1 = SystemProperties.get(VPN_DNS1);
+        String vpnDns2 = SystemProperties.get(VPN_DNS2);
+        SystemProperties.set(DNS1, vpnDns1);
+        SystemProperties.set(DNS2, vpnDns2);
+        Log.i(TAG, String.format("set vpn dns prop: %s, %s",
+                vpnDns1, vpnDns2));
+    }
+
+    private void saveAndSetDomainSuffices() {
+        mOriginalDomainSuffices = SystemProperties.get(DNS_DOMAIN_SUFFICES);
+        Log.i(TAG, "save original suffices: " + mOriginalDomainSuffices);
+        String list = mProfile.getDomainSuffices();
+        if (!TextUtils.isEmpty(list)) {
+            SystemProperties.set(DNS_DOMAIN_SUFFICES, list);
+        }
+    }
+
+    private void restoreOriginalDomainSuffices() {
+        Log.i(TAG, "restore original suffices --> " + mOriginalDomainSuffices);
+        SystemProperties.set(DNS_DOMAIN_SUFFICES, mOriginalDomainSuffices);
+    }
+
+    private void setState(VpnState newState) {
+        mState = newState;
+        broadcastConnectivity(newState);
+    }
+
+    private void broadcastConnectivity(VpnState s) {
+        VpnManager m = new VpnManager(mContext);
+        Throwable err = mError;
+        if ((s == VpnState.IDLE) && (err != null)) {
+            if (err instanceof UnknownHostException) {
+                m.broadcastConnectivity(mProfile.getName(), s,
+                        VpnManager.VPN_ERROR_UNKNOWN_SERVER);
+            } else if (err instanceof VpnConnectingError) {
+                m.broadcastConnectivity(mProfile.getName(), s,
+                        ((VpnConnectingError) err).getErrorCode());
+            } else if (VPN_IS_UP.equals(SystemProperties.get(VPN_STATUS))) {
+                m.broadcastConnectivity(mProfile.getName(), s,
+                        VpnManager.VPN_ERROR_CONNECTION_LOST);
+            } else {
+                m.broadcastConnectivity(mProfile.getName(), s,
+                        VpnManager.VPN_ERROR_CONNECTION_FAILED);
+            }
+        } else {
+            m.broadcastConnectivity(mProfile.getName(), s);
+        }
+    }
+
+    private void startConnectivityMonitor() {
+        new Thread(new Runnable() {
+            public void run() {
+                Log.i(TAG, "VPN connectivity monitor running");
+                try {
+                    mNotification.update(mStartTime); // to pop up notification
+                    for (int i = 10; ; i--) {
+                        long now = System.currentTimeMillis();
+
+                        boolean heavyCheck = i == 0;
+                        synchronized (VpnService.this) {
+                            if (mState != VpnState.CONNECTED) break;
+                            mNotification.update(now);
+
+                            if (heavyCheck) {
+                                i = 10;
+                                if (checkConnectivity()) checkDns();
+                            }
+                            long t = 1000L - System.currentTimeMillis() + now;
+                            if (t > 100L) VpnService.this.wait(t);
+                        }
+                    }
+                } catch (InterruptedException e) {
+                    onError(e);
+                }
+                Log.i(TAG, "VPN connectivity monitor stopped");
+            }
+        }).start();
+    }
+
+    private void saveLocalIpAndInterface(String serverIp) throws IOException {
+        DatagramSocket s = new DatagramSocket();
+        int port = 80; // arbitrary
+        s.connect(InetAddress.getByName(serverIp), port);
+        InetAddress localIp = s.getLocalAddress();
+        mLocalIp = localIp.getHostAddress();
+        NetworkInterface localIf = NetworkInterface.getByInetAddress(localIp);
+        mLocalIf = (localIf == null) ? null : localIf.getName();
+        if (TextUtils.isEmpty(mLocalIf)) {
+            throw new IOException("Local interface is empty!");
+        }
+        if (DBG) {
+            Log.d(TAG, "  Local IP: " + mLocalIp + ", if: " + mLocalIf);
+        }
+    }
+
+    // returns false if vpn connectivity is broken
+    private boolean checkConnectivity() {
+        if (mDaemons.anyDaemonStopped() || isLocalIpChanged()) {
+            onError(new IOException("Connectivity lost"));
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    private void checkDns() {
+        String dns1 = SystemProperties.get(DNS1);
+        String vpnDns1 = SystemProperties.get(VPN_DNS1);
+        if (!dns1.equals(vpnDns1) && dns1.equals(mOriginalDns1)) {
+            // dhcp expires?
+            setVpnDns();
+        }
+    }
+
+    private boolean isLocalIpChanged() {
+        try {
+            InetAddress localIp = InetAddress.getByName(mLocalIp);
+            NetworkInterface localIf =
+                    NetworkInterface.getByInetAddress(localIp);
+            if (localIf == null || !mLocalIf.equals(localIf.getName())) {
+                Log.w(TAG, "       local If changed from " + mLocalIf
+                        + " to " + localIf);
+                return true;
+            } else {
+                return false;
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "isLocalIpChanged()", e);
+            return true;
+        }
+    }
+
+    protected void sleep(int ms) {
+        try {
+            Thread.currentThread().sleep(ms);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    // Helper class for showing, updating notification.
+    private class NotificationHelper {
+        private NotificationManager mNotificationManager = (NotificationManager)
+                mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        private Notification mNotification =
+                new Notification(R.drawable.vpn_connected, null, 0L);
+        private PendingIntent mPendingIntent = PendingIntent.getActivity(
+                mContext, 0,
+                new VpnManager(mContext).createSettingsActivityIntent(), 0);
+        private String mConnectedTitle;
+
+        void update(long now) {
+            Notification n = mNotification;
+            if (now == mStartTime) {
+                // to pop up the notification for the first time
+                n.when = mStartTime;
+                n.tickerText = mConnectedTitle = getNotificationTitle(true);
+            } else {
+                n.tickerText = null;
+            }
+            n.setLatestEventInfo(mContext, mConnectedTitle,
+                    getConnectedNotificationMessage(now),
+                    mPendingIntent);
+            n.flags |= Notification.FLAG_NO_CLEAR;
+            n.flags |= Notification.FLAG_ONGOING_EVENT;
+            enableNotification(n);
+        }
+
+        void showDisconnect() {
+            String title = getNotificationTitle(false);
+            Notification n = new Notification(R.drawable.vpn_disconnected,
+                    title, System.currentTimeMillis());
+            n.setLatestEventInfo(mContext, title,
+                    getDisconnectedNotificationMessage(),
+                    mPendingIntent);
+            n.flags |= Notification.FLAG_AUTO_CANCEL;
+            disableNotification();
+            enableNotification(n);
+        }
+
+        void disableNotification() {
+            mNotificationManager.cancel(NOTIFICATION_ID);
+        }
+
+        private void enableNotification(Notification n) {
+            mNotificationManager.notify(NOTIFICATION_ID, n);
+        }
+
+        private String getNotificationTitle(boolean connected) {
+            String formatString = connected
+                    ? mContext.getString(
+                            R.string.vpn_notification_title_connected)
+                    : mContext.getString(
+                            R.string.vpn_notification_title_disconnected);
+            return String.format(formatString, mProfile.getName());
+        }
+
+        private String getFormattedTime(int duration) {
+            int hours = duration / 3600;
+            StringBuilder sb = new StringBuilder();
+            if (hours > 0) sb.append(hours).append(':');
+            sb.append(String.format("%02d:%02d", (duration % 3600 / 60),
+                    (duration % 60)));
+            return sb.toString();
+        }
+
+        private String getConnectedNotificationMessage(long now) {
+            return getFormattedTime((int) (now - mStartTime) / 1000);
+        }
+
+        private String getDisconnectedNotificationMessage() {
+            return mContext.getString(
+                    R.string.vpn_notification_hint_disconnected);
+        }
+    }
+}
diff --git a/vpn/java/com/android/server/vpn/VpnServiceBinder.java b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
new file mode 100644
index 0000000..c474ff9
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+package com.android.server.vpn;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.vpn.IVpnService;
+import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.L2tpIpsecPskProfile;
+import android.net.vpn.L2tpProfile;
+import android.net.vpn.PptpProfile;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.util.Log;
+
+/**
+ * The service class for managing a VPN connection. It implements the
+ * {@link IVpnService} binder interface.
+ */
+public class VpnServiceBinder extends IVpnService.Stub {
+    private static final String TAG = VpnServiceBinder.class.getSimpleName();
+    private static final boolean DBG = true;
+
+    // The actual implementation is delegated to the VpnService class.
+    private VpnService<? extends VpnProfile> mService;
+
+    private Context mContext;
+
+    public VpnServiceBinder(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public synchronized boolean connect(VpnProfile p, final String username,
+            final String password) {
+        if ((mService != null) && !mService.isIdle()) return false;
+        final VpnService s = mService = createService(p);
+
+        new Thread(new Runnable() {
+            public void run() {
+                s.onConnect(username, password);
+            }
+        }).start();
+        return true;
+    }
+
+    @Override
+    public synchronized void disconnect() {
+        if (mService == null) return;
+        final VpnService s = mService;
+        mService = null;
+
+        new Thread(new Runnable() {
+            public void run() {
+                s.onDisconnect();
+            }
+        }).start();
+    }
+
+    @Override
+    public synchronized String getState(VpnProfile p) {
+        if ((mService == null)
+                || (!p.getName().equals(mService.mProfile.getName()))) {
+            return VpnState.IDLE.toString();
+        } else {
+            return mService.getState().toString();
+        }
+    }
+
+    @Override
+    public synchronized boolean isIdle() {
+        return (mService == null || mService.isIdle());
+    }
+
+    private VpnService<? extends VpnProfile> createService(VpnProfile p) {
+        switch (p.getType()) {
+            case L2TP:
+                L2tpService l2tp = new L2tpService();
+                l2tp.setContext(mContext, (L2tpProfile) p);
+                return l2tp;
+
+            case PPTP:
+                PptpService pptp = new PptpService();
+                pptp.setContext(mContext, (PptpProfile) p);
+                return pptp;
+
+            case L2TP_IPSEC_PSK:
+                L2tpIpsecPskService psk = new L2tpIpsecPskService();
+                psk.setContext(mContext, (L2tpIpsecPskProfile) p);
+                return psk;
+
+            case L2TP_IPSEC:
+                L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
+                l2tpIpsec.setContext(mContext, (L2tpIpsecProfile) p);
+                return l2tpIpsec;
+
+            default:
+                return null;
+        }
+    }
+}
