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/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..77d37f1
--- /dev/null
+++ b/include/gui/ISurfaceTexture.h
@@ -0,0 +1,91 @@
+/*
+ * 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;
+};
+
+// ----------------------------------------------------------------------------
+
+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
new file mode 100644
index 0000000..79c33f5
--- /dev/null
+++ b/include/gui/SurfaceTexture.h
@@ -0,0 +1,220 @@
+/*
+ * 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_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 {
+// ----------------------------------------------------------------------------
+
+class IGraphicBufferAlloc;
+
+class SurfaceTexture : public BnSurfaceTexture {
+public:
+    enum { MIN_BUFFER_SLOTS = 3 };
+    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);
+
+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 // ANDROID_GUI_SURFACETEXTURE_H
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
new file mode 100644
index 0000000..dd1d490
--- /dev/null
+++ b/include/gui/SurfaceTextureClient.h
@@ -0,0 +1,118 @@
+/*
+ * 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_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 {
+
+class SurfaceTextureClient
+    : public EGLNativeBase<ANativeWindow, SurfaceTextureClient, RefBase>
+{
+public:
+    SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);
+
+private:
+
+    // can't be copied
+    SurfaceTextureClient& operator = (const SurfaceTextureClient& rhs);
+    SurfaceTextureClient(const SurfaceTextureClient& rhs);
+
+    // ANativeWindow hooks
+    static int setSwapInterval(ANativeWindow* window, int interval);
+    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
+    static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int query(ANativeWindow* window, int what, int* value);
+    static int perform(ANativeWindow* window, int operation, ...);
+
+    int setSwapInterval(int interval);
+    int dequeueBuffer(android_native_buffer_t** buffer);
+    int lockBuffer(android_native_buffer_t* buffer);
+    int queueBuffer(android_native_buffer_t* buffer);
+    int cancelBuffer(android_native_buffer_t* buffer);
+    int query(int what, int* value);
+    int perform(int operation, va_list args);
+
+    int dispatchSetUsage(va_list args);
+    int dispatchConnect(va_list args);
+    int dispatchDisconnect(va_list args);
+    int dispatchSetCrop(va_list args);
+    int dispatchSetBufferCount(va_list args);
+    int dispatchSetBuffersGeometry(va_list args);
+    int dispatchSetBuffersTransform(va_list args);
+
+    int connect(int api);
+    int disconnect(int api);
+    int setUsage(uint32_t reqUsage);
+    int setCrop(Rect const* rect);
+    int setBufferCount(int bufferCount);
+    int setBuffersGeometry(int w, int h, int format);
+    int setBuffersTransform(int transform);
+
+    void freeAllBuffers();
+
+    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;
+
+    // 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  // ANDROID_GUI_SURFACETEXTURECLIENT_H
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 4ae3cdf..eb599b5 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -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;
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..56ed3a4 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,7 @@
         eDestroyBackbuffer  = 0x00000020,
         eSecure             = 0x00000080,
         eNonPremultiplied   = 0x00000100,
-        ePushBuffers        = 0x00000200,
+        eOpaque             = 0x00000400,
 
         eFXSurfaceNormal    = 0x00000000,
         eFXSurfaceBlur      = 0x00010000,
@@ -96,6 +97,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 +126,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;
@@ -143,6 +149,7 @@
         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
         CREATE_CONNECTION,
         CREATE_CLIENT_CONNECTION,
+        CREATE_GRAPHIC_BUFFER_ALLOC,
         GET_CBLK,
         OPEN_GLOBAL_TRANSACTION,
         CLOSE_GLOBAL_TRANSACTION,
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 7b2a7f5..d783caf 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,7 +239,7 @@
      *  private stuff...
      */
     void init();
-    status_t validate() const;
+    status_t validate(bool inCancelBuffer = false) const;
     sp<ISurface> getISurface() const;
 
     inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
@@ -314,4 +321,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..8b256f4 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 {
@@ -65,13 +63,6 @@
         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 +72,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 +82,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 +121,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 +144,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..2012fcc 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -50,8 +50,10 @@
 /*
  * 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.
@@ -85,7 +87,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 +98,7 @@
     POLICY_FLAG_MENU = 0x00000040,
     POLICY_FLAG_LAUNCHER = 0x00000080,
     POLICY_FLAG_VIRTUAL = 0x00000100,
+    POLICY_FLAG_FUNCTION = 0x00000200,
 
     POLICY_FLAG_RAW_MASK = 0x0000ffff,
 
@@ -505,6 +508,54 @@
     KeyedVector<int32_t, 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..f0a6d00
--- /dev/null
+++ b/include/ui/KeyLayoutMap.h
@@ -0,0 +1,65 @@
+/*
+ * 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 {
+
+/**
+ * Describes a mapping from keyboard scan codes to Android key codes.
+ */
+class KeyLayoutMap {
+public:
+    ~KeyLayoutMap();
+
+    static status_t load(const String8& filename, KeyLayoutMap** outMap);
+
+    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;
+    };
+
+    KeyedVector<int32_t,Key> mKeys;
+
+    KeyLayoutMap();
+
+    class Parser {
+        KeyLayoutMap* mMap;
+        Tokenizer* mTokenizer;
+
+    public:
+        Parser(KeyLayoutMap* map, Tokenizer* tokenizer);
+        ~Parser();
+        status_t parse();
+
+    private:
+        status_t parseKey();
+    };
+};
+
+} // 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..50296e2
--- /dev/null
+++ b/include/ui/Keyboard.h
@@ -0,0 +1,120 @@
+/*
+ * 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);
+
+/**
+ * Updates a meta state field when a key is pressed or released.
+ */
+extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
+
+} // namespace android
+
+#endif // _UI_KEYBOARD_H
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index f71d9cd..9b1a897 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -135,6 +135,83 @@
     { "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 },
 
     // 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 +219,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,6 +230,7 @@
     { "MENU", 0x00000040 },
     { "LAUNCHER", 0x00000080 },
     { "VIRTUAL", 0x00000100 },
+    { "FUNCTION", 0x00000200 },
     { NULL, 0 }
 };
 
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/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
new file mode 100644
index 0000000..3955bc3
--- /dev/null
+++ b/include/utils/Functor.h
@@ -0,0 +1,33 @@
+/*
+ * 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_FUNCTOR_H
+#define ANDROID_FUNCTOR_H
+
+#include <utils/Errors.h>
+
+namespace  android {
+
+class Functor {
+public:
+    Functor() {}
+    virtual ~Functor() {}
+    virtual status_t operator ()() { return true; }
+};
+
+}; // namespace android
+
+#endif // ANDROID_FUNCTOR_H
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/ResourceTypes.h b/include/utils/ResourceTypes.h
index da86da4..ed7f53d 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..6b49ff5 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);
@@ -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/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/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/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/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/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..90bca3c
--- /dev/null
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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,
+};
+
+
+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;
+    }
+};
+
+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;
+    }
+    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..1dadd53
--- /dev/null
+++ b/libs/gui/SurfaceTexture.cpp
@@ -0,0 +1,373 @@
+/*
+ * 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),
+    mLastQueued(INVALID_BUFFER_SLOT), 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");
+    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;
+        }
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image);
+        GLint error = glGetError();
+        if (error != GL_NO_ERROR) {
+            LOGE("error binding external texture image %p (slot %d): %#04x",
+                    image, mLastQueued, error);
+            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()) {
+        tx = float(mCurrentCrop.left) / float(buf->getWidth());
+        ty = float(buf->getHeight() - mCurrentCrop.bottom) /
+                float(buf->getHeight());
+        sx = float(mCurrentCrop.width()) / float(buf->getWidth());
+        sy = float(mCurrentCrop.height()) / 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,
+        sx*tx, sy*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;
+}
+
+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..0ed8be5
--- /dev/null
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -0,0 +1,300 @@
+/*
+ * 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), 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;
+}
+
+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) {
+        LOGE("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);
+    // XXX: Implement this!
+    return INVALID_OPERATION;
+}
+
+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);
+
+    // empty/invalid rects are not allowed
+    if (rect->isEmpty())
+        return BAD_VALUE;
+
+    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;
+
+    return NO_ERROR;
+}
+
+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/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..01ae23f 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -64,6 +64,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 +136,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();
@@ -186,6 +198,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 +248,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);
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..e21bab7 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:
@@ -854,6 +854,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;
 }
 
@@ -1022,7 +1028,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 (buffer->handle == mBuffers[i]->handle) {
+                idx = mBuffers[i]->getIndex();
+                break;
+            }
+        }
+    }
+    return idx;
 }
 
 status_t Surface::getBufferLocked(int index,
@@ -1036,7 +1055,6 @@
     // free the current buffer
     sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
     if (currentBuffer != 0) {
-        getBufferMapper().unregisterBuffer(currentBuffer->handle);
         currentBuffer.clear();
     }
 
@@ -1044,7 +1062,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 +1070,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/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/ui/Android.mk b/libs/ui/Android.mk
index c4a09d6..0d55f08 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,7 +58,6 @@
 	libcutils \
 	libutils \
 	libEGL \
-	libbinder \
 	libpixelflinger \
 	libhardware \
 	libhardware_legacy
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..0702d49 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
 {
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 9847a5f..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,7 +54,7 @@
     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);
@@ -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..b8d59e6 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -7,11 +7,117 @@
 
 //#define LOG_NDEBUG 0
 
+#define DEBUG_PROBE 0
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+
 #include <ui/Input.h>
 
 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 +129,7 @@
     mSource = from.mSource;
 }
 
-// class KeyEvent
+// --- KeyEvent ---
 
 bool KeyEvent::hasDefaultAction(int32_t keyCode) {
     switch (keyCode) {
@@ -33,6 +139,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 +147,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 +177,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 +237,7 @@
     mEventTime = from.mEventTime;
 }
 
-// class MotionEvent
+// --- MotionEvent ---
 
 void MotionEvent::initialize(
         int32_t deviceId,
@@ -170,7 +284,7 @@
     mYOffset += yOffset;
 }
 
-// class InputDeviceInfo
+// --- InputDeviceInfo ---
 
 InputDeviceInfo::InputDeviceInfo() {
     initialize(-1, String8("uninitialized device info"));
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
deleted file mode 100644
index 421ad66..0000000
--- a/libs/ui/InputDispatcher.cpp
+++ /dev/null
@@ -1,3518 +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;
-
-    if (entry->repeatCount == 1) {
-        entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
-    }
-
-    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();
-        }
-
-        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..83d9556 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 ---
@@ -497,7 +501,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 +510,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 +635,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..56bc26f 100644
--- a/libs/ui/KeyLayoutMap.cpp
+++ b/libs/ui/KeyLayoutMap.cpp
@@ -1,234 +1,213 @@
+/*
+ * 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::map(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("map: 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("map: 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::findScanCodes(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;
+}
+
+// --- 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 {
+                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 scan code number, got '%s'.", mTokenizer->getLocation().string(),
+                scanCodeToken.string());
+        return BAD_VALUE;
+    }
+    if (mMap->mKeys.indexOfKey(scanCode) >= 0) {
+        LOGE("%s: Duplicate entry for 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 flag label, got '%s'.", mTokenizer->getLocation().string(),
+                    flagToken.string());
+            return BAD_VALUE;
+        }
+        if (flags & flag) {
+            LOGE("%s: Duplicate 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;
 }
 
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..6faa600
--- /dev/null
+++ b/libs/ui/Keyboard.cpp
@@ -0,0 +1,308 @@
+/*
+ * 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 lookupLabel(const char* literal, const KeycodeLabel *list) {
+    while (list->literal) {
+        if (strcmp(literal, list->literal) == 0) {
+            return list->value;
+        }
+        list++;
+    }
+    return list->value;
+}
+
+int32_t getKeyCodeByLabel(const char* label) {
+    return int32_t(lookupLabel(label, KEYCODES));
+}
+
+uint32_t getKeyFlagByLabel(const char* label) {
+    return uint32_t(lookupLabel(label, FLAGS));
+}
+
+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;
+    }
+}
+
+
+} // 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/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..580d73c 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -7,8 +7,6 @@
 # Build the unit tests.
 test_src_files := \
     InputChannel_test.cpp \
-    InputReader_test.cpp \
-    InputDispatcher_test.cpp \
     InputPublisherAndConsumer_test.cpp
 
 shared_libraries := \
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/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
index 952b974..903fcaf 100644
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -118,13 +118,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)
@@ -279,13 +282,16 @@
         EXPECT_EQ(samplePointerCoords[offset].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)
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/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/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 8345cc3..bbf5093 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;
 }
 
@@ -4127,13 +4230,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++) {
@@ -4340,11 +4446,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;
@@ -4402,18 +4511,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/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/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..7ac6f92 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>
 
@@ -446,15 +445,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 +456,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 +540,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 +1976,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 ebe2193..8977fbf 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -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,13 @@
     return tls;
 }
 
+static inline void clearError() {
+    if (gEGLThreadLocalStorageKey != -1) {
+        tls_t* tls = getTLS();
+        tls->error = EGL_SUCCESS;
+    }
+}
+
 template<typename T>
 static __attribute__((noinline))
 T setErrorEtc(const char* caller, int line, EGLint error, T returnValue) {
@@ -410,10 +487,6 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "glEGLImageTargetTexture2DOES",
-            (__eglMustCastToProperFunctionPointerType)NULL },
-    { "glEGLImageTargetRenderbufferStorageOES",
-            (__eglMustCastToProperFunctionPointerType)NULL },
 };
 
 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
@@ -450,13 +523,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 +567,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 +715,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 +736,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 +749,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 +869,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);
 
@@ -814,7 +910,7 @@
     dp->refs--;
     dp->numTotalConfigs = 0;
     delete [] dp->configs;
-    clearTLS();
+
     return res;
 }
 
@@ -826,6 +922,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 +948,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 +1063,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 +1086,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) {
@@ -1014,6 +1118,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 +1138,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 +1157,8 @@
                                     
 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1071,6 +1181,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 +1210,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 +1249,8 @@
 
 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
+    clearError();
+
     ContextRef _c(ctx);
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
     
@@ -1150,9 +1266,32 @@
     return result;
 }
 
+static void loseCurrent(egl_context_t * cur_c)
+{
+    if (cur_c) {
+        egl_surface_t * cur_r = get_surface(cur_c->read);
+        egl_surface_t * cur_d = get_surface(cur_c->draw);
+
+        // by construction, these are either 0 or valid (possibly terminated)
+        // it should be impossible for these to be invalid
+        ContextRef _cur_c(cur_c);
+        SurfaceRef _cur_r(cur_r);
+        SurfaceRef _cur_d(cur_d);
+
+        cur_c->read = NULL;
+        cur_c->draw = NULL;
+
+        _cur_c.release();
+        _cur_r.release();
+        _cur_d.release();
+    }
+}
+
 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);
@@ -1178,13 +1317,9 @@
 
     // these are the current objects structs
     egl_context_t * cur_c = get_context(getContext());
-    egl_surface_t * cur_r = NULL;
-    egl_surface_t * cur_d = NULL;
     
     if (ctx != EGL_NO_CONTEXT) {
         c = get_context(ctx);
-        cur_r = get_surface(c->read);
-        cur_d = get_surface(c->draw);
         impl_ctx = c->context;
     } else {
         // no context given, use the implementation of the current context
@@ -1230,30 +1365,21 @@
     }
 
     if (result == EGL_TRUE) {
-        // by construction, these are either 0 or valid (possibly terminated)
-        // it should be impossible for these to be invalid
-        ContextRef _cur_c(cur_c);
-        SurfaceRef _cur_r(cur_r);
-        SurfaceRef _cur_d(cur_d);
 
-        // cur_c has to be valid here (but could be terminated)
+        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();
+            _d.acquire();
+            c->read = read;
+            c->draw = draw;
         } else {
-            setGlThreadSpecific(&gHooksNoContext);
+            setGLHooksThreadSpecific(&gHooksNoContext);
             setContext(EGL_NO_CONTEXT);
         }
-        _cur_c.release();
-
-        _r.acquire();
-        _cur_r.release();
-        if (c) c->read = read;
-
-        _d.acquire();
-        _cur_d.release();
-        if (c) c->draw = draw;
     }
     return result;
 }
@@ -1262,6 +1388,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);
 
@@ -1288,6 +1416,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;
 }
@@ -1297,6 +1427,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);
@@ -1315,6 +1447,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);
@@ -1329,6 +1463,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) {
@@ -1348,7 +1484,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) {
@@ -1382,12 +1520,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;
@@ -1434,11 +1597,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++;
             }
@@ -1450,6 +1626,8 @@
 
 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
 {
+    clearError();
+
     SurfaceRef _s(draw);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1463,6 +1641,8 @@
 EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
                             NativePixmapType target)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1476,6 +1656,8 @@
 
 const char* eglQueryString(EGLDisplay dpy, EGLint name)
 {
+    clearError();
+
     egl_display_t const * const dp = get_display(dpy);
     switch (name) {
         case EGL_VENDOR:
@@ -1498,6 +1680,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);
 
@@ -1515,6 +1699,8 @@
 EGLBoolean eglBindTexImage(
         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1532,6 +1718,8 @@
 EGLBoolean eglReleaseTexImage(
         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1548,6 +1736,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);
 
@@ -1573,6 +1763,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;
@@ -1596,6 +1788,8 @@
 
 EGLBoolean eglBindAPI(EGLenum api)
 {
+    clearError();
+
     if (egl_init_drivers() == EGL_FALSE) {
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
     }
@@ -1617,6 +1811,8 @@
 
 EGLenum eglQueryAPI(void)
 {
+    clearError();
+
     if (egl_init_drivers() == EGL_FALSE) {
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
     }
@@ -1637,6 +1833,11 @@
 
 EGLBoolean eglReleaseThread(void)
 {
+    clearError();
+
+    // If there is context bound to the thread, release it
+    loseCurrent(get_context(getContext()));
+
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
@@ -1653,6 +1854,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;
@@ -1672,6 +1875,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);
 
@@ -1690,6 +1895,8 @@
 
 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
 {
+    clearError();
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1709,6 +1916,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);
@@ -1780,6 +1989,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);
@@ -1811,6 +2022,119 @@
      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;
+
+    egl_context_t * const c = get_context(ctx);
+
+    if (c->cnx->egl.eglDestroySyncKHR) {
+        return c->cnx->egl.eglDestroySyncKHR(
+                dp->disp[c->impl].dpy, syncObject->sync);
+    }
+
+    return EGL_FALSE;
+}
+
+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
@@ -1819,6 +2143,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);
 
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..602ea1a
--- /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 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");
+
+    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..3730739 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
@@ -57,8 +58,7 @@
         mSecure(false),
         mTextureManager(),
         mBufferManager(mTextureManager),
-        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false),
-        mBypassState(false)
+        mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false)
 {
 }
 
@@ -83,8 +83,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);
@@ -171,7 +191,8 @@
     mReqHeight = h;
 
     mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
-    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
+            (flags & ISurfaceComposer::eOpaque) == 0;
 
     // we use the red index
     int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
@@ -182,6 +203,71 @@
     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,29 +338,6 @@
         }
         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);
 }
 
@@ -302,8 +365,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 +400,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 +420,7 @@
             mReqWidth  = reqWidth;
             mReqHeight = reqHeight;
             mReqFormat = reqFormat;
+            mFixedSize = fixedSize;
             mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
 
             lcblk->reallocateAllExcept(index);
@@ -365,40 +430,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();
@@ -445,39 +479,6 @@
     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,12 +582,20 @@
     }
 
     // we retired a buffer, which becomes the new front buffer
+
+    const bool noActiveBuffer = !mBufferManager.hasActiveBuffer();
     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) {
         // get the dirty region
@@ -712,9 +721,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);
 }
@@ -779,7 +788,7 @@
 
 Layer::BufferManager::BufferManager(TextureManager& tm)
     : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
-      mActiveBuffer(-1), mFailover(false)
+      mActiveBufferIndex(-1), mFailover(false)
 {
 }
 
@@ -787,9 +796,52 @@
 {
 }
 
-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) {
+        // Move the active texture into slot 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 +852,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 +923,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..2908119 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -68,6 +68,8 @@
     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);
@@ -80,12 +82,6 @@
     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 +163,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 +177,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 +188,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
@@ -237,7 +237,6 @@
     uint32_t mReqFormat;
     bool mNeedsScaling;
     bool mFixedSize;
-    bool mBypassState;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 916d420..8d83f0b 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
@@ -490,12 +499,18 @@
 
 void LayerBase::setBufferCrop(const Rect& crop) {
     if (!crop.isEmpty()) {
-        mBufferCrop = crop;
+        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
@@ -548,10 +563,15 @@
     if (s == 0) {
         s = createSurface();
         mClientSurface = s;
+        mClientSurfaceBinder = s->asBinder();
     }
     return s;
 }
 
+wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
+    return mClientSurfaceBinder;
+}
+
 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
 {
     return new Surface(mFlinger, mIdentity,
@@ -609,21 +629,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);
 }
 
@@ -638,26 +643,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 1470729..8ed4749 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;
@@ -285,6 +285,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); }
@@ -309,12 +310,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;
@@ -331,6 +326,7 @@
 private:
     mutable Mutex mLock;
     mutable wp<Surface> mClientSurface;
+    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..11f8feb 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -67,8 +67,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)
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4876946..87b66ea 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);
@@ -272,7 +269,7 @@
 
     // start boot animation
     property_set("ctl.start", "bootanim");
-    
+
     return NO_ERROR;
 }
 
@@ -375,17 +372,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 +403,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 +461,7 @@
         handleTransactionLocked(transactionFlags, ditchedLayers);
         mLastTransactionTime = systemTime() - now;
         mDebugInTransaction = 0;
+        invalidateHwcGeometry();
         // here the transaction has been committed
     }
 
@@ -487,6 +469,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 +673,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 +700,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 +725,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 +763,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 +797,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 +841,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 +1025,8 @@
             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
         }
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        glLoadIdentity();
+        glMatrixMode(GL_MODELVIEW);
     }
 }
 
@@ -1054,7 +1088,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) {
@@ -1113,7 +1147,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) {
@@ -1157,7 +1191,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))
@@ -1190,21 +1224,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;
@@ -1216,7 +1246,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;
@@ -1268,15 +1298,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)
@@ -1286,21 +1307,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).
@@ -1321,7 +1333,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;
@@ -1334,9 +1346,9 @@
             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.
@@ -1437,7 +1449,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()) {
@@ -1464,7 +1476,7 @@
         }
         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);
@@ -1507,9 +1519,9 @@
         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"
@@ -1530,10 +1542,21 @@
         }
 
         /*
+         * 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();
@@ -1607,6 +1630,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());
@@ -2100,7 +2128,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;
 
@@ -2123,6 +2152,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 ) ;
 
@@ -2137,6 +2169,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
@@ -2156,7 +2189,10 @@
         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
@@ -2191,8 +2227,6 @@
         glMatrixMode(GL_PROJECTION);
         glPopMatrix();
         glMatrixMode(GL_MODELVIEW);
-
-
     } else {
         result = BAD_VALUE;
     }
@@ -2204,6 +2238,8 @@
 
     hw.compositionComplete();
 
+    LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
+
     return result;
 }
 
@@ -2211,7 +2247,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))
@@ -2229,13 +2266,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 {
@@ -2249,14 +2291,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();
@@ -2406,12 +2448,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 {
@@ -2452,6 +2497,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 a023347..6dd91ac 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,32 @@
     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 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 +248,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 +310,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 +326,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);
@@ -395,18 +399,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..99f4b4f 100644
--- a/services/surfaceflinger/tests/resize/resize.cpp
+++ b/services/surfaceflinger/tests/resize/resize.cpp
@@ -10,8 +10,6 @@
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
-#include <ui/Overlay.h>
-
 using namespace android;
 
 namespace android {
@@ -32,7 +30,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..194fbb6 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -10,8 +10,6 @@
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
-#include <ui/Overlay.h>
-
 using namespace android;
 
 int main(int argc, char** argv)
@@ -23,7 +21,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;
+        }
+    }
+}
