diff --git a/cmds/bugreport/bugreport.c b/cmds/bugreport/bugreport.c
index 4a0b511..11e9057 100644
--- a/cmds/bugreport/bugreport.c
+++ b/cmds/bugreport/bugreport.c
@@ -29,7 +29,7 @@
     property_set("ctl.start", "dumpstate");
 
     /* socket will not be available until service starts */
-    for (i = 0; i < 10; i++) {
+    for (i = 0; i < 20; i++) {
         s = socket_local_client("dumpstate",
                              ANDROID_SOCKET_NAMESPACE_RESERVED,
                              SOCK_STREAM);
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 220af47..7fb5b12 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -174,9 +174,7 @@
     dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
     dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
 
-    run_command("SYSTEM SETTINGS", 20, SU_PATH, "root", "sqlite3",
-            "/data/data/com.android.providers.settings/databases/settings.db",
-            "pragma user_version; select * from system; select * from secure; select * from global;", NULL);
+    for_each_userid(do_dump_settings, NULL);
 
     /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
     run_command("NETWORK INTERFACES", 10, SU_PATH, "root", "netcfg", NULL);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 67bbd7e..d820495 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -26,6 +26,7 @@
 
 typedef void (for_each_pid_func)(int, const char *);
 typedef void (for_each_tid_func)(int, int, const char *);
+typedef void (for_each_userid_func)(int);
 
 /* prints the contents of a file */
 int dump_file(const char *title, const char* path);
@@ -51,6 +52,9 @@
 /* for each thread in the system, run the specified function */
 void for_each_tid(for_each_tid_func func, const char *header);
 
+/* for each user id in the system, run the specified function */
+void for_each_userid(for_each_userid_func func, const char *header);
+
 /* Displays a blocked processes in-kernel wait channel */
 void show_wchan(int pid, int tid, const char *name);
 
@@ -60,6 +64,9 @@
 /* Gets the dmesg output for the kernel */
 void do_dmesg();
 
+/* Dumps settings for a given user id */
+void do_dump_settings(int userid);
+
 /* Play a sound via Stagefright */
 void play_sound(const char* path);
 
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index fe716ac..7f84f98 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -51,6 +51,29 @@
         NULL,
 };
 
+void for_each_userid(void (*func)(int), const char *header) {
+    DIR *d;
+    struct dirent *de;
+
+    if (header) printf("\n------ %s ------\n", header);
+    func(0);
+
+    if (!(d = opendir("/data/system/users"))) {
+        printf("Failed to open /data/system/users (%s)\n", strerror(errno));
+        return;
+    }
+
+    while ((de = readdir(d))) {
+        int userid;
+        if (de->d_type != DT_DIR || !(userid = atoi(de->d_name))) {
+            continue;
+        }
+        func(userid);
+    }
+
+    closedir(d);
+}
+
 static void __for_each_pid(void (*helper)(int, const char *, void *), const char *header, void *arg) {
     DIR *d;
     struct dirent *de;
@@ -175,6 +198,22 @@
     return;
 }
 
+void do_dump_settings(int userid) {
+    char title[255];
+    char dbpath[255];
+    char sql[255];
+    sprintf(title, "SYSTEM SETTINGS (user %d)", userid);
+    if (userid == 0) {
+        strcpy(dbpath, "/data/data/com.android.providers.settings/databases/settings.db");
+        strcpy(sql, "pragma user_version; select * from system; select * from secure; select * from global;");
+    } else {
+        sprintf(dbpath, "/data/system/users/%d/settings.db", userid);
+        strcpy(sql, "pragma user_version; select * from system; select * from secure;");
+    }
+    run_command(title, 20, SU_PATH, "root", "sqlite3", dbpath, sql, NULL);
+    return;
+}
+
 void do_dmesg() {
     printf("------ KERNEL LOG (dmesg) ------\n");
     /* Get size of kernel buffer */
diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp
index d6ac3d2..e80dbb1 100644
--- a/cmds/flatland/Main.cpp
+++ b/cmds/flatland/Main.cpp
@@ -73,7 +73,7 @@
         },
     },
 
-    { "3:2 Single Static Window",
+    { "4:3 Single Static Window",
         2048, 1536, { 1536 },
         {
             {   // Window
@@ -117,7 +117,7 @@
         },
     },
 
-    { "3:2 App -> Home Transition",
+    { "4:3 App -> Home Transition",
         2048, 1536, { 1536 },
         {
             {   // Wallpaper
@@ -173,7 +173,7 @@
         },
     },
 
-    { "3:2 SurfaceView -> Home Transition",
+    { "4:3 SurfaceView -> Home Transition",
         2048, 1536, { 1536 },
         {
             {   // Wallpaper
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 79ce6ed..cacbea0 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -32,6 +32,8 @@
     { AID_MEDIA, "media.player" },
     { AID_MEDIA, "media.camera" },
     { AID_MEDIA, "media.audio_policy" },
+    { AID_AUDIO, "audio" },
+    { AID_INPUT, "input" },
     { AID_DRM,   "drm.drmManager" },
     { AID_NFC,   "nfc" },
     { AID_BLUETOOTH, "bluetooth" },
diff --git a/include/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h
index 829061a..7ae1342 100644
--- a/include/batteryservice/BatteryService.h
+++ b/include/batteryservice/BatteryService.h
@@ -43,6 +43,13 @@
     BATTERY_HEALTH_COLD = 7, // equals BatteryManager.BATTERY_HEALTH_COLD constant
 };
 
+// must be kept in sync with definitions in BatteryProperty.java
+enum {
+    BATTERY_PROP_CHARGE_COUNTER = 1, // equals BatteryProperty.BATTERY_PROP_CHARGE_COUNTER constant
+    BATTERY_PROP_CURRENT_NOW = 2, // equals BatteryProperty.BATTERY_PROP_CURRENT_NOW constant
+    BATTERY_PROP_CURRENT_AVG = 3, // equals BatteryProperty.BATTERY_PROP_CURRENT_AVG constant
+};
+
 struct BatteryProperties {
     bool chargerAcOnline;
     bool chargerUsbOnline;
@@ -52,8 +59,6 @@
     bool batteryPresent;
     int batteryLevel;
     int batteryVoltage;
-    int batteryCurrentNow;
-    int batteryChargeCounter;
     int batteryTemperature;
     String8 batteryTechnology;
 
@@ -61,6 +66,13 @@
     status_t readFromParcel(Parcel* parcel);
 };
 
+struct BatteryProperty {
+    int valueInt;
+
+    status_t writeToParcel(Parcel* parcel) const;
+    status_t readFromParcel(Parcel* parcel);
+};
+
 }; // namespace android
 
 #endif // ANDROID_BATTERYSERVICE_H
diff --git a/include/batteryservice/IBatteryPropertiesRegistrar.h b/include/batteryservice/IBatteryPropertiesRegistrar.h
index 8d28b1d..eca075d 100644
--- a/include/batteryservice/IBatteryPropertiesRegistrar.h
+++ b/include/batteryservice/IBatteryPropertiesRegistrar.h
@@ -26,6 +26,7 @@
 enum {
     REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
     UNREGISTER_LISTENER,
+    GET_PROPERTY,
 };
 
 class IBatteryPropertiesRegistrar : public IInterface {
@@ -34,6 +35,7 @@
 
     virtual void registerListener(const sp<IBatteryPropertiesListener>& listener) = 0;
     virtual void unregisterListener(const sp<IBatteryPropertiesListener>& listener) = 0;
+    virtual status_t getProperty(int id, struct BatteryProperty *val) = 0;
 };
 
 class BnBatteryPropertiesRegistrar : public BnInterface<IBatteryPropertiesRegistrar> {
diff --git a/include/binder/IBatteryStats.h b/include/binder/IBatteryStats.h
new file mode 100644
index 0000000..f4a8aa3
--- /dev/null
+++ b/include/binder/IBatteryStats.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 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_IBATTERYSTATS_H
+#define ANDROID_IBATTERYSTATS_H
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IBatteryStats : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(BatteryStats);
+
+    virtual void noteStartSensor(int uid, int sensor) = 0;
+    virtual void noteStopSensor(int uid, int sensor) = 0;
+
+    enum {
+        NOTE_START_SENSOR_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+        NOTE_STOP_SENSOR_TRANSACTION,
+    };
+};
+
+// ----------------------------------------------------------------------
+
+class BnBatteryStats : public BnInterface<IBatteryStats>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IBATTERYSTATS_H
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 8b84951..43b6543 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -81,14 +81,6 @@
                                         Parcel* reply,
                                         uint32_t flags = 0) = 0;
 
-    /**
-     * This method allows you to add data that is transported through
-     * IPC along with your IBinder pointer.  When implementing a Binder
-     * object, override it to write your desired data in to @a outData.
-     * You can then call getConstantData() on your IBinder to retrieve
-     * that data, from any process.  You MUST return the number of bytes
-     * written in to the parcel (including padding).
-     */
     class DeathRecipient : public virtual RefBase
     {
     public:
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index ed2e7df..e9966fe 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -128,6 +128,11 @@
     // will be closed once the parcel is destroyed.
     status_t            writeDupFileDescriptor(int fd);
 
+    // Writes a raw fd and optional comm channel fd to the parcel as a ParcelFileDescriptor.
+    // A dup's of the fds are made, which will be closed once the parcel is destroyed.
+    // Null values are passed as -1.
+    status_t            writeParcelFileDescriptor(int fd, int commChannel = -1);
+
     // Writes a blob to the parcel.
     // If the blob is small, then it is stored in-place, otherwise it is
     // transferred by way of an anonymous shared memory region.
@@ -187,6 +192,11 @@
     // in the parcel, which you do not own -- use dup() to get your own copy.
     int                 readFileDescriptor() const;
 
+    // Reads a ParcelFileDescriptor from the parcel.  Returns the raw fd as
+    // the result, and the optional comm channel fd in outCommChannel.
+    // Null values are returned as -1.
+    int                 readParcelFileDescriptor(int& outCommChannel) const;
+
     // Reads a blob from the parcel.
     // The caller should call release() on the blob after reading its contents.
     status_t            readBlob(size_t len, ReadableBlob* outBlob) const;
diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h
index 52edf17..2c58ca5 100644
--- a/include/gui/BufferItemConsumer.h
+++ b/include/gui/BufferItemConsumer.h
@@ -44,6 +44,7 @@
 
     typedef BufferQueue::BufferItem BufferItem;
 
+    enum { MIN_UNDEQUEUED_BUFFERS = -1 };
     enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
     enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
 
@@ -54,7 +55,7 @@
     // controlledByApp tells whether this consumer is controlled by the
     // application.
     BufferItemConsumer(const sp<BufferQueue>& bq, uint32_t consumerUsage,
-            int bufferCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS,
+            int bufferCount = MIN_UNDEQUEUED_BUFFERS,
             bool controlledByApp = false);
 
     virtual ~BufferItemConsumer();
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 408956b..15dc645 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -41,11 +41,16 @@
                     public BnGraphicBufferConsumer,
                     private IBinder::DeathRecipient {
 public:
-    enum { MIN_UNDEQUEUED_BUFFERS = 2 };
+    // BufferQueue will keep track of at most this value of buffers.
+    // Attempts at runtime to increase the number of buffers past this will fail.
     enum { NUM_BUFFER_SLOTS = 32 };
-    enum { NO_CONNECTED_API = 0 };
-    enum { INVALID_BUFFER_SLOT = -1 };
-    enum { STALE_BUFFER_SLOT = 1, NO_BUFFER_AVAILABLE, PRESENT_LATER };
+    // Used as a placeholder slot# when the value isn't pointing to an existing buffer.
+    enum { INVALID_BUFFER_SLOT = IGraphicBufferConsumer::BufferItem::INVALID_BUFFER_SLOT };
+    // Alias to <IGraphicBufferConsumer.h> -- please scope from there in future code!
+    enum {
+        NO_BUFFER_AVAILABLE = IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
+        PRESENT_LATER = IGraphicBufferConsumer::PRESENT_LATER,
+    };
 
     // When in async mode we reserve two slots in order to guarantee that the
     // producer and consumer can run asynchronously.
@@ -75,7 +80,6 @@
         wp<ConsumerListener> mConsumerListener;
     };
 
-
     // BufferQueue manages a pool of gralloc memory slots to be used by
     // producers and consumers. allocator is used to allocate all the
     // needed gralloc buffers.
@@ -103,7 +107,7 @@
     //
     // This will fail if the producer has dequeued any buffers, or if
     // bufferCount is invalid.  bufferCount must generally be a value
-    // between the minimum undequeued buffer count and NUM_BUFFER_SLOTS
+    // between the minimum undequeued buffer count (exclusive) and NUM_BUFFER_SLOTS
     // (inclusive).  It may also be set to zero (the default) to indicate
     // that the producer does not wish to set a value.  The minimum value
     // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
@@ -212,7 +216,7 @@
      */
 
     // acquireBuffer attempts to acquire ownership of the next pending buffer in
-    // the BufferQueue.  If no buffer is pending then it returns -EINVAL.  If a
+    // the BufferQueue.  If no buffer is pending then it returns NO_BUFFER_AVAILABLE. If a
     // buffer is successfully acquired, the information about the buffer is
     // returned in BufferItem.  If the buffer returned had previously been
     // acquired then the BufferItem::mGraphicBuffer field of buffer is set to
@@ -224,7 +228,7 @@
     // future, the buffer won't be acquired, and PRESENT_LATER will be
     // returned.  The presentation time is in nanoseconds, and the time base
     // is CLOCK_MONOTONIC.
-    virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen);
+    virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen);
 
     // releaseBuffer releases a buffer slot from the consumer back to the
     // BufferQueue.  This may be done while the buffer's contents are still
@@ -312,8 +316,13 @@
     // dump our state in a String
     virtual void dump(String8& result, const char* prefix) const;
 
-
 private:
+    // The default API number used to indicate no producer client is connected.
+    enum { NO_CONNECTED_API = 0 };
+
+    // Aliases for using enums from <IGraphicBufferConsumer.h>
+    enum { STALE_BUFFER_SLOT = IGraphicBufferConsumer::STALE_BUFFER_SLOT };
+
     // freeBufferLocked frees the GraphicBuffer and sync resources for the
     // given slot.
     void freeBufferLocked(int index);
diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h
index 0e35f13..9a6645c 100644
--- a/include/gui/IGraphicBufferConsumer.h
+++ b/include/gui/IGraphicBufferConsumer.h
@@ -48,6 +48,7 @@
         status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
 
     public:
+        // The default value of mBuf, used to indicate this doesn't correspond to a slot.
         enum { INVALID_BUFFER_SLOT = -1 };
         BufferItem();
 
@@ -63,13 +64,17 @@
         Rect mCrop;
 
         // mTransform is the current transform flags for this buffer slot.
+        // refer to NATIVE_WINDOW_TRANSFORM_* in <window.h>
         uint32_t mTransform;
 
         // mScalingMode is the current scaling mode for this buffer slot.
+        // refer to NATIVE_WINDOW_SCALING_* in <window.h>
         uint32_t mScalingMode;
 
         // mTimestamp is the current timestamp for this buffer slot. This gets
-        // to set by queueBuffer each time this slot is queued.
+        // to set by queueBuffer each time this slot is queued. This value
+        // is guaranteed to be monotonically increasing for each newly
+        // acquired buffer.
         int64_t mTimestamp;
 
         // mIsAutoTimestamp indicates whether mTimestamp was generated
@@ -79,7 +84,7 @@
         // mFrameNumber is the number of the queued frame for this slot.
         uint64_t mFrameNumber;
 
-        // mBuf is the slot index of this buffer
+        // mBuf is the slot index of this buffer (default INVALID_BUFFER_SLOT).
         int mBuf;
 
         // mIsDroppable whether this buffer was queued with the
@@ -97,21 +102,42 @@
         bool mTransformToDisplayInverse;
     };
 
+    enum {
+        // Returned by releaseBuffer, after which the consumer must
+        // free any references to the just-released buffer that it might have.
+        STALE_BUFFER_SLOT = 1,
+        // Returned by dequeueBuffer if there are no pending buffers available.
+        NO_BUFFER_AVAILABLE,
+        // Returned by dequeueBuffer if it's too early for the buffer to be acquired.
+        PRESENT_LATER,
+    };
 
     // acquireBuffer attempts to acquire ownership of the next pending buffer in
-    // the BufferQueue.  If no buffer is pending then it returns -EINVAL.  If a
-    // buffer is successfully acquired, the information about the buffer is
-    // returned in BufferItem.  If the buffer returned had previously been
+    // the BufferQueue.  If no buffer is pending then it returns
+    // NO_BUFFER_AVAILABLE.  If a buffer is successfully acquired, the
+    // information about the buffer is returned in BufferItem.
+    //
+    // If the buffer returned had previously been
     // acquired then the BufferItem::mGraphicBuffer field of buffer is set to
     // NULL and it is assumed that the consumer still holds a reference to the
     // buffer.
     //
-    // If presentWhen is nonzero, it indicates the time when the buffer will
+    // If presentWhen is non-zero, it indicates the time when the buffer will
     // be displayed on screen.  If the buffer's timestamp is farther in the
     // future, the buffer won't be acquired, and PRESENT_LATER will be
     // returned.  The presentation time is in nanoseconds, and the time base
     // is CLOCK_MONOTONIC.
-    virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) = 0;
+    //
+    // Return of NO_ERROR means the operation completed as normal.
+    //
+    // Return of a positive value means the operation could not be completed
+    //    at this time, but the user should try again later:
+    // * NO_BUFFER_AVAILABLE - no buffer is pending (nothing queued by producer)
+    // * PRESENT_LATER - the buffer's timestamp is farther in the future
+    //
+    // Return of a negative value means an error has occurred:
+    // * INVALID_OPERATION - too many buffers have been acquired
+    virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen) = 0;
 
     // releaseBuffer releases a buffer slot from the consumer back to the
     // BufferQueue.  This may be done while the buffer's contents are still
@@ -125,6 +151,18 @@
     //
     // Note that the dependencies on EGL will be removed once we switch to using
     // the Android HW Sync HAL.
+    //
+    // Return of NO_ERROR means the operation completed as normal.
+    //
+    // Return of a positive value means the operation could not be completed
+    //    at this time, but the user should try again later:
+    // * STALE_BUFFER_SLOT - see above (second paragraph)
+    //
+    // Return of a negative value means an error has occurred:
+    // * BAD_VALUE - one of the following could've happened:
+    //               * the buffer slot was invalid
+    //               * the fence was NULL
+    //               * the buffer slot specified is not in the acquired state
     virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
             EGLDisplay display, EGLSyncKHR fence,
             const sp<Fence>& releaseFence) = 0;
@@ -137,24 +175,38 @@
     // the application.
     //
     // consumer may not be NULL.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - the buffer queue has been abandoned
+    // * BAD_VALUE - a NULL consumer was provided
     virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) = 0;
 
     // consumerDisconnect disconnects a consumer from the BufferQueue. All
     // buffers will be freed and the BufferQueue is placed in the "abandoned"
     // state, causing most interactions with the BufferQueue by the producer to
     // fail.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * BAD_VALUE - no consumer is currently connected
     virtual status_t consumerDisconnect() = 0;
 
-    // getReleasedBuffers sets the value pointed to by slotMask to a bit mask
-    // indicating which buffer slots have been released by the BufferQueue
-    // but have not yet been released by the consumer.
+    // getReleasedBuffers sets the value pointed to by slotMask to a bit set.
+    // Each bit index with a 1 corresponds to a released buffer slot with that
+    // index value.  In particular, a released buffer is one that has
+    // been released by the BufferQueue but have not yet been released by the consumer.
     //
     // This should be called from the onBuffersReleased() callback.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - the buffer queue has been abandoned.
     virtual status_t getReleasedBuffers(uint32_t* slotMask) = 0;
 
     // setDefaultBufferSize is used to set the size of buffers returned by
     // dequeueBuffer when a width and height of zero is requested.  Default
     // is 1x1.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * BAD_VALUE - either w or h was zero
     virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) = 0;
 
     // setDefaultMaxBufferCount sets the default value for the maximum buffer
@@ -163,6 +215,9 @@
     // take effect if the producer sets the count back to zero.
     //
     // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * BAD_VALUE - bufferCount was out of range (see above).
     virtual status_t setDefaultMaxBufferCount(int bufferCount) = 0;
 
     // disableAsyncBuffer disables the extra buffer used in async mode
@@ -170,11 +225,20 @@
     // flag) and has dequeueBuffer() return WOULD_BLOCK instead.
     //
     // This can only be called before consumerConnect().
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * INVALID_OPERATION - attempting to call this after consumerConnect.
     virtual status_t disableAsyncBuffer() = 0;
 
     // setMaxAcquiredBufferCount sets the maximum number of buffers that can
     // be acquired by the consumer at one time (default 1).  This call will
     // fail if a producer is connected to the BufferQueue.
+    //
+    // maxAcquiredBuffers must be (inclusive) between 1 and MAX_MAX_ACQUIRED_BUFFERS.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * BAD_VALUE - maxAcquiredBuffers was out of range (see above).
+    // * INVALID_OPERATION - attempting to call this after a producer connected.
     virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0;
 
     // setConsumerName sets the name used in logging
@@ -184,16 +248,22 @@
     // GraphicBuffers of a defaultFormat if no format is specified
     // in dequeueBuffer.  Formats are enumerated in graphics.h; the
     // initial default is HAL_PIXEL_FORMAT_RGBA_8888.
+    //
+    // Return of a value other than NO_ERROR means an unknown error has occurred.
     virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) = 0;
 
     // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer.
     // These are merged with the bits passed to dequeueBuffer.  The values are
     // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0.
+    //
+    // Return of a value other than NO_ERROR means an unknown error has occurred.
     virtual status_t setConsumerUsageBits(uint32_t usage) = 0;
 
     // setTransformHint bakes in rotation to buffers so overlays can be used.
     // The values are enumerated in window.h, e.g.
     // NATIVE_WINDOW_TRANSFORM_ROT_90.  The default is 0 (no transform).
+    //
+    // Return of a value other than NO_ERROR means an unknown error has occurred.
     virtual status_t setTransformHint(uint32_t hint) = 0;
 
     // dump state into a string
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 342ba08..7002530 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -54,7 +54,11 @@
     DECLARE_META_INTERFACE(GraphicBufferProducer);
 
     enum {
+        // A flag returned by dequeueBuffer when the client needs to call
+        // requestBuffer immediately thereafter.
         BUFFER_NEEDS_REALLOCATION = 0x1,
+        // A flag returned by dequeueBuffer when all mirrored slots should be
+        // released by the client. This flag should always be processed first.
         RELEASE_ALL_BUFFERS       = 0x2,
     };
 
@@ -63,51 +67,144 @@
     // 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.
+    //
+    // The slot must be in the range of [0, NUM_BUFFER_SLOTS).
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - the buffer queue has been abandoned.
+    // * BAD_VALUE - one of the two conditions occurred:
+    //              * slot was out of range (see above)
+    //              * buffer specified by the slot is not dequeued
     virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 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.
+    //
+    // This function should not be called when there are any dequeued buffer
+    // slots, doing so will result in a BAD_VALUE error returned.
+    //
+    // The buffer count should be at most NUM_BUFFER_SLOTS (inclusive), but at least
+    // the minimum undequeued buffer count (exclusive). The minimum value
+    // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS).
+    // In particular the range is (minUndequeudBuffers, NUM_BUFFER_SLOTS].
+    //
+    // The buffer count may also be set to 0 (the default), to indicate that
+    // the producer does not wish to set a value.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - the buffer queue has been abandoned.
+    // * BAD_VALUE - one of the below conditions occurred:
+    //              * bufferCount was out of range (see above)
+    //              * client has one or more buffers dequeued
     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.
-    // If dequeueBuffer return BUFFER_NEEDS_REALLOCATION, the client is
+    // use the contents of the buffer associated with that slot.
+    //
+    // The slot index returned may or may not contain a buffer (client-side).
+    // If the slot is empty the client should call requestBuffer to assign a new
+    // buffer to that slot.
+    //
+    // Once the client is done filling this buffer, it is expected to transfer
+    // buffer ownership back to the server with either cancelBuffer on
+    // the dequeued slot or to fill in the contents of its associated buffer
+    // contents and call queueBuffer.
+    //
+    // If dequeueBuffer returns the BUFFER_NEEDS_REALLOCATION flag, the client is
     // expected to call requestBuffer immediately.
     //
+    // If dequeueBuffer returns the RELEASE_ALL_BUFFERS flag, the client is
+    // expected to release all of the mirrored slot->buffer mappings.
+    //
     // The fence parameter will be updated to hold the fence associated with
     // the buffer. The contents of the buffer must not be overwritten until the
-    // fence signals. If the fence is NULL, the buffer may be written
+    // fence signals. If the fence is Fence::NO_FENCE, the buffer may be written
     // immediately.
     //
-    // The async parameter sets whether we're in asynchrnous mode for this
-    // deququeBuffer() call.
-    virtual status_t dequeueBuffer(int *slot, sp<Fence>* fence, bool async,
+    // The async parameter sets whether we're in asynchronous mode for this
+    // dequeueBuffer() call.
+    //
+    // The width and height parameters must be no greater than the minimum of
+    // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
+    // An error due to invalid dimensions might not be reported until
+    // updateTexImage() is called.  If width and height are both zero, the
+    // default values specified by setDefaultBufferSize() are used instead.
+    //
+    // The pixel formats are enumerated in <graphics.h>, e.g.
+    // HAL_PIXEL_FORMAT_RGBA_8888.  If the format is 0, the default format
+    // will be used.
+    //
+    // The usage argument specifies gralloc buffer usage flags.  The values
+    // are enumerated in <gralloc.h>, e.g. GRALLOC_USAGE_HW_RENDER.  These
+    // will be merged with the usage flags specified by
+    // IGraphicBufferConsumer::setConsumerUsageBits.
+    //
+    // This call will block until a buffer is available to be dequeued. If
+    // both the producer and consumer are controlled by the app, then this call
+    // can never block and will return WOULD_BLOCK if no buffer is available.
+    //
+    // A non-negative value with flags set (see above) will be returned upon
+    // success.
+    //
+    // Return of a negative means an error has occurred:
+    // * NO_INIT - the buffer queue has been abandoned.
+    // * BAD_VALUE - one of the below conditions occurred:
+    //              * both in async mode and buffer count was less than the
+    //                max numbers of buffers that can be allocated at once
+    //              * attempting dequeue more than one buffer at a time
+    //                without setting the buffer count with setBufferCount()
+    // * -EBUSY - attempting to dequeue too many buffers at a time
+    // * WOULD_BLOCK - no buffer is currently available, and blocking is disabled
+    //                 since both the producer/consumer are controlled by app
+    // * NO_MEMORY - out of memory, cannot allocate the graphics buffer.
+    //
+    // All other negative values are an unknown error returned downstream
+    // from the graphics allocator (typically errno).
+    virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, bool async,
             uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 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. In addition, a timestamp must be provided by the
-    // client for this buffer. The timestamp is measured in nanoseconds, and
-    // must be monotonically increasing. Its other properties (zero point, etc)
+    // 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
+    // (an attempt to do so will fail with a return value of BAD_VALUE).
+    //
+    // In addition, the input must be described by the client (as documented
+    // below). Any other properties (zero point, etc)
     // are client-dependent, and should be documented by the client.
     //
-    // The async parameter sets whether we're queuing a buffer in asynchronous mode.
+    // The slot must be in the range of [0, NUM_BUFFER_SLOTS).
     //
-    // outWidth, outHeight and outTransform are filled with the default width
-    // and height of the window and current transform applied to buffers,
-    // respectively.
+    // Upon success, the output will be filled with meaningful values
+    // (refer to the documentation below).
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - the buffer queue has been abandoned.
+    // * BAD_VALUE - one of the below conditions occurred:
+    //              * fence was NULL
+    //              * scaling mode was unknown
+    //              * both in async mode and buffer count was less than the
+    //                max numbers of buffers that can be allocated at once
+    //              * slot index was out of range (see above).
+    //              * the slot was not in the dequeued state
+    //              * the slot was enqueued without requesting a buffer
+    //              * crop rect is out of bounds of the buffer dimensions
 
     struct QueueBufferInput : public Flattenable<QueueBufferInput> {
         friend class Flattenable<QueueBufferInput>;
         inline QueueBufferInput(const Parcel& parcel);
+        // timestamp - a monotonically increasing value in nanoseconds
+        // isAutoTimestamp - if the timestamp was synthesized at queue time
+        // crop - a crop rectangle that's used as a hint to the consumer
+        // scalingMode - a set of flags from NATIVE_WINDOW_SCALING_* in <window.h>
+        // transform - a set of flags from NATIVE_WINDOW_TRANSFORM_* in <window.h>
+        // async - if the buffer is queued in asynchronous mode
+        // fence - a fence that the consumer must wait on before reading the buffer,
+        //         set this to Fence::NO_FENCE if the buffer is ready immediately
         inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp,
                 const Rect& crop, int scalingMode, uint32_t transform, bool async,
                 const sp<Fence>& fence)
@@ -143,8 +240,13 @@
     };
 
     // QueueBufferOutput must be a POD structure
-    struct QueueBufferOutput {
+    struct __attribute__ ((__packed__)) QueueBufferOutput {
         inline QueueBufferOutput() { }
+        // outWidth - filled with default width applied to the buffer
+        // outHeight - filled with default height applied to the buffer
+        // outTransformHint - filled with default transform applied to the buffer
+        // outNumPendingBuffers - num buffers queued that haven't yet been acquired
+        //                        (counting the currently queued buffer)
         inline void deflate(uint32_t* outWidth,
                 uint32_t* outHeight,
                 uint32_t* outTransformHint,
@@ -174,24 +276,54 @@
     // 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.
+    //
+    // The buffer is not queued for use by the consumer.
+    //
+    // The buffer will not be overwritten until the fence signals.  The fence
+    // will usually be the one obtained from dequeueBuffer.
     virtual void cancelBuffer(int slot, const sp<Fence>& fence) = 0;
 
     // query retrieves some information for this surface
-    // 'what' tokens allowed are that of android_natives.h
+    // 'what' tokens allowed are that of NATIVE_WINDOW_* in <window.h>
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - the buffer queue has been abandoned.
+    // * BAD_VALUE - what was out of range
     virtual int query(int what, int* value) = 0;
 
     // connect attempts to connect a client API to the IGraphicBufferProducer.
     // This must be called before any other IGraphicBufferProducer methods are
-    // called except for getAllocator.
+    // called except for getAllocator. A consumer must be already connected.
     //
     // This method will fail if the connect was previously called on the
     // IGraphicBufferProducer and no corresponding disconnect call was made.
     //
-    // outWidth, outHeight and outTransform are filled with the default width
-    // and height of the window and current transform applied to buffers,
-    // respectively. The token needs to be any binder object that lives in the
+    // The token needs to be any opaque binder object that lives in the
     // producer process -- it is solely used for obtaining a death notification
     // when the producer is killed.
+    //
+    // The api should be one of the NATIVE_WINDOW_API_* values in <window.h>
+    //
+    // The producerControlledByApp should be set to true if the producer is hosted
+    // by an untrusted process (typically app_process-forked processes). If both
+    // the producer and the consumer are app-controlled then all buffer queues
+    // will operate in async mode regardless of the async flag.
+    //
+    // Upon success, the output will be filled with meaningful data
+    // (refer to QueueBufferOutput documentation above).
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - one of the following occurred:
+    //             * the buffer queue was abandoned
+    //             * no consumer has yet connected
+    // * BAD_VALUE - one of the following has occurred:
+    //             * the producer is already connected
+    //             * api was out of range (see above).
+    //             * output was NULL.
+    // * DEAD_OBJECT - the token is hosted by an already-dead process
+    //
+    // Additional negative errors may be returned by the internals, they
+    // should be treated as opaque fatal unrecoverable errors.
     virtual status_t connect(const sp<IBinder>& token,
             int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;
 
@@ -203,6 +335,17 @@
     //
     // This method will fail if the the IGraphicBufferProducer is not currently
     // connected to the specified client API.
+    //
+    // The api should be one of the NATIVE_WINDOW_API_* values in <window.h>
+    //
+    // Disconnecting from an abandoned IGraphicBufferProducer is legal and
+    // is considered a no-op.
+    //
+    // Return of a value other than NO_ERROR means an error has occurred:
+    // * BAD_VALUE - one of the following has occurred:
+    //             * the api specified does not match the one that was connected
+    //             * api was out of range (see above).
+    // * DEAD_OBJECT - the token is hosted by an already-dead process
     virtual status_t disconnect(int api) = 0;
 };
 
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
new file mode 100644
index 0000000..79ff12a
--- /dev/null
+++ b/include/input/IInputFlinger.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 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 _LIBINPUT_IINPUT_FLINGER_H
+#define _LIBINPUT_IINPUT_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+/*
+ * This class defines the Binder IPC interface for accessing various
+ * InputFlinger features.
+ */
+class IInputFlinger : public IInterface {
+public:
+    DECLARE_META_INTERFACE(InputFlinger);
+
+    virtual status_t doSomething() = 0;
+};
+
+
+/**
+ * Binder implementation.
+ */
+class BnInputFlinger : public BnInterface<IInputFlinger> {
+public:
+    enum {
+        DO_SOMETHING_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+    };
+
+    virtual status_t onTransact(uint32_t code, const Parcel& data,
+            Parcel* reply, uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_IINPUT_FLINGER_H
diff --git a/include/input/Input.h b/include/input/Input.h
index e778076..37f3b72 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -65,6 +65,34 @@
     AINPUT_SOURCE_SWITCH = 0x80000000,
 };
 
+enum {
+    /**
+     * Constants for LEDs. Hidden from the API since we don't actually expose a way to interact
+     * with LEDs to developers
+     *
+     * NOTE: If you add LEDs here, you must also add them to KeycodeLabels.h
+     */
+
+    ALED_NUM_LOCK = 0x00,
+    ALED_CAPS_LOCK = 0x01,
+    ALED_SCROLL_LOCK = 0x02,
+    ALED_COMPOSE = 0x03,
+    ALED_KANA = 0x04,
+    ALED_SLEEP = 0x05,
+    ALED_SUSPEND = 0x06,
+    ALED_MUTE = 0x07,
+    ALED_MISC = 0x08,
+    ALED_MAIL = 0x09,
+    ALED_CHARGING = 0x0a,
+    ALED_CONTROLLER_1 = 0x10,
+    ALED_CONTROLLER_2 = 0x11,
+    ALED_CONTROLLER_3 = 0x12,
+    ALED_CONTROLLER_4 = 0x13,
+};
+
+/* Maximum number of controller LEDs we support */
+#define MAX_CONTROLLER_LEDS 4
+
 /*
  * SystemUiVisibility constants from View.
  */
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index 1419b45..adf9fb9 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -46,6 +46,11 @@
     // Ideally, the way this value is computed should not change between Android releases
     // because that would invalidate persistent settings that rely on it.
     String8 descriptor;
+
+    // A value added to uniquely identify a device in the absence of a unique id. This
+    // is intended to be a minimum way to distinguish from other active devices and may
+    // reuse values that are not associated with an input anymore.
+    uint16_t nonce;
 };
 
 /*
diff --git a/include/input/KeyLayoutMap.h b/include/input/KeyLayoutMap.h
index eec11cf..1e8de71 100644
--- a/include/input/KeyLayoutMap.h
+++ b/include/input/KeyLayoutMap.h
@@ -67,6 +67,8 @@
     status_t mapKey(int32_t scanCode, int32_t usageCode,
             int32_t* outKeyCode, uint32_t* outFlags) const;
     status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
+    status_t findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const;
+    status_t findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const;
 
     status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
 
@@ -79,9 +81,16 @@
         uint32_t flags;
     };
 
+    struct Led {
+        int32_t ledCode;
+    };
+
+
     KeyedVector<int32_t, Key> mKeysByScanCode;
     KeyedVector<int32_t, Key> mKeysByUsageCode;
     KeyedVector<int32_t, AxisInfo> mAxes;
+    KeyedVector<int32_t, Led> mLedsByScanCode;
+    KeyedVector<int32_t, Led> mLedsByUsageCode;
 
     KeyLayoutMap();
 
@@ -99,6 +108,7 @@
     private:
         status_t parseKey();
         status_t parseAxis();
+        status_t parseLed();
     };
 };
 
diff --git a/include/input/Keyboard.h b/include/input/Keyboard.h
index 846cb0c..25b2f07 100644
--- a/include/input/Keyboard.h
+++ b/include/input/Keyboard.h
@@ -94,18 +94,24 @@
 extern uint32_t getKeyFlagByLabel(const char* label);
 
 /**
- * Gets a axis by its short form label, eg. "X".
+ * Gets an axis by its short form label, eg. "X".
  * Returns -1 if unknown.
  */
 extern int32_t getAxisByLabel(const char* label);
 
 /**
- * Gets a axis label by its id.
+ * Gets an axis label by its id.
  * Returns NULL if unknown.
  */
 extern const char* getAxisLabel(int32_t axisId);
 
 /**
+ * Gets an LED by its short form label, eg. "CAPS_LOCK".
+ * Returns -1 if unknown.
+ */
+extern int32_t getLedByLabel(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);
diff --git a/include/input/KeycodeLabels.h b/include/input/KeycodeLabels.h
index c64c5d8..19582e9 100644
--- a/include/input/KeycodeLabels.h
+++ b/include/input/KeycodeLabels.h
@@ -319,4 +319,26 @@
     { NULL, -1 }
 };
 
+static const KeycodeLabel LEDS[] = {
+    { "NUM_LOCK", 0x00 },
+    { "CAPS_LOCK", 0x01 },
+    { "SCROLL_LOCK", 0x02 },
+    { "COMPOSE", 0x03 },
+    { "KANA", 0x04 },
+    { "SLEEP", 0x05 },
+    { "SUSPEND", 0x06 },
+    { "MUTE", 0x07 },
+    { "MISC", 0x08 },
+    { "MAIL", 0x09 },
+    { "CHARGING", 0x0a },
+    { "CONTROLLER_1", 0x10 },
+    { "CONTROLLER_2", 0x11 },
+    { "CONTROLLER_3", 0x12 },
+    { "CONTROLLER_4", 0x13 },
+
+    // NOTE: If you add new LEDs here, you must also add them to Input.h
+
+    { NULL, -1 }
+};
+
 #endif // _LIBINPUT_KEYCODE_LABELS_H
diff --git a/include/media/hardware/HDCPAPI.h b/include/media/hardware/HDCPAPI.h
index d4abb3f..3a53e9f 100644
--- a/include/media/hardware/HDCPAPI.h
+++ b/include/media/hardware/HDCPAPI.h
@@ -88,6 +88,11 @@
     // Request to shutdown the active HDCP session.
     virtual status_t shutdownAsync() = 0;
 
+    // Returns the capability bitmask of this HDCP session.
+    virtual uint32_t getCaps() {
+        return HDCP_CAPS_ENCRYPT;
+    }
+
     // ENCRYPTION only:
     // Encrypt data according to the HDCP spec. "size" bytes of data are
     // available at "inData" (virtual address), "size" may not be a multiple
diff --git a/include/powermanager/PowerManager.h b/include/powermanager/PowerManager.h
index 4590174..cbddc11 100644
--- a/include/powermanager/PowerManager.h
+++ b/include/powermanager/PowerManager.h
@@ -24,6 +24,14 @@
     POWERMANAGER_PARTIAL_WAKE_LOCK = 1, // equals PowerManager.PARTIAL_WAKE_LOCK constant
 };
 
+enum {
+    USER_ACTIVITY_EVENT_OTHER = 0,
+    USER_ACTIVITY_EVENT_BUTTON = 1,
+    USER_ACTIVITY_EVENT_TOUCH = 2,
+
+    USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_TOUCH, // Last valid event code.
+};
+
 }; // namespace android
 
 #endif // ANDROID_POWERMANAGER_H
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index bf4bf03..5584fb1 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -30,11 +30,15 @@
 class Parcel;
 class ISurfaceComposerClient;
 
+/*
+ * Used to communicate layer information between SurfaceFlinger and its clients.
+ */
 struct layer_state_t {
 
 
     enum {
-        eLayerHidden        = 0x01,
+        eLayerHidden        = 0x01,     // SURFACE_HIDDEN in SurfaceControl.java
+        eLayerOpaque        = 0x02,     // SURFACE_OPAQUE
     };
 
     enum {
@@ -47,6 +51,7 @@
         eVisibilityChanged          = 0x00000040,
         eLayerStackChanged          = 0x00000080,
         eCropChanged                = 0x00000100,
+        eOpacityChanged             = 0x00000200,
     };
 
     layer_state_t()
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index 627cfb6..7e46945 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -56,13 +56,15 @@
 
     // real pixel formats supported for rendering -----------------------------
 
-    PIXEL_FORMAT_RGBA_8888   = HAL_PIXEL_FORMAT_RGBA_8888,  // 4x8-bit RGBA
-    PIXEL_FORMAT_RGBX_8888   = HAL_PIXEL_FORMAT_RGBX_8888,  // 4x8-bit RGB0
-    PIXEL_FORMAT_RGB_888     = HAL_PIXEL_FORMAT_RGB_888,    // 3x8-bit RGB
-    PIXEL_FORMAT_RGB_565     = HAL_PIXEL_FORMAT_RGB_565,    // 16-bit RGB
-    PIXEL_FORMAT_BGRA_8888   = HAL_PIXEL_FORMAT_BGRA_8888,  // 4x8-bit BGRA
-    PIXEL_FORMAT_RGBA_5551   = 6,                           // 16-bit ARGB
-    PIXEL_FORMAT_RGBA_4444   = 7,                           // 16-bit ARGB
+    PIXEL_FORMAT_RGBA_8888   = HAL_PIXEL_FORMAT_RGBA_8888,   // 4x8-bit RGBA
+    PIXEL_FORMAT_RGBX_8888   = HAL_PIXEL_FORMAT_RGBX_8888,   // 4x8-bit RGB0
+    PIXEL_FORMAT_RGB_888     = HAL_PIXEL_FORMAT_RGB_888,     // 3x8-bit RGB
+    PIXEL_FORMAT_RGB_565     = HAL_PIXEL_FORMAT_RGB_565,     // 16-bit RGB
+    PIXEL_FORMAT_BGRA_8888   = HAL_PIXEL_FORMAT_BGRA_8888,   // 4x8-bit BGRA
+    PIXEL_FORMAT_RGBA_5551   = 6,                            // 16-bit ARGB
+    PIXEL_FORMAT_RGBA_4444   = 7,                            // 16-bit ARGB
+    PIXEL_FORMAT_sRGB_A_8888 = HAL_PIXEL_FORMAT_sRGB_A_8888, // 4x8-bit sRGB + A
+    PIXEL_FORMAT_sRGB_X_8888 = HAL_PIXEL_FORMAT_sRGB_X_8888, // 4x8-bit sRGB, no A
 };
 
 typedef int32_t PixelFormat;
diff --git a/include/ui/Region.h b/include/ui/Region.h
index d906dbb..0d1c68c 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -50,6 +50,9 @@
     inline  Rect        getBounds() const   { return mStorage[mStorage.size() - 1]; }
     inline  Rect        bounds() const      { return getBounds(); }
 
+            bool        contains(const Point& point) const;
+            bool        contains(int x, int y) const;
+
             // the region becomes its bounds
             Region&     makeBoundsSelf();
     
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index 673fc82..d8ae0aa 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -21,6 +21,7 @@
     Debug.cpp \
     IAppOpsCallback.cpp \
     IAppOpsService.cpp \
+    IBatteryStats.cpp \
     IInterface.cpp \
     IMemory.cpp \
     IPCThreadState.cpp \
diff --git a/libs/binder/IBatteryStats.cpp b/libs/binder/IBatteryStats.cpp
new file mode 100644
index 0000000..6469b08
--- /dev/null
+++ b/libs/binder/IBatteryStats.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013 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/IBatteryStats.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+#include <private/binder/Static.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpBatteryStats : public BpInterface<IBatteryStats>
+{
+public:
+    BpBatteryStats(const sp<IBinder>& impl)
+        : BpInterface<IBatteryStats>(impl)
+    {
+    }
+
+    virtual void noteStartSensor(int uid, int sensor) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        data.writeInt32(sensor);
+        remote()->transact(NOTE_START_SENSOR_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteStopSensor(int uid, int sensor) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        data.writeInt32(sensor);
+        remote()->transact(NOTE_STOP_SENSOR_TRANSACTION, data, &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(BatteryStats, "com.android.internal.app.IBatteryStats");
+
+// ----------------------------------------------------------------------
+
+status_t BnBatteryStats::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case NOTE_START_SENSOR_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            int sensor = data.readInt32();
+            noteStartSensor(uid, sensor);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_STOP_SENSOR_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            int sensor = data.readInt32();
+            noteStopSensor(uid, sensor);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 03bcf01..3791ad5 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -766,6 +766,32 @@
     return err;
 }
 
+// WARNING: This method must stay in sync with
+// Parcelable.Creator<ParcelFileDescriptor> CREATOR
+// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
+status_t Parcel::writeParcelFileDescriptor(int fd, int commChannel) {
+    status_t status;
+
+    if (fd < 0) {
+        status = writeInt32(0); // ParcelFileDescriptor is null
+        if (status) return status;
+    } else {
+        status = writeInt32(1); // ParcelFileDescriptor is not null
+        if (status) return status;
+        status = writeDupFileDescriptor(fd);
+        if (status) return status;
+        if (commChannel < 0) {
+            status = writeInt32(0); // commChannel is null
+            if (status) return status;
+        } else {
+            status = writeInt32(1); // commChannel is not null
+            if (status) return status;
+            status = writeDupFileDescriptor(commChannel);
+        }
+    }
+    return status;
+}
+
 status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
 {
     status_t status;
@@ -1180,6 +1206,23 @@
     return BAD_TYPE;
 }
 
+// WARNING: This method must stay in sync with writeToParcel()
+// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
+int Parcel::readParcelFileDescriptor(int& outCommChannel) const {
+    int fd;
+    outCommChannel = -1;
+
+    if (readInt32() == 0) {
+        fd = -1;
+    } else {
+        fd = readFileDescriptor();
+        if (fd >= 0 && readInt32() != 0) {
+            outCommChannel = readFileDescriptor();
+        }
+    }
+    return fd;
+}
+
 status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
 {
     int32_t useAshmem;
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 350887a..74a65ed 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -33,6 +33,13 @@
         uint32_t consumerUsage, int bufferCount, bool controlledByApp) :
     ConsumerBase(bq, controlledByApp)
 {
+    if (bufferCount == MIN_UNDEQUEUED_BUFFERS) {
+        status_t res;
+        res = bq->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &bufferCount);
+        LOG_ALWAYS_FATAL_IF(res != OK || bufferCount < 0,
+                            "Failed to query min buffer count");
+    }
+
     mConsumer->setConsumerUsageBits(consumerUsage);
     mConsumer->setMaxAcquiredBufferCount(bufferCount);
 }
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 2aecb67..2fa0433 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -31,7 +31,6 @@
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
-#include <utils/CallStack.h>
 
 // Macros for including the BufferQueue name in log messages
 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
@@ -196,6 +195,11 @@
     ATRACE_CALL();
     Mutex::Autolock lock(mMutex);
 
+    if (outValue == NULL) {
+        ST_LOGE("query: outValue was NULL");
+        return BAD_VALUE;
+    }
+
     if (mAbandoned) {
         ST_LOGE("query: BufferQueue has been abandoned!");
         return NO_INIT;
@@ -655,10 +659,15 @@
         return NO_INIT;
     }
 
+    if (output == NULL) {
+        ST_LOGE("connect: output was NULL");
+        return BAD_VALUE;
+    }
+
     if (mConnectedApi != NO_CONNECTED_API) {
         ST_LOGE("connect: already connected (cur=%d, req=%d)",
                 mConnectedApi, api);
-        return -EINVAL;
+        return BAD_VALUE;
     }
 
     // If we disconnect and reconnect quickly, we can be in a state where our slots are
@@ -694,7 +703,7 @@
             }
             break;
         default:
-            err = -EINVAL;
+            err = BAD_VALUE;
             break;
     }
 
@@ -704,7 +713,7 @@
     return err;
 }
 
-void BufferQueue::binderDied(const wp<IBinder>& who) {
+void BufferQueue::binderDied(const wp<IBinder>& who __attribute__((unused))) {
     // If we're here, it means that a producer we were connected to died.
     // We're GUARANTEED that we still are connected to it because it has no other way
     // to get disconnected -- or -- we wouldn't be here because we're removing this
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index c4ec857..c5900aa 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -85,7 +85,7 @@
         "consumer is not abandoned!", mName.string());
 }
 
-void ConsumerBase::onLastStrongRef(const void* id) {
+void ConsumerBase::onLastStrongRef(const void* id __attribute__((unused))) {
     abandon();
 }
 
@@ -243,7 +243,7 @@
             slot, mSlots[slot].mFrameNumber);
     status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
             display, eglFence, mSlots[slot].mFence);
-    if (err == BufferQueue::STALE_BUFFER_SLOT) {
+    if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
         freeBufferLocked(slot);
     }
 
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index 9574b61..876c895 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -223,7 +223,7 @@
     }
 
     virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
-            EGLDisplay display, EGLSyncKHR fence,
+            EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
             const sp<Fence>& releaseFence) {
         Parcel data, reply;
         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 27dbc4e..975d005 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -251,7 +251,7 @@
     return BAD_VALUE;
 }
 
-int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) {
+int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
     ALOGV("Surface::lockBuffer");
     Mutex::Autolock lock(mMutex);
     return OK;
@@ -482,7 +482,7 @@
     return lock(outBuffer, inOutDirtyBounds);
 }
 
-int Surface::dispatchUnlockAndPost(va_list args) {
+int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
     return unlockAndPost();
 }
 
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index aafc4d2..2246f5f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -309,7 +309,12 @@
     layer_state_t* s = getLayerStateLocked(client, id);
     if (!s)
         return BAD_INDEX;
-    s->what |= layer_state_t::eVisibilityChanged;
+    if (mask & layer_state_t::eLayerOpaque) {
+        s->what |= layer_state_t::eOpacityChanged;
+    }
+    if (mask & layer_state_t::eLayerHidden) {
+        s->what |= layer_state_t::eVisibilityChanged;
+    }
     s->flags &= ~mask;
     s->flags |= (flags & mask);
     s->mask |= mask;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 16e533c..de182ee 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -23,7 +23,6 @@
 
 #include <android/native_window.h>
 
-#include <utils/CallStack.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index 21bd875..2eeb5c7 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -9,9 +9,19 @@
 LOCAL_SRC_FILES := \
     BufferQueue_test.cpp \
     CpuConsumer_test.cpp \
+    FillBuffer.cpp \
+    GLTest.cpp \
+    IGraphicBufferProducer_test.cpp \
+    MultiTextureConsumer_test.cpp \
+    SRGB_test.cpp \
     SurfaceTextureClient_test.cpp \
-    SurfaceTexture_test.cpp \
+    SurfaceTextureFBO_test.cpp \
+    SurfaceTextureGLThreadToGL_test.cpp \
+    SurfaceTextureGLToGL_test.cpp \
+    SurfaceTextureGL_test.cpp \
+    SurfaceTextureMultiContextGL_test.cpp \
     Surface_test.cpp \
+    TextureRenderer.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
 	libEGL \
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 03c1a29..06f9a92 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -52,6 +52,12 @@
                 testInfo->name());
     }
 
+    void GetMinUndequeuedBufferCount(int* bufferCount) {
+        ASSERT_NE((void*)NULL, bufferCount);
+        ASSERT_EQ(OK, mBQ->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, bufferCount));
+        ASSERT_LE(0, *bufferCount); // non-negative
+    }
+
     sp<BufferQueue> mBQ;
 };
 
@@ -97,20 +103,28 @@
     sp<DummyConsumer> dc(new DummyConsumer);
     mBQ->consumerConnect(dc, false);
 
-    ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(0));
-    ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(-3));
-    ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(
+    int minBufferCount;
+    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
+    EXPECT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(minBufferCount - 1));
+
+    EXPECT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(0));
+    EXPECT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(-3));
+    EXPECT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(
             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
-    ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(100));
+    EXPECT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(100));
 }
 
 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
     sp<DummyConsumer> dc(new DummyConsumer);
     mBQ->consumerConnect(dc, false);
 
-    ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount(1));
-    ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount(2));
-    ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount(
+    int minBufferCount;
+    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
+
+    EXPECT_EQ(OK, mBQ->setMaxAcquiredBufferCount(1));
+    EXPECT_EQ(OK, mBQ->setMaxAcquiredBufferCount(2));
+    EXPECT_EQ(OK, mBQ->setMaxAcquiredBufferCount(minBufferCount));
+    EXPECT_EQ(OK, mBQ->setMaxAcquiredBufferCount(
             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
 }
 
diff --git a/libs/gui/tests/DisconnectWaiter.h b/libs/gui/tests/DisconnectWaiter.h
new file mode 100644
index 0000000..3a30a19
--- /dev/null
+++ b/libs/gui/tests/DisconnectWaiter.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2013 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_DISCONNECT_WAITER_H
+#define ANDROID_DISCONNECT_WAITER_H
+
+#include <gui/IConsumerListener.h>
+
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+// Note that GLConsumer will lose the notifications
+// onBuffersReleased and onFrameAvailable as there is currently
+// no way to forward the events.  This DisconnectWaiter will not let the
+// disconnect finish until finishDisconnect() is called.  It will
+// also block until a disconnect is called
+class DisconnectWaiter : public BnConsumerListener {
+public:
+    DisconnectWaiter () :
+        mWaitForDisconnect(false),
+        mPendingFrames(0) {
+    }
+
+    void waitForFrame() {
+        Mutex::Autolock lock(mMutex);
+        while (mPendingFrames == 0) {
+            mFrameCondition.wait(mMutex);
+        }
+        mPendingFrames--;
+    }
+
+    virtual void onFrameAvailable() {
+        Mutex::Autolock lock(mMutex);
+        mPendingFrames++;
+        mFrameCondition.signal();
+    }
+
+    virtual void onBuffersReleased() {
+        Mutex::Autolock lock(mMutex);
+        while (!mWaitForDisconnect) {
+            mDisconnectCondition.wait(mMutex);
+        }
+    }
+
+    void finishDisconnect() {
+        Mutex::Autolock lock(mMutex);
+        mWaitForDisconnect = true;
+        mDisconnectCondition.signal();
+    }
+
+private:
+    Mutex mMutex;
+
+    bool mWaitForDisconnect;
+    Condition mDisconnectCondition;
+
+    int mPendingFrames;
+    Condition mFrameCondition;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/FillBuffer.cpp b/libs/gui/tests/FillBuffer.cpp
new file mode 100644
index 0000000..079962c
--- /dev/null
+++ b/libs/gui/tests/FillBuffer.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2013 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 "FillBuffer.h"
+
+#include <ui/GraphicBuffer.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
+    const int blockWidth = w > 16 ? w / 16 : 1;
+    const int blockHeight = h > 16 ? h / 16 : 1;
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            int parityX = (x / blockWidth) & 1;
+            int parityY = (y / blockHeight) & 1;
+            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+            if (x < w / 2 && y < h / 2) {
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+                if (x * 2 < w / 2 && y * 2 < h / 2) {
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
+                        intensity;
+                }
+            }
+        }
+    }
+}
+
+void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
+        const android_native_rect_t& rect) {
+    const int yuvTexOffsetY = 0;
+    int yuvTexStrideY = stride;
+    int yuvTexOffsetV = yuvTexStrideY * h;
+    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+    int yuvTexStrideU = yuvTexStrideV;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            bool inside = rect.left <= x && x < rect.right &&
+                    rect.top <= y && y < rect.bottom;
+            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
+            if (x < w / 2 && y < h / 2) {
+                bool inside = rect.left <= 2*x && 2*x < rect.right &&
+                        rect.top <= 2*y && 2*y < rect.bottom;
+                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
+                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
+                        inside ? 16 : 255;
+            }
+        }
+    }
+}
+
+void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
+    const size_t PIXEL_SIZE = 4;
+    for (int x = 0; x < w; x++) {
+        for (int y = 0; y < h; y++) {
+            off_t offset = (y * stride + x) * PIXEL_SIZE;
+            for (int c = 0; c < 4; c++) {
+                int parityX = (x / (1 << (c+2))) & 1;
+                int parityY = (y / (1 << (c+2))) & 1;
+                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
+            }
+        }
+    }
+}
+
+void produceOneRGBA8Frame(const sp<ANativeWindow>& anw) {
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(),
+            &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+
+    uint8_t* img = NULL;
+    ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
+            (void**)(&img)));
+    fillRGBA8Buffer(img, buf->getWidth(), buf->getHeight(), buf->getStride());
+    ASSERT_EQ(NO_ERROR, buf->unlock());
+    ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf->getNativeBuffer(),
+            -1));
+}
+} // namespace android
diff --git a/libs/gui/tests/FillBuffer.h b/libs/gui/tests/FillBuffer.h
new file mode 100644
index 0000000..b584179
--- /dev/null
+++ b/libs/gui/tests/FillBuffer.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2013 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_FILL_BUFFER_H
+#define ANDROID_FILL_BUFFER_H
+
+#include <system/window.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+// Fill a YV12 buffer with a multi-colored checkerboard pattern
+void fillYV12Buffer(uint8_t* buf, int w, int h, int stride);
+
+// Fill a YV12 buffer with red outside a given rectangle and green inside it.
+void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
+        const android_native_rect_t& rect);
+
+void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride);
+
+// Produce a single RGBA8 frame by filling a buffer with a checkerboard pattern
+// using the CPU.  This assumes that the ANativeWindow is already configured to
+// allow this to be done (e.g. the format is set to RGBA8).
+//
+// Calls to this function should be wrapped in an ASSERT_NO_FATAL_FAILURE().
+void produceOneRGBA8Frame(const sp<ANativeWindow>& anw);
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/FrameWaiter.h b/libs/gui/tests/FrameWaiter.h
new file mode 100644
index 0000000..bdedba6
--- /dev/null
+++ b/libs/gui/tests/FrameWaiter.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2013 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_FRAME_WAITER_H
+#define ANDROID_FRAME_WAITER_H
+
+#include <gui/GLConsumer.h>
+
+namespace android {
+
+class FrameWaiter : public GLConsumer::FrameAvailableListener {
+public:
+    FrameWaiter():
+            mPendingFrames(0) {
+    }
+
+    void waitForFrame() {
+        Mutex::Autolock lock(mMutex);
+        while (mPendingFrames == 0) {
+            mCondition.wait(mMutex);
+        }
+        mPendingFrames--;
+    }
+
+    virtual void onFrameAvailable() {
+        Mutex::Autolock lock(mMutex);
+        mPendingFrames++;
+        mCondition.signal();
+    }
+
+private:
+    int mPendingFrames;
+    Mutex mMutex;
+    Condition mCondition;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/GLTest.cpp b/libs/gui/tests/GLTest.cpp
new file mode 100644
index 0000000..1739d9c
--- /dev/null
+++ b/libs/gui/tests/GLTest.cpp
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2013 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 "GLTest.h"
+
+#include <gui/Surface.h>
+
+#include <GLES2/gl2.h>
+
+namespace android {
+
+static int abs(int value) {
+    return value > 0 ? value : -value;
+}
+
+void GLTest::SetUp() {
+    const ::testing::TestInfo* const testInfo =
+        ::testing::UnitTest::GetInstance()->current_test_info();
+    ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
+
+    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
+
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    RecordProperty("EglVersionMajor", majorVersion);
+    RecordProperty("EglVersionMinor", minorVersion);
+
+    EGLint numConfigs = 0;
+    EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig, 1,
+            &numConfigs));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
+    if (displaySecsEnv != NULL) {
+        mDisplaySecs = atoi(displaySecsEnv);
+        if (mDisplaySecs < 0) {
+            mDisplaySecs = 0;
+        }
+    } else {
+        mDisplaySecs = 0;
+    }
+
+    if (mDisplaySecs > 0) {
+        mComposerClient = new SurfaceComposerClient;
+        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+        mSurfaceControl = mComposerClient->createSurface(
+                String8("Test Surface"), getSurfaceWidth(), getSurfaceHeight(),
+                PIXEL_FORMAT_RGB_888, 0);
+
+        ASSERT_TRUE(mSurfaceControl != NULL);
+        ASSERT_TRUE(mSurfaceControl->isValid());
+
+        SurfaceComposerClient::openGlobalTransaction();
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+        SurfaceComposerClient::closeGlobalTransaction();
+
+        sp<ANativeWindow> window = mSurfaceControl->getSurface();
+        mEglSurface = createWindowSurface(mEglDisplay, mGlConfig, window);
+    } else {
+        EGLint pbufferAttribs[] = {
+            EGL_WIDTH, getSurfaceWidth(),
+            EGL_HEIGHT, getSurfaceHeight(),
+            EGL_NONE };
+
+        mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
+                pbufferAttribs);
+    }
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
+
+    mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
+            getContextAttribs());
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EGLint w, h;
+    EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    RecordProperty("EglSurfaceWidth", w);
+    RecordProperty("EglSurfaceHeight", h);
+
+    glViewport(0, 0, w, h);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+}
+
+void GLTest::TearDown() {
+    // Display the result
+    if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
+        eglSwapBuffers(mEglDisplay, mEglSurface);
+        sleep(mDisplaySecs);
+    }
+
+    if (mComposerClient != NULL) {
+        mComposerClient->dispose();
+    }
+    if (mEglContext != EGL_NO_CONTEXT) {
+        eglDestroyContext(mEglDisplay, mEglContext);
+    }
+    if (mEglSurface != EGL_NO_SURFACE) {
+        eglDestroySurface(mEglDisplay, mEglSurface);
+    }
+    if (mEglDisplay != EGL_NO_DISPLAY) {
+        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                EGL_NO_CONTEXT);
+        eglTerminate(mEglDisplay);
+    }
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    const ::testing::TestInfo* const testInfo =
+        ::testing::UnitTest::GetInstance()->current_test_info();
+    ALOGV("End test:   %s.%s", testInfo->test_case_name(), testInfo->name());
+}
+
+EGLint const* GLTest::getConfigAttribs() {
+    static const EGLint sDefaultConfigAttribs[] = {
+        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+        EGL_RED_SIZE, 8,
+        EGL_GREEN_SIZE, 8,
+        EGL_BLUE_SIZE, 8,
+        EGL_ALPHA_SIZE, 8,
+        EGL_DEPTH_SIZE, 16,
+        EGL_STENCIL_SIZE, 8,
+        EGL_NONE };
+
+    return sDefaultConfigAttribs;
+}
+
+EGLint const* GLTest::getContextAttribs() {
+    static const EGLint sDefaultContextAttribs[] = {
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+        EGL_NONE };
+
+    return sDefaultContextAttribs;
+}
+
+EGLint GLTest::getSurfaceWidth() {
+    return 512;
+}
+
+EGLint GLTest::getSurfaceHeight() {
+    return 512;
+}
+
+EGLSurface GLTest::createWindowSurface(EGLDisplay display, EGLConfig config,
+                                       sp<ANativeWindow>& window) const {
+    return eglCreateWindowSurface(display, config, window.get(), NULL);
+}
+
+::testing::AssertionResult GLTest::checkPixel(int x, int y,
+        int r, int g, int b, int a, int tolerance) {
+    GLubyte pixel[4];
+    String8 msg;
+    glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+    GLenum err = glGetError();
+    if (err != GL_NO_ERROR) {
+        msg += String8::format("error reading pixel: %#x", err);
+        while ((err = glGetError()) != GL_NO_ERROR) {
+            msg += String8::format(", %#x", err);
+        }
+        return ::testing::AssertionFailure(::testing::Message(msg.string()));
+    }
+    if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
+        msg += String8::format("r(%d isn't %d)", pixel[0], r);
+    }
+    if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
+        if (!msg.isEmpty()) {
+            msg += " ";
+        }
+        msg += String8::format("g(%d isn't %d)", pixel[1], g);
+    }
+    if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
+        if (!msg.isEmpty()) {
+            msg += " ";
+        }
+        msg += String8::format("b(%d isn't %d)", pixel[2], b);
+    }
+    if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
+        if (!msg.isEmpty()) {
+            msg += " ";
+        }
+        msg += String8::format("a(%d isn't %d)", pixel[3], a);
+    }
+    if (!msg.isEmpty()) {
+        return ::testing::AssertionFailure(::testing::Message(msg.string()));
+    } else {
+        return ::testing::AssertionSuccess();
+    }
+}
+
+::testing::AssertionResult GLTest::assertRectEq(const Rect &r1, const Rect &r2,
+                                                int tolerance) {
+    String8 msg;
+
+    if (abs(r1.left - r2.left) > tolerance) {
+        msg += String8::format("left(%d isn't %d)", r1.left, r2.left);
+    }
+    if (abs(r1.top - r2.top) > tolerance) {
+        if (!msg.isEmpty()) {
+            msg += " ";
+        }
+        msg += String8::format("top(%d isn't %d)", r1.top, r2.top);
+    }
+    if (abs(r1.right - r2.right) > tolerance) {
+        if (!msg.isEmpty()) {
+            msg += " ";
+        }
+        msg += String8::format("right(%d isn't %d)", r1.right, r2.right);
+    }
+    if (abs(r1.bottom - r2.bottom) > tolerance) {
+        if (!msg.isEmpty()) {
+            msg += " ";
+        }
+        msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom);
+    }
+    if (!msg.isEmpty()) {
+        msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]",
+                               r1.left, r1.top, r1.right, r1.bottom,
+                               r2.left, r2.top, r2.right, r2.bottom);
+        fprintf(stderr, "assertRectEq: %s\n", msg.string());
+        return ::testing::AssertionFailure(::testing::Message(msg.string()));
+    } else {
+        return ::testing::AssertionSuccess();
+    }
+}
+
+void GLTest::loadShader(GLenum shaderType, const char* pSource,
+        GLuint* outShader) {
+    GLuint shader = glCreateShader(shaderType);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glCompileShader(shader);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    printf("Shader compile log:\n%s\n", buf);
+                    free(buf);
+                    FAIL();
+                }
+            } else {
+                char* buf = (char*) malloc(0x1000);
+                if (buf) {
+                    glGetShaderInfoLog(shader, 0x1000, NULL, buf);
+                    printf("Shader compile log:\n%s\n", buf);
+                    free(buf);
+                    FAIL();
+                }
+            }
+            glDeleteShader(shader);
+            shader = 0;
+        }
+    }
+    ASSERT_TRUE(shader != 0);
+    *outShader = shader;
+}
+
+void GLTest::createProgram(const char* pVertexSource,
+        const char* pFragmentSource, GLuint* outPgm) {
+    GLuint vertexShader, fragmentShader;
+    {
+        SCOPED_TRACE("compiling vertex shader");
+        ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource,
+                &vertexShader));
+    }
+    {
+        SCOPED_TRACE("compiling fragment shader");
+        ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource,
+                &fragmentShader));
+    }
+
+    GLuint program = glCreateProgram();
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    if (program) {
+        glAttachShader(program, vertexShader);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glAttachShader(program, fragmentShader);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    printf("Program link log:\n%s\n", buf);
+                    free(buf);
+                    FAIL();
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    glDeleteShader(vertexShader);
+    glDeleteShader(fragmentShader);
+    ASSERT_TRUE(program != 0);
+    *outPgm = program;
+}
+
+} // namespace android
diff --git a/libs/gui/tests/GLTest.h b/libs/gui/tests/GLTest.h
new file mode 100644
index 0000000..d3c4a95
--- /dev/null
+++ b/libs/gui/tests/GLTest.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2013 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_GL_TEST_H
+#define ANDROID_GL_TEST_H
+
+#include <gtest/gtest.h>
+
+#include <gui/SurfaceComposerClient.h>
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+namespace android {
+
+class GLTest : public ::testing::Test {
+public:
+    static void loadShader(GLenum shaderType, const char* pSource,
+            GLuint* outShader);
+    static void createProgram(const char* pVertexSource,
+            const char* pFragmentSource, GLuint* outPgm);
+
+protected:
+    GLTest() :
+            mEglDisplay(EGL_NO_DISPLAY),
+            mEglSurface(EGL_NO_SURFACE),
+            mEglContext(EGL_NO_CONTEXT) {
+    }
+
+    virtual void SetUp();
+    virtual void TearDown();
+
+    virtual EGLint const* getConfigAttribs();
+    virtual EGLint const* getContextAttribs();
+    virtual EGLint getSurfaceWidth();
+    virtual EGLint getSurfaceHeight();
+    virtual EGLSurface createWindowSurface(EGLDisplay display, EGLConfig config,
+                                           sp<ANativeWindow>& window) const;
+
+    ::testing::AssertionResult checkPixel(int x, int y,
+            int r, int g, int b, int a, int tolerance = 2);
+    ::testing::AssertionResult assertRectEq(const Rect &r1, const Rect &r2,
+            int tolerance = 1);
+
+    int mDisplaySecs;
+    sp<SurfaceComposerClient> mComposerClient;
+    sp<SurfaceControl> mSurfaceControl;
+
+    EGLDisplay mEglDisplay;
+    EGLSurface mEglSurface;
+    EGLContext mEglContext;
+    EGLConfig  mGlConfig;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
new file mode 100644
index 0000000..d16177b
--- /dev/null
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2013 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 "IGraphicBufferProducer_test"
+//#define LOG_NDEBUG 0
+
+#include <gtest/gtest.h>
+
+#include <utils/String8.h>
+#include <utils/threads.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/FramebufferNativeWindow.h>
+
+#include <gui/BufferQueue.h>
+
+#include <vector>
+
+#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
+#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
+
+#define TEST_TOKEN ((IBinder*)(NULL))
+#define TEST_API NATIVE_WINDOW_API_CPU
+#define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API
+#define TEST_CONTROLLED_BY_APP false
+#define TEST_PRODUCER_USAGE_BITS (0)
+
+// TODO: Make these public constants in a header
+enum {
+    // Default dimensions before setDefaultBufferSize is called
+    DEFAULT_WIDTH = 1,
+    DEFAULT_HEIGHT = 1,
+
+    // Default format before setDefaultBufferFormat is called
+    DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888,
+
+    // Default transform hint before setTransformHint is called
+    DEFAULT_TRANSFORM_HINT = 0,
+};
+
+namespace android {
+
+namespace {
+// Parameters for a generic "valid" input for queueBuffer.
+const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
+const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
+const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
+const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
+const bool QUEUE_BUFFER_INPUT_ASYNC = false;
+const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
+}; // namespace anonymous
+
+struct DummyConsumer : public BnConsumerListener {
+    virtual void onFrameAvailable() {}
+    virtual void onBuffersReleased() {}
+};
+
+class IGraphicBufferProducerTest : public ::testing::Test {
+protected:
+
+    IGraphicBufferProducerTest() {}
+
+    virtual void SetUp() {
+        const ::testing::TestInfo* const testInfo =
+            ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
+                testInfo->name());
+
+        mBQ = new BufferQueue();
+        mDC = new DummyConsumer;
+
+        mProducer = mBQ;
+        mConsumer = mBQ;
+
+        // Test check: Can't connect producer if no consumer yet
+        ASSERT_EQ(NO_INIT, TryConnectProducer());
+
+        // Must connect consumer before producer connects will succeed.
+        ASSERT_OK(mConsumer->consumerConnect(mDC, /*controlledByApp*/false));
+    }
+
+    virtual void TearDown() {
+        const ::testing::TestInfo* const testInfo =
+            ::testing::UnitTest::GetInstance()->current_test_info();
+        ALOGV("End test:   %s.%s", testInfo->test_case_name(),
+                testInfo->name());
+    }
+
+    status_t TryConnectProducer() {
+        IGraphicBufferProducer::QueueBufferOutput output;
+        return mProducer->connect(TEST_TOKEN,
+                                  TEST_API,
+                                  TEST_CONTROLLED_BY_APP,
+                                  &output);
+        // TODO: use params to vary token, api, producercontrolledbyapp, etc
+    }
+
+    // Connect to a producer in a 'correct' fashion.
+    //   Precondition: Consumer is connected.
+    void ConnectProducer() {
+        ASSERT_OK(TryConnectProducer());
+    }
+
+    // Create a generic "valid" input for queueBuffer
+    // -- uses the default buffer format, width, etc.
+    static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
+        return QueueBufferInputBuilder().build();
+    }
+
+    // Builder pattern to slightly vary *almost* correct input
+    // -- avoids copying and pasting
+    struct QueueBufferInputBuilder {
+        QueueBufferInputBuilder() {
+           timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
+           isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
+           crop = QUEUE_BUFFER_INPUT_RECT;
+           scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
+           transform = QUEUE_BUFFER_INPUT_TRANSFORM;
+           async = QUEUE_BUFFER_INPUT_ASYNC;
+           fence = QUEUE_BUFFER_INPUT_FENCE;
+        }
+
+        IGraphicBufferProducer::QueueBufferInput build() {
+            return IGraphicBufferProducer::QueueBufferInput(
+                    timestamp,
+                    isAutoTimestamp,
+                    crop,
+                    scalingMode,
+                    transform,
+                    async,
+                    fence);
+        }
+
+        QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
+            this->timestamp = timestamp;
+            return *this;
+        }
+
+        QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
+            this->isAutoTimestamp = isAutoTimestamp;
+            return *this;
+        }
+
+        QueueBufferInputBuilder& setCrop(Rect crop) {
+            this->crop = crop;
+            return *this;
+        }
+
+        QueueBufferInputBuilder& setScalingMode(int scalingMode) {
+            this->scalingMode = scalingMode;
+            return *this;
+        }
+
+        QueueBufferInputBuilder& setTransform(uint32_t transform) {
+            this->transform = transform;
+            return *this;
+        }
+
+        QueueBufferInputBuilder& setAsync(bool async) {
+            this->async = async;
+            return *this;
+        }
+
+        QueueBufferInputBuilder& setFence(sp<Fence> fence) {
+            this->fence = fence;
+            return *this;
+        }
+
+    private:
+        int64_t timestamp;
+        bool isAutoTimestamp;
+        Rect crop;
+        int scalingMode;
+        uint32_t transform;
+        int async;
+        sp<Fence> fence;
+    }; // struct QueueBufferInputBuilder
+
+    // To easily store dequeueBuffer results into containers
+    struct DequeueBufferResult {
+        int slot;
+        sp<Fence> fence;
+    };
+
+    status_t dequeueBuffer(bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage, DequeueBufferResult* result) {
+        return mProducer->dequeueBuffer(&result->slot, &result->fence, async, w, h, format, usage);
+    }
+
+private: // hide from test body
+    sp<BufferQueue> mBQ;
+    sp<DummyConsumer> mDC;
+
+protected: // accessible from test body
+    sp<IGraphicBufferProducer> mProducer;
+    sp<IGraphicBufferConsumer> mConsumer;
+};
+
+TEST_F(IGraphicBufferProducerTest, ConnectFirst_ReturnsError) {
+    IGraphicBufferProducer::QueueBufferOutput output;
+
+    // NULL output returns BAD_VALUE
+    EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
+                                            TEST_API,
+                                            TEST_CONTROLLED_BY_APP,
+                                            /*output*/NULL));
+
+    // Invalid API returns bad value
+    EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
+                                            /*api*/0xDEADBEEF,
+                                            TEST_CONTROLLED_BY_APP,
+                                            &output));
+
+    // TODO: get a token from a dead process somehow
+}
+
+TEST_F(IGraphicBufferProducerTest, ConnectAgain_ReturnsError) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    // Can't connect when there is already a producer connected
+    IGraphicBufferProducer::QueueBufferOutput output;
+    EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
+                                            TEST_API,
+                                            TEST_CONTROLLED_BY_APP,
+                                            &output));
+
+    ASSERT_OK(mConsumer->consumerDisconnect());
+    // Can't connect when IGBP is abandoned
+    EXPECT_EQ(NO_INIT, mProducer->connect(TEST_TOKEN,
+                                          TEST_API,
+                                          TEST_CONTROLLED_BY_APP,
+                                          &output));
+}
+
+TEST_F(IGraphicBufferProducerTest, Disconnect_Succeeds) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    ASSERT_OK(mProducer->disconnect(TEST_API));
+}
+
+
+TEST_F(IGraphicBufferProducerTest, Disconnect_ReturnsError) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    // Must disconnect with same API number
+    ASSERT_EQ(BAD_VALUE, mProducer->disconnect(TEST_API_OTHER));
+    // API must not be out of range
+    ASSERT_EQ(BAD_VALUE, mProducer->disconnect(/*api*/0xDEADBEEF));
+
+    // TODO: somehow kill mProducer so that this returns DEAD_OBJECT
+}
+
+TEST_F(IGraphicBufferProducerTest, Query_Succeeds) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    // TODO: Make these constants in header
+    const int DEFAULT_CONSUMER_USAGE_BITS = 0;
+
+    int value = -1;
+    EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
+    EXPECT_EQ(DEFAULT_WIDTH, value);
+
+    EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
+    EXPECT_EQ(DEFAULT_HEIGHT, value);
+
+    EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
+    EXPECT_EQ(DEFAULT_FORMAT, value);
+
+    EXPECT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
+    EXPECT_LE(0, value);
+    EXPECT_GE(BufferQueue::NUM_BUFFER_SLOTS, value);
+
+    EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
+    EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
+
+    EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
+    EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, value);
+
+}
+
+TEST_F(IGraphicBufferProducerTest, Query_ReturnsError) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    // One past the end of the last 'query' enum value. Update this if we add more enums.
+    const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_CONSUMER_USAGE_BITS + 1;
+
+    int value;
+    // What was out of range
+    EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/-1, &value));
+    EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/0xDEADBEEF, &value));
+    EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
+
+    // Some enums from window.h are 'invalid'
+    EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
+    EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
+    EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
+    EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
+    EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
+    // TODO: Consider documented the above enums as unsupported or make a new enum for IGBP
+
+    // Value was NULL
+    EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/NULL));
+
+    ASSERT_OK(mConsumer->consumerDisconnect());
+
+    // BQ was abandoned
+    EXPECT_EQ(NO_INIT, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
+
+    // TODO: other things in window.h that are supported by Surface::query
+    // but not by BufferQueue::query
+}
+
+// TODO: queue under more complicated situations not involving just a single buffer
+TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    int dequeuedSlot = -1;
+    sp<Fence> dequeuedFence;
+
+    // XX: OK to assume first call returns this flag or not? Not really documented.
+    ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
+            mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+                                     QUEUE_BUFFER_INPUT_ASYNC,
+                                     DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+                                     TEST_PRODUCER_USAGE_BITS));
+
+    EXPECT_LE(0, dequeuedSlot);
+    EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
+
+    // Request the buffer (pre-requisite for queueing)
+    sp<GraphicBuffer> dequeuedBuffer;
+    ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
+
+    // A generic "valid" input
+    IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
+    IGraphicBufferProducer::QueueBufferOutput output;
+
+    // Queue the buffer back into the BQ
+    ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
+
+    {
+        uint32_t width;
+        uint32_t height;
+        uint32_t transformHint;
+        uint32_t numPendingBuffers;
+
+        output.deflate(&width, &height, &transformHint, &numPendingBuffers);
+
+        EXPECT_EQ(DEFAULT_WIDTH, width);
+        EXPECT_EQ(DEFAULT_HEIGHT, height);
+        EXPECT_EQ(DEFAULT_TRANSFORM_HINT, transformHint);
+        EXPECT_EQ(1, numPendingBuffers); // since queueBuffer was called exactly once
+    }
+
+    // Buffer was not in the dequeued state
+    EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
+}
+
+TEST_F(IGraphicBufferProducerTest, Queue_ReturnsError) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    // Invalid slot number
+    {
+        // A generic "valid" input
+        IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
+        IGraphicBufferProducer::QueueBufferOutput output;
+
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/-1, input, &output));
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0xDEADBEEF, input, &output));
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueue::NUM_BUFFER_SLOTS,
+                                                    input, &output));
+    }
+
+    // Slot was not in the dequeued state (all slots start out in Free state)
+    {
+        IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
+        IGraphicBufferProducer::QueueBufferOutput output;
+
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0, input, &output));
+    }
+
+    // Put the slot into the "dequeued" state for the rest of the test
+    int dequeuedSlot = -1;
+    sp<Fence> dequeuedFence;
+
+    ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
+            mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+                                     QUEUE_BUFFER_INPUT_ASYNC,
+                                     DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+                                     TEST_PRODUCER_USAGE_BITS));
+
+    // Slot was enqueued without requesting a buffer
+    {
+        IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
+        IGraphicBufferProducer::QueueBufferOutput output;
+
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
+    }
+
+    // Request the buffer so that the rest of the tests don't fail on earlier checks.
+    sp<GraphicBuffer> dequeuedBuffer;
+    ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
+
+    // Fence was NULL
+    {
+        sp<Fence> nullFence = NULL;
+
+        IGraphicBufferProducer::QueueBufferInput input =
+                QueueBufferInputBuilder().setFence(nullFence).build();
+        IGraphicBufferProducer::QueueBufferOutput output;
+
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
+    }
+
+    // Scaling mode was unknown
+    {
+        IGraphicBufferProducer::QueueBufferInput input =
+                QueueBufferInputBuilder().setScalingMode(-1).build();
+        IGraphicBufferProducer::QueueBufferOutput output;
+
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
+
+        input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
+
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
+    }
+
+    // Crop rect is out of bounds of the buffer dimensions
+    {
+        IGraphicBufferProducer::QueueBufferInput input =
+                QueueBufferInputBuilder().setCrop(Rect(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1))
+                .build();
+        IGraphicBufferProducer::QueueBufferOutput output;
+
+        EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
+    }
+
+    // Abandon the buffer queue so that the last test fails
+    ASSERT_OK(mConsumer->consumerDisconnect());
+
+    // The buffer queue has been abandoned.
+    {
+        IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
+        IGraphicBufferProducer::QueueBufferOutput output;
+
+        EXPECT_EQ(NO_INIT, mProducer->queueBuffer(dequeuedSlot, input, &output));
+    }
+}
+
+TEST_F(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) {
+    ASSERT_NO_FATAL_FAILURE(ConnectProducer());
+
+    int dequeuedSlot = -1;
+    sp<Fence> dequeuedFence;
+
+    ASSERT_EQ(OK | IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
+            mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+                                     QUEUE_BUFFER_INPUT_ASYNC,
+                                     DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+                                     TEST_PRODUCER_USAGE_BITS));
+
+    // No return code, but at least test that it doesn't blow up...
+    // TODO: add a return code
+    mProducer->cancelBuffer(dequeuedSlot, dequeuedFence);
+}
+
+TEST_F(IGraphicBufferProducerTest, SetBufferCount_Succeeds) {
+
+    // The producer does not wish to set a buffer count
+    EXPECT_OK(mProducer->setBufferCount(0)) << "bufferCount: " << 0;
+    // TODO: how to test "0" buffer count?
+
+    int minBuffers;
+    ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minBuffers));
+
+    // The MIN_UNDEQUEUED_BUFFERS limit is exclusive, so need to increment by at least 1
+    minBuffers++;
+
+    ASSERT_OK(mProducer->setBufferCount(minBuffers)) << "bufferCount: " << minBuffers;
+
+    std::vector<DequeueBufferResult> dequeueList;
+
+    // Should now be able to dequeue up to minBuffers times
+    for (int i = 0; i < minBuffers; ++i) {
+        DequeueBufferResult result;
+
+        EXPECT_LE(OK,
+                dequeueBuffer(QUEUE_BUFFER_INPUT_ASYNC,
+                              DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+                              TEST_PRODUCER_USAGE_BITS, &result))
+                << "iteration: " << i << ", slot: " << result.slot;
+
+        dequeueList.push_back(result);
+    }
+
+    // Cancel every buffer, so we can set buffer count again
+    for (int i = 0; i < minBuffers; ++i) {
+        DequeueBufferResult& result = dequeueList[i];
+        mProducer->cancelBuffer(result.slot, result.fence);
+    }
+
+    ASSERT_OK(mProducer->setBufferCount(BufferQueue::NUM_BUFFER_SLOTS));
+
+    // Should now be able to dequeue up to NUM_BUFFER_SLOTS times
+    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; ++i) {
+        int dequeuedSlot = -1;
+        sp<Fence> dequeuedFence;
+
+        EXPECT_LE(OK,
+                mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+                                         QUEUE_BUFFER_INPUT_ASYNC,
+                                         DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+                                         TEST_PRODUCER_USAGE_BITS))
+                << "iteration: " << i << ", slot: " << dequeuedSlot;
+    }
+}
+
+TEST_F(IGraphicBufferProducerTest, SetBufferCount_Fails) {
+    int minBuffers;
+    ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minBuffers));
+
+    // The MIN_UNDEQUEUED_BUFFERS limit is exclusive, so need to increment by at least 1
+    minBuffers++;
+
+    // Buffer count was out of range
+    EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(-1)) << "bufferCount: " << -1;
+    EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(minBuffers - 1)) << "bufferCount: " << minBuffers - 1;
+    EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(BufferQueue::NUM_BUFFER_SLOTS + 1))
+            << "bufferCount: " << BufferQueue::NUM_BUFFER_SLOTS + 1;
+
+    // Pre-requisite to fail out a valid setBufferCount call
+    {
+        int dequeuedSlot = -1;
+        sp<Fence> dequeuedFence;
+
+        ASSERT_LE(OK,
+                mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
+                                         QUEUE_BUFFER_INPUT_ASYNC,
+                                         DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
+                                         TEST_PRODUCER_USAGE_BITS))
+                << "slot: " << dequeuedSlot;
+    }
+
+    // Client has one or more buffers dequeued
+    EXPECT_EQ(BAD_VALUE, mProducer->setBufferCount(minBuffers)) << "bufferCount: " << minBuffers;
+
+    // Abandon buffer queue
+    ASSERT_OK(mConsumer->consumerDisconnect());
+
+    // Fail because the buffer queue was abandoned
+    EXPECT_EQ(NO_INIT, mProducer->setBufferCount(minBuffers)) << "bufferCount: " << minBuffers;
+
+}
+
+} // namespace android
diff --git a/libs/gui/tests/MultiTextureConsumer_test.cpp b/libs/gui/tests/MultiTextureConsumer_test.cpp
new file mode 100644
index 0000000..853c25c
--- /dev/null
+++ b/libs/gui/tests/MultiTextureConsumer_test.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2013 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 "MultiTextureConsumer_test"
+//#define LOG_NDEBUG 0
+
+#include "GLTest.h"
+
+#include <gui/GLConsumer.h>
+#include <gui/Surface.h>
+
+#include <android/native_window.h>
+
+#include <GLES/glext.h>
+
+namespace android {
+
+class MultiTextureConsumerTest : public GLTest {
+protected:
+    enum { TEX_ID = 123 };
+
+    virtual void SetUp() {
+        GLTest::SetUp();
+        sp<BufferQueue> bq = new BufferQueue();
+        mGlConsumer = new GLConsumer(bq, TEX_ID);
+        mSurface = new Surface(bq);
+        mANW = mSurface.get();
+
+    }
+    virtual void TearDown() {
+        GLTest::TearDown();
+    }
+    virtual EGLint const* getContextAttribs() {
+        return NULL;
+    }
+    virtual EGLint const* getConfigAttribs() {
+        static EGLint sDefaultConfigAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+            EGL_NONE };
+
+        return sDefaultConfigAttribs;
+    }
+    sp<GLConsumer> mGlConsumer;
+    sp<Surface> mSurface;
+    ANativeWindow* mANW;
+};
+
+TEST_F(MultiTextureConsumerTest, EGLImageTargetWorks) {
+    ANativeWindow_Buffer buffer;
+
+    ASSERT_EQ(native_window_set_usage(mANW, GRALLOC_USAGE_SW_WRITE_OFTEN), NO_ERROR);
+    ASSERT_EQ(native_window_set_buffers_format(mANW, HAL_PIXEL_FORMAT_RGBA_8888), NO_ERROR);
+
+    glShadeModel(GL_FLAT);
+    glDisable(GL_DITHER);
+    glDisable(GL_CULL_FACE);
+    glViewport(0, 0, getSurfaceWidth(), getSurfaceHeight());
+    glOrthof(0, getSurfaceWidth(), 0, getSurfaceHeight(), 0, 1);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glColor4f(1, 1, 1, 1);
+
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
+    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+    uint32_t texel = 0x80808080;
+    glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+    glActiveTexture(GL_TEXTURE1);
+    glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
+    glEnable(GL_TEXTURE_2D);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
+    glEnable(GL_TEXTURE_EXTERNAL_OES);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+    for (int i=0 ; i<8 ; i++) {
+        mSurface->lock(&buffer, NULL);
+        memset(buffer.bits, (i&7) * 0x20, buffer.stride * buffer.height * 4);
+        mSurface->unlockAndPost();
+
+        mGlConsumer->updateTexImage();
+
+        GLfloat vertices[][2] = { {i*16.0f, 0}, {(i+1)*16.0f, 0}, {(i+1)*16.0f, 16.0f}, {i*16.0f, 16.0f} };
+        glVertexPointer(2, GL_FLOAT, 0, vertices);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    }
+
+    for (int i=0 ; i<8 ; i++) {
+        EXPECT_TRUE(checkPixel(i*16 + 8,  8, i*16, i*16, i*16, i*16, 0));
+    }
+}
+
+} // namespace android
diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp
new file mode 100644
index 0000000..1077c9d
--- /dev/null
+++ b/libs/gui/tests/SRGB_test.cpp
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2013 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 "SRGB_test"
+//#define LOG_NDEBUG 0
+
+#include "GLTest.h"
+
+#include <gui/CpuConsumer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES3/gl3.h>
+
+#include <android/native_window.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+class SRGBTest : public ::testing::Test {
+protected:
+    // Class constants
+    enum {
+        DISPLAY_WIDTH = 512,
+        DISPLAY_HEIGHT = 512,
+        PIXEL_SIZE = 4, // bytes or components
+        DISPLAY_SIZE = DISPLAY_WIDTH * DISPLAY_HEIGHT * PIXEL_SIZE,
+        ALPHA_VALUE = 223, // should be in [0, 255]
+        TOLERANCE = 1,
+    };
+    static const char SHOW_DEBUG_STRING[];
+
+    SRGBTest() :
+            mInputSurface(), mCpuConsumer(), mLockedBuffer(),
+            mEglDisplay(EGL_NO_DISPLAY), mEglConfig(),
+            mEglContext(EGL_NO_CONTEXT), mEglSurface(EGL_NO_SURFACE),
+            mComposerClient(), mSurfaceControl(), mOutputSurface() {
+    }
+
+    virtual ~SRGBTest() {
+        if (mEglDisplay != EGL_NO_DISPLAY) {
+            if (mEglSurface != EGL_NO_SURFACE) {
+                eglDestroySurface(mEglDisplay, mEglSurface);
+            }
+            if (mEglContext != EGL_NO_CONTEXT) {
+                eglDestroyContext(mEglDisplay, mEglContext);
+            }
+            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                    EGL_NO_CONTEXT);
+            eglTerminate(mEglDisplay);
+        }
+    }
+
+    virtual void SetUp() {
+        mBufferQueue = new BufferQueue();
+        ASSERT_EQ(NO_ERROR, mBufferQueue->setDefaultBufferSize(
+                DISPLAY_WIDTH, DISPLAY_HEIGHT));
+        mCpuConsumer = new CpuConsumer(mBufferQueue, 1);
+        String8 name("CpuConsumer_for_SRGBTest");
+        mCpuConsumer->setName(name);
+        mInputSurface = new Surface(mBufferQueue);
+
+        ASSERT_NO_FATAL_FAILURE(createEGLSurface(mInputSurface.get()));
+        ASSERT_NO_FATAL_FAILURE(createDebugSurface());
+    }
+
+    virtual void TearDown() {
+        ASSERT_NO_FATAL_FAILURE(copyToDebugSurface());
+        ASSERT_TRUE(mLockedBuffer.data != NULL);
+        ASSERT_EQ(NO_ERROR, mCpuConsumer->unlockBuffer(mLockedBuffer));
+    }
+
+    static float linearToSRGB(float l) {
+        if (l <= 0.0031308f) {
+            return l * 12.92f;
+        } else {
+            return 1.055f * pow(l, (1 / 2.4f)) - 0.055f;
+        }
+    }
+
+    static float srgbToLinear(float s) {
+        if (s <= 0.04045) {
+            return s / 12.92f;
+        } else {
+            return pow(((s + 0.055f) / 1.055f), 2.4f);
+        }
+    }
+
+    static uint8_t srgbToLinear(uint8_t u) {
+        float f = u / 255.0f;
+        return static_cast<uint8_t>(srgbToLinear(f) * 255.0f + 0.5f);
+    }
+
+    void fillTexture(bool writeAsSRGB) {
+        uint8_t* textureData = new uint8_t[DISPLAY_SIZE];
+
+        for (int y = 0; y < DISPLAY_HEIGHT; ++y) {
+            for (int x = 0; x < DISPLAY_WIDTH; ++x) {
+                float realValue = static_cast<float>(x) / (DISPLAY_WIDTH - 1);
+                realValue *= ALPHA_VALUE / 255.0f; // Premultiply by alpha
+                if (writeAsSRGB) {
+                    realValue = linearToSRGB(realValue);
+                }
+
+                int offset = (y * DISPLAY_WIDTH + x) * PIXEL_SIZE;
+                for (int c = 0; c < 3; ++c) {
+                    uint8_t intValue = static_cast<uint8_t>(
+                            realValue * 255.0f + 0.5f);
+                    textureData[offset + c] = intValue;
+                }
+                textureData[offset + 3] = ALPHA_VALUE;
+            }
+        }
+
+        glTexImage2D(GL_TEXTURE_2D, 0, writeAsSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA8,
+                DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                textureData);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+
+        delete[] textureData;
+    }
+
+    void initShaders() {
+        static const char vertexSource[] =
+            "attribute vec4 vPosition;\n"
+            "varying vec2 texCoords;\n"
+            "void main() {\n"
+            "  texCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
+            "  gl_Position = vPosition;\n"
+            "}\n";
+
+        static const char fragmentSource[] =
+            "precision mediump float;\n"
+            "uniform sampler2D texSampler;\n"
+            "varying vec2 texCoords;\n"
+            "void main() {\n"
+            "  gl_FragColor = texture2D(texSampler, texCoords);\n"
+            "}\n";
+
+        GLuint program;
+        {
+            SCOPED_TRACE("Creating shader program");
+            ASSERT_NO_FATAL_FAILURE(GLTest::createProgram(
+                    vertexSource, fragmentSource, &program));
+        }
+
+        GLint positionHandle = glGetAttribLocation(program, "vPosition");
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        ASSERT_NE(-1, positionHandle);
+
+        GLint samplerHandle = glGetUniformLocation(program, "texSampler");
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        ASSERT_NE(-1, samplerHandle);
+
+        static const GLfloat vertices[] = {
+            -1.0f, 1.0f,
+            -1.0f, -1.0f,
+            1.0f, -1.0f,
+            1.0f, 1.0f,
+        };
+
+        glVertexAttribPointer(positionHandle, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        glEnableVertexAttribArray(positionHandle);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+
+        glUseProgram(program);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        glUniform1i(samplerHandle, 0);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+
+        GLuint textureHandle;
+        glGenTextures(1, &textureHandle);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        glBindTexture(GL_TEXTURE_2D, textureHandle);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+    }
+
+    void drawTexture(bool asSRGB, GLint x, GLint y, GLsizei width,
+            GLsizei height) {
+        ASSERT_NO_FATAL_FAILURE(fillTexture(asSRGB));
+        glViewport(x, y, width, height);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        ASSERT_EQ(GL_NO_ERROR, glGetError());
+    }
+
+    void checkLockedBuffer(PixelFormat format) {
+        ASSERT_EQ(mLockedBuffer.format, format);
+        ASSERT_EQ(mLockedBuffer.width, DISPLAY_WIDTH);
+        ASSERT_EQ(mLockedBuffer.height, DISPLAY_HEIGHT);
+    }
+
+    static bool withinTolerance(int a, int b) {
+        int diff = a - b;
+        return diff >= 0 ? diff <= TOLERANCE : -diff <= TOLERANCE;
+    }
+
+    // Primary producer and consumer
+    sp<BufferQueue> mBufferQueue;
+    sp<Surface> mInputSurface;
+    sp<CpuConsumer> mCpuConsumer;
+    CpuConsumer::LockedBuffer mLockedBuffer;
+
+    EGLDisplay mEglDisplay;
+    EGLConfig mEglConfig;
+    EGLContext mEglContext;
+    EGLSurface mEglSurface;
+
+    // Auxiliary display output
+    sp<SurfaceComposerClient> mComposerClient;
+    sp<SurfaceControl> mSurfaceControl;
+    sp<Surface> mOutputSurface;
+
+private:
+    void createEGLSurface(Surface* inputSurface) {
+        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
+
+        EXPECT_TRUE(eglInitialize(mEglDisplay, NULL, NULL));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        static const EGLint configAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+            EGL_NONE };
+
+        EGLint numConfigs = 0;
+        EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &mEglConfig, 1,
+                &numConfigs));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_GT(numConfigs, 0);
+
+        static const EGLint contextAttribs[] = {
+            EGL_CONTEXT_CLIENT_VERSION, 3,
+            EGL_NONE } ;
+
+        mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT,
+                contextAttribs);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
+
+        mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig,
+                inputSurface, NULL);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
+
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    }
+
+    void createDebugSurface() {
+        if (getenv(SHOW_DEBUG_STRING) == NULL) return;
+
+        mComposerClient = new SurfaceComposerClient;
+        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
+
+        mSurfaceControl = mComposerClient->createSurface(
+                String8("SRGBTest Surface"), DISPLAY_WIDTH, DISPLAY_HEIGHT,
+                PIXEL_FORMAT_RGBA_8888);
+
+        ASSERT_TRUE(mSurfaceControl != NULL);
+        ASSERT_TRUE(mSurfaceControl->isValid());
+
+        SurfaceComposerClient::openGlobalTransaction();
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
+        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
+        SurfaceComposerClient::closeGlobalTransaction();
+
+        ANativeWindow_Buffer outBuffer;
+        ARect inOutDirtyBounds;
+        mOutputSurface = mSurfaceControl->getSurface();
+        mOutputSurface->lock(&outBuffer, &inOutDirtyBounds);
+        uint8_t* bytePointer = reinterpret_cast<uint8_t*>(outBuffer.bits);
+        for (int y = 0; y < outBuffer.height; ++y) {
+            int rowOffset = y * outBuffer.stride; // pixels
+            for (int x = 0; x < outBuffer.width; ++x) {
+                int colOffset = (rowOffset + x) * PIXEL_SIZE; // bytes
+                for (int c = 0; c < PIXEL_SIZE; ++c) {
+                    int offset = colOffset + c;
+                    bytePointer[offset] = ((c + 1) * 56) - 1;
+                }
+            }
+        }
+        mOutputSurface->unlockAndPost();
+    }
+
+    void copyToDebugSurface() {
+        if (!mOutputSurface.get()) return;
+
+        size_t bufferSize = mLockedBuffer.height * mLockedBuffer.stride *
+                PIXEL_SIZE;
+
+        ANativeWindow_Buffer outBuffer;
+        ARect outBufferBounds;
+        mOutputSurface->lock(&outBuffer, &outBufferBounds);
+        ASSERT_EQ(mLockedBuffer.width, outBuffer.width);
+        ASSERT_EQ(mLockedBuffer.height, outBuffer.height);
+        ASSERT_EQ(mLockedBuffer.stride, outBuffer.stride);
+
+        if (mLockedBuffer.format == outBuffer.format) {
+            memcpy(outBuffer.bits, mLockedBuffer.data, bufferSize);
+        } else {
+            ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_sRGB_A_8888);
+            ASSERT_EQ(outBuffer.format, PIXEL_FORMAT_RGBA_8888);
+            uint8_t* outPointer = reinterpret_cast<uint8_t*>(outBuffer.bits);
+            for (int y = 0; y < outBuffer.height; ++y) {
+                int rowOffset = y * outBuffer.stride; // pixels
+                for (int x = 0; x < outBuffer.width; ++x) {
+                    int colOffset = (rowOffset + x) * PIXEL_SIZE; // bytes
+
+                    // RGB are converted
+                    for (int c = 0; c < (PIXEL_SIZE - 1); ++c) {
+                        outPointer[colOffset + c] = srgbToLinear(
+                                mLockedBuffer.data[colOffset + c]);
+                    }
+
+                    // Alpha isn't converted
+                    outPointer[colOffset + 3] =
+                            mLockedBuffer.data[colOffset + 3];
+                }
+            }
+        }
+        mOutputSurface->unlockAndPost();
+
+        int sleepSeconds = atoi(getenv(SHOW_DEBUG_STRING));
+        sleep(sleepSeconds);
+    }
+};
+
+const char SRGBTest::SHOW_DEBUG_STRING[] = "DEBUG_OUTPUT_SECONDS";
+
+TEST_F(SRGBTest, GLRenderFromSRGBTexture) {
+    ASSERT_NO_FATAL_FAILURE(initShaders());
+
+    // The RGB texture is displayed in the top half
+    ASSERT_NO_FATAL_FAILURE(drawTexture(false, 0, DISPLAY_HEIGHT / 2,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT / 2));
+
+    // The SRGB texture is displayed in the bottom half
+    ASSERT_NO_FATAL_FAILURE(drawTexture(true, 0, 0,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT / 2));
+
+    eglSwapBuffers(mEglDisplay, mEglSurface);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Lock
+    ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
+    ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+
+    // Compare a pixel in the middle of each texture
+    int midSRGBOffset = (DISPLAY_HEIGHT / 4) * mLockedBuffer.stride *
+            PIXEL_SIZE;
+    int midRGBOffset = midSRGBOffset * 3;
+    midRGBOffset += (DISPLAY_WIDTH / 2) * PIXEL_SIZE;
+    midSRGBOffset += (DISPLAY_WIDTH / 2) * PIXEL_SIZE;
+    for (int c = 0; c < PIXEL_SIZE; ++c) {
+        int expectedValue = mLockedBuffer.data[midRGBOffset + c];
+        int actualValue = mLockedBuffer.data[midSRGBOffset + c];
+        ASSERT_PRED2(withinTolerance, expectedValue, actualValue);
+    }
+
+    // mLockedBuffer is unlocked in TearDown so we can copy data from it to
+    // the debug surface if necessary
+}
+
+TEST_F(SRGBTest, RenderToSRGBSurface) {
+    ASSERT_NO_FATAL_FAILURE(initShaders());
+
+    // By default, the first buffer we write into will be RGB
+
+    // Render an RGB texture across the whole surface
+    ASSERT_NO_FATAL_FAILURE(drawTexture(false, 0, 0,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT));
+    eglSwapBuffers(mEglDisplay, mEglSurface);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Lock
+    ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
+    ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+
+    // Save the values of the middle pixel for later comparison against SRGB
+    uint8_t values[PIXEL_SIZE] = {};
+    int middleOffset = (DISPLAY_HEIGHT / 2) * mLockedBuffer.stride *
+            PIXEL_SIZE;
+    middleOffset += (DISPLAY_WIDTH / 2) * PIXEL_SIZE;
+    for (int c = 0; c < PIXEL_SIZE; ++c) {
+        values[c] = mLockedBuffer.data[middleOffset + c];
+    }
+
+    // Unlock
+    ASSERT_EQ(NO_ERROR, mCpuConsumer->unlockBuffer(mLockedBuffer));
+
+    // Switch to SRGB window surface
+#define EGL_GL_COLORSPACE_KHR      EGL_VG_COLORSPACE
+#define EGL_GL_COLORSPACE_SRGB_KHR EGL_VG_COLORSPACE_sRGB
+
+    static const int srgbAttribs[] = {
+        EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR,
+        EGL_NONE,
+    };
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig,
+            mInputSurface.get(), srgbAttribs);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Render the texture again
+    ASSERT_NO_FATAL_FAILURE(drawTexture(false, 0, 0,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT));
+    eglSwapBuffers(mEglDisplay, mEglSurface);
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Lock
+    ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
+
+    // Make sure we actually got the SRGB buffer on the consumer side
+    ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_sRGB_A_8888));
+
+    // Verify that the stored value is the same, accounting for RGB/SRGB
+    for (int c = 0; c < PIXEL_SIZE; ++c) {
+        // The alpha value should be equivalent before linear->SRGB
+        float rgbAsSRGB = (c == 3) ? values[c] / 255.0f :
+                linearToSRGB(values[c] / 255.0f);
+        int expectedValue = rgbAsSRGB * 255.0f + 0.5f;
+        int actualValue = mLockedBuffer.data[middleOffset + c];
+        ASSERT_PRED2(withinTolerance, expectedValue, actualValue);
+    }
+
+    // mLockedBuffer is unlocked in TearDown so we can copy data from it to
+    // the debug surface if necessary
+}
+
+} // namespace android
diff --git a/libs/gui/tests/SurfaceTextureFBO.h b/libs/gui/tests/SurfaceTextureFBO.h
new file mode 100644
index 0000000..7f1ae84
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureFBO.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2013 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_SURFACE_TEXTURE_FBO_H
+#define ANDROID_SURFACE_TEXTURE_FBO_H
+
+#include "SurfaceTextureGL.h"
+
+#include <GLES2/gl2.h>
+
+namespace android {
+
+class SurfaceTextureFBOTest : public SurfaceTextureGLTest {
+protected:
+    virtual void SetUp() {
+        SurfaceTextureGLTest::SetUp();
+
+        glGenFramebuffers(1, &mFbo);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        glGenTextures(1, &mFboTex);
+        glBindTexture(GL_TEXTURE_2D, mFboTex);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
+                getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+        glBindTexture(GL_TEXTURE_2D, 0);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                GL_TEXTURE_2D, mFboTex, 0);
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    }
+
+    virtual void TearDown() {
+        SurfaceTextureGLTest::TearDown();
+
+        glDeleteTextures(1, &mFboTex);
+        glDeleteFramebuffers(1, &mFbo);
+    }
+
+    GLuint mFbo;
+    GLuint mFboTex;
+};
+
+void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride,
+        uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
+    const size_t PIXEL_SIZE = 4;
+    for (int y = 0; y < h; y++) {
+        for (int x = 0; x < w; x++) {
+            off_t offset = (y * stride + x) * PIXEL_SIZE;
+            buf[offset + 0] = r;
+            buf[offset + 1] = g;
+            buf[offset + 2] = b;
+            buf[offset + 3] = a;
+        }
+    }
+}
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/SurfaceTextureFBO_test.cpp b/libs/gui/tests/SurfaceTextureFBO_test.cpp
new file mode 100644
index 0000000..b165ae6
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureFBO_test.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2013 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 "SurfaceTextureFBO_test"
+//#define LOG_NDEBUG 0
+
+#include "SurfaceTextureFBO.h"
+
+namespace android {
+
+// This test is intended to verify that proper synchronization is done when
+// rendering into an FBO.
+TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+            &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+
+    // Fill the buffer with green
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
+            0, 255);
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
+            -1));
+
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
+    drawTexture();
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    for (int i = 0; i < 4; i++) {
+        SCOPED_TRACE(String8::format("frame %d", i).string());
+
+        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+                &anb));
+        ASSERT_TRUE(anb != NULL);
+
+        buf = new GraphicBuffer(anb, false);
+
+        // Fill the buffer with red
+        ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
+                (void**)(&img)));
+        fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
+                0, 255);
+        ASSERT_EQ(NO_ERROR, buf->unlock());
+        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
+                buf->getNativeBuffer(), -1));
+
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+        drawTexture();
+
+        EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
+    }
+
+    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
+
+    EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
+}
+
+} // namespace android
diff --git a/libs/gui/tests/SurfaceTextureGL.h b/libs/gui/tests/SurfaceTextureGL.h
new file mode 100644
index 0000000..ac112c4
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureGL.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2013 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_SURFACE_TEXTURE_GL_H
+#define ANDROID_SURFACE_TEXTURE_GL_H
+
+#include "GLTest.h"
+
+#include "FrameWaiter.h"
+#include "TextureRenderer.h"
+
+#include <gui/GLConsumer.h>
+#include <gui/Surface.h>
+
+namespace android {
+
+class FrameWaiter;
+class GLConsumer;
+class TextureRenderer;
+
+class SurfaceTextureGLTest : public GLTest {
+protected:
+    enum { TEX_ID = 123 };
+
+    void SetUp() {
+        GLTest::SetUp();
+        sp<BufferQueue> bq = new BufferQueue();
+        mBQ = bq;
+        mST = new GLConsumer(bq, TEX_ID);
+        mSTC = new Surface(bq);
+        mANW = mSTC;
+        mTextureRenderer = new TextureRenderer(TEX_ID, mST);
+        ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
+        mFW = new FrameWaiter;
+        mST->setFrameAvailableListener(mFW);
+    }
+
+    void TearDown() {
+        mTextureRenderer.clear();
+        mANW.clear();
+        mSTC.clear();
+        mST.clear();
+        GLTest::TearDown();
+    }
+
+    void drawTexture() {
+        mTextureRenderer->drawTexture();
+    }
+
+    sp<BufferQueue> mBQ;
+    sp<GLConsumer> mST;
+    sp<Surface> mSTC;
+    sp<ANativeWindow> mANW;
+    sp<TextureRenderer> mTextureRenderer;
+    sp<FrameWaiter> mFW;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/SurfaceTextureGLThreadToGL.h b/libs/gui/tests/SurfaceTextureGLThreadToGL.h
new file mode 100644
index 0000000..6410516
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureGLThreadToGL.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2013 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_SURFACE_TEXTURE_GL_THREAD_TO_GL_H
+#define ANDROID_SURFACE_TEXTURE_GL_THREAD_TO_GL_H
+
+#include "SurfaceTextureGLToGL.h"
+
+namespace android {
+
+/*
+ * This test fixture is for testing GL -> GL texture streaming from one thread
+ * to another.  It contains functionality to create a producer thread that will
+ * perform GL rendering to an ANativeWindow that feeds frames to a
+ * GLConsumer.  Additionally it supports interlocking the producer and
+ * consumer threads so that a specific sequence of calls can be
+ * deterministically created by the test.
+ *
+ * The intended usage is as follows:
+ *
+ * TEST_F(...) {
+ *     class PT : public ProducerThread {
+ *         virtual void render() {
+ *             ...
+ *             swapBuffers();
+ *         }
+ *     };
+ *
+ *     runProducerThread(new PT());
+ *
+ *     // The order of these calls will vary from test to test and may include
+ *     // multiple frames and additional operations (e.g. GL rendering from the
+ *     // texture).
+ *     fc->waitForFrame();
+ *     mST->updateTexImage();
+ *     fc->finishFrame();
+ * }
+ *
+ */
+class SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
+protected:
+
+    // ProducerThread is an abstract base class to simplify the creation of
+    // OpenGL ES frame producer threads.
+    class ProducerThread : public Thread {
+    public:
+        virtual ~ProducerThread() {
+        }
+
+        void setEglObjects(EGLDisplay producerEglDisplay,
+                EGLSurface producerEglSurface,
+                EGLContext producerEglContext) {
+            mProducerEglDisplay = producerEglDisplay;
+            mProducerEglSurface = producerEglSurface;
+            mProducerEglContext = producerEglContext;
+        }
+
+        virtual bool threadLoop() {
+            eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
+                    mProducerEglSurface, mProducerEglContext);
+            render();
+            eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                    EGL_NO_CONTEXT);
+            return false;
+        }
+
+    protected:
+        virtual void render() = 0;
+
+        void swapBuffers() {
+            eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
+        }
+
+        EGLDisplay mProducerEglDisplay;
+        EGLSurface mProducerEglSurface;
+        EGLContext mProducerEglContext;
+    };
+
+    // FrameCondition is a utility class for interlocking between the producer
+    // and consumer threads.  The FrameCondition object should be created and
+    // destroyed in the consumer thread only.  The consumer thread should set
+    // the FrameCondition as the FrameAvailableListener of the GLConsumer,
+    // and should call both waitForFrame and finishFrame once for each expected
+    // frame.
+    //
+    // This interlocking relies on the fact that onFrameAvailable gets called
+    // synchronously from GLConsumer::queueBuffer.
+    class FrameCondition : public GLConsumer::FrameAvailableListener {
+    public:
+        FrameCondition():
+                mFrameAvailable(false),
+                mFrameFinished(false) {
+        }
+
+        // waitForFrame waits for the next frame to arrive.  This should be
+        // called from the consumer thread once for every frame expected by the
+        // test.
+        void waitForFrame() {
+            Mutex::Autolock lock(mMutex);
+            ALOGV("+waitForFrame");
+            while (!mFrameAvailable) {
+                mFrameAvailableCondition.wait(mMutex);
+            }
+            mFrameAvailable = false;
+            ALOGV("-waitForFrame");
+        }
+
+        // Allow the producer to return from its swapBuffers call and continue
+        // on to produce the next frame.  This should be called by the consumer
+        // thread once for every frame expected by the test.
+        void finishFrame() {
+            Mutex::Autolock lock(mMutex);
+            ALOGV("+finishFrame");
+            mFrameFinished = true;
+            mFrameFinishCondition.signal();
+            ALOGV("-finishFrame");
+        }
+
+        // This should be called by GLConsumer on the producer thread.
+        virtual void onFrameAvailable() {
+            Mutex::Autolock lock(mMutex);
+            ALOGV("+onFrameAvailable");
+            mFrameAvailable = true;
+            mFrameAvailableCondition.signal();
+            while (!mFrameFinished) {
+                mFrameFinishCondition.wait(mMutex);
+            }
+            mFrameFinished = false;
+            ALOGV("-onFrameAvailable");
+        }
+
+    protected:
+        bool mFrameAvailable;
+        bool mFrameFinished;
+
+        Mutex mMutex;
+        Condition mFrameAvailableCondition;
+        Condition mFrameFinishCondition;
+    };
+
+    virtual void SetUp() {
+        SurfaceTextureGLToGLTest::SetUp();
+        mFC = new FrameCondition();
+        mST->setFrameAvailableListener(mFC);
+    }
+
+    virtual void TearDown() {
+        if (mProducerThread != NULL) {
+            mProducerThread->requestExitAndWait();
+        }
+        mProducerThread.clear();
+        mFC.clear();
+        SurfaceTextureGLToGLTest::TearDown();
+    }
+
+    void runProducerThread(const sp<ProducerThread> producerThread) {
+        ASSERT_TRUE(mProducerThread == NULL);
+        mProducerThread = producerThread;
+        producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
+                mProducerEglContext);
+        producerThread->run();
+    }
+
+    sp<ProducerThread> mProducerThread;
+    sp<FrameCondition> mFC;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/SurfaceTextureGLThreadToGL_test.cpp b/libs/gui/tests/SurfaceTextureGLThreadToGL_test.cpp
new file mode 100644
index 0000000..9776733
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureGLThreadToGL_test.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 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 "SurfaceTextureGLThreadToGL_test"
+//#define LOG_NDEBUG 0
+
+#include "SurfaceTextureGLThreadToGL.h"
+
+namespace android {
+
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        UpdateTexImageBeforeFrameFinishedCompletes) {
+    class PT : public ProducerThread {
+        virtual void render() {
+            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+            glClear(GL_COLOR_BUFFER_BIT);
+            swapBuffers();
+        }
+    };
+
+    runProducerThread(new PT());
+
+    mFC->waitForFrame();
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    mFC->finishFrame();
+
+    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
+}
+
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        UpdateTexImageAfterFrameFinishedCompletes) {
+    class PT : public ProducerThread {
+        virtual void render() {
+            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+            glClear(GL_COLOR_BUFFER_BIT);
+            swapBuffers();
+        }
+    };
+
+    runProducerThread(new PT());
+
+    mFC->waitForFrame();
+    mFC->finishFrame();
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
+}
+
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
+    enum { NUM_ITERATIONS = 1024 };
+
+    class PT : public ProducerThread {
+        virtual void render() {
+            for (int i = 0; i < NUM_ITERATIONS; i++) {
+                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+                glClear(GL_COLOR_BUFFER_BIT);
+                ALOGV("+swapBuffers");
+                swapBuffers();
+                ALOGV("-swapBuffers");
+            }
+        }
+    };
+
+    runProducerThread(new PT());
+
+    for (int i = 0; i < NUM_ITERATIONS; i++) {
+        mFC->waitForFrame();
+        ALOGV("+updateTexImage");
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        ALOGV("-updateTexImage");
+        mFC->finishFrame();
+
+        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
+    }
+}
+
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
+    enum { NUM_ITERATIONS = 1024 };
+
+    class PT : public ProducerThread {
+        virtual void render() {
+            for (int i = 0; i < NUM_ITERATIONS; i++) {
+                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+                glClear(GL_COLOR_BUFFER_BIT);
+                ALOGV("+swapBuffers");
+                swapBuffers();
+                ALOGV("-swapBuffers");
+            }
+        }
+    };
+
+    runProducerThread(new PT());
+
+    for (int i = 0; i < NUM_ITERATIONS; i++) {
+        mFC->waitForFrame();
+        mFC->finishFrame();
+        ALOGV("+updateTexImage");
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        ALOGV("-updateTexImage");
+
+        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
+    }
+}
+
+// XXX: This test is disabled because it is currently hanging on some devices.
+TEST_F(SurfaceTextureGLThreadToGLTest,
+        DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
+    enum { NUM_ITERATIONS = 64 };
+
+    class PT : public ProducerThread {
+        virtual void render() {
+            for (int i = 0; i < NUM_ITERATIONS; i++) {
+                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+                glClear(GL_COLOR_BUFFER_BIT);
+                ALOGV("+swapBuffers");
+                swapBuffers();
+                ALOGV("-swapBuffers");
+            }
+        }
+    };
+
+    ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
+
+    runProducerThread(new PT());
+
+    // Allow three frames to be rendered and queued before starting the
+    // rendering in this thread.  For the latter two frames we don't call
+    // updateTexImage so the next dequeue from the producer thread will block
+    // waiting for a frame to become available.
+    mFC->waitForFrame();
+    mFC->finishFrame();
+
+    // We must call updateTexImage to consume the first frame so that the
+    // SurfaceTexture is able to reduce the buffer count to 2.  This is because
+    // the GL driver may dequeue a buffer when the EGLSurface is created, and
+    // that happens before we call setDefaultMaxBufferCount.  It's possible that the
+    // driver does not dequeue a buffer at EGLSurface creation time, so we
+    // cannot rely on this to cause the second dequeueBuffer call to block.
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    mFC->waitForFrame();
+    mFC->finishFrame();
+    mFC->waitForFrame();
+    mFC->finishFrame();
+
+    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
+    // block waiting for a buffer to become available.
+    usleep(100000);
+
+    // Render and present a number of images.  This thread should not be blocked
+    // by the fact that the producer thread is blocking in dequeue.
+    for (int i = 0; i < NUM_ITERATIONS; i++) {
+        glClear(GL_COLOR_BUFFER_BIT);
+        eglSwapBuffers(mEglDisplay, mEglSurface);
+    }
+
+    // Consume the two pending buffers to unblock the producer thread.
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    // Consume the remaining buffers from the producer thread.
+    for (int i = 0; i < NUM_ITERATIONS-3; i++) {
+        mFC->waitForFrame();
+        mFC->finishFrame();
+        ALOGV("+updateTexImage");
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        ALOGV("-updateTexImage");
+    }
+}
+
+} // namespace android
diff --git a/libs/gui/tests/SurfaceTextureGLToGL.h b/libs/gui/tests/SurfaceTextureGLToGL.h
new file mode 100644
index 0000000..5a2eff3
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureGLToGL.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 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_SURFACE_TEXTURE_GL_TO_GL_H
+#define ANDROID_SURFACE_TEXTURE_GL_TO_GL_H
+
+#include "SurfaceTextureGL.h"
+
+namespace android {
+
+/*
+ * This test fixture is for testing GL -> GL texture streaming.  It creates an
+ * EGLSurface and an EGLContext for the image producer to use.
+ */
+class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
+protected:
+    SurfaceTextureGLToGLTest():
+            mProducerEglSurface(EGL_NO_SURFACE),
+            mProducerEglContext(EGL_NO_CONTEXT) {
+    }
+
+    virtual void SetUp() {
+        SurfaceTextureGLTest::SetUp();
+
+        mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
+                mANW.get(), NULL);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
+
+        mProducerEglContext = eglCreateContext(mEglDisplay, mGlConfig,
+                EGL_NO_CONTEXT, getContextAttribs());
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
+    }
+
+    virtual void TearDown() {
+        if (mProducerEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mProducerEglContext);
+        }
+        if (mProducerEglSurface != EGL_NO_SURFACE) {
+            eglDestroySurface(mEglDisplay, mProducerEglSurface);
+        }
+        SurfaceTextureGLTest::TearDown();
+    }
+
+    EGLSurface mProducerEglSurface;
+    EGLContext mProducerEglContext;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/gui/tests/SurfaceTextureGLToGL_test.cpp b/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
new file mode 100644
index 0000000..f4c7961
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureGLToGL_test.cpp
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2013 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 "SurfaceTextureGLToGL_test"
+//#define LOG_NDEBUG 0
+
+#include "SurfaceTextureGLToGL.h"
+
+namespace android {
+
+TEST_F(SurfaceTextureGLToGLTest, TransformHintGetsRespected) {
+    const uint32_t texWidth = 32;
+    const uint32_t texHeight = 64;
+
+    mST->setDefaultBufferSize(texWidth, texHeight);
+    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
+
+    // This test requires 3 buffers to avoid deadlock because we're
+    // both producer and consumer, and only using one thread.
+    mST->setDefaultMaxBufferCount(3);
+
+    // Do the producer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Start a buffer with our chosen size and transform hint moving
+    // through the system.
+    glClear(GL_COLOR_BUFFER_BIT);  // give the driver something to do
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();  // consume it
+    // Swap again.
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();
+
+    // The current buffer should either show the effects of the transform
+    // hint (in the form of an inverse transform), or show that the
+    // transform hint has been ignored.
+    sp<GraphicBuffer> buf = mST->getCurrentBuffer();
+    if (mST->getCurrentTransform() == NATIVE_WINDOW_TRANSFORM_ROT_270) {
+        ASSERT_EQ(texWidth, buf->getHeight());
+        ASSERT_EQ(texHeight, buf->getWidth());
+    } else {
+        ASSERT_EQ(texWidth, buf->getWidth());
+        ASSERT_EQ(texHeight, buf->getHeight());
+    }
+
+    // Reset the transform hint and confirm that it takes.
+    mST->setTransformHint(0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+    mST->updateTexImage();
+
+    buf = mST->getCurrentBuffer();
+    ASSERT_EQ((uint32_t) 0, mST->getCurrentTransform());
+    ASSERT_EQ(texWidth, buf->getWidth());
+    ASSERT_EQ(texHeight, buf->getHeight());
+}
+
+TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    mST->setDefaultBufferSize(texWidth, texHeight);
+
+    // This test requires 3 buffers to complete run on a single thread.
+    mST->setDefaultMaxBufferCount(3);
+
+    // Do the producer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // This is needed to ensure we pick up a buffer of the correct size.
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    glClearColor(0.6, 0.6, 0.6, 0.6);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(4, 4, 4, 4);
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScissor(24, 48, 4, 4);
+    glClearColor(0.0, 1.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScissor(37, 17, 4, 4);
+    glClearColor(0.0, 0.0, 1.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    // Do the consumer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    glDisable(GL_SCISSOR_TEST);
+
+    // Skip the first frame, which was empty
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
+
+    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
+    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
+    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
+    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
+    sp<GraphicBuffer> buffers[2];
+
+    // This test requires async mode to run on a single thread.
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    for (int i = 0; i < 2; i++) {
+        // Produce a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+                mProducerEglSurface, mProducerEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        glClear(GL_COLOR_BUFFER_BIT);
+        eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+        // Consume a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        mFW->waitForFrame();
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        buffers[i] = mST->getCurrentBuffer();
+    }
+
+    // Destroy the GL texture object to release its ref on buffers[2].
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy the EGLSurface
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    mProducerEglSurface = EGL_NO_SURFACE;
+
+    // This test should have the only reference to buffer 0.
+    EXPECT_EQ(1, buffers[0]->getStrongCount());
+
+    // The GLConsumer should hold a single reference to buffer 1 in its
+    // mCurrentBuffer member.  All of the references in the slots should have
+    // been released.
+    EXPECT_EQ(2, buffers[1]->getStrongCount());
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
+    sp<GraphicBuffer> buffers[3];
+
+    // This test requires async mode to run on a single thread.
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    for (int i = 0; i < 3; i++) {
+        // Produce a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+                mProducerEglSurface, mProducerEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        glClear(GL_COLOR_BUFFER_BIT);
+        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        // Consume a frame
+        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        mFW->waitForFrame();
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        buffers[i] = mST->getCurrentBuffer();
+    }
+
+    // Abandon the GLConsumer, releasing the ref that the GLConsumer has
+    // on buffers[2].
+    mST->abandon();
+
+    // Destroy the GL texture object to release its ref on buffers[2].
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy the EGLSurface.
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    mProducerEglSurface = EGL_NO_SURFACE;
+
+    EXPECT_EQ(1, buffers[0]->getStrongCount());
+    EXPECT_EQ(1, buffers[1]->getStrongCount());
+
+    // Depending on how lazily the GL driver dequeues buffers, we may end up
+    // with either two or three total buffers.  If there are three, make sure
+    // the last one was properly down-ref'd.
+    if (buffers[2] != buffers[0]) {
+        EXPECT_EQ(1, buffers[2]->getStrongCount());
+    }
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentBeforeConsumerDeathUnrefsBuffers) {
+    sp<GraphicBuffer> buffer;
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+
+    // Produce a frame
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Destroy the EGLSurface.
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    mProducerEglSurface = EGL_NO_SURFACE;
+    mSTC.clear();
+    mANW.clear();
+    mTextureRenderer.clear();
+
+    // Consume a frame
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    buffer = mST->getCurrentBuffer();
+
+    // Destroy the GL texture object to release its ref
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // make un-current, all references to buffer should be gone
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
+            EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+    // Destroy consumer
+    mST.clear();
+
+    EXPECT_EQ(1, buffer->getStrongCount());
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentAfterConsumerDeathUnrefsBuffers) {
+    sp<GraphicBuffer> buffer;
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+
+    // Produce a frame
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Destroy the EGLSurface.
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    mProducerEglSurface = EGL_NO_SURFACE;
+    mSTC.clear();
+    mANW.clear();
+    mTextureRenderer.clear();
+
+    // Consume a frame
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    buffer = mST->getCurrentBuffer();
+
+    // Destroy the GL texture object to release its ref
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy consumer
+    mST.clear();
+
+    // make un-current, all references to buffer should be gone
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
+            EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+    EXPECT_EQ(1, buffer->getStrongCount());
+}
+
+TEST_F(SurfaceTextureGLToGLTest, TexturingFromUserSizedGLFilledBuffer) {
+    enum { texWidth = 64 };
+    enum { texHeight = 64 };
+
+    // This test requires 3 buffers to complete run on a single thread.
+    mST->setDefaultMaxBufferCount(3);
+
+    // Set the user buffer size.
+    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
+
+    // Do the producer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // This is needed to ensure we pick up a buffer of the correct size.
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    glClearColor(0.6, 0.6, 0.6, 0.6);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(4, 4, 1, 1);
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    // Do the consumer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    glDisable(GL_SCISSOR_TEST);
+
+    // Skip the first frame, which was empty
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
+
+    EXPECT_TRUE(checkPixel( 4,  4, 255,   0,   0, 255));
+    EXPECT_TRUE(checkPixel( 5,  5, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 3,  3, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(45, 52, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(12, 36, 153, 153, 153, 153));
+}
+
+TEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedUserSizedGLFilledBuffer) {
+    enum { texWidth = 64 };
+    enum { texHeight = 16 };
+
+    // This test requires 3 buffers to complete run on a single thread.
+    mST->setDefaultMaxBufferCount(3);
+
+    // Set the transform hint.
+    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
+
+    // Set the user buffer size.
+    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
+
+    // Do the producer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // This is needed to ensure we pick up a buffer of the correct size and the
+    // new rotation hint.
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    glClearColor(0.6, 0.6, 0.6, 0.6);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(24, 4, 1, 1);
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    // Do the consumer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    glDisable(GL_SCISSOR_TEST);
+
+    // Skip the first frame, which was empty
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
+
+    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
+    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
+}
+
+TEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedGLFilledBuffer) {
+    enum { texWidth = 64 };
+    enum { texHeight = 16 };
+
+    // This test requires 3 buffers to complete run on a single thread.
+    mST->setDefaultMaxBufferCount(3);
+
+    // Set the transform hint.
+    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
+
+    // Set the default buffer size.
+    mST->setDefaultBufferSize(texWidth, texHeight);
+
+    // Do the producer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // This is needed to ensure we pick up a buffer of the correct size and the
+    // new rotation hint.
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    glClearColor(0.6, 0.6, 0.6, 0.6);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(24, 4, 1, 1);
+    glClearColor(1.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+    // Do the consumer side of things
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    glDisable(GL_SCISSOR_TEST);
+
+    // Skip the first frame, which was empty
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
+
+    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
+    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
+    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
+}
+
+} // namespace android
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
new file mode 100644
index 0000000..25b2319
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -0,0 +1,703 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceTextureGL_test"
+//#define LOG_NDEBUG 0
+
+#include "SurfaceTextureGL.h"
+
+#include "DisconnectWaiter.h"
+#include "FillBuffer.h"
+
+namespace android {
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
+    const int texWidth = 64;
+    const int texHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    ANativeWindowBuffer* anb;
+    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+            &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
+            -1));
+
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255, 3));
+    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255, 3));
+    EXPECT_TRUE(checkPixel(63, 65,   0, 133,   0, 255, 3));
+    EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255, 3));
+
+    EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255, 3));
+    EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255, 3));
+    EXPECT_TRUE(checkPixel(52, 51,  98, 255,  73, 255, 3));
+    EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255, 3));
+    EXPECT_TRUE(checkPixel(31,  9, 107,  24,  87, 255, 3));
+    EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255, 3));
+    EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255, 3));
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    ANativeWindowBuffer* anb;
+    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+            &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+
+    // Fill the buffer with the a checkerboard pattern
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
+            -1));
+
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
+    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
+
+    EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
+    EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
+    EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
+    EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
+    EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
+    EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
+    const int texWidth = 64;
+    const int texHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_rect_t crops[] = {
+        {4, 6, 22, 36},
+        {0, 6, 22, 36},
+        {4, 0, 22, 36},
+        {4, 6, texWidth, 36},
+        {4, 6, 22, texHeight},
+    };
+
+    for (int i = 0; i < 5; i++) {
+        const android_native_rect_t& crop(crops[i]);
+        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
+                crop.left, crop.top, crop.right, crop.bottom).string());
+
+        ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
+
+        ANativeWindowBuffer* anb;
+        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+                &anb));
+        ASSERT_TRUE(anb != NULL);
+
+        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+
+        uint8_t* img = NULL;
+        buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+        fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
+        buf->unlock();
+        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
+                buf->getNativeBuffer(), -1));
+
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+        glClearColor(0.2, 0.2, 0.2, 0.2);
+        glClear(GL_COLOR_BUFFER_BIT);
+
+        glViewport(0, 0, 64, 64);
+        drawTexture();
+
+        EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
+
+        EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
+        EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
+    }
+}
+
+// This test is intended to catch synchronization bugs between the CPU-written
+// and GPU-read buffers.
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
+    enum { texWidth = 16 };
+    enum { texHeight = 16 };
+    enum { numFrames = 1024 };
+
+    ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    struct TestPixel {
+        int x;
+        int y;
+    };
+    const TestPixel testPixels[] = {
+        {  4, 11 },
+        { 12, 14 },
+        {  7,  2 },
+    };
+    enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
+
+    class ProducerThread : public Thread {
+    public:
+        ProducerThread(const sp<ANativeWindow>& anw,
+                const TestPixel* testPixels):
+                mANW(anw),
+                mTestPixels(testPixels) {
+        }
+
+        virtual ~ProducerThread() {
+        }
+
+        virtual bool threadLoop() {
+            for (int i = 0; i < numFrames; i++) {
+                ANativeWindowBuffer* anb;
+                if (native_window_dequeue_buffer_and_wait(mANW.get(),
+                        &anb) != NO_ERROR) {
+                    return false;
+                }
+                if (anb == NULL) {
+                    return false;
+                }
+
+                sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+
+                const int yuvTexOffsetY = 0;
+                int stride = buf->getStride();
+                int yuvTexStrideY = stride;
+                int yuvTexOffsetV = yuvTexStrideY * texHeight;
+                int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+                int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
+                int yuvTexStrideU = yuvTexStrideV;
+
+                uint8_t* img = NULL;
+                buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+
+                // Gray out all the test pixels first, so we're more likely to
+                // see a failure if GL is still texturing from the buffer we
+                // just dequeued.
+                for (int j = 0; j < numTestPixels; j++) {
+                    int x = mTestPixels[j].x;
+                    int y = mTestPixels[j].y;
+                    uint8_t value = 128;
+                    img[y*stride + x] = value;
+                }
+
+                // Fill the buffer with gray.
+                for (int y = 0; y < texHeight; y++) {
+                    for (int x = 0; x < texWidth; x++) {
+                        img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
+                        img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
+                        img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
+                    }
+                }
+
+                // Set the test pixels to either white or black.
+                for (int j = 0; j < numTestPixels; j++) {
+                    int x = mTestPixels[j].x;
+                    int y = mTestPixels[j].y;
+                    uint8_t value = 0;
+                    if (j == (i % numTestPixels)) {
+                        value = 255;
+                    }
+                    img[y*stride + x] = value;
+                }
+
+                buf->unlock();
+                if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1)
+                        != NO_ERROR) {
+                    return false;
+                }
+            }
+            return false;
+        }
+
+        sp<ANativeWindow> mANW;
+        const TestPixel* mTestPixels;
+    };
+
+    sp<Thread> pt(new ProducerThread(mANW, testPixels));
+    pt->run();
+
+    glViewport(0, 0, texWidth, texHeight);
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    // We wait for the first two frames up front so that the producer will be
+    // likely to dequeue the buffer that's currently being textured from.
+    mFW->waitForFrame();
+    mFW->waitForFrame();
+
+    for (int i = 0; i < numFrames; i++) {
+        SCOPED_TRACE(String8::format("frame %d", i).string());
+
+        // We must wait for each frame to come in because if we ever do an
+        // updateTexImage call that doesn't consume a newly available buffer
+        // then the producer and consumer will get out of sync, which will cause
+        // a deadlock.
+        if (i > 1) {
+            mFW->waitForFrame();
+        }
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+        drawTexture();
+
+        for (int j = 0; j < numTestPixels; j++) {
+            int x = testPixels[j].x;
+            int y = testPixels[j].y;
+            uint8_t value = 0;
+            if (j == (i % numTestPixels)) {
+                // We must y-invert the texture coords
+                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
+            } else {
+                // We must y-invert the texture coords
+                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
+            }
+        }
+    }
+
+    pt->requestExitAndWait();
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
+    const int texWidth = 64;
+    const int texHeight = 66;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
+    EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
+
+    EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
+    EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
+    EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
+    EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
+    EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
+    EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
+    EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
+    EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
+    EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
+}
+
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glViewport(0, 0, texWidth, texHeight);
+    drawTexture();
+
+    EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
+    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
+    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
+
+    EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
+    EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
+    EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
+    EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
+    EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
+    EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
+    EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
+    EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
+    EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
+    EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
+    EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
+    EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
+    EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
+    EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
+    EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
+}
+
+// Tests if GLConsumer and BufferQueue are robust enough
+// to handle a special case where updateTexImage is called
+// in the middle of disconnect.  This ordering is enforced
+// by blocking in the disconnect callback.
+TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
+
+    class ProducerThread : public Thread {
+    public:
+        ProducerThread(const sp<ANativeWindow>& anw):
+                mANW(anw) {
+        }
+
+        virtual ~ProducerThread() {
+        }
+
+        virtual bool threadLoop() {
+            ANativeWindowBuffer* anb;
+
+            native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
+
+            for (int numFrames =0 ; numFrames < 2; numFrames ++) {
+
+                if (native_window_dequeue_buffer_and_wait(mANW.get(),
+                        &anb) != NO_ERROR) {
+                    return false;
+                }
+                if (anb == NULL) {
+                    return false;
+                }
+                if (mANW->queueBuffer(mANW.get(), anb, -1)
+                        != NO_ERROR) {
+                    return false;
+                }
+            }
+
+            native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL);
+
+            return false;
+        }
+
+    private:
+        sp<ANativeWindow> mANW;
+    };
+
+    sp<DisconnectWaiter> dw(new DisconnectWaiter());
+    mBQ->consumerConnect(dw, false);
+
+
+    sp<Thread> pt(new ProducerThread(mANW));
+    pt->run();
+
+    // eat a frame so GLConsumer will own an at least one slot
+    dw->waitForFrame();
+    EXPECT_EQ(OK,mST->updateTexImage());
+
+    dw->waitForFrame();
+    // Could fail here as GLConsumer thinks it still owns the slot
+    // but bufferQueue has released all slots
+    EXPECT_EQ(OK,mST->updateTexImage());
+
+    dw->finishDisconnect();
+}
+
+
+// This test ensures that the GLConsumer clears the mCurrentTexture
+// when it is disconnected and reconnected.  Otherwise it will
+// attempt to release a buffer that it does not owned
+TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
+    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
+            NATIVE_WINDOW_API_EGL));
+
+    ANativeWindowBuffer *anb;
+
+    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
+    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
+
+    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
+    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
+
+    EXPECT_EQ(OK,mST->updateTexImage());
+    EXPECT_EQ(OK,mST->updateTexImage());
+
+    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
+            NATIVE_WINDOW_API_EGL));
+    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
+            NATIVE_WINDOW_API_EGL));
+
+    EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
+    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
+
+    // Will fail here if mCurrentTexture is not cleared properly
+    mFW->waitForFrame();
+    EXPECT_EQ(OK,mST->updateTexImage());
+
+    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
+            NATIVE_WINDOW_API_EGL));
+}
+
+TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
+    ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
+        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
+
+    // The producer image size
+    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
+
+    // The consumer image size (16 x 9) ratio
+    mST->setDefaultBufferSize(1280, 720);
+
+    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
+            NATIVE_WINDOW_API_CPU));
+
+    ANativeWindowBuffer *anb;
+
+    android_native_rect_t odd = {23, 78, 123, 477};
+    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd));
+    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
+    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
+    mFW->waitForFrame();
+    EXPECT_EQ(OK, mST->updateTexImage());
+    Rect r = mST->getCurrentCrop();
+    assertRectEq(Rect(23, 78, 123, 477), r);
+
+    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
+            NATIVE_WINDOW_API_CPU));
+}
+
+// This test ensures the scaling mode does the right thing
+// ie NATIVE_WINDOW_SCALING_MODE_CROP should crop
+// the image such that it has the same aspect ratio as the
+// default buffer size
+TEST_F(SurfaceTextureGLTest, CroppedScalingMode) {
+    ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
+        NATIVE_WINDOW_SCALING_MODE_SCALE_CROP));
+
+    // The producer image size
+    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
+
+    // The consumer image size (16 x 9) ratio
+    mST->setDefaultBufferSize(1280, 720);
+
+    native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU);
+
+    ANativeWindowBuffer *anb;
+
+    // The crop is in the shape of (320, 180) === 16 x 9
+    android_native_rect_t standard = {10, 20, 330, 200};
+    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard));
+    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
+    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
+    mFW->waitForFrame();
+    EXPECT_EQ(OK, mST->updateTexImage());
+    Rect r = mST->getCurrentCrop();
+    // crop should be the same as crop (same aspect ratio)
+    assertRectEq(Rect(10, 20, 330, 200), r);
+
+    // make this wider then desired aspect 239 x 100 (2.39:1)
+    android_native_rect_t wide = {20, 30, 259, 130};
+    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide));
+    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
+    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
+    mFW->waitForFrame();
+    EXPECT_EQ(OK, mST->updateTexImage());
+    r = mST->getCurrentCrop();
+    // crop should be the same height, but have cropped left and right borders
+    // offset is 30.6 px L+, R-
+    assertRectEq(Rect(51, 30, 228, 130), r);
+
+    // This image is taller then desired aspect 400 x 300 (4:3)
+    android_native_rect_t narrow = {0, 0, 400, 300};
+    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow));
+    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
+    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
+    mFW->waitForFrame();
+    EXPECT_EQ(OK, mST->updateTexImage());
+    r = mST->getCurrentCrop();
+    // crop should be the same width, but have cropped top and bottom borders
+    // offset is 37.5 px
+    assertRectEq(Rect(0, 37, 400, 262), r);
+
+    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
+}
+
+TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
+    class ProducerThread : public Thread {
+    public:
+        ProducerThread(const sp<ANativeWindow>& anw):
+                mANW(anw),
+                mDequeueError(NO_ERROR) {
+        }
+
+        virtual ~ProducerThread() {
+        }
+
+        virtual bool threadLoop() {
+            Mutex::Autolock lock(mMutex);
+            ANativeWindowBuffer* anb;
+
+            // Frame 1
+            if (native_window_dequeue_buffer_and_wait(mANW.get(),
+                    &anb) != NO_ERROR) {
+                return false;
+            }
+            if (anb == NULL) {
+                return false;
+            }
+            if (mANW->queueBuffer(mANW.get(), anb, -1)
+                    != NO_ERROR) {
+                return false;
+            }
+
+            // Frame 2
+            if (native_window_dequeue_buffer_and_wait(mANW.get(),
+                    &anb) != NO_ERROR) {
+                return false;
+            }
+            if (anb == NULL) {
+                return false;
+            }
+            if (mANW->queueBuffer(mANW.get(), anb, -1)
+                    != NO_ERROR) {
+                return false;
+            }
+
+            // Frame 3 - error expected
+            mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(),
+                &anb);
+            return false;
+        }
+
+        status_t getDequeueError() {
+            Mutex::Autolock lock(mMutex);
+            return mDequeueError;
+        }
+
+    private:
+        sp<ANativeWindow> mANW;
+        status_t mDequeueError;
+        Mutex mMutex;
+    };
+
+    ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
+
+    sp<Thread> pt(new ProducerThread(mANW));
+    pt->run();
+
+    mFW->waitForFrame();
+    mFW->waitForFrame();
+
+    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
+    // block waiting for a buffer to become available.
+    usleep(100000);
+
+    mST->abandon();
+
+    pt->requestExitAndWait();
+    ASSERT_EQ(NO_INIT,
+            reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
+}
+
+TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
+    int texHeight = 16;
+    ANativeWindowBuffer* anb;
+
+    GLint maxTextureSize;
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+
+    // make sure it works with small textures
+    mST->setDefaultBufferSize(16, texHeight);
+    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+            &anb));
+    EXPECT_EQ(16, anb->width);
+    EXPECT_EQ(texHeight, anb->height);
+    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
+    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
+
+    // make sure it works with GL_MAX_TEXTURE_SIZE
+    mST->setDefaultBufferSize(maxTextureSize, texHeight);
+    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+            &anb));
+    EXPECT_EQ(maxTextureSize, anb->width);
+    EXPECT_EQ(texHeight, anb->height);
+    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
+    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
+
+    // make sure it fails with GL_MAX_TEXTURE_SIZE+1
+    mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
+    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
+            &anb));
+    EXPECT_EQ(maxTextureSize+1, anb->width);
+    EXPECT_EQ(texHeight, anb->height);
+    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
+    ASSERT_NE(NO_ERROR, mST->updateTexImage());
+}
+
+} // namespace android
diff --git a/libs/gui/tests/SurfaceTextureMultiContextGL.h b/libs/gui/tests/SurfaceTextureMultiContextGL.h
new file mode 100644
index 0000000..7934bbc
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureMultiContextGL.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2013 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_SURFACE_TEXTURE_MULTI_CONTEXT_GL_H
+#define ANDROID_SURFACE_TEXTURE_MULTI_CONTEXT_GL_H
+
+#include "SurfaceTextureGL.h"
+
+namespace android {
+
+class SurfaceTextureMultiContextGLTest : public SurfaceTextureGLTest {
+protected:
+    enum { SECOND_TEX_ID = 123 };
+    enum { THIRD_TEX_ID = 456 };
+
+    SurfaceTextureMultiContextGLTest():
+            mSecondEglContext(EGL_NO_CONTEXT) {
+    }
+
+    virtual void SetUp() {
+        SurfaceTextureGLTest::SetUp();
+
+        // Set up the secondary context and texture renderer.
+        mSecondEglContext = eglCreateContext(mEglDisplay, mGlConfig,
+                EGL_NO_CONTEXT, getContextAttribs());
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mSecondEglContext);
+
+        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mSecondEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        mSecondTextureRenderer = new TextureRenderer(SECOND_TEX_ID, mST);
+        ASSERT_NO_FATAL_FAILURE(mSecondTextureRenderer->SetUp());
+
+        // Set up the tertiary context and texture renderer.
+        mThirdEglContext = eglCreateContext(mEglDisplay, mGlConfig,
+                EGL_NO_CONTEXT, getContextAttribs());
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mThirdEglContext);
+
+        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mThirdEglContext));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        mThirdTextureRenderer = new TextureRenderer(THIRD_TEX_ID, mST);
+        ASSERT_NO_FATAL_FAILURE(mThirdTextureRenderer->SetUp());
+
+        // Switch back to the primary context to start the tests.
+        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                mEglContext));
+    }
+
+    virtual void TearDown() {
+        if (mThirdEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mThirdEglContext);
+        }
+        if (mSecondEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mSecondEglContext);
+        }
+        SurfaceTextureGLTest::TearDown();
+    }
+
+    EGLContext mSecondEglContext;
+    sp<TextureRenderer> mSecondTextureRenderer;
+
+    EGLContext mThirdEglContext;
+    sp<TextureRenderer> mThirdTextureRenderer;
+};
+
+}
+
+#endif
diff --git a/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp b/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
new file mode 100644
index 0000000..115a47d
--- /dev/null
+++ b/libs/gui/tests/SurfaceTextureMultiContextGL_test.cpp
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2013 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 "SurfaceTextureMultiContextGL_test"
+//#define LOG_NDEBUG 0
+
+#include "SurfaceTextureMultiContextGL.h"
+
+#include "FillBuffer.h"
+
+#include <GLES/glext.h>
+
+namespace android {
+
+TEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Attempt to latch the texture on the secondary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Check that the GL texture was deleted.
+    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest,
+        DetachFromContextSucceedsAfterProducerDisconnect) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Check that the GL texture was deleted.
+    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Attempt to detach from the primary context.
+    mST->abandon();
+    ASSERT_EQ(NO_INIT, mST->detachFromContext());
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attempt to detach from the primary context again.
+    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Make there be no current display.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+            EGL_NO_CONTEXT));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Attempt to detach from the primary context.
+    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Make current context be incorrect.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Attempt to detach from the primary context.
+    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attempt to latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attach to the secondary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
+
+    // Verify that the texture object was created and bound.
+    GLint texBinding = -1;
+    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
+    EXPECT_EQ(SECOND_TEX_ID, texBinding);
+
+    // Try to use the texture from the secondary context.
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glViewport(0, 0, 1, 1);
+    mSecondTextureRenderer->drawTexture();
+    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest,
+        AttachToContextSucceedsAfterProducerDisconnect) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attach to the secondary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
+
+    // Verify that the texture object was created and bound.
+    GLint texBinding = -1;
+    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
+    EXPECT_EQ(SECOND_TEX_ID, texBinding);
+
+    // Try to use the texture from the secondary context.
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glViewport(0, 0, 1, 1);
+    mSecondTextureRenderer->drawTexture();
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest,
+        AttachToContextSucceedsBeforeUpdateTexImage) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Detach from the primary context.
+    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attach to the secondary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
+
+    // Verify that the texture object was created and bound.
+    GLint texBinding = -1;
+    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
+    EXPECT_EQ(SECOND_TEX_ID, texBinding);
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Try to use the texture from the secondary context.
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glViewport(0, 0, 1, 1);
+    mSecondTextureRenderer->drawTexture();
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attempt to attach to the secondary context.
+    mST->abandon();
+
+    // Attempt to attach to the primary context.
+    ASSERT_EQ(NO_INIT, mST->attachToContext(SECOND_TEX_ID));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Attempt to attach to the primary context.
+    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest,
+        AttachToContextFailsWhenAttachedBeforeUpdateTexImage) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Attempt to attach to the primary context.
+    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Make there be no current display.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+            EGL_NO_CONTEXT));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Attempt to attach with no context current.
+    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Latch the texture contents on the primary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attach to the secondary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
+
+    // Detach from the secondary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attach to the tertiary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mThirdEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
+
+    // Verify that the texture object was created and bound.
+    GLint texBinding = -1;
+    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
+    EXPECT_EQ(THIRD_TEX_ID, texBinding);
+
+    // Try to use the texture from the tertiary context.
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glViewport(0, 0, 1, 1);
+    mThirdTextureRenderer->drawTexture();
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest,
+        AttachToContextSucceedsTwiceBeforeUpdateTexImage) {
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Detach from the primary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attach to the secondary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
+
+    // Detach from the secondary context.
+    ASSERT_EQ(OK, mST->detachFromContext());
+
+    // Attach to the tertiary context.
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mThirdEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
+
+    // Verify that the texture object was created and bound.
+    GLint texBinding = -1;
+    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
+    EXPECT_EQ(THIRD_TEX_ID, texBinding);
+
+    // Latch the texture contents on the tertiary context.
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // Try to use the texture from the tertiary context.
+    glClearColor(0.2, 0.2, 0.2, 0.2);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glViewport(0, 0, 1, 1);
+    mThirdTextureRenderer->drawTexture();
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
+}
+
+TEST_F(SurfaceTextureMultiContextGLTest,
+        UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
+    ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
+
+    // produce two frames and consume them both on the primary context
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+
+    // produce one more frame
+    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
+
+    // Detach from the primary context and attach to the secondary context
+    ASSERT_EQ(OK, mST->detachFromContext());
+    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+            mSecondEglContext));
+    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
+
+    // Consume final frame on secondary context
+    mFW->waitForFrame();
+    ASSERT_EQ(OK, mST->updateTexImage());
+}
+
+} // namespace android
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
deleted file mode 100644
index e4fba15..0000000
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ /dev/null
@@ -1,2816 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceTexture_test"
-//#define LOG_NDEBUG 0
-
-#include <gtest/gtest.h>
-#include <gui/GLConsumer.h>
-#include <ui/GraphicBuffer.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include <gui/ISurfaceComposer.h>
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <ui/FramebufferNativeWindow.h>
-#include <android/native_window.h>
-
-namespace android {
-
-class GLTest : public ::testing::Test {
-protected:
-
-    GLTest():
-            mEglDisplay(EGL_NO_DISPLAY),
-            mEglSurface(EGL_NO_SURFACE),
-            mEglContext(EGL_NO_CONTEXT) {
-    }
-
-    virtual void SetUp() {
-        const ::testing::TestInfo* const testInfo =
-            ::testing::UnitTest::GetInstance()->current_test_info();
-        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
-                testInfo->name());
-
-        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
-
-        EGLint majorVersion;
-        EGLint minorVersion;
-        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        RecordProperty("EglVersionMajor", majorVersion);
-        RecordProperty("EglVersionMajor", minorVersion);
-
-        EGLint numConfigs = 0;
-        EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig,
-                1, &numConfigs));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
-        if (displaySecsEnv != NULL) {
-            mDisplaySecs = atoi(displaySecsEnv);
-            if (mDisplaySecs < 0) {
-                mDisplaySecs = 0;
-            }
-        } else {
-            mDisplaySecs = 0;
-        }
-
-        if (mDisplaySecs > 0) {
-            mComposerClient = new SurfaceComposerClient;
-            ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
-
-            mSurfaceControl = mComposerClient->createSurface(
-                    String8("Test Surface"),
-                    getSurfaceWidth(), getSurfaceHeight(),
-                    PIXEL_FORMAT_RGB_888, 0);
-
-            ASSERT_TRUE(mSurfaceControl != NULL);
-            ASSERT_TRUE(mSurfaceControl->isValid());
-
-            SurfaceComposerClient::openGlobalTransaction();
-            ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
-            ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
-            SurfaceComposerClient::closeGlobalTransaction();
-
-            sp<ANativeWindow> window = mSurfaceControl->getSurface();
-            mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
-                    window.get(), NULL);
-        } else {
-            EGLint pbufferAttribs[] = {
-                EGL_WIDTH, getSurfaceWidth(),
-                EGL_HEIGHT, getSurfaceHeight(),
-                EGL_NONE };
-
-            mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
-                    pbufferAttribs);
-        }
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
-
-        mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
-                getContextAttribs());
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
-
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        EGLint w, h;
-        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        RecordProperty("EglSurfaceWidth", w);
-        RecordProperty("EglSurfaceHeight", h);
-
-        glViewport(0, 0, w, h);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    }
-
-    virtual void TearDown() {
-        // Display the result
-        if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
-            eglSwapBuffers(mEglDisplay, mEglSurface);
-            sleep(mDisplaySecs);
-        }
-
-        if (mComposerClient != NULL) {
-            mComposerClient->dispose();
-        }
-        if (mEglContext != EGL_NO_CONTEXT) {
-            eglDestroyContext(mEglDisplay, mEglContext);
-        }
-        if (mEglSurface != EGL_NO_SURFACE) {
-            eglDestroySurface(mEglDisplay, mEglSurface);
-        }
-        if (mEglDisplay != EGL_NO_DISPLAY) {
-            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                    EGL_NO_CONTEXT);
-            eglTerminate(mEglDisplay);
-        }
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        const ::testing::TestInfo* const testInfo =
-            ::testing::UnitTest::GetInstance()->current_test_info();
-        ALOGV("End test:   %s.%s", testInfo->test_case_name(),
-                testInfo->name());
-    }
-
-    virtual EGLint const* getConfigAttribs() {
-        static EGLint sDefaultConfigAttribs[] = {
-            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-            EGL_RED_SIZE, 8,
-            EGL_GREEN_SIZE, 8,
-            EGL_BLUE_SIZE, 8,
-            EGL_ALPHA_SIZE, 8,
-            EGL_DEPTH_SIZE, 16,
-            EGL_STENCIL_SIZE, 8,
-            EGL_NONE };
-
-        return sDefaultConfigAttribs;
-    }
-
-    virtual EGLint const* getContextAttribs() {
-        static EGLint sDefaultContextAttribs[] = {
-            EGL_CONTEXT_CLIENT_VERSION, 2,
-            EGL_NONE };
-
-        return sDefaultContextAttribs;
-    }
-
-    virtual EGLint getSurfaceWidth() {
-        return 512;
-    }
-
-    virtual EGLint getSurfaceHeight() {
-        return 512;
-    }
-
-    ::testing::AssertionResult checkPixel(int x, int y, int r,
-            int g, int b, int a, int tolerance=2) {
-        GLubyte pixel[4];
-        String8 msg;
-        glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
-        GLenum err = glGetError();
-        if (err != GL_NO_ERROR) {
-            msg += String8::format("error reading pixel: %#x", err);
-            while ((err = glGetError()) != GL_NO_ERROR) {
-                msg += String8::format(", %#x", err);
-            }
-            return ::testing::AssertionFailure(
-                    ::testing::Message(msg.string()));
-        }
-        if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
-            msg += String8::format("r(%d isn't %d)", pixel[0], r);
-        }
-        if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
-            if (!msg.isEmpty()) {
-                msg += " ";
-            }
-            msg += String8::format("g(%d isn't %d)", pixel[1], g);
-        }
-        if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
-            if (!msg.isEmpty()) {
-                msg += " ";
-            }
-            msg += String8::format("b(%d isn't %d)", pixel[2], b);
-        }
-        if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
-            if (!msg.isEmpty()) {
-                msg += " ";
-            }
-            msg += String8::format("a(%d isn't %d)", pixel[3], a);
-        }
-        if (!msg.isEmpty()) {
-            return ::testing::AssertionFailure(
-                    ::testing::Message(msg.string()));
-        } else {
-            return ::testing::AssertionSuccess();
-        }
-    }
-
-    ::testing::AssertionResult assertRectEq(const Rect &r1,
-        const Rect &r2, int tolerance=1) {
-
-        String8 msg;
-
-        if (abs(r1.left - r2.left) > tolerance) {
-            msg += String8::format("left(%d isn't %d)", r1.left, r2.left);
-        }
-        if (abs(r1.top - r2.top) > tolerance) {
-            if (!msg.isEmpty()) {
-                msg += " ";
-            }
-            msg += String8::format("top(%d isn't %d)", r1.top, r2.top);
-        }
-        if (abs(r1.right - r2.right) > tolerance) {
-            if (!msg.isEmpty()) {
-                msg += " ";
-            }
-            msg += String8::format("right(%d isn't %d)", r1.right, r2.right);
-        }
-        if (abs(r1.bottom - r2.bottom) > tolerance) {
-            if (!msg.isEmpty()) {
-                msg += " ";
-            }
-            msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom);
-        }
-        if (!msg.isEmpty()) {
-            msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]",
-                r1.left, r1.top, r1.right, r1.bottom,
-                r2.left, r2.top, r2.right, r2.bottom);
-            fprintf(stderr, "assertRectEq: %s\n", msg.string());
-            return ::testing::AssertionFailure(
-                    ::testing::Message(msg.string()));
-        } else {
-            return ::testing::AssertionSuccess();
-        }
-    }
-
-    int mDisplaySecs;
-    sp<SurfaceComposerClient> mComposerClient;
-    sp<SurfaceControl> mSurfaceControl;
-
-    EGLDisplay mEglDisplay;
-    EGLSurface mEglSurface;
-    EGLContext mEglContext;
-    EGLConfig  mGlConfig;
-};
-
-static void loadShader(GLenum shaderType, const char* pSource,
-        GLuint* outShader) {
-    GLuint shader = glCreateShader(shaderType);
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    if (shader) {
-        glShaderSource(shader, 1, &pSource, NULL);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        glCompileShader(shader);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        GLint compiled = 0;
-        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        if (!compiled) {
-            GLint infoLen = 0;
-            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            if (infoLen) {
-                char* buf = (char*) malloc(infoLen);
-                if (buf) {
-                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
-                    printf("Shader compile log:\n%s\n", buf);
-                    free(buf);
-                    FAIL();
-                }
-            } else {
-                char* buf = (char*) malloc(0x1000);
-                if (buf) {
-                    glGetShaderInfoLog(shader, 0x1000, NULL, buf);
-                    printf("Shader compile log:\n%s\n", buf);
-                    free(buf);
-                    FAIL();
-                }
-            }
-            glDeleteShader(shader);
-            shader = 0;
-        }
-    }
-    ASSERT_TRUE(shader != 0);
-    *outShader = shader;
-}
-
-static void createProgram(const char* pVertexSource,
-        const char* pFragmentSource, GLuint* outPgm) {
-    GLuint vertexShader, fragmentShader;
-    {
-        SCOPED_TRACE("compiling vertex shader");
-        ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource,
-                &vertexShader));
-    }
-    {
-        SCOPED_TRACE("compiling fragment shader");
-        ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource,
-                &fragmentShader));
-    }
-
-    GLuint program = glCreateProgram();
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    if (program) {
-        glAttachShader(program, vertexShader);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        glAttachShader(program, fragmentShader);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        glLinkProgram(program);
-        GLint linkStatus = GL_FALSE;
-        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
-        if (linkStatus != GL_TRUE) {
-            GLint bufLength = 0;
-            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
-            if (bufLength) {
-                char* buf = (char*) malloc(bufLength);
-                if (buf) {
-                    glGetProgramInfoLog(program, bufLength, NULL, buf);
-                    printf("Program link log:\n%s\n", buf);
-                    free(buf);
-                    FAIL();
-                }
-            }
-            glDeleteProgram(program);
-            program = 0;
-        }
-    }
-    glDeleteShader(vertexShader);
-    glDeleteShader(fragmentShader);
-    ASSERT_TRUE(program != 0);
-    *outPgm = program;
-}
-
-static int abs(int value) {
-    return value > 0 ? value : -value;
-}
-
-
-// XXX: Code above this point should live elsewhere
-
-class MultiTextureConsumerTest : public GLTest {
-protected:
-    enum { TEX_ID = 123 };
-
-    virtual void SetUp() {
-        GLTest::SetUp();
-        sp<BufferQueue> bq = new BufferQueue();
-        mGlConsumer = new GLConsumer(bq, TEX_ID);
-        mSurface = new Surface(bq);
-        mANW = mSurface.get();
-
-    }
-    virtual void TearDown() {
-        GLTest::TearDown();
-    }
-    virtual EGLint const* getContextAttribs() {
-        return NULL;
-    }
-    virtual EGLint const* getConfigAttribs() {
-        static EGLint sDefaultConfigAttribs[] = {
-            EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-            EGL_RED_SIZE, 8,
-            EGL_GREEN_SIZE, 8,
-            EGL_BLUE_SIZE, 8,
-            EGL_ALPHA_SIZE, 8,
-            EGL_NONE };
-
-        return sDefaultConfigAttribs;
-    }
-    sp<GLConsumer> mGlConsumer;
-    sp<Surface> mSurface;
-    ANativeWindow* mANW;
-};
-
-
-TEST_F(MultiTextureConsumerTest, EGLImageTargetWorks) {
-    ANativeWindow_Buffer buffer;
-
-    ASSERT_EQ(native_window_set_usage(mANW, GRALLOC_USAGE_SW_WRITE_OFTEN), NO_ERROR);
-    ASSERT_EQ(native_window_set_buffers_format(mANW, HAL_PIXEL_FORMAT_RGBA_8888), NO_ERROR);
-
-    glShadeModel(GL_FLAT);
-    glDisable(GL_DITHER);
-    glDisable(GL_CULL_FACE);
-    glViewport(0, 0, getSurfaceWidth(), getSurfaceHeight());
-    glOrthof(0, getSurfaceWidth(), 0, getSurfaceHeight(), 0, 1);
-    glEnableClientState(GL_VERTEX_ARRAY);
-    glColor4f(1, 1, 1, 1);
-
-    glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
-    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-    uint32_t texel = 0x80808080;
-    glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texel);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-    glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, TEX_ID+1);
-    glEnable(GL_TEXTURE_2D);
-    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID);
-    glEnable(GL_TEXTURE_EXTERNAL_OES);
-    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
-    glClear(GL_COLOR_BUFFER_BIT);
-    for (int i=0 ; i<8 ; i++) {
-        mSurface->lock(&buffer, NULL);
-        memset(buffer.bits, (i&7) * 0x20, buffer.stride * buffer.height * 4);
-        mSurface->unlockAndPost();
-
-        mGlConsumer->updateTexImage();
-
-        GLfloat vertices[][2] = { {i*16.0f, 0}, {(i+1)*16.0f, 0}, {(i+1)*16.0f, 16.0f}, {i*16.0f, 16.0f} };
-        glVertexPointer(2, GL_FLOAT, 0, vertices);
-        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    }
-
-    for (int i=0 ; i<8 ; i++) {
-        EXPECT_TRUE(checkPixel(i*16 + 8,  8, i*16, i*16, i*16, i*16, 0));
-    }
-}
-
-
-
-class SurfaceTextureGLTest : public GLTest {
-protected:
-    enum { TEX_ID = 123 };
-
-    virtual void SetUp() {
-        GLTest::SetUp();
-        sp<BufferQueue> bq = new BufferQueue();
-        mBQ = bq;
-        mST = new GLConsumer(bq, TEX_ID);
-        mSTC = new Surface(bq);
-        mANW = mSTC;
-        mTextureRenderer = new TextureRenderer(TEX_ID, mST);
-        ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
-        mFW = new FrameWaiter;
-        mST->setFrameAvailableListener(mFW);
-    }
-
-    virtual void TearDown() {
-        mANW.clear();
-        mSTC.clear();
-        mST.clear();
-        GLTest::TearDown();
-    }
-
-    void drawTexture() {
-        mTextureRenderer->drawTexture();
-    }
-
-    class TextureRenderer: public RefBase {
-    public:
-        TextureRenderer(GLuint texName, const sp<GLConsumer>& st):
-                mTexName(texName),
-                mST(st) {
-        }
-
-        void SetUp() {
-            const char vsrc[] =
-                "attribute vec4 vPosition;\n"
-                "varying vec2 texCoords;\n"
-                "uniform mat4 texMatrix;\n"
-                "void main() {\n"
-                "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
-                "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
-                "  gl_Position = vPosition;\n"
-                "}\n";
-
-            const char fsrc[] =
-                "#extension GL_OES_EGL_image_external : require\n"
-                "precision mediump float;\n"
-                "uniform samplerExternalOES texSampler;\n"
-                "varying vec2 texCoords;\n"
-                "void main() {\n"
-                "  gl_FragColor = texture2D(texSampler, texCoords);\n"
-                "}\n";
-
-            {
-                SCOPED_TRACE("creating shader program");
-                ASSERT_NO_FATAL_FAILURE(createProgram(vsrc, fsrc, &mPgm));
-            }
-
-            mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            ASSERT_NE(-1, mPositionHandle);
-            mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            ASSERT_NE(-1, mTexSamplerHandle);
-            mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            ASSERT_NE(-1, mTexMatrixHandle);
-        }
-
-        // drawTexture draws the GLConsumer over the entire GL viewport.
-        void drawTexture() {
-            static const GLfloat triangleVertices[] = {
-                -1.0f, 1.0f,
-                -1.0f, -1.0f,
-                1.0f, -1.0f,
-                1.0f, 1.0f,
-            };
-
-            glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
-                    triangleVertices);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            glEnableVertexAttribArray(mPositionHandle);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
-            glUseProgram(mPgm);
-            glUniform1i(mTexSamplerHandle, 0);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
-            // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
-            // they're setting the defautls for that target, but when hacking
-            // things to use GL_TEXTURE_2D they are needed to achieve the same
-            // behavior.
-            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
-                    GL_LINEAR);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
-                    GL_LINEAR);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
-                    GL_CLAMP_TO_EDGE);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-            glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
-                    GL_CLAMP_TO_EDGE);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
-            GLfloat texMatrix[16];
-            mST->getTransformMatrix(texMatrix);
-            glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
-
-            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-            ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-        }
-
-        GLuint mTexName;
-        sp<GLConsumer> mST;
-        GLuint mPgm;
-        GLint mPositionHandle;
-        GLint mTexSamplerHandle;
-        GLint mTexMatrixHandle;
-    };
-
-    class FrameWaiter : public GLConsumer::FrameAvailableListener {
-    public:
-        FrameWaiter():
-                mPendingFrames(0) {
-        }
-
-        void waitForFrame() {
-            Mutex::Autolock lock(mMutex);
-            while (mPendingFrames == 0) {
-                mCondition.wait(mMutex);
-            }
-            mPendingFrames--;
-        }
-
-        virtual void onFrameAvailable() {
-            Mutex::Autolock lock(mMutex);
-            mPendingFrames++;
-            mCondition.signal();
-        }
-
-        int mPendingFrames;
-        Mutex mMutex;
-        Condition mCondition;
-    };
-
-    // Note that GLConsumer will lose the notifications
-    // onBuffersReleased and onFrameAvailable as there is currently
-    // no way to forward the events.  This DisconnectWaiter will not let the
-    // disconnect finish until finishDisconnect() is called.  It will
-    // also block until a disconnect is called
-    class DisconnectWaiter : public BnConsumerListener {
-    public:
-        DisconnectWaiter () :
-            mWaitForDisconnect(false),
-            mPendingFrames(0) {
-        }
-
-        void waitForFrame() {
-            Mutex::Autolock lock(mMutex);
-            while (mPendingFrames == 0) {
-                mFrameCondition.wait(mMutex);
-            }
-            mPendingFrames--;
-        }
-
-        virtual void onFrameAvailable() {
-            Mutex::Autolock lock(mMutex);
-            mPendingFrames++;
-            mFrameCondition.signal();
-        }
-
-        virtual void onBuffersReleased() {
-            Mutex::Autolock lock(mMutex);
-            while (!mWaitForDisconnect) {
-                mDisconnectCondition.wait(mMutex);
-            }
-        }
-
-        void finishDisconnect() {
-            Mutex::Autolock lock(mMutex);
-            mWaitForDisconnect = true;
-            mDisconnectCondition.signal();
-        }
-
-    private:
-        Mutex mMutex;
-
-        bool mWaitForDisconnect;
-        Condition mDisconnectCondition;
-
-        int mPendingFrames;
-        Condition mFrameCondition;
-    };
-
-    sp<BufferQueue> mBQ;
-    sp<GLConsumer> mST;
-    sp<Surface> mSTC;
-    sp<ANativeWindow> mANW;
-    sp<TextureRenderer> mTextureRenderer;
-    sp<FrameWaiter> mFW;
-};
-
-// Fill a YV12 buffer with a multi-colored checkerboard pattern
-void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
-    const int blockWidth = w > 16 ? w / 16 : 1;
-    const int blockHeight = h > 16 ? h / 16 : 1;
-    const int yuvTexOffsetY = 0;
-    int yuvTexStrideY = stride;
-    int yuvTexOffsetV = yuvTexStrideY * h;
-    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
-    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
-    int yuvTexStrideU = yuvTexStrideV;
-    for (int x = 0; x < w; x++) {
-        for (int y = 0; y < h; y++) {
-            int parityX = (x / blockWidth) & 1;
-            int parityY = (y / blockHeight) & 1;
-            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
-            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
-            if (x < w / 2 && y < h / 2) {
-                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
-                if (x * 2 < w / 2 && y * 2 < h / 2) {
-                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
-                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
-                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
-                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
-                        intensity;
-                }
-            }
-        }
-    }
-}
-
-// Fill a YV12 buffer with red outside a given rectangle and green inside it.
-void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
-        const android_native_rect_t& rect) {
-    const int yuvTexOffsetY = 0;
-    int yuvTexStrideY = stride;
-    int yuvTexOffsetV = yuvTexStrideY * h;
-    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
-    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
-    int yuvTexStrideU = yuvTexStrideV;
-    for (int x = 0; x < w; x++) {
-        for (int y = 0; y < h; y++) {
-            bool inside = rect.left <= x && x < rect.right &&
-                    rect.top <= y && y < rect.bottom;
-            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
-            if (x < w / 2 && y < h / 2) {
-                bool inside = rect.left <= 2*x && 2*x < rect.right &&
-                        rect.top <= 2*y && 2*y < rect.bottom;
-                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
-                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
-                        inside ? 16 : 255;
-            }
-        }
-    }
-}
-
-void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
-    const size_t PIXEL_SIZE = 4;
-    for (int x = 0; x < w; x++) {
-        for (int y = 0; y < h; y++) {
-            off_t offset = (y * stride + x) * PIXEL_SIZE;
-            for (int c = 0; c < 4; c++) {
-                int parityX = (x / (1 << (c+2))) & 1;
-                int parityY = (y / (1 << (c+2))) & 1;
-                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
-            }
-        }
-    }
-}
-
-void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
-        uint8_t g, uint8_t b, uint8_t a) {
-    const size_t PIXEL_SIZE = 4;
-    for (int y = 0; y < h; y++) {
-        for (int x = 0; x < h; x++) {
-            off_t offset = (y * stride + x) * PIXEL_SIZE;
-            buf[offset + 0] = r;
-            buf[offset + 1] = g;
-            buf[offset + 2] = b;
-            buf[offset + 3] = a;
-        }
-    }
-}
-
-// Produce a single RGBA8 frame by filling a buffer with a checkerboard pattern
-// using the CPU.  This assumes that the ANativeWindow is already configured to
-// allow this to be done (e.g. the format is set to RGBA8).
-//
-// Calls to this function should be wrapped in an ASSERT_NO_FATAL_FAILURE().
-void produceOneRGBA8Frame(const sp<ANativeWindow>& anw) {
-    android_native_buffer_t* anb;
-    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(),
-            &anb));
-    ASSERT_TRUE(anb != NULL);
-
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
-    uint8_t* img = NULL;
-    ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
-            (void**)(&img)));
-    fillRGBA8Buffer(img, buf->getWidth(), buf->getHeight(), buf->getStride());
-    ASSERT_EQ(NO_ERROR, buf->unlock());
-    ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf->getNativeBuffer(),
-            -1));
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
-    const int texWidth = 64;
-    const int texHeight = 66;
-
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
-            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
-    ANativeWindowBuffer* anb;
-    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-            &anb));
-    ASSERT_TRUE(anb != NULL);
-
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
-    // Fill the buffer with the a checkerboard pattern
-    uint8_t* img = NULL;
-    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
-    buf->unlock();
-    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
-            -1));
-
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255, 3));
-    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255, 3));
-    EXPECT_TRUE(checkPixel(63, 65,   0, 133,   0, 255, 3));
-    EXPECT_TRUE(checkPixel( 0, 65, 255, 127, 255, 255, 3));
-
-    EXPECT_TRUE(checkPixel(22, 44, 255, 127, 255, 255, 3));
-    EXPECT_TRUE(checkPixel(45, 52, 255, 127, 255, 255, 3));
-    EXPECT_TRUE(checkPixel(52, 51,  98, 255,  73, 255, 3));
-    EXPECT_TRUE(checkPixel( 7, 31, 155,   0, 118, 255, 3));
-    EXPECT_TRUE(checkPixel(31,  9, 107,  24,  87, 255, 3));
-    EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255, 3));
-    EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255, 3));
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
-    const int texWidth = 64;
-    const int texHeight = 64;
-
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
-            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
-    ANativeWindowBuffer* anb;
-    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-            &anb));
-    ASSERT_TRUE(anb != NULL);
-
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
-    // Fill the buffer with the a checkerboard pattern
-    uint8_t* img = NULL;
-    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-    fillYV12Buffer(img, texWidth, texHeight, buf->getStride());
-    buf->unlock();
-    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
-            -1));
-
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
-    EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
-    EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
-    EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
-
-    EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
-    EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
-    EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
-    EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
-    EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
-    EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
-    EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
-    const int texWidth = 64;
-    const int texHeight = 66;
-
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
-            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
-    android_native_rect_t crops[] = {
-        {4, 6, 22, 36},
-        {0, 6, 22, 36},
-        {4, 0, 22, 36},
-        {4, 6, texWidth, 36},
-        {4, 6, 22, texHeight},
-    };
-
-    for (int i = 0; i < 5; i++) {
-        const android_native_rect_t& crop(crops[i]);
-        SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
-                crop.left, crop.top, crop.right, crop.bottom).string());
-
-        ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
-
-        ANativeWindowBuffer* anb;
-        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-                &anb));
-        ASSERT_TRUE(anb != NULL);
-
-        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
-        uint8_t* img = NULL;
-        buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-        fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
-        buf->unlock();
-        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
-                buf->getNativeBuffer(), -1));
-
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-        glClearColor(0.2, 0.2, 0.2, 0.2);
-        glClear(GL_COLOR_BUFFER_BIT);
-
-        glViewport(0, 0, 64, 64);
-        drawTexture();
-
-        EXPECT_TRUE(checkPixel( 0,  0,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel(63,  0,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel(63, 63,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel( 0, 63,  82, 255,  35, 255));
-
-        EXPECT_TRUE(checkPixel(25, 14,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel(35, 31,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel(57,  6,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel( 5, 42,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel(32, 33,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel(16, 26,  82, 255,  35, 255));
-        EXPECT_TRUE(checkPixel(46, 51,  82, 255,  35, 255));
-    }
-}
-
-// This test is intended to catch synchronization bugs between the CPU-written
-// and GPU-read buffers.
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
-    enum { texWidth = 16 };
-    enum { texHeight = 16 };
-    enum { numFrames = 1024 };
-
-    ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
-            GRALLOC_USAGE_SW_WRITE_OFTEN));
-
-    struct TestPixel {
-        int x;
-        int y;
-    };
-    const TestPixel testPixels[] = {
-        {  4, 11 },
-        { 12, 14 },
-        {  7,  2 },
-    };
-    enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
-
-    class ProducerThread : public Thread {
-    public:
-        ProducerThread(const sp<ANativeWindow>& anw,
-                const TestPixel* testPixels):
-                mANW(anw),
-                mTestPixels(testPixels) {
-        }
-
-        virtual ~ProducerThread() {
-        }
-
-        virtual bool threadLoop() {
-            for (int i = 0; i < numFrames; i++) {
-                ANativeWindowBuffer* anb;
-                if (native_window_dequeue_buffer_and_wait(mANW.get(),
-                        &anb) != NO_ERROR) {
-                    return false;
-                }
-                if (anb == NULL) {
-                    return false;
-                }
-
-                sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
-                const int yuvTexOffsetY = 0;
-                int stride = buf->getStride();
-                int yuvTexStrideY = stride;
-                int yuvTexOffsetV = yuvTexStrideY * texHeight;
-                int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
-                int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
-                int yuvTexStrideU = yuvTexStrideV;
-
-                uint8_t* img = NULL;
-                buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-
-                // Gray out all the test pixels first, so we're more likely to
-                // see a failure if GL is still texturing from the buffer we
-                // just dequeued.
-                for (int j = 0; j < numTestPixels; j++) {
-                    int x = mTestPixels[j].x;
-                    int y = mTestPixels[j].y;
-                    uint8_t value = 128;
-                    img[y*stride + x] = value;
-                }
-
-                // Fill the buffer with gray.
-                for (int y = 0; y < texHeight; y++) {
-                    for (int x = 0; x < texWidth; x++) {
-                        img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
-                        img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
-                        img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
-                    }
-                }
-
-                // Set the test pixels to either white or black.
-                for (int j = 0; j < numTestPixels; j++) {
-                    int x = mTestPixels[j].x;
-                    int y = mTestPixels[j].y;
-                    uint8_t value = 0;
-                    if (j == (i % numTestPixels)) {
-                        value = 255;
-                    }
-                    img[y*stride + x] = value;
-                }
-
-                buf->unlock();
-                if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(), -1)
-                        != NO_ERROR) {
-                    return false;
-                }
-            }
-            return false;
-        }
-
-        sp<ANativeWindow> mANW;
-        const TestPixel* mTestPixels;
-    };
-
-    sp<Thread> pt(new ProducerThread(mANW, testPixels));
-    pt->run();
-
-    glViewport(0, 0, texWidth, texHeight);
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    // We wait for the first two frames up front so that the producer will be
-    // likely to dequeue the buffer that's currently being textured from.
-    mFW->waitForFrame();
-    mFW->waitForFrame();
-
-    for (int i = 0; i < numFrames; i++) {
-        SCOPED_TRACE(String8::format("frame %d", i).string());
-
-        // We must wait for each frame to come in because if we ever do an
-        // updateTexImage call that doesn't consume a newly available buffer
-        // then the producer and consumer will get out of sync, which will cause
-        // a deadlock.
-        if (i > 1) {
-            mFW->waitForFrame();
-        }
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-        drawTexture();
-
-        for (int j = 0; j < numTestPixels; j++) {
-            int x = testPixels[j].x;
-            int y = testPixels[j].y;
-            uint8_t value = 0;
-            if (j == (i % numTestPixels)) {
-                // We must y-invert the texture coords
-                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
-            } else {
-                // We must y-invert the texture coords
-                EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
-            }
-        }
-    }
-
-    pt->requestExitAndWait();
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
-    const int texWidth = 64;
-    const int texHeight = 66;
-
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
-            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
-    EXPECT_TRUE(checkPixel(63,  0, 231, 231, 231, 231));
-    EXPECT_TRUE(checkPixel(63, 65, 231, 231, 231, 231));
-    EXPECT_TRUE(checkPixel( 0, 65,  35,  35,  35,  35));
-
-    EXPECT_TRUE(checkPixel(15, 10,  35, 231, 231, 231));
-    EXPECT_TRUE(checkPixel(23, 65, 231,  35, 231,  35));
-    EXPECT_TRUE(checkPixel(19, 40,  35, 231,  35,  35));
-    EXPECT_TRUE(checkPixel(38, 30, 231,  35,  35,  35));
-    EXPECT_TRUE(checkPixel(42, 54,  35,  35,  35, 231));
-    EXPECT_TRUE(checkPixel(37, 34,  35, 231, 231, 231));
-    EXPECT_TRUE(checkPixel(31,  8, 231,  35,  35, 231));
-    EXPECT_TRUE(checkPixel(37, 47, 231,  35, 231, 231));
-    EXPECT_TRUE(checkPixel(25, 38,  35,  35,  35,  35));
-    EXPECT_TRUE(checkPixel(49,  6,  35, 231,  35,  35));
-    EXPECT_TRUE(checkPixel(54, 50,  35, 231, 231, 231));
-    EXPECT_TRUE(checkPixel(27, 26, 231, 231, 231, 231));
-    EXPECT_TRUE(checkPixel(10,  6,  35,  35, 231, 231));
-    EXPECT_TRUE(checkPixel(29,  4,  35,  35,  35, 231));
-    EXPECT_TRUE(checkPixel(55, 28,  35,  35, 231,  35));
-    EXPECT_TRUE(checkPixel(58, 55,  35,  35, 231, 231));
-}
-
-TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
-    const int texWidth = 64;
-    const int texHeight = 64;
-
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
-            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0, 231, 231, 231, 231));
-    EXPECT_TRUE(checkPixel(63,  0,  35,  35,  35,  35));
-    EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231));
-    EXPECT_TRUE(checkPixel( 0, 63,  35,  35,  35,  35));
-
-    EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231,  35));
-    EXPECT_TRUE(checkPixel(16,  1, 231, 231,  35, 231));
-    EXPECT_TRUE(checkPixel(21, 12, 231,  35,  35, 231));
-    EXPECT_TRUE(checkPixel(26, 51, 231,  35, 231,  35));
-    EXPECT_TRUE(checkPixel( 5, 32,  35, 231, 231,  35));
-    EXPECT_TRUE(checkPixel(13,  8,  35, 231, 231, 231));
-    EXPECT_TRUE(checkPixel(46,  3,  35,  35, 231,  35));
-    EXPECT_TRUE(checkPixel(30, 33,  35,  35,  35,  35));
-    EXPECT_TRUE(checkPixel( 6, 52, 231, 231,  35,  35));
-    EXPECT_TRUE(checkPixel(55, 33,  35, 231,  35, 231));
-    EXPECT_TRUE(checkPixel(16, 29,  35,  35, 231, 231));
-    EXPECT_TRUE(checkPixel( 1, 30,  35,  35,  35, 231));
-    EXPECT_TRUE(checkPixel(41, 37,  35,  35, 231, 231));
-    EXPECT_TRUE(checkPixel(46, 29, 231, 231,  35,  35));
-    EXPECT_TRUE(checkPixel(15, 25,  35, 231,  35, 231));
-    EXPECT_TRUE(checkPixel( 3, 52,  35, 231,  35,  35));
-}
-
-// Tests if GLConsumer and BufferQueue are robust enough
-// to handle a special case where updateTexImage is called
-// in the middle of disconnect.  This ordering is enforced
-// by blocking in the disconnect callback.
-TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
-
-    class ProducerThread : public Thread {
-    public:
-        ProducerThread(const sp<ANativeWindow>& anw):
-                mANW(anw) {
-        }
-
-        virtual ~ProducerThread() {
-        }
-
-        virtual bool threadLoop() {
-            ANativeWindowBuffer* anb;
-
-            native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_EGL);
-
-            for (int numFrames =0 ; numFrames < 2; numFrames ++) {
-
-                if (native_window_dequeue_buffer_and_wait(mANW.get(),
-                        &anb) != NO_ERROR) {
-                    return false;
-                }
-                if (anb == NULL) {
-                    return false;
-                }
-                if (mANW->queueBuffer(mANW.get(), anb, -1)
-                        != NO_ERROR) {
-                    return false;
-                }
-            }
-
-            native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_EGL);
-
-            return false;
-        }
-
-    private:
-        sp<ANativeWindow> mANW;
-    };
-
-    sp<DisconnectWaiter> dw(new DisconnectWaiter());
-    mBQ->consumerConnect(dw, false);
-
-
-    sp<Thread> pt(new ProducerThread(mANW));
-    pt->run();
-
-    // eat a frame so GLConsumer will own an at least one slot
-    dw->waitForFrame();
-    EXPECT_EQ(OK,mST->updateTexImage());
-
-    dw->waitForFrame();
-    // Could fail here as GLConsumer thinks it still owns the slot
-    // but bufferQueue has released all slots
-    EXPECT_EQ(OK,mST->updateTexImage());
-
-    dw->finishDisconnect();
-}
-
-
-// This test ensures that the GLConsumer clears the mCurrentTexture
-// when it is disconnected and reconnected.  Otherwise it will
-// attempt to release a buffer that it does not owned
-TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
-    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
-            NATIVE_WINDOW_API_EGL));
-
-    ANativeWindowBuffer *anb;
-
-    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
-    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
-
-    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
-    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
-
-    EXPECT_EQ(OK,mST->updateTexImage());
-    EXPECT_EQ(OK,mST->updateTexImage());
-
-    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
-            NATIVE_WINDOW_API_EGL));
-    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
-            NATIVE_WINDOW_API_EGL));
-
-    EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
-    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
-
-    // Will fail here if mCurrentTexture is not cleared properly
-    mFW->waitForFrame();
-    EXPECT_EQ(OK,mST->updateTexImage());
-
-    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
-            NATIVE_WINDOW_API_EGL));
-}
-
-TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
-    ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
-        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
-
-    // The producer image size
-    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
-
-    // The consumer image size (16 x 9) ratio
-    mST->setDefaultBufferSize(1280, 720);
-
-    ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
-            NATIVE_WINDOW_API_CPU));
-
-    ANativeWindowBuffer *anb;
-
-    android_native_rect_t odd = {23, 78, 123, 477};
-    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &odd));
-    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
-    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
-    mFW->waitForFrame();
-    EXPECT_EQ(OK, mST->updateTexImage());
-    Rect r = mST->getCurrentCrop();
-    assertRectEq(Rect(23, 78, 123, 477), r);
-
-    ASSERT_EQ(OK, native_window_api_disconnect(mANW.get(),
-            NATIVE_WINDOW_API_CPU));
-}
-
-// This test ensures the scaling mode does the right thing
-// ie NATIVE_WINDOW_SCALING_MODE_CROP should crop
-// the image such that it has the same aspect ratio as the
-// default buffer size
-TEST_F(SurfaceTextureGLTest, CroppedScalingMode) {
-    ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
-        NATIVE_WINDOW_SCALING_MODE_SCALE_CROP));
-
-    // The producer image size
-    ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 512, 512));
-
-    // The consumer image size (16 x 9) ratio
-    mST->setDefaultBufferSize(1280, 720);
-
-    native_window_api_connect(mANW.get(), NATIVE_WINDOW_API_CPU);
-
-    ANativeWindowBuffer *anb;
-
-    // The crop is in the shape of (320, 180) === 16 x 9
-    android_native_rect_t standard = {10, 20, 330, 200};
-    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &standard));
-    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
-    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
-    mFW->waitForFrame();
-    EXPECT_EQ(OK, mST->updateTexImage());
-    Rect r = mST->getCurrentCrop();
-    // crop should be the same as crop (same aspect ratio)
-    assertRectEq(Rect(10, 20, 330, 200), r);
-
-    // make this wider then desired aspect 239 x 100 (2.39:1)
-    android_native_rect_t wide = {20, 30, 259, 130};
-    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &wide));
-    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
-    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
-    mFW->waitForFrame();
-    EXPECT_EQ(OK, mST->updateTexImage());
-    r = mST->getCurrentCrop();
-    // crop should be the same height, but have cropped left and right borders
-    // offset is 30.6 px L+, R-
-    assertRectEq(Rect(51, 30, 228, 130), r);
-
-    // This image is taller then desired aspect 400 x 300 (4:3)
-    android_native_rect_t narrow = {0, 0, 400, 300};
-    ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &narrow));
-    EXPECT_EQ (OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
-    EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
-    mFW->waitForFrame();
-    EXPECT_EQ(OK, mST->updateTexImage());
-    r = mST->getCurrentCrop();
-    // crop should be the same width, but have cropped top and bottom borders
-    // offset is 37.5 px
-    assertRectEq(Rect(0, 37, 400, 262), r);
-
-    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
-}
-
-TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
-    class ProducerThread : public Thread {
-    public:
-        ProducerThread(const sp<ANativeWindow>& anw):
-                mANW(anw),
-                mDequeueError(NO_ERROR) {
-        }
-
-        virtual ~ProducerThread() {
-        }
-
-        virtual bool threadLoop() {
-            Mutex::Autolock lock(mMutex);
-            ANativeWindowBuffer* anb;
-
-            // Frame 1
-            if (native_window_dequeue_buffer_and_wait(mANW.get(),
-                    &anb) != NO_ERROR) {
-                return false;
-            }
-            if (anb == NULL) {
-                return false;
-            }
-            if (mANW->queueBuffer(mANW.get(), anb, -1)
-                    != NO_ERROR) {
-                return false;
-            }
-
-            // Frame 2
-            if (native_window_dequeue_buffer_and_wait(mANW.get(),
-                    &anb) != NO_ERROR) {
-                return false;
-            }
-            if (anb == NULL) {
-                return false;
-            }
-            if (mANW->queueBuffer(mANW.get(), anb, -1)
-                    != NO_ERROR) {
-                return false;
-            }
-
-            // Frame 3 - error expected
-            mDequeueError = native_window_dequeue_buffer_and_wait(mANW.get(),
-                &anb);
-            return false;
-        }
-
-        status_t getDequeueError() {
-            Mutex::Autolock lock(mMutex);
-            return mDequeueError;
-        }
-
-    private:
-        sp<ANativeWindow> mANW;
-        status_t mDequeueError;
-        Mutex mMutex;
-    };
-
-    ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
-
-    sp<Thread> pt(new ProducerThread(mANW));
-    pt->run();
-
-    mFW->waitForFrame();
-    mFW->waitForFrame();
-
-    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
-    // block waiting for a buffer to become available.
-    usleep(100000);
-
-    mST->abandon();
-
-    pt->requestExitAndWait();
-    ASSERT_EQ(NO_INIT,
-            reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
-}
-
-TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
-    int texHeight = 16;
-    ANativeWindowBuffer* anb;
-
-    GLint maxTextureSize;
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
-
-    // make sure it works with small textures
-    mST->setDefaultBufferSize(16, texHeight);
-    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-            &anb));
-    EXPECT_EQ(16, anb->width);
-    EXPECT_EQ(texHeight, anb->height);
-    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
-    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
-    // make sure it works with GL_MAX_TEXTURE_SIZE
-    mST->setDefaultBufferSize(maxTextureSize, texHeight);
-    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-            &anb));
-    EXPECT_EQ(maxTextureSize, anb->width);
-    EXPECT_EQ(texHeight, anb->height);
-    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
-    EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
-    // make sure it fails with GL_MAX_TEXTURE_SIZE+1
-    mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
-    EXPECT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-            &anb));
-    EXPECT_EQ(maxTextureSize+1, anb->width);
-    EXPECT_EQ(texHeight, anb->height);
-    EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb, -1));
-    ASSERT_NE(NO_ERROR, mST->updateTexImage());
-}
-
-/*
- * This test fixture is for testing GL -> GL texture streaming.  It creates an
- * EGLSurface and an EGLContext for the image producer to use.
- */
-class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
-protected:
-    SurfaceTextureGLToGLTest():
-            mProducerEglSurface(EGL_NO_SURFACE),
-            mProducerEglContext(EGL_NO_CONTEXT) {
-    }
-
-    virtual void SetUp() {
-        SurfaceTextureGLTest::SetUp();
-
-        mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
-                mANW.get(), NULL);
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
-
-        mProducerEglContext = eglCreateContext(mEglDisplay, mGlConfig,
-                EGL_NO_CONTEXT, getContextAttribs());
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
-    }
-
-    virtual void TearDown() {
-        if (mProducerEglContext != EGL_NO_CONTEXT) {
-            eglDestroyContext(mEglDisplay, mProducerEglContext);
-        }
-        if (mProducerEglSurface != EGL_NO_SURFACE) {
-            eglDestroySurface(mEglDisplay, mProducerEglSurface);
-        }
-        SurfaceTextureGLTest::TearDown();
-    }
-
-    EGLSurface mProducerEglSurface;
-    EGLContext mProducerEglContext;
-};
-
-TEST_F(SurfaceTextureGLToGLTest, TransformHintGetsRespected) {
-    const uint32_t texWidth = 32;
-    const uint32_t texHeight = 64;
-
-    mST->setDefaultBufferSize(texWidth, texHeight);
-    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
-
-    // This test requires 3 buffers to avoid deadlock because we're
-    // both producer and consumer, and only using one thread.
-    mST->setDefaultMaxBufferCount(3);
-
-    // Do the producer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // Start a buffer with our chosen size and transform hint moving
-    // through the system.
-    glClear(GL_COLOR_BUFFER_BIT);  // give the driver something to do
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-    mST->updateTexImage();  // consume it
-    // Swap again.
-    glClear(GL_COLOR_BUFFER_BIT);
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-    mST->updateTexImage();
-
-    // The current buffer should either show the effects of the transform
-    // hint (in the form of an inverse transform), or show that the
-    // transform hint has been ignored.
-    sp<GraphicBuffer> buf = mST->getCurrentBuffer();
-    if (mST->getCurrentTransform() == NATIVE_WINDOW_TRANSFORM_ROT_270) {
-        ASSERT_EQ(texWidth, buf->getHeight());
-        ASSERT_EQ(texHeight, buf->getWidth());
-    } else {
-        ASSERT_EQ(texWidth, buf->getWidth());
-        ASSERT_EQ(texHeight, buf->getHeight());
-    }
-
-    // Reset the transform hint and confirm that it takes.
-    mST->setTransformHint(0);
-    glClear(GL_COLOR_BUFFER_BIT);
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-    mST->updateTexImage();
-    glClear(GL_COLOR_BUFFER_BIT);
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-    mST->updateTexImage();
-
-    buf = mST->getCurrentBuffer();
-    ASSERT_EQ((uint32_t) 0, mST->getCurrentTransform());
-    ASSERT_EQ(texWidth, buf->getWidth());
-    ASSERT_EQ(texHeight, buf->getHeight());
-}
-
-TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
-    const int texWidth = 64;
-    const int texHeight = 64;
-
-    mST->setDefaultBufferSize(texWidth, texHeight);
-
-    // This test requires 3 buffers to complete run on a single thread.
-    mST->setDefaultMaxBufferCount(3);
-
-    // Do the producer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // This is needed to ensure we pick up a buffer of the correct size.
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    glClearColor(0.6, 0.6, 0.6, 0.6);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(4, 4, 4, 4);
-    glClearColor(1.0, 0.0, 0.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glScissor(24, 48, 4, 4);
-    glClearColor(0.0, 1.0, 0.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glScissor(37, 17, 4, 4);
-    glClearColor(0.0, 0.0, 1.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    // Do the consumer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    glDisable(GL_SCISSOR_TEST);
-
-    // Skip the first frame, which was empty
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
-
-    EXPECT_TRUE(checkPixel( 4,  7, 255,   0,   0, 255));
-    EXPECT_TRUE(checkPixel(25, 51,   0, 255,   0, 255));
-    EXPECT_TRUE(checkPixel(40, 19,   0,   0, 255, 255));
-    EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(13,  8, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(46,  3, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
-}
-
-TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
-    sp<GraphicBuffer> buffers[2];
-
-    // This test requires async mode to run on a single thread.
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    for (int i = 0; i < 2; i++) {
-        // Produce a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-                mProducerEglSurface, mProducerEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        glClear(GL_COLOR_BUFFER_BIT);
-        eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-        // Consume a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        mFW->waitForFrame();
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-        buffers[i] = mST->getCurrentBuffer();
-    }
-
-    // Destroy the GL texture object to release its ref on buffers[2].
-    GLuint texID = TEX_ID;
-    glDeleteTextures(1, &texID);
-
-    // Destroy the EGLSurface
-    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    mProducerEglSurface = EGL_NO_SURFACE;
-
-    // This test should have the only reference to buffer 0.
-    EXPECT_EQ(1, buffers[0]->getStrongCount());
-
-    // The GLConsumer should hold a single reference to buffer 1 in its
-    // mCurrentBuffer member.  All of the references in the slots should have
-    // been released.
-    EXPECT_EQ(2, buffers[1]->getStrongCount());
-}
-
-TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
-    sp<GraphicBuffer> buffers[3];
-
-    // This test requires async mode to run on a single thread.
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    for (int i = 0; i < 3; i++) {
-        // Produce a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-                mProducerEglSurface, mProducerEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        glClear(GL_COLOR_BUFFER_BIT);
-        EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-        // Consume a frame
-        EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        mFW->waitForFrame();
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-        buffers[i] = mST->getCurrentBuffer();
-    }
-
-    // Abandon the GLConsumer, releasing the ref that the GLConsumer has
-    // on buffers[2].
-    mST->abandon();
-
-    // Destroy the GL texture object to release its ref on buffers[2].
-    GLuint texID = TEX_ID;
-    glDeleteTextures(1, &texID);
-
-    // Destroy the EGLSurface.
-    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    mProducerEglSurface = EGL_NO_SURFACE;
-
-    EXPECT_EQ(1, buffers[0]->getStrongCount());
-    EXPECT_EQ(1, buffers[1]->getStrongCount());
-
-    // Depending on how lazily the GL driver dequeues buffers, we may end up
-    // with either two or three total buffers.  If there are three, make sure
-    // the last one was properly down-ref'd.
-    if (buffers[2] != buffers[0]) {
-        EXPECT_EQ(1, buffers[2]->getStrongCount());
-    }
-}
-
-TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentBeforeConsumerDeathUnrefsBuffers) {
-    sp<GraphicBuffer> buffer;
-
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-
-    // Produce a frame
-    glClear(GL_COLOR_BUFFER_BIT);
-    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // Destroy the EGLSurface.
-    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    mProducerEglSurface = EGL_NO_SURFACE;
-    mSTC.clear();
-    mANW.clear();
-    mTextureRenderer.clear();
-
-    // Consume a frame
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    buffer = mST->getCurrentBuffer();
-
-    // Destroy the GL texture object to release its ref
-    GLuint texID = TEX_ID;
-    glDeleteTextures(1, &texID);
-
-    // make un-current, all references to buffer should be gone
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
-            EGL_NO_SURFACE, EGL_NO_CONTEXT));
-
-    // Destroy consumer
-    mST.clear();
-
-    EXPECT_EQ(1, buffer->getStrongCount());
-}
-
-TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentAfterConsumerDeathUnrefsBuffers) {
-    sp<GraphicBuffer> buffer;
-
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-
-    // Produce a frame
-    glClear(GL_COLOR_BUFFER_BIT);
-    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // Destroy the EGLSurface.
-    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    mProducerEglSurface = EGL_NO_SURFACE;
-    mSTC.clear();
-    mANW.clear();
-    mTextureRenderer.clear();
-
-    // Consume a frame
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    buffer = mST->getCurrentBuffer();
-
-    // Destroy the GL texture object to release its ref
-    GLuint texID = TEX_ID;
-    glDeleteTextures(1, &texID);
-
-    // Destroy consumer
-    mST.clear();
-
-    // make un-current, all references to buffer should be gone
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
-            EGL_NO_SURFACE, EGL_NO_CONTEXT));
-
-    EXPECT_EQ(1, buffer->getStrongCount());
-}
-
-TEST_F(SurfaceTextureGLToGLTest, TexturingFromUserSizedGLFilledBuffer) {
-    enum { texWidth = 64 };
-    enum { texHeight = 64 };
-
-    // This test requires 3 buffers to complete run on a single thread.
-    mST->setDefaultMaxBufferCount(3);
-
-    // Set the user buffer size.
-    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
-
-    // Do the producer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // This is needed to ensure we pick up a buffer of the correct size.
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    glClearColor(0.6, 0.6, 0.6, 0.6);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(4, 4, 1, 1);
-    glClearColor(1.0, 0.0, 0.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    // Do the consumer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    glDisable(GL_SCISSOR_TEST);
-
-    // Skip the first frame, which was empty
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
-
-    EXPECT_TRUE(checkPixel( 4,  4, 255,   0,   0, 255));
-    EXPECT_TRUE(checkPixel( 5,  5, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 3,  3, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(45, 52, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(12, 36, 153, 153, 153, 153));
-}
-
-TEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedUserSizedGLFilledBuffer) {
-    enum { texWidth = 64 };
-    enum { texHeight = 16 };
-
-    // This test requires 3 buffers to complete run on a single thread.
-    mST->setDefaultMaxBufferCount(3);
-
-    // Set the transform hint.
-    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
-
-    // Set the user buffer size.
-    native_window_set_buffers_user_dimensions(mANW.get(), texWidth, texHeight);
-
-    // Do the producer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // This is needed to ensure we pick up a buffer of the correct size and the
-    // new rotation hint.
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    glClearColor(0.6, 0.6, 0.6, 0.6);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(24, 4, 1, 1);
-    glClearColor(1.0, 0.0, 0.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    // Do the consumer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    glDisable(GL_SCISSOR_TEST);
-
-    // Skip the first frame, which was empty
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
-
-    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
-    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
-}
-
-TEST_F(SurfaceTextureGLToGLTest, TexturingFromPreRotatedGLFilledBuffer) {
-    enum { texWidth = 64 };
-    enum { texHeight = 16 };
-
-    // This test requires 3 buffers to complete run on a single thread.
-    mST->setDefaultMaxBufferCount(3);
-
-    // Set the transform hint.
-    mST->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_90);
-
-    // Set the default buffer size.
-    mST->setDefaultBufferSize(texWidth, texHeight);
-
-    // Do the producer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
-            mProducerEglSurface, mProducerEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // This is needed to ensure we pick up a buffer of the correct size and the
-    // new rotation hint.
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    glClearColor(0.6, 0.6, 0.6, 0.6);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(24, 4, 1, 1);
-    glClearColor(1.0, 0.0, 0.0, 1.0);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    eglSwapBuffers(mEglDisplay, mProducerEglSurface);
-
-    // Do the consumer side of things
-    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    glDisable(GL_SCISSOR_TEST);
-
-    // Skip the first frame, which was empty
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glViewport(0, 0, texWidth, texHeight);
-    drawTexture();
-
-    EXPECT_TRUE(checkPixel( 0,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63,  0, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(63, 15, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel( 0, 15, 153, 153, 153, 153));
-
-    EXPECT_TRUE(checkPixel(24,  4, 255,   0,   0, 255));
-    EXPECT_TRUE(checkPixel(25,  5, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(23,  3, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(45, 13, 153, 153, 153, 153));
-    EXPECT_TRUE(checkPixel(12,  8, 153, 153, 153, 153));
-}
-
-/*
- * This test fixture is for testing GL -> GL texture streaming from one thread
- * to another.  It contains functionality to create a producer thread that will
- * perform GL rendering to an ANativeWindow that feeds frames to a
- * GLConsumer.  Additionally it supports interlocking the producer and
- * consumer threads so that a specific sequence of calls can be
- * deterministically created by the test.
- *
- * The intended usage is as follows:
- *
- * TEST_F(...) {
- *     class PT : public ProducerThread {
- *         virtual void render() {
- *             ...
- *             swapBuffers();
- *         }
- *     };
- *
- *     runProducerThread(new PT());
- *
- *     // The order of these calls will vary from test to test and may include
- *     // multiple frames and additional operations (e.g. GL rendering from the
- *     // texture).
- *     fc->waitForFrame();
- *     mST->updateTexImage();
- *     fc->finishFrame();
- * }
- *
- */
-class SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
-protected:
-
-    // ProducerThread is an abstract base class to simplify the creation of
-    // OpenGL ES frame producer threads.
-    class ProducerThread : public Thread {
-    public:
-        virtual ~ProducerThread() {
-        }
-
-        void setEglObjects(EGLDisplay producerEglDisplay,
-                EGLSurface producerEglSurface,
-                EGLContext producerEglContext) {
-            mProducerEglDisplay = producerEglDisplay;
-            mProducerEglSurface = producerEglSurface;
-            mProducerEglContext = producerEglContext;
-        }
-
-        virtual bool threadLoop() {
-            eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface,
-                    mProducerEglSurface, mProducerEglContext);
-            render();
-            eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                    EGL_NO_CONTEXT);
-            return false;
-        }
-
-    protected:
-        virtual void render() = 0;
-
-        void swapBuffers() {
-            eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface);
-        }
-
-        EGLDisplay mProducerEglDisplay;
-        EGLSurface mProducerEglSurface;
-        EGLContext mProducerEglContext;
-    };
-
-    // FrameCondition is a utility class for interlocking between the producer
-    // and consumer threads.  The FrameCondition object should be created and
-    // destroyed in the consumer thread only.  The consumer thread should set
-    // the FrameCondition as the FrameAvailableListener of the GLConsumer,
-    // and should call both waitForFrame and finishFrame once for each expected
-    // frame.
-    //
-    // This interlocking relies on the fact that onFrameAvailable gets called
-    // synchronously from GLConsumer::queueBuffer.
-    class FrameCondition : public GLConsumer::FrameAvailableListener {
-    public:
-        FrameCondition():
-                mFrameAvailable(false),
-                mFrameFinished(false) {
-        }
-
-        // waitForFrame waits for the next frame to arrive.  This should be
-        // called from the consumer thread once for every frame expected by the
-        // test.
-        void waitForFrame() {
-            Mutex::Autolock lock(mMutex);
-            ALOGV("+waitForFrame");
-            while (!mFrameAvailable) {
-                mFrameAvailableCondition.wait(mMutex);
-            }
-            mFrameAvailable = false;
-            ALOGV("-waitForFrame");
-        }
-
-        // Allow the producer to return from its swapBuffers call and continue
-        // on to produce the next frame.  This should be called by the consumer
-        // thread once for every frame expected by the test.
-        void finishFrame() {
-            Mutex::Autolock lock(mMutex);
-            ALOGV("+finishFrame");
-            mFrameFinished = true;
-            mFrameFinishCondition.signal();
-            ALOGV("-finishFrame");
-        }
-
-        // This should be called by GLConsumer on the producer thread.
-        virtual void onFrameAvailable() {
-            Mutex::Autolock lock(mMutex);
-            ALOGV("+onFrameAvailable");
-            mFrameAvailable = true;
-            mFrameAvailableCondition.signal();
-            while (!mFrameFinished) {
-                mFrameFinishCondition.wait(mMutex);
-            }
-            mFrameFinished = false;
-            ALOGV("-onFrameAvailable");
-        }
-
-    protected:
-        bool mFrameAvailable;
-        bool mFrameFinished;
-
-        Mutex mMutex;
-        Condition mFrameAvailableCondition;
-        Condition mFrameFinishCondition;
-    };
-
-    virtual void SetUp() {
-        SurfaceTextureGLToGLTest::SetUp();
-        mFC = new FrameCondition();
-        mST->setFrameAvailableListener(mFC);
-    }
-
-    virtual void TearDown() {
-        if (mProducerThread != NULL) {
-            mProducerThread->requestExitAndWait();
-        }
-        mProducerThread.clear();
-        mFC.clear();
-        SurfaceTextureGLToGLTest::TearDown();
-    }
-
-    void runProducerThread(const sp<ProducerThread> producerThread) {
-        ASSERT_TRUE(mProducerThread == NULL);
-        mProducerThread = producerThread;
-        producerThread->setEglObjects(mEglDisplay, mProducerEglSurface,
-                mProducerEglContext);
-        producerThread->run();
-    }
-
-    sp<ProducerThread> mProducerThread;
-    sp<FrameCondition> mFC;
-};
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
-        UpdateTexImageBeforeFrameFinishedCompletes) {
-    class PT : public ProducerThread {
-        virtual void render() {
-            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
-            glClear(GL_COLOR_BUFFER_BIT);
-            swapBuffers();
-        }
-    };
-
-    runProducerThread(new PT());
-
-    mFC->waitForFrame();
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    mFC->finishFrame();
-
-    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
-}
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
-        UpdateTexImageAfterFrameFinishedCompletes) {
-    class PT : public ProducerThread {
-        virtual void render() {
-            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
-            glClear(GL_COLOR_BUFFER_BIT);
-            swapBuffers();
-        }
-    };
-
-    runProducerThread(new PT());
-
-    mFC->waitForFrame();
-    mFC->finishFrame();
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
-}
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
-        RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
-    enum { NUM_ITERATIONS = 1024 };
-
-    class PT : public ProducerThread {
-        virtual void render() {
-            for (int i = 0; i < NUM_ITERATIONS; i++) {
-                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
-                glClear(GL_COLOR_BUFFER_BIT);
-                ALOGV("+swapBuffers");
-                swapBuffers();
-                ALOGV("-swapBuffers");
-            }
-        }
-    };
-
-    runProducerThread(new PT());
-
-    for (int i = 0; i < NUM_ITERATIONS; i++) {
-        mFC->waitForFrame();
-        ALOGV("+updateTexImage");
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-        ALOGV("-updateTexImage");
-        mFC->finishFrame();
-
-        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
-    }
-}
-
-TEST_F(SurfaceTextureGLThreadToGLTest,
-        RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
-    enum { NUM_ITERATIONS = 1024 };
-
-    class PT : public ProducerThread {
-        virtual void render() {
-            for (int i = 0; i < NUM_ITERATIONS; i++) {
-                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
-                glClear(GL_COLOR_BUFFER_BIT);
-                ALOGV("+swapBuffers");
-                swapBuffers();
-                ALOGV("-swapBuffers");
-            }
-        }
-    };
-
-    runProducerThread(new PT());
-
-    for (int i = 0; i < NUM_ITERATIONS; i++) {
-        mFC->waitForFrame();
-        mFC->finishFrame();
-        ALOGV("+updateTexImage");
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-        ALOGV("-updateTexImage");
-
-        // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
-    }
-}
-
-// XXX: This test is disabled because it is currently hanging on some devices.
-TEST_F(SurfaceTextureGLThreadToGLTest,
-        DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
-    enum { NUM_ITERATIONS = 64 };
-
-    class PT : public ProducerThread {
-        virtual void render() {
-            for (int i = 0; i < NUM_ITERATIONS; i++) {
-                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
-                glClear(GL_COLOR_BUFFER_BIT);
-                ALOGV("+swapBuffers");
-                swapBuffers();
-                ALOGV("-swapBuffers");
-            }
-        }
-    };
-
-    ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
-
-    runProducerThread(new PT());
-
-    // Allow three frames to be rendered and queued before starting the
-    // rendering in this thread.  For the latter two frames we don't call
-    // updateTexImage so the next dequeue from the producer thread will block
-    // waiting for a frame to become available.
-    mFC->waitForFrame();
-    mFC->finishFrame();
-
-    // We must call updateTexImage to consume the first frame so that the
-    // SurfaceTexture is able to reduce the buffer count to 2.  This is because
-    // the GL driver may dequeue a buffer when the EGLSurface is created, and
-    // that happens before we call setDefaultMaxBufferCount.  It's possible that the
-    // driver does not dequeue a buffer at EGLSurface creation time, so we
-    // cannot rely on this to cause the second dequeueBuffer call to block.
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    mFC->waitForFrame();
-    mFC->finishFrame();
-    mFC->waitForFrame();
-    mFC->finishFrame();
-
-    // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
-    // block waiting for a buffer to become available.
-    usleep(100000);
-
-    // Render and present a number of images.  This thread should not be blocked
-    // by the fact that the producer thread is blocking in dequeue.
-    for (int i = 0; i < NUM_ITERATIONS; i++) {
-        glClear(GL_COLOR_BUFFER_BIT);
-        eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
-
-    // Consume the two pending buffers to unblock the producer thread.
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    // Consume the remaining buffers from the producer thread.
-    for (int i = 0; i < NUM_ITERATIONS-3; i++) {
-        mFC->waitForFrame();
-        mFC->finishFrame();
-        ALOGV("+updateTexImage");
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-        ALOGV("-updateTexImage");
-    }
-}
-
-class SurfaceTextureFBOTest : public SurfaceTextureGLTest {
-protected:
-
-    virtual void SetUp() {
-        SurfaceTextureGLTest::SetUp();
-
-        glGenFramebuffers(1, &mFbo);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
-        glGenTextures(1, &mFboTex);
-        glBindTexture(GL_TEXTURE_2D, mFboTex);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
-                getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-        glBindTexture(GL_TEXTURE_2D, 0);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-
-        glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                GL_TEXTURE_2D, mFboTex, 0);
-        glBindFramebuffer(GL_FRAMEBUFFER, 0);
-        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    }
-
-    virtual void TearDown() {
-        SurfaceTextureGLTest::TearDown();
-
-        glDeleteTextures(1, &mFboTex);
-        glDeleteFramebuffers(1, &mFbo);
-    }
-
-    GLuint mFbo;
-    GLuint mFboTex;
-};
-
-// This test is intended to verify that proper synchronization is done when
-// rendering into an FBO.
-TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
-    const int texWidth = 64;
-    const int texHeight = 64;
-
-    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
-    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
-            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
-    android_native_buffer_t* anb;
-    ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-            &anb));
-    ASSERT_TRUE(anb != NULL);
-
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
-    // Fill the buffer with green
-    uint8_t* img = NULL;
-    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-    fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
-            0, 255);
-    buf->unlock();
-    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer(),
-            -1));
-
-    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
-    drawTexture();
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
-    for (int i = 0; i < 4; i++) {
-        SCOPED_TRACE(String8::format("frame %d", i).string());
-
-        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(mANW.get(),
-                &anb));
-        ASSERT_TRUE(anb != NULL);
-
-        buf = new GraphicBuffer(anb, false);
-
-        // Fill the buffer with red
-        ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
-                (void**)(&img)));
-        fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
-                0, 255);
-        ASSERT_EQ(NO_ERROR, buf->unlock());
-        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
-                buf->getNativeBuffer(), -1));
-
-        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
-
-        drawTexture();
-
-        EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
-    }
-
-    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
-
-    EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
-}
-
-class SurfaceTextureMultiContextGLTest : public SurfaceTextureGLTest {
-protected:
-    enum { SECOND_TEX_ID = 123 };
-    enum { THIRD_TEX_ID = 456 };
-
-    SurfaceTextureMultiContextGLTest():
-            mSecondEglContext(EGL_NO_CONTEXT) {
-    }
-
-    virtual void SetUp() {
-        SurfaceTextureGLTest::SetUp();
-
-        // Set up the secondary context and texture renderer.
-        mSecondEglContext = eglCreateContext(mEglDisplay, mGlConfig,
-                EGL_NO_CONTEXT, getContextAttribs());
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_CONTEXT, mSecondEglContext);
-
-        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mSecondEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        mSecondTextureRenderer = new TextureRenderer(SECOND_TEX_ID, mST);
-        ASSERT_NO_FATAL_FAILURE(mSecondTextureRenderer->SetUp());
-
-        // Set up the tertiary context and texture renderer.
-        mThirdEglContext = eglCreateContext(mEglDisplay, mGlConfig,
-                EGL_NO_CONTEXT, getContextAttribs());
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        ASSERT_NE(EGL_NO_CONTEXT, mThirdEglContext);
-
-        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mThirdEglContext));
-        ASSERT_EQ(EGL_SUCCESS, eglGetError());
-        mThirdTextureRenderer = new TextureRenderer(THIRD_TEX_ID, mST);
-        ASSERT_NO_FATAL_FAILURE(mThirdTextureRenderer->SetUp());
-
-        // Switch back to the primary context to start the tests.
-        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-                mEglContext));
-    }
-
-    virtual void TearDown() {
-        if (mThirdEglContext != EGL_NO_CONTEXT) {
-            eglDestroyContext(mEglDisplay, mThirdEglContext);
-        }
-        if (mSecondEglContext != EGL_NO_CONTEXT) {
-            eglDestroyContext(mEglDisplay, mSecondEglContext);
-        }
-        SurfaceTextureGLTest::TearDown();
-    }
-
-    EGLContext mSecondEglContext;
-    sp<TextureRenderer> mSecondTextureRenderer;
-
-    EGLContext mThirdEglContext;
-    sp<TextureRenderer> mThirdTextureRenderer;
-};
-
-TEST_F(SurfaceTextureMultiContextGLTest, UpdateFromMultipleContextsFails) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Attempt to latch the texture on the secondary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextSucceeds) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Check that the GL texture was deleted.
-    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest,
-        DetachFromContextSucceedsAfterProducerDisconnect) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Check that the GL texture was deleted.
-    EXPECT_EQ(GL_FALSE, glIsTexture(TEX_ID));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenAbandoned) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Attempt to detach from the primary context.
-    mST->abandon();
-    ASSERT_EQ(NO_INIT, mST->detachFromContext());
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWhenDetached) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attempt to detach from the primary context again.
-    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoDisplay) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Make there be no current display.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
-            EGL_NO_CONTEXT));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // Attempt to detach from the primary context.
-    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, DetachFromContextFailsWithNoContext) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Make current context be incorrect.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // Attempt to detach from the primary context.
-    ASSERT_EQ(INVALID_OPERATION, mST->detachFromContext());
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, UpdateTexImageFailsWhenDetached) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attempt to latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(INVALID_OPERATION, mST->updateTexImage());
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceeds) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attach to the secondary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
-
-    // Verify that the texture object was created and bound.
-    GLint texBinding = -1;
-    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
-    EXPECT_EQ(SECOND_TEX_ID, texBinding);
-
-    // Try to use the texture from the secondary context.
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glViewport(0, 0, 1, 1);
-    mSecondTextureRenderer->drawTexture();
-    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest,
-        AttachToContextSucceedsAfterProducerDisconnect) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attach to the secondary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
-
-    // Verify that the texture object was created and bound.
-    GLint texBinding = -1;
-    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
-    EXPECT_EQ(SECOND_TEX_ID, texBinding);
-
-    // Try to use the texture from the secondary context.
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glViewport(0, 0, 1, 1);
-    mSecondTextureRenderer->drawTexture();
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest,
-        AttachToContextSucceedsBeforeUpdateTexImage) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Detach from the primary context.
-    native_window_api_disconnect(mANW.get(), NATIVE_WINDOW_API_CPU);
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attach to the secondary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
-
-    // Verify that the texture object was created and bound.
-    GLint texBinding = -1;
-    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
-    EXPECT_EQ(SECOND_TEX_ID, texBinding);
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Try to use the texture from the secondary context.
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glViewport(0, 0, 1, 1);
-    mSecondTextureRenderer->drawTexture();
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAbandoned) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attempt to attach to the secondary context.
-    mST->abandon();
-
-    // Attempt to attach to the primary context.
-    ASSERT_EQ(NO_INIT, mST->attachToContext(SECOND_TEX_ID));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWhenAttached) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Attempt to attach to the primary context.
-    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest,
-        AttachToContextFailsWhenAttachedBeforeUpdateTexImage) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Attempt to attach to the primary context.
-    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextFailsWithNoDisplay) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Make there be no current display.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
-            EGL_NO_CONTEXT));
-    ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
-    // Attempt to attach with no context current.
-    ASSERT_EQ(INVALID_OPERATION, mST->attachToContext(SECOND_TEX_ID));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest, AttachToContextSucceedsTwice) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Latch the texture contents on the primary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attach to the secondary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
-
-    // Detach from the secondary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attach to the tertiary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mThirdEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
-
-    // Verify that the texture object was created and bound.
-    GLint texBinding = -1;
-    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
-    EXPECT_EQ(THIRD_TEX_ID, texBinding);
-
-    // Try to use the texture from the tertiary context.
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glViewport(0, 0, 1, 1);
-    mThirdTextureRenderer->drawTexture();
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest,
-        AttachToContextSucceedsTwiceBeforeUpdateTexImage) {
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Detach from the primary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attach to the secondary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
-
-    // Detach from the secondary context.
-    ASSERT_EQ(OK, mST->detachFromContext());
-
-    // Attach to the tertiary context.
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mThirdEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(THIRD_TEX_ID));
-
-    // Verify that the texture object was created and bound.
-    GLint texBinding = -1;
-    glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texBinding);
-    EXPECT_EQ(THIRD_TEX_ID, texBinding);
-
-    // Latch the texture contents on the tertiary context.
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // Try to use the texture from the tertiary context.
-    glClearColor(0.2, 0.2, 0.2, 0.2);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glViewport(0, 0, 1, 1);
-    mThirdTextureRenderer->drawTexture();
-    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
-    ASSERT_TRUE(checkPixel( 0,  0,  35,  35,  35,  35));
-}
-
-TEST_F(SurfaceTextureMultiContextGLTest,
-        UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
-    ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
-
-    // produce two frames and consume them both on the primary context
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-
-    // produce one more frame
-    ASSERT_NO_FATAL_FAILURE(produceOneRGBA8Frame(mANW));
-
-    // Detach from the primary context and attach to the secondary context
-    ASSERT_EQ(OK, mST->detachFromContext());
-    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
-            mSecondEglContext));
-    ASSERT_EQ(OK, mST->attachToContext(SECOND_TEX_ID));
-
-    // Consume final frame on secondary context
-    mFW->waitForFrame();
-    ASSERT_EQ(OK, mST->updateTexImage());
-}
-
-} // namespace android
diff --git a/libs/gui/tests/TextureRenderer.cpp b/libs/gui/tests/TextureRenderer.cpp
new file mode 100644
index 0000000..90951b3
--- /dev/null
+++ b/libs/gui/tests/TextureRenderer.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2013 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 "TextureRenderer.h"
+
+#include "GLTest.h"
+
+#include <gui/GLConsumer.h>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+TextureRenderer::TextureRenderer(GLuint texName,
+        const sp<GLConsumer>& st) : mTexName(texName), mST(st) {
+}
+
+void TextureRenderer::SetUp() {
+    const char vsrc[] =
+        "attribute vec4 vPosition;\n"
+        "varying vec2 texCoords;\n"
+        "uniform mat4 texMatrix;\n"
+        "void main() {\n"
+        "  vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
+        "  texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n"
+        "  gl_Position = vPosition;\n"
+        "}\n";
+
+    const char fsrc[] =
+        "#extension GL_OES_EGL_image_external : require\n"
+        "precision mediump float;\n"
+        "uniform samplerExternalOES texSampler;\n"
+        "varying vec2 texCoords;\n"
+        "void main() {\n"
+        "  gl_FragColor = texture2D(texSampler, texCoords);\n"
+        "}\n";
+
+    {
+        SCOPED_TRACE("creating shader program");
+        ASSERT_NO_FATAL_FAILURE(GLTest::createProgram(vsrc, fsrc, &mPgm));
+    }
+
+    mPositionHandle = glGetAttribLocation(mPgm, "vPosition");
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    ASSERT_NE(-1, mPositionHandle);
+    mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler");
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    ASSERT_NE(-1, mTexSamplerHandle);
+    mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix");
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    ASSERT_NE(-1, mTexMatrixHandle);
+}
+
+// drawTexture draws the GLConsumer over the entire GL viewport.
+void TextureRenderer::drawTexture() {
+    static const GLfloat triangleVertices[] = {
+        -1.0f, 1.0f,
+        -1.0f, -1.0f,
+        1.0f, -1.0f,
+        1.0f, 1.0f,
+    };
+
+    glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
+            triangleVertices);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    glEnableVertexAttribArray(mPositionHandle);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+    glUseProgram(mPgm);
+    glUniform1i(mTexSamplerHandle, 0);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+    // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
+    // they're setting the defautls for that target, but when hacking
+    // things to use GL_TEXTURE_2D they are needed to achieve the same
+    // behavior.
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
+            GL_LINEAR);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
+            GL_LINEAR);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
+            GL_CLAMP_TO_EDGE);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
+            GL_CLAMP_TO_EDGE);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+    GLfloat texMatrix[16];
+    mST->getTransformMatrix(texMatrix);
+    glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix);
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+}
+
+} // namespace android
diff --git a/libs/gui/tests/TextureRenderer.h b/libs/gui/tests/TextureRenderer.h
new file mode 100644
index 0000000..37b2b47
--- /dev/null
+++ b/libs/gui/tests/TextureRenderer.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013 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_TEXTURE_RENDERER_H
+#define ANDROID_TEXTURE_RENDERER_H
+
+#include <GLES/gl.h>
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+class GLConsumer;
+
+class TextureRenderer : public RefBase {
+public:
+    TextureRenderer(GLuint texName, const sp<GLConsumer>& st);
+
+    void SetUp();
+    void drawTexture();
+
+private:
+    GLuint mTexName;
+    sp<GLConsumer> mST;
+    GLuint mPgm;
+    GLint mPositionHandle;
+    GLint mTexSamplerHandle;
+    GLint mTexMatrixHandle;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
index f1921a4..944ac7f 100644
--- a/libs/input/Android.mk
+++ b/libs/input/Android.mk
@@ -27,6 +27,7 @@
 
 deviceSources := \
     $(commonSources) \
+    IInputFlinger.cpp \
     InputTransport.cpp \
     VelocityControl.cpp \
     VelocityTracker.cpp
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
new file mode 100644
index 0000000..e009731
--- /dev/null
+++ b/libs/input/IInputFlinger.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 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 <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <input/IInputFlinger.h>
+
+
+namespace android {
+
+class BpInputFlinger : public BpInterface<IInputFlinger> {
+public:
+    BpInputFlinger(const sp<IBinder>& impl) :
+            BpInterface<IInputFlinger>(impl) { }
+
+    virtual status_t doSomething() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
+        remote()->transact(BnInputFlinger::DO_SOMETHING_TRANSACTION, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(InputFlinger, "android.input.IInputFlinger");
+
+
+status_t BnInputFlinger::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    switch(code) {
+    case DO_SOMETHING_TRANSACTION: {
+        CHECK_INTERFACE(IInputFlinger, data, reply);
+        reply->writeInt32(0);
+        break;
+    }
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
+    }
+    return NO_ERROR;
+}
+
+};
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index 2f5494b..0800a31 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -150,6 +150,40 @@
     return NO_ERROR;
 }
 
+status_t KeyLayoutMap::findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const {
+    const size_t N = mLedsByScanCode.size();
+    for (size_t i = 0; i < N; i++) {
+        if (mLedsByScanCode.valueAt(i).ledCode == ledCode) {
+            *outScanCode = mLedsByScanCode.keyAt(i);
+#if DEBUG_MAPPING
+            ALOGD("findScanCodeForLed: ledCode=%d, scanCode=%d.", ledCode, *outScanCode);
+#endif
+            return NO_ERROR;
+        }
+    }
+#if DEBUG_MAPPING
+            ALOGD("findScanCodeForLed: ledCode=%d ~ Not found.", ledCode);
+#endif
+    return NAME_NOT_FOUND;
+}
+
+status_t KeyLayoutMap::findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const {
+    const size_t N = mLedsByUsageCode.size();
+    for (size_t i = 0; i < N; i++) {
+        if (mLedsByUsageCode.valueAt(i).ledCode == ledCode) {
+            *outUsageCode = mLedsByUsageCode.keyAt(i);
+#if DEBUG_MAPPING
+            ALOGD("findUsageForLed: ledCode=%d, usage=%x.", ledCode, *outUsageCode);
+#endif
+            return NO_ERROR;
+        }
+    }
+#if DEBUG_MAPPING
+            ALOGD("findUsageForLed: ledCode=%d ~ Not found.", ledCode);
+#endif
+    return NAME_NOT_FOUND;
+}
+
 
 // --- KeyLayoutMap::Parser ---
 
@@ -179,6 +213,10 @@
                 mTokenizer->skipDelimiters(WHITESPACE);
                 status_t status = parseAxis();
                 if (status) return status;
+            } else if (keywordToken == "led") {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                status_t status = parseLed();
+                if (status) return status;
             } else {
                 ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
                         keywordToken.string());
@@ -215,8 +253,7 @@
                 mapUsage ? "usage" : "scan code", codeToken.string());
         return BAD_VALUE;
     }
-    KeyedVector<int32_t, Key>& map =
-            mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
+    KeyedVector<int32_t, Key>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
     if (map.indexOfKey(code) >= 0) {
         ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
                 mapUsage ? "usage" : "scan code", codeToken.string());
@@ -364,4 +401,46 @@
     return NO_ERROR;
 }
 
+status_t KeyLayoutMap::Parser::parseLed() {
+    String8 codeToken = mTokenizer->nextToken(WHITESPACE);
+    bool mapUsage = false;
+    if (codeToken == "usage") {
+        mapUsage = true;
+        mTokenizer->skipDelimiters(WHITESPACE);
+        codeToken = mTokenizer->nextToken(WHITESPACE);
+    }
+    char* end;
+    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
+    if (*end) {
+        ALOGE("%s: Expected led %s number, got '%s'.", mTokenizer->getLocation().string(),
+                mapUsage ? "usage" : "scan code", codeToken.string());
+        return BAD_VALUE;
+    }
+
+    KeyedVector<int32_t, Led>& map = mapUsage ? mMap->mLedsByUsageCode : mMap->mLedsByScanCode;
+    if (map.indexOfKey(code) >= 0) {
+        ALOGE("%s: Duplicate entry for led %s '%s'.", mTokenizer->getLocation().string(),
+                mapUsage ? "usage" : "scan code", codeToken.string());
+        return BAD_VALUE;
+    }
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 ledCodeToken = mTokenizer->nextToken(WHITESPACE);
+    int32_t ledCode = getLedByLabel(ledCodeToken.string());
+    if (ledCode < 0) {
+        ALOGE("%s: Expected LED code label, got '%s'.", mTokenizer->getLocation().string(),
+                ledCodeToken.string());
+        return BAD_VALUE;
+    }
+
+#if DEBUG_PARSER
+    ALOGD("Parsed led %s: code=%d, ledCode=%d.",
+            mapUsage ? "usage" : "scan code", code, ledCode);
+#endif
+
+    Led led;
+    led.ledCode = ledCode;
+    map.add(code, led);
+    return NO_ERROR;
+}
 };
diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp
index b6551ee..7d4ac92 100644
--- a/libs/input/Keyboard.cpp
+++ b/libs/input/Keyboard.cpp
@@ -203,6 +203,10 @@
     return lookupLabelByValue(axisId, AXES);
 }
 
+int32_t getLedByLabel(const char* label) {
+    return int32_t(lookupValueByLabel(label, LEDS));
+}
+
 static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
     int32_t newMetaState;
     if (down) {
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index d2d103a..5ce7fba 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -26,6 +26,8 @@
         case PIXEL_FORMAT_RGBA_8888:
         case PIXEL_FORMAT_RGBX_8888:
         case PIXEL_FORMAT_BGRA_8888:
+        case PIXEL_FORMAT_sRGB_A_8888:
+        case PIXEL_FORMAT_sRGB_X_8888:
             return 4;
         case PIXEL_FORMAT_RGB_888:
             return 3;
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index e5abcf5..7de48a4 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -221,6 +221,22 @@
     return *this;
 }
 
+bool Region::contains(const Point& point) const {
+    return contains(point.x, point.y);
+}
+
+bool Region::contains(int x, int y) const {
+    const_iterator cur = begin();
+    const_iterator const tail = end();
+    while (cur != tail) {
+        if (y >= cur->top && y < cur->bottom && x >= cur->left && x < cur->right) {
+            return true;
+        }
+        cur++;
+    }
+    return false;
+}
+
 void Region::clear()
 {
     mStorage.clear();
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index d96b54f..b6ffdb2 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -408,9 +408,11 @@
     if (dp) {
         EGLDisplay iDpy = dp->disp.dpy;
 
-        if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
-            ALOGE("EGLNativeWindowType %p already connected to another API",
-                    window);
+        int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
+        if (result != OK) {
+            ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
+                    "failed (%#x) (already connected to another API?)",
+                    window, result);
             return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
         }
 
diff --git a/services/batteryservice/Android.mk b/services/batteryservice/Android.mk
index 0a29c36..9354b99 100644
--- a/services/batteryservice/Android.mk
+++ b/services/batteryservice/Android.mk
@@ -3,6 +3,7 @@
 
 LOCAL_SRC_FILES:= \
 	BatteryProperties.cpp \
+	BatteryProperty.cpp \
 	IBatteryPropertiesListener.cpp \
 	IBatteryPropertiesRegistrar.cpp
 
diff --git a/services/batteryservice/BatteryProperties.cpp b/services/batteryservice/BatteryProperties.cpp
index e4a42ed..ab636a9 100644
--- a/services/batteryservice/BatteryProperties.cpp
+++ b/services/batteryservice/BatteryProperties.cpp
@@ -38,8 +38,6 @@
     batteryPresent = p->readInt32() == 1 ? true : false;
     batteryLevel = p->readInt32();
     batteryVoltage = p->readInt32();
-    batteryCurrentNow = p->readInt32();
-    batteryChargeCounter = p->readInt32();
     batteryTemperature = p->readInt32();
     batteryTechnology = String8((p->readString16()).string());
     return OK;
@@ -54,8 +52,6 @@
     p->writeInt32(batteryPresent ? 1 : 0);
     p->writeInt32(batteryLevel);
     p->writeInt32(batteryVoltage);
-    p->writeInt32(batteryCurrentNow);
-    p->writeInt32(batteryChargeCounter);
     p->writeInt32(batteryTemperature);
     p->writeString16(String16(batteryTechnology));
     return OK;
diff --git a/services/batteryservice/BatteryProperty.cpp b/services/batteryservice/BatteryProperty.cpp
new file mode 100644
index 0000000..6cbc896
--- /dev/null
+++ b/services/batteryservice/BatteryProperty.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 <batteryservice/BatteryService.h>
+#include <binder/Parcel.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+/*
+ * Parcel read/write code must be kept in sync with
+ * frameworks/base/core/java/android/os/BatteryProperty.java
+ */
+
+status_t BatteryProperty::readFromParcel(Parcel* p) {
+    valueInt = p->readInt32();
+    return OK;
+}
+
+status_t BatteryProperty::writeToParcel(Parcel* p) const {
+    p->writeInt32(valueInt);
+    return OK;
+}
+
+}; // namespace android
diff --git a/services/batteryservice/IBatteryPropertiesRegistrar.cpp b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
index 6c2d2a5..6647122 100644
--- a/services/batteryservice/IBatteryPropertiesRegistrar.cpp
+++ b/services/batteryservice/IBatteryPropertiesRegistrar.cpp
@@ -44,6 +44,18 @@
             data.writeStrongBinder(listener->asBinder());
             remote()->transact(UNREGISTER_LISTENER, data, NULL);
         }
+
+        status_t getProperty(int id, struct BatteryProperty *val) {
+            Parcel data, reply;
+            data.writeInterfaceToken(IBatteryPropertiesRegistrar::getInterfaceDescriptor());
+            data.writeInt32(id);
+            remote()->transact(GET_PROPERTY, data, &reply);
+            status_t ret = reply.readInt32();
+            int parcelpresent = reply.readInt32();
+            if (parcelpresent)
+                val->readFromParcel(&reply);
+            return ret;
+        }
 };
 
 IMPLEMENT_META_INTERFACE(BatteryPropertiesRegistrar, "android.os.IBatteryPropertiesRegistrar");
@@ -69,6 +81,18 @@
             unregisterListener(listener);
             return OK;
         }
+
+        case GET_PROPERTY: {
+            CHECK_INTERFACE(IBatteryPropertiesRegistrar, data, reply);
+            int id = data.readInt32();
+            struct BatteryProperty val;
+            status_t result = getProperty(id, &val);
+            reply->writeNoException();
+            reply->writeInt32(result);
+            reply->writeInt32(1);
+            val.writeToParcel(reply);
+            return OK;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 };
diff --git a/services/inputflinger/Android.mk b/services/inputflinger/Android.mk
new file mode 100644
index 0000000..574c14e
--- /dev/null
+++ b/services/inputflinger/Android.mk
@@ -0,0 +1,63 @@
+# Copyright (C) 2013 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_SRC_FILES:= \
+    EventHub.cpp \
+    InputApplication.cpp \
+    InputDispatcher.cpp \
+    InputListener.cpp \
+    InputManager.cpp \
+    InputReader.cpp \
+    InputWindow.cpp \
+    InputFlinger.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libbinder \
+    libcutils \
+    libinput \
+    liblog \
+    libutils \
+	libui \
+	libhardware_legacy
+
+
+# TODO: Move inputflinger to its own process and mark it hidden
+#LOCAL_CFLAGS += -fvisibility=hidden
+
+LOCAL_CFLAGS += -Wno-unused-parameter
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+LOCAL_MODULE := libinputflinger
+
+include $(BUILD_SHARED_LIBRARY)
+
+########################################################################
+# build input flinger executable
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libbinder \
+	libinputflinger \
+	libutils
+
+LOCAL_MODULE := inputflinger
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
new file mode 100644
index 0000000..e2efd17
--- /dev/null
+++ b/services/inputflinger/EventHub.cpp
@@ -0,0 +1,1669 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "EventHub"
+
+// #define LOG_NDEBUG 0
+
+#include "EventHub.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 <input/KeyLayoutMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/VirtualKeyMap.h>
+
+#include <string.h>
+#include <stdint.h>
+#include <dirent.h>
+
+#include <sys/inotify.h>
+#include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <sys/limits.h>
+#include <sys/sha1.h>
+#include <sys/utsname.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 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";
+}
+
+static String8 sha1(const String8& in) {
+    SHA1_CTX ctx;
+    SHA1Init(&ctx);
+    SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size());
+    u_char digest[SHA1_DIGEST_LENGTH];
+    SHA1Final(digest, &ctx);
+
+    String8 out;
+    for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+        out.appendFormat("%02x", digest[i]);
+    }
+    return out;
+}
+
+static void getLinuxRelease(int* major, int* minor) {
+    struct utsname info;
+    if (uname(&info) || sscanf(info.release, "%d.%d", major, minor) <= 0) {
+        *major = 0, *minor = 0;
+        ALOGE("Could not get linux version: %s", strerror(errno));
+    }
+}
+
+// --- Global Functions ---
+
+uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) {
+    // Touch devices get dibs on touch-related axes.
+    if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) {
+        switch (axis) {
+        case ABS_X:
+        case ABS_Y:
+        case ABS_PRESSURE:
+        case ABS_TOOL_WIDTH:
+        case ABS_DISTANCE:
+        case ABS_TILT_X:
+        case ABS_TILT_Y:
+        case ABS_MT_SLOT:
+        case ABS_MT_TOUCH_MAJOR:
+        case ABS_MT_TOUCH_MINOR:
+        case ABS_MT_WIDTH_MAJOR:
+        case ABS_MT_WIDTH_MINOR:
+        case ABS_MT_ORIENTATION:
+        case ABS_MT_POSITION_X:
+        case ABS_MT_POSITION_Y:
+        case ABS_MT_TOOL_TYPE:
+        case ABS_MT_BLOB_ID:
+        case ABS_MT_TRACKING_ID:
+        case ABS_MT_PRESSURE:
+        case ABS_MT_DISTANCE:
+            return INPUT_DEVICE_CLASS_TOUCH;
+        }
+    }
+
+    // Joystick devices get the rest.
+    return deviceClasses & INPUT_DEVICE_CLASS_JOYSTICK;
+}
+
+// --- EventHub::Device ---
+
+EventHub::Device::Device(int fd, int32_t id, const String8& path,
+        const InputDeviceIdentifier& identifier) :
+        next(NULL),
+        fd(fd), id(id), path(path), identifier(identifier),
+        classes(0), configuration(NULL), virtualKeyMap(NULL),
+        ffEffectPlaying(false), ffEffectId(-1), controllerNumber(0),
+        timestampOverrideSec(0), timestampOverrideUsec(0) {
+    memset(keyBitmask, 0, sizeof(keyBitmask));
+    memset(absBitmask, 0, sizeof(absBitmask));
+    memset(relBitmask, 0, sizeof(relBitmask));
+    memset(swBitmask, 0, sizeof(swBitmask));
+    memset(ledBitmask, 0, sizeof(ledBitmask));
+    memset(ffBitmask, 0, sizeof(ffBitmask));
+    memset(propBitmask, 0, sizeof(propBitmask));
+}
+
+EventHub::Device::~Device() {
+    close();
+    delete configuration;
+    delete virtualKeyMap;
+}
+
+void EventHub::Device::close() {
+    if (fd >= 0) {
+        ::close(fd);
+        fd = -1;
+    }
+}
+
+
+// --- EventHub ---
+
+const uint32_t EventHub::EPOLL_ID_INOTIFY;
+const uint32_t EventHub::EPOLL_ID_WAKE;
+const int EventHub::EPOLL_SIZE_HINT;
+const int EventHub::EPOLL_MAX_EVENTS;
+
+EventHub::EventHub(void) :
+        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
+        mOpeningDevices(0), mClosingDevices(0),
+        mNeedToSendFinishedDeviceScan(false),
+        mNeedToReopenDevices(false), mNeedToScanDevices(true),
+        mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+
+    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
+    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
+
+    mINotifyFd = inotify_init();
+    int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
+    LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s.  errno=%d",
+            DEVICE_PATH, errno);
+
+    struct epoll_event eventItem;
+    memset(&eventItem, 0, sizeof(eventItem));
+    eventItem.events = EPOLLIN;
+    eventItem.data.u32 = EPOLL_ID_INOTIFY;
+    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance.  errno=%d", errno);
+
+    int wakeFds[2];
+    result = pipe(wakeFds);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
+
+    mWakeReadPipeFd = wakeFds[0];
+    mWakeWritePipeFd = wakeFds[1];
+
+    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
+            errno);
+
+    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
+            errno);
+
+    eventItem.data.u32 = EPOLL_ID_WAKE;
+    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
+            errno);
+
+    int major, minor;
+    getLinuxRelease(&major, &minor);
+    // EPOLLWAKEUP was introduced in kernel 3.5
+    mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5);
+}
+
+EventHub::~EventHub(void) {
+    closeAllDevicesLocked();
+
+    while (mClosingDevices) {
+        Device* device = mClosingDevices;
+        mClosingDevices = device->next;
+        delete device;
+    }
+
+    ::close(mEpollFd);
+    ::close(mINotifyFd);
+    ::close(mWakeReadPipeFd);
+    ::close(mWakeWritePipeFd);
+
+    release_wake_lock(WAKE_LOCK_ID);
+}
+
+InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device == NULL) return InputDeviceIdentifier();
+    return device->identifier;
+}
+
+uint32_t EventHub::getDeviceClasses(int32_t deviceId) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device == NULL) return 0;
+    return device->classes;
+}
+
+int32_t EventHub::getDeviceControllerNumber(int32_t deviceId) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device == NULL) return 0;
+    return device->controllerNumber;
+}
+
+void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device && device->configuration) {
+        *outConfiguration = *device->configuration;
+    } else {
+        outConfiguration->clear();
+    }
+}
+
+status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
+        RawAbsoluteAxisInfo* outAxisInfo) const {
+    outAxisInfo->clear();
+
+    if (axis >= 0 && axis <= ABS_MAX) {
+        AutoMutex _l(mLock);
+
+        Device* device = getDeviceLocked(deviceId);
+        if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
+            struct input_absinfo info;
+            if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
+                ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
+                     axis, device->identifier.name.string(), device->fd, errno);
+                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;
+                outAxisInfo->resolution = info.resolution;
+            }
+            return OK;
+        }
+    }
+    return -1;
+}
+
+bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
+    if (axis >= 0 && axis <= REL_MAX) {
+        AutoMutex _l(mLock);
+
+        Device* device = getDeviceLocked(deviceId);
+        if (device) {
+            return test_bit(axis, device->relBitmask);
+        }
+    }
+    return false;
+}
+
+bool EventHub::hasInputProperty(int32_t deviceId, int property) const {
+    if (property >= 0 && property <= INPUT_PROP_MAX) {
+        AutoMutex _l(mLock);
+
+        Device* device = getDeviceLocked(deviceId);
+        if (device) {
+            return test_bit(property, device->propBitmask);
+        }
+    }
+    return false;
+}
+
+int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
+    if (scanCode >= 0 && scanCode <= KEY_MAX) {
+        AutoMutex _l(mLock);
+
+        Device* device = getDeviceLocked(deviceId);
+        if (device && !device->isVirtual() && test_bit(scanCode, device->keyBitmask)) {
+            uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
+            memset(keyState, 0, sizeof(keyState));
+            if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
+                return test_bit(scanCode, keyState) ? 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* device = getDeviceLocked(deviceId);
+    if (device && !device->isVirtual() && device->keyMap.haveKeyLayout()) {
+        Vector<int32_t> scanCodes;
+        device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes);
+        if (scanCodes.size() != 0) {
+            uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
+            memset(keyState, 0, sizeof(keyState));
+            if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
+                for (size_t i = 0; i < scanCodes.size(); i++) {
+                    int32_t sc = scanCodes.itemAt(i);
+                    if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, keyState)) {
+                        return AKEY_STATE_DOWN;
+                    }
+                }
+                return AKEY_STATE_UP;
+            }
+        }
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
+    if (sw >= 0 && sw <= SW_MAX) {
+        AutoMutex _l(mLock);
+
+        Device* device = getDeviceLocked(deviceId);
+        if (device && !device->isVirtual() && test_bit(sw, device->swBitmask)) {
+            uint8_t swState[sizeof_bit_array(SW_MAX + 1)];
+            memset(swState, 0, sizeof(swState));
+            if (ioctl(device->fd, EVIOCGSW(sizeof(swState)), swState) >= 0) {
+                return test_bit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
+            }
+        }
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const {
+    *outValue = 0;
+
+    if (axis >= 0 && axis <= ABS_MAX) {
+        AutoMutex _l(mLock);
+
+        Device* device = getDeviceLocked(deviceId);
+        if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
+            struct input_absinfo info;
+            if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
+                ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
+                     axis, device->identifier.name.string(), device->fd, errno);
+                return -errno;
+            }
+
+            *outValue = info.value;
+            return OK;
+        }
+    }
+    return -1;
+}
+
+bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) const {
+    AutoMutex _l(mLock);
+
+    Device* device = getDeviceLocked(deviceId);
+    if (device && device->keyMap.haveKeyLayout()) {
+        Vector<int32_t> scanCodes;
+        for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
+            scanCodes.clear();
+
+            status_t err = device->keyMap.keyLayoutMap->findScanCodesForKey(
+                    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;
+    }
+    return false;
+}
+
+status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
+        int32_t* outKeycode, uint32_t* outFlags) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+
+    if (device) {
+        // Check the key character map first.
+        sp<KeyCharacterMap> kcm = device->getKeyCharacterMap();
+        if (kcm != NULL) {
+            if (!kcm->mapKey(scanCode, usageCode, outKeycode)) {
+                *outFlags = 0;
+                return NO_ERROR;
+            }
+        }
+
+        // Check the key layout next.
+        if (device->keyMap.haveKeyLayout()) {
+            if (!device->keyMap.keyLayoutMap->mapKey(
+                    scanCode, usageCode, outKeycode, outFlags)) {
+                return NO_ERROR;
+            }
+        }
+    }
+
+    *outKeycode = 0;
+    *outFlags = 0;
+    return NAME_NOT_FOUND;
+}
+
+status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+
+    if (device && device->keyMap.haveKeyLayout()) {
+        status_t err = device->keyMap.keyLayoutMap->mapAxis(scanCode, outAxisInfo);
+        if (err == NO_ERROR) {
+            return NO_ERROR;
+        }
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+void EventHub::setExcludedDevices(const Vector<String8>& devices) {
+    AutoMutex _l(mLock);
+
+    mExcludedDevices = devices;
+}
+
+bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device && scanCode >= 0 && scanCode <= KEY_MAX) {
+        if (test_bit(scanCode, device->keyBitmask)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool EventHub::hasLed(int32_t deviceId, int32_t led) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    int32_t sc;
+    if (device && mapLed(device, led, &sc) == NO_ERROR) {
+        if (test_bit(sc, device->ledBitmask)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    setLedStateLocked(device, led, on);
+}
+
+void EventHub::setLedStateLocked(Device* device, int32_t led, bool on) {
+    int32_t sc;
+    if (device && !device->isVirtual() && mapLed(device, led, &sc) != NAME_NOT_FOUND) {
+        struct input_event ev;
+        ev.time.tv_sec = 0;
+        ev.time.tv_usec = 0;
+        ev.type = EV_LED;
+        ev.code = sc;
+        ev.value = on ? 1 : 0;
+
+        ssize_t nWrite;
+        do {
+            nWrite = write(device->fd, &ev, sizeof(struct input_event));
+        } while (nWrite == -1 && errno == EINTR);
+    }
+}
+
+void EventHub::getVirtualKeyDefinitions(int32_t deviceId,
+        Vector<VirtualKeyDefinition>& outVirtualKeys) const {
+    outVirtualKeys.clear();
+
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device && device->virtualKeyMap) {
+        outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys());
+    }
+}
+
+sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device) {
+        return device->getKeyCharacterMap();
+    }
+    return NULL;
+}
+
+bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId,
+        const sp<KeyCharacterMap>& map) {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device) {
+        if (map != device->overlayKeyMap) {
+            device->overlayKeyMap = map;
+            device->combinedKeyMap = KeyCharacterMap::combine(
+                    device->keyMap.keyCharacterMap, map);
+            return true;
+        }
+    }
+    return false;
+}
+
+static String8 generateDescriptor(InputDeviceIdentifier& identifier) {
+    String8 rawDescriptor;
+    rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor,
+            identifier.product);
+    // TODO add handling for USB devices to not uniqueify kbs that show up twice
+    if (!identifier.uniqueId.isEmpty()) {
+        rawDescriptor.append("uniqueId:");
+        rawDescriptor.append(identifier.uniqueId);
+    } else if (identifier.nonce != 0) {
+        rawDescriptor.appendFormat("nonce:%04x", identifier.nonce);
+    }
+
+    if (identifier.vendor == 0 && identifier.product == 0) {
+        // If we don't know the vendor and product id, then the device is probably
+        // built-in so we need to rely on other information to uniquely identify
+        // the input device.  Usually we try to avoid relying on the device name or
+        // location but for built-in input device, they are unlikely to ever change.
+        if (!identifier.name.isEmpty()) {
+            rawDescriptor.append("name:");
+            rawDescriptor.append(identifier.name);
+        } else if (!identifier.location.isEmpty()) {
+            rawDescriptor.append("location:");
+            rawDescriptor.append(identifier.location);
+        }
+    }
+    identifier.descriptor = sha1(rawDescriptor);
+    return rawDescriptor;
+}
+
+void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) {
+    // Compute a device descriptor that uniquely identifies the device.
+    // The descriptor is assumed to be a stable identifier.  Its value should not
+    // change between reboots, reconnections, firmware updates or new releases
+    // of Android. In practice we sometimes get devices that cannot be uniquely
+    // identified. In this case we enforce uniqueness between connected devices.
+    // Ideally, we also want the descriptor to be short and relatively opaque.
+
+    identifier.nonce = 0;
+    String8 rawDescriptor = generateDescriptor(identifier);
+    if (identifier.uniqueId.isEmpty()) {
+        // If it didn't have a unique id check for conflicts and enforce
+        // uniqueness if necessary.
+        while(getDeviceByDescriptorLocked(identifier.descriptor) != NULL) {
+            identifier.nonce++;
+            rawDescriptor = generateDescriptor(identifier);
+        }
+    }
+    ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(),
+            identifier.descriptor.string());
+}
+
+void EventHub::vibrate(int32_t deviceId, nsecs_t duration) {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device && !device->isVirtual()) {
+        ff_effect effect;
+        memset(&effect, 0, sizeof(effect));
+        effect.type = FF_RUMBLE;
+        effect.id = device->ffEffectId;
+        effect.u.rumble.strong_magnitude = 0xc000;
+        effect.u.rumble.weak_magnitude = 0xc000;
+        effect.replay.length = (duration + 999999LL) / 1000000LL;
+        effect.replay.delay = 0;
+        if (ioctl(device->fd, EVIOCSFF, &effect)) {
+            ALOGW("Could not upload force feedback effect to device %s due to error %d.",
+                    device->identifier.name.string(), errno);
+            return;
+        }
+        device->ffEffectId = effect.id;
+
+        struct input_event ev;
+        ev.time.tv_sec = 0;
+        ev.time.tv_usec = 0;
+        ev.type = EV_FF;
+        ev.code = device->ffEffectId;
+        ev.value = 1;
+        if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
+            ALOGW("Could not start force feedback effect on device %s due to error %d.",
+                    device->identifier.name.string(), errno);
+            return;
+        }
+        device->ffEffectPlaying = true;
+    }
+}
+
+void EventHub::cancelVibrate(int32_t deviceId) {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device && !device->isVirtual()) {
+        if (device->ffEffectPlaying) {
+            device->ffEffectPlaying = false;
+
+            struct input_event ev;
+            ev.time.tv_sec = 0;
+            ev.time.tv_usec = 0;
+            ev.type = EV_FF;
+            ev.code = device->ffEffectId;
+            ev.value = 0;
+            if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
+                ALOGW("Could not stop force feedback effect on device %s due to error %d.",
+                        device->identifier.name.string(), errno);
+                return;
+            }
+        }
+    }
+}
+
+EventHub::Device* EventHub::getDeviceByDescriptorLocked(String8& descriptor) const {
+    size_t size = mDevices.size();
+    for (size_t i = 0; i < size; i++) {
+        Device* device = mDevices.valueAt(i);
+        if (descriptor.compare(device->identifier.descriptor) == 0) {
+            return device;
+        }
+    }
+    return NULL;
+}
+
+EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
+    if (deviceId == BUILT_IN_KEYBOARD_ID) {
+        deviceId = mBuiltInKeyboardId;
+    }
+    ssize_t index = mDevices.indexOfKey(deviceId);
+    return index >= 0 ? mDevices.valueAt(index) : NULL;
+}
+
+EventHub::Device* EventHub::getDeviceByPathLocked(const char* devicePath) const {
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        Device* device = mDevices.valueAt(i);
+        if (device->path == devicePath) {
+            return device;
+        }
+    }
+    return NULL;
+}
+
+size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
+    ALOG_ASSERT(bufferSize >= 1);
+
+    AutoMutex _l(mLock);
+
+    struct input_event readBuffer[bufferSize];
+
+    RawEvent* event = buffer;
+    size_t capacity = bufferSize;
+    bool awoken = false;
+    for (;;) {
+        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+
+        // Reopen input devices if needed.
+        if (mNeedToReopenDevices) {
+            mNeedToReopenDevices = false;
+
+            ALOGI("Reopening all input devices due to a configuration change.");
+
+            closeAllDevicesLocked();
+            mNeedToScanDevices = true;
+            break; // return to the caller before we actually rescan
+        }
+
+        // Report any devices that had last been added/removed.
+        while (mClosingDevices) {
+            Device* device = mClosingDevices;
+            ALOGV("Reporting device closed: id=%d, name=%s\n",
+                 device->id, device->path.string());
+            mClosingDevices = device->next;
+            event->when = now;
+            event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;
+            event->type = DEVICE_REMOVED;
+            event += 1;
+            delete device;
+            mNeedToSendFinishedDeviceScan = true;
+            if (--capacity == 0) {
+                break;
+            }
+        }
+
+        if (mNeedToScanDevices) {
+            mNeedToScanDevices = false;
+            scanDevicesLocked();
+            mNeedToSendFinishedDeviceScan = true;
+        }
+
+        while (mOpeningDevices != NULL) {
+            Device* device = mOpeningDevices;
+            ALOGV("Reporting device opened: id=%d, name=%s\n",
+                 device->id, device->path.string());
+            mOpeningDevices = device->next;
+            event->when = now;
+            event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
+            event->type = DEVICE_ADDED;
+            event += 1;
+            mNeedToSendFinishedDeviceScan = true;
+            if (--capacity == 0) {
+                break;
+            }
+        }
+
+        if (mNeedToSendFinishedDeviceScan) {
+            mNeedToSendFinishedDeviceScan = false;
+            event->when = now;
+            event->type = FINISHED_DEVICE_SCAN;
+            event += 1;
+            if (--capacity == 0) {
+                break;
+            }
+        }
+
+        // Grab the next input event.
+        bool deviceChanged = false;
+        while (mPendingEventIndex < mPendingEventCount) {
+            const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
+            if (eventItem.data.u32 == EPOLL_ID_INOTIFY) {
+                if (eventItem.events & EPOLLIN) {
+                    mPendingINotify = true;
+                } else {
+                    ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
+                }
+                continue;
+            }
+
+            if (eventItem.data.u32 == EPOLL_ID_WAKE) {
+                if (eventItem.events & EPOLLIN) {
+                    ALOGV("awoken after wake()");
+                    awoken = true;
+                    char buffer[16];
+                    ssize_t nRead;
+                    do {
+                        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
+                    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
+                } else {
+                    ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.",
+                            eventItem.events);
+                }
+                continue;
+            }
+
+            ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32);
+            if (deviceIndex < 0) {
+                ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.",
+                        eventItem.events, eventItem.data.u32);
+                continue;
+            }
+
+            Device* device = mDevices.valueAt(deviceIndex);
+            if (eventItem.events & EPOLLIN) {
+                int32_t readSize = read(device->fd, readBuffer,
+                        sizeof(struct input_event) * capacity);
+                if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
+                    // Device was removed before INotify noticed.
+                    ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d "
+                            "capacity: %d errno: %d)\n",
+                            device->fd, readSize, bufferSize, capacity, errno);
+                    deviceChanged = true;
+                    closeDeviceLocked(device);
+                } else if (readSize < 0) {
+                    if (errno != EAGAIN && errno != EINTR) {
+                        ALOGW("could not get event (errno=%d)", errno);
+                    }
+                } else if ((readSize % sizeof(struct input_event)) != 0) {
+                    ALOGE("could not get event (wrong size: %d)", readSize);
+                } else {
+                    int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
+
+                    size_t count = size_t(readSize) / sizeof(struct input_event);
+                    for (size_t i = 0; i < count; i++) {
+                        struct input_event& iev = readBuffer[i];
+                        ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d",
+                                device->path.string(),
+                                (int) iev.time.tv_sec, (int) iev.time.tv_usec,
+                                iev.type, iev.code, iev.value);
+
+                        // Some input devices may have a better concept of the time
+                        // when an input event was actually generated than the kernel
+                        // which simply timestamps all events on entry to evdev.
+                        // This is a custom Android extension of the input protocol
+                        // mainly intended for use with uinput based device drivers.
+                        if (iev.type == EV_MSC) {
+                            if (iev.code == MSC_ANDROID_TIME_SEC) {
+                                device->timestampOverrideSec = iev.value;
+                                continue;
+                            } else if (iev.code == MSC_ANDROID_TIME_USEC) {
+                                device->timestampOverrideUsec = iev.value;
+                                continue;
+                            }
+                        }
+                        if (device->timestampOverrideSec || device->timestampOverrideUsec) {
+                            iev.time.tv_sec = device->timestampOverrideSec;
+                            iev.time.tv_usec = device->timestampOverrideUsec;
+                            if (iev.type == EV_SYN && iev.code == SYN_REPORT) {
+                                device->timestampOverrideSec = 0;
+                                device->timestampOverrideUsec = 0;
+                            }
+                            ALOGV("applied override time %d.%06d",
+                                    int(iev.time.tv_sec), int(iev.time.tv_usec));
+                        }
+
+#ifdef HAVE_POSIX_CLOCKS
+                        // Use the time specified in the event instead of the current time
+                        // so that downstream code can get more accurate estimates of
+                        // event dispatch latency from the time the event is enqueued onto
+                        // the evdev client buffer.
+                        //
+                        // The event's timestamp fortuitously uses the same monotonic clock
+                        // time base as the rest of Android.  The kernel event device driver
+                        // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts().
+                        // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere
+                        // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a
+                        // system call that also queries ktime_get_ts().
+                        event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL
+                                + nsecs_t(iev.time.tv_usec) * 1000LL;
+                        ALOGV("event time %lld, now %lld", event->when, now);
+
+                        // Bug 7291243: Add a guard in case the kernel generates timestamps
+                        // that appear to be far into the future because they were generated
+                        // using the wrong clock source.
+                        //
+                        // This can happen because when the input device is initially opened
+                        // it has a default clock source of CLOCK_REALTIME.  Any input events
+                        // enqueued right after the device is opened will have timestamps
+                        // generated using CLOCK_REALTIME.  We later set the clock source
+                        // to CLOCK_MONOTONIC but it is already too late.
+                        //
+                        // Invalid input event timestamps can result in ANRs, crashes and
+                        // and other issues that are hard to track down.  We must not let them
+                        // propagate through the system.
+                        //
+                        // Log a warning so that we notice the problem and recover gracefully.
+                        if (event->when >= now + 10 * 1000000000LL) {
+                            // Double-check.  Time may have moved on.
+                            nsecs_t time = systemTime(SYSTEM_TIME_MONOTONIC);
+                            if (event->when > time) {
+                                ALOGW("An input event from %s has a timestamp that appears to "
+                                        "have been generated using the wrong clock source "
+                                        "(expected CLOCK_MONOTONIC): "
+                                        "event time %lld, current time %lld, call time %lld.  "
+                                        "Using current time instead.",
+                                        device->path.string(), event->when, time, now);
+                                event->when = time;
+                            } else {
+                                ALOGV("Event time is ok but failed the fast path and required "
+                                        "an extra call to systemTime: "
+                                        "event time %lld, current time %lld, call time %lld.",
+                                        event->when, time, now);
+                            }
+                        }
+#else
+                        event->when = now;
+#endif
+                        event->deviceId = deviceId;
+                        event->type = iev.type;
+                        event->code = iev.code;
+                        event->value = iev.value;
+                        event += 1;
+                        capacity -= 1;
+                    }
+                    if (capacity == 0) {
+                        // The result buffer is full.  Reset the pending event index
+                        // so we will try to read the device again on the next iteration.
+                        mPendingEventIndex -= 1;
+                        break;
+                    }
+                }
+            } else if (eventItem.events & EPOLLHUP) {
+                ALOGI("Removing device %s due to epoll hang-up event.",
+                        device->identifier.name.string());
+                deviceChanged = true;
+                closeDeviceLocked(device);
+            } else {
+                ALOGW("Received unexpected epoll event 0x%08x for device %s.",
+                        eventItem.events, device->identifier.name.string());
+            }
+        }
+
+        // readNotify() will modify the list of devices so this must be done after
+        // processing all other events to ensure that we read all remaining events
+        // before closing the devices.
+        if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) {
+            mPendingINotify = false;
+            readNotifyLocked();
+            deviceChanged = true;
+        }
+
+        // Report added or removed devices immediately.
+        if (deviceChanged) {
+            continue;
+        }
+
+        // Return now if we have collected any events or if we were explicitly awoken.
+        if (event != buffer || awoken) {
+            break;
+        }
+
+        // Poll for events.  Mind the wake lock dance!
+        // We hold a wake lock at all times except during epoll_wait().  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.
+        //
+        // The timeout is advisory only.  If the device is asleep, it will not wake just to
+        // service the timeout.
+        mPendingEventIndex = 0;
+
+        mLock.unlock(); // release lock before poll, must be before release_wake_lock
+        release_wake_lock(WAKE_LOCK_ID);
+
+        int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
+
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+        mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock
+
+        if (pollResult == 0) {
+            // Timed out.
+            mPendingEventCount = 0;
+            break;
+        }
+
+        if (pollResult < 0) {
+            // An error occurred.
+            mPendingEventCount = 0;
+
+            // Sleep after errors to avoid locking up the system.
+            // Hopefully the error is transient.
+            if (errno != EINTR) {
+                ALOGW("poll failed (errno=%d)\n", errno);
+                usleep(100000);
+            }
+        } else {
+            // Some events occurred.
+            mPendingEventCount = size_t(pollResult);
+        }
+    }
+
+    // All done, return the number of events we read.
+    return event - buffer;
+}
+
+void EventHub::wake() {
+    ALOGV("wake() called");
+
+    ssize_t nWrite;
+    do {
+        nWrite = write(mWakeWritePipeFd, "W", 1);
+    } while (nWrite == -1 && errno == EINTR);
+
+    if (nWrite != 1 && errno != EAGAIN) {
+        ALOGW("Could not write wake signal, errno=%d", errno);
+    }
+}
+
+void EventHub::scanDevicesLocked() {
+    status_t res = scanDirLocked(DEVICE_PATH);
+    if(res < 0) {
+        ALOGE("scan dir failed for %s\n", DEVICE_PATH);
+    }
+    if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
+        createVirtualKeyboardLocked();
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+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,
+        AKEYCODE_BUTTON_1, AKEYCODE_BUTTON_2, AKEYCODE_BUTTON_3, AKEYCODE_BUTTON_4,
+        AKEYCODE_BUTTON_5, AKEYCODE_BUTTON_6, AKEYCODE_BUTTON_7, AKEYCODE_BUTTON_8,
+        AKEYCODE_BUTTON_9, AKEYCODE_BUTTON_10, AKEYCODE_BUTTON_11, AKEYCODE_BUTTON_12,
+        AKEYCODE_BUTTON_13, AKEYCODE_BUTTON_14, AKEYCODE_BUTTON_15, AKEYCODE_BUTTON_16,
+};
+
+status_t EventHub::openDeviceLocked(const char *devicePath) {
+    char buffer[80];
+
+    ALOGV("Opening device: %s", devicePath);
+
+    int fd = open(devicePath, O_RDWR | O_CLOEXEC);
+    if(fd < 0) {
+        ALOGE("could not open %s, %s\n", devicePath, strerror(errno));
+        return -1;
+    }
+
+    InputDeviceIdentifier identifier;
+
+    // Get device name.
+    if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
+        //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno));
+    } else {
+        buffer[sizeof(buffer) - 1] = '\0';
+        identifier.name.setTo(buffer);
+    }
+
+    // Check to see if the device is on our excluded list
+    for (size_t i = 0; i < mExcludedDevices.size(); i++) {
+        const String8& item = mExcludedDevices.itemAt(i);
+        if (identifier.name == item) {
+            ALOGI("ignoring event id %s driver %s\n", devicePath, item.string());
+            close(fd);
+            return -1;
+        }
+    }
+
+    // Get device driver version.
+    int driverVersion;
+    if(ioctl(fd, EVIOCGVERSION, &driverVersion)) {
+        ALOGE("could not get driver version for %s, %s\n", devicePath, strerror(errno));
+        close(fd);
+        return -1;
+    }
+
+    // Get device identifier.
+    struct input_id inputId;
+    if(ioctl(fd, EVIOCGID, &inputId)) {
+        ALOGE("could not get device input id for %s, %s\n", devicePath, strerror(errno));
+        close(fd);
+        return -1;
+    }
+    identifier.bus = inputId.bustype;
+    identifier.product = inputId.product;
+    identifier.vendor = inputId.vendor;
+    identifier.version = inputId.version;
+
+    // Get device physical location.
+    if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
+        //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
+    } else {
+        buffer[sizeof(buffer) - 1] = '\0';
+        identifier.location.setTo(buffer);
+    }
+
+    // Get device unique id.
+    if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
+        //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
+    } else {
+        buffer[sizeof(buffer) - 1] = '\0';
+        identifier.uniqueId.setTo(buffer);
+    }
+
+    // Fill in the descriptor.
+    assignDescriptorLocked(identifier);
+
+    // Make file descriptor non-blocking for use with poll().
+    if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
+        ALOGE("Error %d making device file descriptor non-blocking.", errno);
+        close(fd);
+        return -1;
+    }
+
+    // Allocate device.  (The device object takes ownership of the fd at this point.)
+    int32_t deviceId = mNextDeviceId++;
+    Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
+
+    ALOGV("add device %d: %s\n", deviceId, devicePath);
+    ALOGV("  bus:        %04x\n"
+         "  vendor      %04x\n"
+         "  product     %04x\n"
+         "  version     %04x\n",
+        identifier.bus, identifier.vendor, identifier.product, identifier.version);
+    ALOGV("  name:       \"%s\"\n", identifier.name.string());
+    ALOGV("  location:   \"%s\"\n", identifier.location.string());
+    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.string());
+    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.string());
+    ALOGV("  driver:     v%d.%d.%d\n",
+        driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);
+
+    // Load the configuration file for the device.
+    loadConfigurationLocked(device);
+
+    // Figure out the kinds of events the device reports.
+    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device->keyBitmask)), device->keyBitmask);
+    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(device->absBitmask)), device->absBitmask);
+    ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask);
+    ioctl(fd, EVIOCGBIT(EV_SW, sizeof(device->swBitmask)), device->swBitmask);
+    ioctl(fd, EVIOCGBIT(EV_LED, sizeof(device->ledBitmask)), device->ledBitmask);
+    ioctl(fd, EVIOCGBIT(EV_FF, sizeof(device->ffBitmask)), device->ffBitmask);
+    ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask);
+
+    // See if this is a keyboard.  Ignore everything in the button range except for
+    // joystick and gamepad buttons which are handled like keyboards for the most part.
+    bool haveKeyboardKeys = containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC))
+            || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK),
+                    sizeof_bit_array(KEY_MAX + 1));
+    bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC),
+                    sizeof_bit_array(BTN_MOUSE))
+            || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_JOYSTICK),
+                    sizeof_bit_array(BTN_DIGI));
+    if (haveKeyboardKeys || haveGamepadButtons) {
+        device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
+    }
+
+    // See if this is a cursor device such as a trackball or mouse.
+    if (test_bit(BTN_MOUSE, device->keyBitmask)
+            && test_bit(REL_X, device->relBitmask)
+            && test_bit(REL_Y, device->relBitmask)) {
+        device->classes |= INPUT_DEVICE_CLASS_CURSOR;
+    }
+
+    // See if this is a touch pad.
+    // Is this a new modern multi-touch driver?
+    if (test_bit(ABS_MT_POSITION_X, device->absBitmask)
+            && test_bit(ABS_MT_POSITION_Y, device->absBitmask)) {
+        // Some joysticks such as the PS3 controller report axes that conflict
+        // with the ABS_MT range.  Try to confirm that the device really is
+        // a touch screen.
+        if (test_bit(BTN_TOUCH, device->keyBitmask) || !haveGamepadButtons) {
+            device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
+        }
+    // Is this an old style single-touch driver?
+    } else if (test_bit(BTN_TOUCH, device->keyBitmask)
+            && test_bit(ABS_X, device->absBitmask)
+            && test_bit(ABS_Y, device->absBitmask)) {
+        device->classes |= INPUT_DEVICE_CLASS_TOUCH;
+    }
+
+    // See if this device is a joystick.
+    // Assumes that joysticks always have gamepad buttons in order to distinguish them
+    // from other devices such as accelerometers that also have absolute axes.
+    if (haveGamepadButtons) {
+        uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK;
+        for (int i = 0; i <= ABS_MAX; i++) {
+            if (test_bit(i, device->absBitmask)
+                    && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) {
+                device->classes = assumedClasses;
+                break;
+            }
+        }
+    }
+
+    // Check whether this device has switches.
+    for (int i = 0; i <= SW_MAX; i++) {
+        if (test_bit(i, device->swBitmask)) {
+            device->classes |= INPUT_DEVICE_CLASS_SWITCH;
+            break;
+        }
+    }
+
+    // Check whether this device supports the vibrator.
+    if (test_bit(FF_RUMBLE, device->ffBitmask)) {
+        device->classes |= INPUT_DEVICE_CLASS_VIBRATOR;
+    }
+
+    // Configure virtual keys.
+    if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
+        // Load the virtual keys for the touch screen, if any.
+        // We do this now so that we can make sure to load the keymap if necessary.
+        status_t status = loadVirtualKeyMapLocked(device);
+        if (!status) {
+            device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
+        }
+    }
+
+    // Load the key map.
+    // We need to do this for joysticks too because the key layout may specify axes.
+    status_t keyMapStatus = NAME_NOT_FOUND;
+    if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) {
+        // Load the keymap for the device.
+        keyMapStatus = loadKeyMapLocked(device);
+    }
+
+    // Configure the keyboard, gamepad or virtual keyboard.
+    if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) {
+        // Register the keyboard as a built-in keyboard if it is eligible.
+        if (!keyMapStatus
+                && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD
+                && isEligibleBuiltInKeyboard(device->identifier,
+                        device->configuration, &device->keyMap)) {
+            mBuiltInKeyboardId = device->id;
+        }
+
+        // '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;
+            }
+        }
+
+        // Disable kernel key repeat since we handle it ourselves
+        unsigned int repeatRate[] = {0,0};
+        if (ioctl(fd, EVIOCSREP, repeatRate)) {
+            ALOGW("Unable to disable kernel key repeat for %s: %s", devicePath, strerror(errno));
+        }
+    }
+
+    // If the device isn't recognized as something we handle, don't monitor it.
+    if (device->classes == 0) {
+        ALOGV("Dropping device: id=%d, path='%s', name='%s'",
+                deviceId, devicePath, device->identifier.name.string());
+        delete device;
+        return -1;
+    }
+
+    // Determine whether the device is external or internal.
+    if (isExternalDeviceLocked(device)) {
+        device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
+    }
+
+    if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_GAMEPAD)) {
+        device->controllerNumber = getNextControllerNumberLocked(device);
+        setLedForController(device);
+    }
+
+    // Register with epoll.
+    struct epoll_event eventItem;
+    memset(&eventItem, 0, sizeof(eventItem));
+    eventItem.events = mUsingEpollWakeup ? EPOLLIN : EPOLLIN | EPOLLWAKEUP;
+    eventItem.data.u32 = deviceId;
+    if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
+        ALOGE("Could not add device fd to epoll instance.  errno=%d", errno);
+        delete device;
+        return -1;
+    }
+
+    String8 wakeMechanism("EPOLLWAKEUP");
+    if (!mUsingEpollWakeup) {
+#ifndef EVIOCSSUSPENDBLOCK
+        // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels
+        // will use an epoll flag instead, so as long as we want to support
+        // this feature, we need to be prepared to define the ioctl ourselves.
+#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int)
+#endif
+        if (ioctl(fd, EVIOCSSUSPENDBLOCK, 1)) {
+            wakeMechanism = "<none>";
+        } else {
+            wakeMechanism = "EVIOCSSUSPENDBLOCK";
+        }
+    }
+
+    // Tell the kernel that we want to use the monotonic clock for reporting timestamps
+    // associated with input events.  This is important because the input system
+    // uses the timestamps extensively and assumes they were recorded using the monotonic
+    // clock.
+    //
+    // In older kernel, before Linux 3.4, there was no way to tell the kernel which
+    // clock to use to input event timestamps.  The standard kernel behavior was to
+    // record a real time timestamp, which isn't what we want.  Android kernels therefore
+    // contained a patch to the evdev_event() function in drivers/input/evdev.c to
+    // replace the call to do_gettimeofday() with ktime_get_ts() to cause the monotonic
+    // clock to be used instead of the real time clock.
+    //
+    // As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock.
+    // Therefore, we no longer require the Android-specific kernel patch described above
+    // as long as we make sure to set select the monotonic clock.  We do that here.
+    int clockId = CLOCK_MONOTONIC;
+    bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId);
+
+    ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
+            "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, "
+            "wakeMechanism=%s, usingClockIoctl=%s",
+         deviceId, fd, devicePath, device->identifier.name.string(),
+         device->classes,
+         device->configurationFile.string(),
+         device->keyMap.keyLayoutFile.string(),
+         device->keyMap.keyCharacterMapFile.string(),
+         toString(mBuiltInKeyboardId == deviceId),
+         wakeMechanism.string(), toString(usingClockIoctl));
+
+    addDeviceLocked(device);
+    return 0;
+}
+
+void EventHub::createVirtualKeyboardLocked() {
+    InputDeviceIdentifier identifier;
+    identifier.name = "Virtual";
+    identifier.uniqueId = "<virtual>";
+    assignDescriptorLocked(identifier);
+
+    Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier);
+    device->classes = INPUT_DEVICE_CLASS_KEYBOARD
+            | INPUT_DEVICE_CLASS_ALPHAKEY
+            | INPUT_DEVICE_CLASS_DPAD
+            | INPUT_DEVICE_CLASS_VIRTUAL;
+    loadKeyMapLocked(device);
+    addDeviceLocked(device);
+}
+
+void EventHub::addDeviceLocked(Device* device) {
+    mDevices.add(device->id, device);
+    device->next = mOpeningDevices;
+    mOpeningDevices = device;
+}
+
+void EventHub::loadConfigurationLocked(Device* device) {
+    device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
+            device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
+    if (device->configurationFile.isEmpty()) {
+        ALOGD("No input device configuration file found for device '%s'.",
+                device->identifier.name.string());
+    } else {
+        status_t status = PropertyMap::load(device->configurationFile,
+                &device->configuration);
+        if (status) {
+            ALOGE("Error loading input device configuration file for device '%s'.  "
+                    "Using default configuration.",
+                    device->identifier.name.string());
+        }
+    }
+}
+
+status_t EventHub::loadVirtualKeyMapLocked(Device* device) {
+    // The virtual key map is supplied by the kernel as a system board property file.
+    String8 path;
+    path.append("/sys/board_properties/virtualkeys.");
+    path.append(device->identifier.name);
+    if (access(path.string(), R_OK)) {
+        return NAME_NOT_FOUND;
+    }
+    return VirtualKeyMap::load(path, &device->virtualKeyMap);
+}
+
+status_t EventHub::loadKeyMapLocked(Device* device) {
+    return device->keyMap.load(device->identifier, device->configuration);
+}
+
+bool EventHub::isExternalDeviceLocked(Device* device) {
+    if (device->configuration) {
+        bool value;
+        if (device->configuration->tryGetProperty(String8("device.internal"), value)) {
+            return !value;
+        }
+    }
+    return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH;
+}
+
+int32_t EventHub::getNextControllerNumberLocked(Device* device) {
+    if (mControllerNumbers.isFull()) {
+        ALOGI("Maximum number of controllers reached, assigning controller number 0 to device %s",
+                device->identifier.name.string());
+        return 0;
+    }
+    // Since the controller number 0 is reserved for non-controllers, translate all numbers up by
+    // one
+    return static_cast<int32_t>(mControllerNumbers.markFirstUnmarkedBit() + 1);
+}
+
+void EventHub::releaseControllerNumberLocked(Device* device) {
+    int32_t num = device->controllerNumber;
+    device->controllerNumber= 0;
+    if (num == 0) {
+        return;
+    }
+    mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1));
+}
+
+void EventHub::setLedForController(Device* device) {
+    for (int i = 0; i < MAX_CONTROLLER_LEDS; i++) {
+        setLedStateLocked(device, ALED_CONTROLLER_1 + i, device->controllerNumber == i + 1);
+    }
+}
+
+bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
+    if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
+        return false;
+    }
+    
+    Vector<int32_t> scanCodes;
+    device->keyMap.keyLayoutMap->findScanCodesForKey(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;
+}
+
+status_t EventHub::mapLed(Device* device, int32_t led, int32_t* outScanCode) const {
+    if (!device->keyMap.haveKeyLayout() || !device->ledBitmask) {
+        return NAME_NOT_FOUND;
+    }
+
+    int32_t scanCode;
+    if(device->keyMap.keyLayoutMap->findScanCodeForLed(led, &scanCode) != NAME_NOT_FOUND) {
+        if(scanCode >= 0 && scanCode <= LED_MAX && test_bit(scanCode, device->ledBitmask)) {
+            *outScanCode = scanCode;
+            return NO_ERROR;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
+status_t EventHub::closeDeviceByPathLocked(const char *devicePath) {
+    Device* device = getDeviceByPathLocked(devicePath);
+    if (device) {
+        closeDeviceLocked(device);
+        return 0;
+    }
+    ALOGV("Remove device: %s not found, device may already have been removed.", devicePath);
+    return -1;
+}
+
+void EventHub::closeAllDevicesLocked() {
+    while (mDevices.size() > 0) {
+        closeDeviceLocked(mDevices.valueAt(mDevices.size() - 1));
+    }
+}
+
+void EventHub::closeDeviceLocked(Device* device) {
+    ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
+         device->path.string(), device->identifier.name.string(), device->id,
+         device->fd, device->classes);
+
+    if (device->id == mBuiltInKeyboardId) {
+        ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
+                device->path.string(), mBuiltInKeyboardId);
+        mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD;
+    }
+
+    if (!device->isVirtual()) {
+        if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) {
+            ALOGW("Could not remove device fd from epoll instance.  errno=%d", errno);
+        }
+    }
+
+    releaseControllerNumberLocked(device);
+
+    mDevices.removeItem(device->id);
+    device->close();
+
+    // Unlink for opening devices list if it is present.
+    Device* pred = NULL;
+    bool found = false;
+    for (Device* entry = mOpeningDevices; entry != NULL; ) {
+        if (entry == device) {
+            found = true;
+            break;
+        }
+        pred = entry;
+        entry = entry->next;
+    }
+    if (found) {
+        // Unlink the device from the opening devices list then delete it.
+        // We don't need to tell the client that the device was closed because
+        // it does not even know it was opened in the first place.
+        ALOGI("Device %s was immediately closed after opening.", device->path.string());
+        if (pred) {
+            pred->next = device->next;
+        } else {
+            mOpeningDevices = device->next;
+        }
+        delete device;
+    } else {
+        // Link into closing devices list.
+        // The device will be deleted later after we have informed the client.
+        device->next = mClosingDevices;
+        mClosingDevices = device;
+    }
+}
+
+status_t EventHub::readNotifyLocked() {
+    int res;
+    char devname[PATH_MAX];
+    char *filename;
+    char event_buf[512];
+    int event_size;
+    int event_pos = 0;
+    struct inotify_event *event;
+
+    ALOGV("EventHub::readNotify nfd: %d\n", mINotifyFd);
+    res = read(mINotifyFd, event_buf, sizeof(event_buf));
+    if(res < (int)sizeof(*event)) {
+        if(errno == EINTR)
+            return 0;
+        ALOGW("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) {
+                openDeviceLocked(devname);
+            } else {
+                ALOGI("Removing device '%s' due to inotify event\n", devname);
+                closeDeviceByPathLocked(devname);
+            }
+        }
+        event_size = sizeof(*event) + event->len;
+        res -= event_size;
+        event_pos += event_size;
+    }
+    return 0;
+}
+
+status_t EventHub::scanDirLocked(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);
+        openDeviceLocked(devname);
+    }
+    closedir(dir);
+    return 0;
+}
+
+void EventHub::requestReopenDevices() {
+    ALOGV("requestReopenDevices() called");
+
+    AutoMutex _l(mLock);
+    mNeedToReopenDevices = true;
+}
+
+void EventHub::dump(String8& dump) {
+    dump.append("Event Hub State:\n");
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        dump.appendFormat(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId);
+
+        dump.append(INDENT "Devices:\n");
+
+        for (size_t i = 0; i < mDevices.size(); i++) {
+            const Device* device = mDevices.valueAt(i);
+            if (mBuiltInKeyboardId == device->id) {
+                dump.appendFormat(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n",
+                        device->id, device->identifier.name.string());
+            } else {
+                dump.appendFormat(INDENT2 "%d: %s\n", device->id,
+                        device->identifier.name.string());
+            }
+            dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
+            dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
+            dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string());
+            dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string());
+            dump.appendFormat(INDENT3 "ControllerNumber: %d\n", device->controllerNumber);
+            dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string());
+            dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
+                    "product=0x%04x, version=0x%04x\n",
+                    device->identifier.bus, device->identifier.vendor,
+                    device->identifier.product, device->identifier.version);
+            dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n",
+                    device->keyMap.keyLayoutFile.string());
+            dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n",
+                    device->keyMap.keyCharacterMapFile.string());
+            dump.appendFormat(INDENT3 "ConfigurationFile: %s\n",
+                    device->configurationFile.string());
+            dump.appendFormat(INDENT3 "HaveKeyboardLayoutOverlay: %s\n",
+                    toString(device->overlayKeyMap != NULL));
+        }
+    } // release lock
+}
+
+void EventHub::monitor() {
+    // Acquire and release the lock to ensure that the event hub has not deadlocked.
+    mLock.lock();
+    mLock.unlock();
+}
+
+
+}; // namespace android
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
new file mode 100644
index 0000000..20179ae
--- /dev/null
+++ b/services/inputflinger/EventHub.h
@@ -0,0 +1,457 @@
+/*
+ * 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 <input/Input.h>
+#include <input/InputDevice.h>
+#include <input/Keyboard.h>
+#include <input/KeyLayoutMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/VirtualKeyMap.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 <utils/PropertyMap.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/BitSet.h>
+
+#include <linux/input.h>
+#include <sys/epoll.h>
+
+/* Convenience constants. */
+
+#define BTN_FIRST 0x100  // first button code
+#define BTN_LAST 0x15f   // last button code
+
+/*
+ * These constants are used privately in Android to pass raw timestamps
+ * through evdev from uinput device drivers because there is currently no
+ * other way to transfer this information.  The evdev driver automatically
+ * timestamps all input events with the time they were posted and clobbers
+ * whatever information was passed in.
+ *
+ * For the purposes of this hack, the timestamp is specified in the
+ * CLOCK_MONOTONIC timebase and is split into two EV_MSC events specifying
+ * seconds and microseconds.
+ */
+#define MSC_ANDROID_TIME_SEC 0x6
+#define MSC_ANDROID_TIME_USEC 0x7
+
+namespace android {
+
+enum {
+    // Device id of a special "virtual" keyboard that is always present.
+    VIRTUAL_KEYBOARD_ID = -1,
+    // Device id of the "built-in" keyboard if there is one.
+    BUILT_IN_KEYBOARD_ID = 0,
+};
+
+/*
+ * A raw event as retrieved from the EventHub.
+ */
+struct RawEvent {
+    nsecs_t when;
+    int32_t deviceId;
+    int32_t type;
+    int32_t code;
+    int32_t value;
+};
+
+/* 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
+    int32_t resolution; // resolution in units per mm or radians per mm
+
+    inline void clear() {
+        valid = false;
+        minValue = 0;
+        maxValue = 0;
+        flat = 0;
+        fuzz = 0;
+        resolution = 0;
+    }
+};
+
+/*
+ * Input device classes.
+ */
+enum {
+    /* The input device is a keyboard or has buttons. */
+    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 or a touchpad (either single-touch or multi-touch). */
+    INPUT_DEVICE_CLASS_TOUCH         = 0x00000004,
+
+    /* The input device is a cursor device such as a trackball or mouse. */
+    INPUT_DEVICE_CLASS_CURSOR        = 0x00000008,
+
+    /* The input device is a multi-touch touchscreen. */
+    INPUT_DEVICE_CLASS_TOUCH_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,
+
+    /* The input device is a joystick (implies gamepad, has joystick absolute axes). */
+    INPUT_DEVICE_CLASS_JOYSTICK      = 0x00000100,
+
+    /* The input device has a vibrator (supports FF_RUMBLE). */
+    INPUT_DEVICE_CLASS_VIBRATOR      = 0x00000200,
+
+    /* The input device is virtual (not a real device, not part of UI configuration). */
+    INPUT_DEVICE_CLASS_VIRTUAL       = 0x40000000,
+
+    /* The input device is external (not built-in). */
+    INPUT_DEVICE_CLASS_EXTERNAL      = 0x80000000,
+};
+
+/*
+ * Gets the class that owns an axis, in cases where multiple classes might claim
+ * the same axis for different purposes.
+ */
+extern uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses);
+
+/*
+ * 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 provides 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,
+
+        FIRST_SYNTHETIC_EVENT = DEVICE_ADDED,
+    };
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
+
+    virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const = 0;
+
+    virtual int32_t getDeviceControllerNumber(int32_t deviceId) const = 0;
+
+    virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0;
+
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const = 0;
+
+    virtual bool hasRelativeAxis(int32_t deviceId, int axis) const = 0;
+
+    virtual bool hasInputProperty(int32_t deviceId, int property) const = 0;
+
+    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
+            int32_t* outKeycode, uint32_t* outFlags) const = 0;
+
+    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
+            AxisInfo* outAxisInfo) const = 0;
+
+    // Sets devices that are excluded from opening.
+    // This can be used to ignore input devices for sensors.
+    virtual void setExcludedDevices(const Vector<String8>& devices) = 0;
+
+    /*
+     * Wait for events to become available and returns them.
+     * 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).
+     *
+     * The timeout is advisory only.  If the device is asleep, it will not wake just to
+     * service the timeout.
+     *
+     * Returns the number of events obtained, or 0 if the timeout expired.
+     */
+    virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) = 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;
+    virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+            int32_t* outValue) 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 bool hasScanCode(int32_t deviceId, int32_t scanCode) const = 0;
+
+    /* LED related functions expect Android LED constants, not scan codes or HID usages */
+    virtual bool hasLed(int32_t deviceId, int32_t led) const = 0;
+    virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0;
+
+    virtual void getVirtualKeyDefinitions(int32_t deviceId,
+            Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
+
+    virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0;
+    virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) = 0;
+
+    /* Control the vibrator. */
+    virtual void vibrate(int32_t deviceId, nsecs_t duration) = 0;
+    virtual void cancelVibrate(int32_t deviceId) = 0;
+
+    /* Requests the EventHub to reopen all input devices on the next call to getEvents(). */
+    virtual void requestReopenDevices() = 0;
+
+    /* Wakes up getEvents() if it is blocked on a read. */
+    virtual void wake() = 0;
+
+    /* Dump EventHub state to a string. */
+    virtual void dump(String8& dump) = 0;
+
+    /* Called by the heatbeat to ensures that the reader has not deadlocked. */
+    virtual void monitor() = 0;
+};
+
+class EventHub : public EventHubInterface
+{
+public:
+    EventHub();
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const;
+
+    virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const;
+
+    virtual int32_t getDeviceControllerNumber(int32_t deviceId) const;
+
+    virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const;
+
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const;
+
+    virtual bool hasRelativeAxis(int32_t deviceId, int axis) const;
+
+    virtual bool hasInputProperty(int32_t deviceId, int property) const;
+
+    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
+            int32_t* outKeycode, uint32_t* outFlags) const;
+
+    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
+            AxisInfo* outAxisInfo) const;
+
+    virtual void setExcludedDevices(const Vector<String8>& devices);
+
+    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 status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const;
+
+    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags) const;
+
+    virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize);
+
+    virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const;
+    virtual bool hasLed(int32_t deviceId, int32_t led) const;
+    virtual void setLedState(int32_t deviceId, int32_t led, bool on);
+
+    virtual void getVirtualKeyDefinitions(int32_t deviceId,
+            Vector<VirtualKeyDefinition>& outVirtualKeys) const;
+
+    virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const;
+    virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map);
+
+    virtual void vibrate(int32_t deviceId, nsecs_t duration);
+    virtual void cancelVibrate(int32_t deviceId);
+
+    virtual void requestReopenDevices();
+
+    virtual void wake();
+
+    virtual void dump(String8& dump);
+    virtual void monitor();
+
+protected:
+    virtual ~EventHub();
+
+private:
+    struct Device {
+        Device* next;
+
+        int fd; // may be -1 if device is virtual
+        const int32_t id;
+        const String8 path;
+        const InputDeviceIdentifier identifier;
+
+        uint32_t classes;
+
+        uint8_t keyBitmask[(KEY_MAX + 1) / 8];
+        uint8_t absBitmask[(ABS_MAX + 1) / 8];
+        uint8_t relBitmask[(REL_MAX + 1) / 8];
+        uint8_t swBitmask[(SW_MAX + 1) / 8];
+        uint8_t ledBitmask[(LED_MAX + 1) / 8];
+        uint8_t ffBitmask[(FF_MAX + 1) / 8];
+        uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8];
+
+        String8 configurationFile;
+        PropertyMap* configuration;
+        VirtualKeyMap* virtualKeyMap;
+        KeyMap keyMap;
+
+        sp<KeyCharacterMap> overlayKeyMap;
+        sp<KeyCharacterMap> combinedKeyMap;
+
+        bool ffEffectPlaying;
+        int16_t ffEffectId; // initially -1
+
+        int32_t controllerNumber;
+
+        int32_t timestampOverrideSec;
+        int32_t timestampOverrideUsec;
+
+        Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
+        ~Device();
+
+        void close();
+
+        inline bool isVirtual() const { return fd < 0; }
+
+        const sp<KeyCharacterMap>& getKeyCharacterMap() const {
+            if (combinedKeyMap != NULL) {
+                return combinedKeyMap;
+            }
+            return keyMap.keyCharacterMap;
+        }
+    };
+
+    status_t openDeviceLocked(const char *devicePath);
+    void createVirtualKeyboardLocked();
+    void addDeviceLocked(Device* device);
+    void assignDescriptorLocked(InputDeviceIdentifier& identifier);
+
+    status_t closeDeviceByPathLocked(const char *devicePath);
+    void closeDeviceLocked(Device* device);
+    void closeAllDevicesLocked();
+
+    status_t scanDirLocked(const char *dirname);
+    void scanDevicesLocked();
+    status_t readNotifyLocked();
+
+    Device* getDeviceByDescriptorLocked(String8& descriptor) const;
+    Device* getDeviceLocked(int32_t deviceId) const;
+    Device* getDeviceByPathLocked(const char* devicePath) const;
+
+    bool hasKeycodeLocked(Device* device, int keycode) const;
+
+    void loadConfigurationLocked(Device* device);
+    status_t loadVirtualKeyMapLocked(Device* device);
+    status_t loadKeyMapLocked(Device* device);
+
+    bool isExternalDeviceLocked(Device* device);
+
+    int32_t getNextControllerNumberLocked(Device* device);
+    void releaseControllerNumberLocked(Device* device);
+    void setLedForController(Device* device);
+
+    status_t mapLed(Device* device, int32_t led, int32_t* outScanCode) const;
+    void setLedStateLocked(Device* device, int32_t led, bool on);
+
+    // Protect all internal state.
+    mutable Mutex mLock;
+
+    // The actual id of the built-in keyboard, or NO_BUILT_IN_KEYBOARD if none.
+    // EventHub remaps the built-in keyboard to id 0 externally as required by the API.
+    enum {
+        // Must not conflict with any other assigned device ids, including
+        // the virtual keyboard id (-1).
+        NO_BUILT_IN_KEYBOARD = -2,
+    };
+    int32_t mBuiltInKeyboardId;
+
+    int32_t mNextDeviceId;
+
+    BitSet32 mControllerNumbers;
+
+    KeyedVector<int32_t, Device*> mDevices;
+
+    Device *mOpeningDevices;
+    Device *mClosingDevices;
+
+    bool mNeedToSendFinishedDeviceScan;
+    bool mNeedToReopenDevices;
+    bool mNeedToScanDevices;
+    Vector<String8> mExcludedDevices;
+
+    int mEpollFd;
+    int mINotifyFd;
+    int mWakeReadPipeFd;
+    int mWakeWritePipeFd;
+
+    // Ids used for epoll notifications not associated with devices.
+    static const uint32_t EPOLL_ID_INOTIFY = 0x80000001;
+    static const uint32_t EPOLL_ID_WAKE = 0x80000002;
+
+    // Epoll FD list size hint.
+    static const int EPOLL_SIZE_HINT = 8;
+
+    // Maximum number of signalled FDs to handle at a time.
+    static const int EPOLL_MAX_EVENTS = 16;
+
+    // The array of pending epoll events and the index of the next event to be handled.
+    struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];
+    size_t mPendingEventCount;
+    size_t mPendingEventIndex;
+    bool mPendingINotify;
+
+    bool mUsingEpollWakeup;
+};
+
+}; // namespace android
+
+#endif // _RUNTIME_EVENT_HUB_H
diff --git a/services/inputflinger/InputApplication.cpp b/services/inputflinger/InputApplication.cpp
new file mode 100644
index 0000000..a99e637
--- /dev/null
+++ b/services/inputflinger/InputApplication.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "InputApplication"
+
+#include "InputApplication.h"
+
+#include <cutils/log.h>
+
+namespace android {
+
+// --- InputApplicationHandle ---
+
+InputApplicationHandle::InputApplicationHandle() :
+    mInfo(NULL) {
+}
+
+InputApplicationHandle::~InputApplicationHandle() {
+    delete mInfo;
+}
+
+void InputApplicationHandle::releaseInfo() {
+    if (mInfo) {
+        delete mInfo;
+        mInfo = NULL;
+    }
+}
+
+} // namespace android
diff --git a/services/inputflinger/InputApplication.h b/services/inputflinger/InputApplication.h
new file mode 100644
index 0000000..1f5504c
--- /dev/null
+++ b/services/inputflinger/InputApplication.h
@@ -0,0 +1,83 @@
+/*
+ * 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 _UI_INPUT_APPLICATION_H
+#define _UI_INPUT_APPLICATION_H
+
+#include <input/Input.h>
+
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/*
+ * Describes the properties of an application that can receive input.
+ */
+struct InputApplicationInfo {
+    String8 name;
+    nsecs_t dispatchingTimeout;
+};
+
+
+/*
+ * Handle for an application that can receive input.
+ *
+ * Used by the native input dispatcher as a handle for the window manager objects
+ * that describe an application.
+ */
+class InputApplicationHandle : public RefBase {
+public:
+    inline const InputApplicationInfo* getInfo() const {
+        return mInfo;
+    }
+
+    inline String8 getName() const {
+        return mInfo ? mInfo->name : String8("<invalid>");
+    }
+
+    inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
+        return mInfo ? mInfo->dispatchingTimeout : defaultValue;
+    }
+
+    /**
+     * Requests that the state of this object be updated to reflect
+     * the most current available information about the application.
+     *
+     * This method should only be called from within the input dispatcher's
+     * critical section.
+     *
+     * Returns true on success, or false if the handle is no longer valid.
+     */
+    virtual bool updateInfo() = 0;
+
+    /**
+     * Releases the storage used by the associated information when it is
+     * no longer needed.
+     */
+    void releaseInfo();
+
+protected:
+    InputApplicationHandle();
+    virtual ~InputApplicationHandle();
+
+    InputApplicationInfo* mInfo;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_APPLICATION_H
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
new file mode 100644
index 0000000..c000460
--- /dev/null
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -0,0 +1,4473 @@
+/*
+ * 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 "InputDispatcher"
+#define ATRACE_TAG ATRACE_TAG_INPUT
+
+//#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 the dispatch cycle.
+#define DEBUG_DISPATCH_CYCLE 0
+
+// Log debug messages about registrations.
+#define DEBUG_REGISTRATION 0
+
+// Log debug messages about input event injection.
+#define DEBUG_INJECTION 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
+
+// Log debug messages about hover events.
+#define DEBUG_HOVER 0
+
+#include "InputDispatcher.h"
+
+#include <utils/Trace.h>
+#include <cutils/log.h>
+#include <powermanager/PowerManager.h>
+#include <ui/Region.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <time.h>
+
+#define INDENT "  "
+#define INDENT2 "    "
+#define INDENT3 "      "
+#define INDENT4 "        "
+
+namespace android {
+
+// 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
+
+// Amount of time to allow for an event to be dispatched (measured since its eventTime)
+// before considering it stale and dropping it.
+const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
+
+// Amount of time to allow touch events to be streamed out to a connection before requiring
+// that the first event be finished.  This value extends the ANR timeout by the specified
+// amount.  For example, if streaming is allowed to get ahead by one second relative to the
+// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
+const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
+
+// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
+const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
+
+// Number of recent events to keep for debugging purposes.
+const size_t RECENT_QUEUE_MAX_SIZE = 10;
+
+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)) {
+        ALOGE("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:
+    case AMOTION_EVENT_ACTION_HOVER_ENTER:
+    case AMOTION_EVENT_ACTION_HOVER_MOVE:
+    case AMOTION_EVENT_ACTION_HOVER_EXIT:
+    case AMOTION_EVENT_ACTION_SCROLL:
+        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 PointerProperties* pointerProperties) {
+    if (! isValidMotionAction(action, pointerCount)) {
+        ALOGE("Motion event has invalid action code 0x%x", action);
+        return false;
+    }
+    if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
+        ALOGE("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 = pointerProperties[i].id;
+        if (id < 0 || id > MAX_POINTER_ID) {
+            ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
+                    id, MAX_POINTER_ID);
+            return false;
+        }
+        if (pointerIdBits.hasBit(id)) {
+            ALOGE("Motion event has duplicate pointer id %d", id);
+            return false;
+        }
+        pointerIdBits.markBit(id);
+    }
+    return true;
+}
+
+static bool isMainDisplay(int32_t displayId) {
+    return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
+}
+
+static void dumpRegion(String8& dump, const Region& region) {
+    if (region.isEmpty()) {
+        dump.append("<empty>");
+        return;
+    }
+
+    bool first = true;
+    Region::const_iterator cur = region.begin();
+    Region::const_iterator const tail = region.end();
+    while (cur != tail) {
+        if (first) {
+            first = false;
+        } else {
+            dump.append("|");
+        }
+        dump.appendFormat("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
+        cur++;
+    }
+}
+
+
+// --- InputDispatcher ---
+
+InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
+    mPolicy(policy),
+    mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
+    mNextUnblockedEvent(NULL),
+    mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
+    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
+    mLooper = new Looper(false);
+
+    mKeyRepeatState.lastKeyEntry = NULL;
+
+    policy->getDispatcherConfiguration(&mConfig);
+}
+
+InputDispatcher::~InputDispatcher() {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        resetKeyRepeatLocked();
+        releasePendingEventLocked();
+        drainInboundQueueLocked();
+    }
+
+    while (mConnectionsByFd.size() != 0) {
+        unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
+    }
+}
+
+void InputDispatcher::dispatchOnce() {
+    nsecs_t nextWakeupTime = LONG_LONG_MAX;
+    { // acquire lock
+        AutoMutex _l(mLock);
+        mDispatcherIsAliveCondition.broadcast();
+
+        // Run a dispatch loop if there are no pending commands.
+        // The dispatch loop might enqueue commands to run afterwards.
+        if (!haveCommandsLocked()) {
+            dispatchOnceInnerLocked(&nextWakeupTime);
+        }
+
+        // Run all pending commands if there are any.
+        // If any commands were run then force the next poll to wake up immediately.
+        if (runCommandsLockedInterruptible()) {
+            nextWakeupTime = LONG_LONG_MIN;
+        }
+    } // release lock
+
+    // Wait for callback or timeout or wake.  (make sure we round up, not down)
+    nsecs_t currentTime = now();
+    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
+    mLooper->pollOnce(timeoutMillis);
+}
+
+void InputDispatcher::dispatchOnceInnerLocked(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 (!mPolicy->isKeyRepeatEnabled()) {
+        resetKeyRepeatLocked();
+    }
+
+    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
+    if (mDispatchFrozen) {
+#if DEBUG_FOCUS
+        ALOGD("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);
+                } else {
+                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
+                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
+                    }
+                }
+            }
+
+            // Nothing to do if there is no pending event.
+            if (!mPendingEvent) {
+                return;
+            }
+        } else {
+            // Inbound queue has at least one entry.
+            mPendingEvent = mInboundQueue.dequeueAtHead();
+            traceInboundQueueLengthLocked();
+        }
+
+        // Poke user activity for this event.
+        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
+            pokeUserActivityLocked(mPendingEvent);
+        }
+
+        // Get ready to dispatch the event.
+        resetANRTimeoutsLocked();
+    }
+
+    // Now we have an event to dispatch.
+    // All events are eventually dequeued and processed this way, even if we intend to drop them.
+    ALOG_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;
+    }
+
+    if (mNextUnblockedEvent == mPendingEvent) {
+        mNextUnblockedEvent = NULL;
+    }
+
+    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_DEVICE_RESET: {
+        DeviceResetEntry* typedEntry =
+                static_cast<DeviceResetEntry*>(mPendingEvent);
+        done = dispatchDeviceResetLocked(currentTime, typedEntry);
+        dropReason = DROP_REASON_NOT_DROPPED; // device resets 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;
+            }
+        }
+        if (dropReason == DROP_REASON_NOT_DROPPED
+                && isStaleEventLocked(currentTime, typedEntry)) {
+            dropReason = DROP_REASON_STALE;
+        }
+        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
+            dropReason = DROP_REASON_BLOCKED;
+        }
+        done = dispatchKeyLocked(currentTime, typedEntry, &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;
+        }
+        if (dropReason == DROP_REASON_NOT_DROPPED
+                && isStaleEventLocked(currentTime, typedEntry)) {
+            dropReason = DROP_REASON_STALE;
+        }
+        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
+            dropReason = DROP_REASON_BLOCKED;
+        }
+        done = dispatchMotionLocked(currentTime, typedEntry,
+                &dropReason, nextWakeupTime);
+        break;
+    }
+
+    default:
+        ALOG_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);
+    traceInboundQueueLengthLocked();
+
+    switch (entry->type) {
+    case EventEntry::TYPE_KEY: {
+        // Optimize app switch latency.
+        // If the application takes too long to catch up then we drop all events preceding
+        // the app switch 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
+                    ALOGD("App switch is pending!");
+#endif
+                    mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
+                    mAppSwitchSawKeyDown = false;
+                    needWake = true;
+                }
+            }
+        }
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        // Optimize case where the current application is unresponsive and the user
+        // decides to touch a window in a different application.
+        // If the application takes too long to catch up then we drop all events preceding
+        // the touch into the other window.
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+        if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
+                && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
+                && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
+                && mInputTargetWaitApplicationHandle != NULL) {
+            int32_t displayId = motionEntry->displayId;
+            int32_t x = int32_t(motionEntry->pointerCoords[0].
+                    getAxisValue(AMOTION_EVENT_AXIS_X));
+            int32_t y = int32_t(motionEntry->pointerCoords[0].
+                    getAxisValue(AMOTION_EVENT_AXIS_Y));
+            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
+            if (touchedWindowHandle != NULL
+                    && touchedWindowHandle->inputApplicationHandle
+                            != mInputTargetWaitApplicationHandle) {
+                // User touched a different application than the one we are waiting on.
+                // Flag the event, and start pruning the input queue.
+                mNextUnblockedEvent = motionEntry;
+                needWake = true;
+            }
+        }
+        break;
+    }
+    }
+
+    return needWake;
+}
+
+void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
+    entry->refCount += 1;
+    mRecentQueue.enqueueAtTail(entry);
+    if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) {
+        mRecentQueue.dequeueAtHead()->release();
+    }
+}
+
+sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
+        int32_t x, int32_t y) {
+    // Traverse windows from front to back to find touched window.
+    size_t numWindows = mWindowHandles.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
+        const InputWindowInfo* windowInfo = windowHandle->getInfo();
+        if (windowInfo->displayId == displayId) {
+            int32_t flags = windowInfo->layoutParamsFlags;
+            int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
+
+            if (windowInfo->visible) {
+                if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
+                    bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
+                            | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
+                    if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
+                        // Found window.
+                        return windowHandle;
+                    }
+                }
+            }
+
+            if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
+                // Error window is on top but not visible, so touch is dropped.
+                return NULL;
+            }
+        }
+    }
+    return NULL;
+}
+
+void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
+    const char* reason;
+    switch (dropReason) {
+    case DROP_REASON_POLICY:
+#if DEBUG_INBOUND_EVENT_DETAILS
+        ALOGD("Dropped event because policy consumed it.");
+#endif
+        reason = "inbound event was dropped because the policy consumed it";
+        break;
+    case DROP_REASON_DISABLED:
+        ALOGI("Dropped event because input dispatch is disabled.");
+        reason = "inbound event was dropped because input dispatch is disabled";
+        break;
+    case DROP_REASON_APP_SWITCH:
+        ALOGI("Dropped event because of pending overdue app switch.");
+        reason = "inbound event was dropped because of pending overdue app switch";
+        break;
+    case DROP_REASON_BLOCKED:
+        ALOGI("Dropped event because the current application is not responding and the user "
+                "has started interacting with a different application.");
+        reason = "inbound event was dropped because the current application is not responding "
+                "and the user has started interacting with a different application";
+        break;
+    case DROP_REASON_STALE:
+        ALOGI("Dropped event because it is stale.");
+        reason = "inbound event was dropped because it is stale";
+        break;
+    default:
+        ALOG_ASSERT(false);
+        return;
+    }
+
+    switch (entry->type) {
+    case EventEntry::TYPE_KEY: {
+        CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
+        synthesizeCancelationEventsForAllConnectionsLocked(options);
+        break;
+    }
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
+            synthesizeCancelationEventsForAllConnectionsLocked(options);
+        } else {
+            CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
+            synthesizeCancelationEventsForAllConnectionsLocked(options);
+        }
+        break;
+    }
+    }
+}
+
+bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
+    return keyCode == AKEYCODE_HOME
+            || keyCode == AKEYCODE_ENDCALL
+            || keyCode == AKEYCODE_APP_SWITCH;
+}
+
+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) {
+        ALOGD("App switch has arrived.");
+    } else {
+        ALOGD("App switch was abandoned.");
+    }
+#endif
+}
+
+bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
+    return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
+}
+
+bool InputDispatcher::haveCommandsLocked() const {
+    return !mCommandQueue.isEmpty();
+}
+
+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();
+        delete commandEntry;
+    } while (! mCommandQueue.isEmpty());
+    return true;
+}
+
+InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
+    CommandEntry* commandEntry = new CommandEntry(command);
+    mCommandQueue.enqueueAtTail(commandEntry);
+    return commandEntry;
+}
+
+void InputDispatcher::drainInboundQueueLocked() {
+    while (! mInboundQueue.isEmpty()) {
+        EventEntry* entry = mInboundQueue.dequeueAtHead();
+        releaseInboundEventLocked(entry);
+    }
+    traceInboundQueueLengthLocked();
+}
+
+void InputDispatcher::releasePendingEventLocked() {
+    if (mPendingEvent) {
+        resetANRTimeoutsLocked();
+        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
+        ALOGD("Injected inbound event was dropped.");
+#endif
+        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+    }
+    if (entry == mNextUnblockedEvent) {
+        mNextUnblockedEvent = NULL;
+    }
+    addRecentEventLocked(entry);
+    entry->release();
+}
+
+void InputDispatcher::resetKeyRepeatLocked() {
+    if (mKeyRepeatState.lastKeyEntry) {
+        mKeyRepeatState.lastKeyEntry->release();
+        mKeyRepeatState.lastKeyEntry = NULL;
+    }
+}
+
+InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
+    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) {
+        entry->recycle();
+        entry->eventTime = currentTime;
+        entry->policyFlags = policyFlags;
+        entry->repeatCount += 1;
+    } else {
+        KeyEntry* newEntry = new KeyEntry(currentTime,
+                entry->deviceId, entry->source, policyFlags,
+                entry->action, entry->flags, entry->keyCode, entry->scanCode,
+                entry->metaState, entry->repeatCount + 1, entry->downTime);
+
+        mKeyRepeatState.lastKeyEntry = newEntry;
+        entry->release();
+
+        entry = newEntry;
+    }
+    entry->syntheticRepeat = true;
+
+    // Increment reference count since we keep a reference to the event in
+    // mKeyRepeatState.lastKeyEntry in addition to the one we return.
+    entry->refCount += 1;
+
+    mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
+    return entry;
+}
+
+bool InputDispatcher::dispatchConfigurationChangedLocked(
+        nsecs_t currentTime, ConfigurationChangedEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    ALOGD("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::dispatchDeviceResetLocked(
+        nsecs_t currentTime, DeviceResetEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    ALOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId);
+#endif
+
+    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
+            "device was reset");
+    options.deviceId = entry->deviceId;
+    synthesizeCancelationEventsForAllConnectionsLocked(options);
+    return true;
+}
+
+bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
+        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->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
+            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 + mConfig.keyRepeatTimeout;
+            }
+            mKeyRepeatState.lastKeyEntry = entry;
+            entry->refCount += 1;
+        } else if (! entry->syntheticRepeat) {
+            resetKeyRepeatLocked();
+        }
+
+        if (entry->repeatCount == 1) {
+            entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
+        } else {
+            entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
+        }
+
+        entry->dispatchInProgress = true;
+
+        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
+    }
+
+    // Handle case where the policy asked us to try again later last time.
+    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
+        if (currentTime < entry->interceptKeyWakeupTime) {
+            if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
+                *nextWakeupTime = entry->interceptKeyWakeupTime;
+            }
+            return false; // wait until next wakeup
+        }
+        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+        entry->interceptKeyWakeupTime = 0;
+    }
+
+    // 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 (mFocusedWindowHandle != NULL) {
+                commandEntry->inputWindowHandle = mFocusedWindowHandle;
+            }
+            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) {
+        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
+                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
+        return true;
+    }
+
+    // Identify targets.
+    Vector<InputTarget> inputTargets;
+    int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
+            entry, inputTargets, nextWakeupTime);
+    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+        return false;
+    }
+
+    setInjectionResultLocked(entry, injectionResult);
+    if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+        return true;
+    }
+
+    addMonitoringTargetsLocked(inputTargets);
+
+    // Dispatch the key.
+    dispatchEventLocked(currentTime, entry, inputTargets);
+    return true;
+}
+
+void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    ALOGD("%seventTime=%lld, deviceId=%d, 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;
+
+        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
+    }
+
+    // Clean up if dropping the event.
+    if (*dropReason != DROP_REASON_NOT_DROPPED) {
+        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.
+    Vector<InputTarget> inputTargets;
+
+    bool conflictingPointerActions = false;
+    int32_t injectionResult;
+    if (isPointerEvent) {
+        // Pointer event.  (eg. touchscreen)
+        injectionResult = findTouchedWindowTargetsLocked(currentTime,
+                entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
+    } else {
+        // Non touch event.  (eg. trackball)
+        injectionResult = findFocusedWindowTargetsLocked(currentTime,
+                entry, inputTargets, nextWakeupTime);
+    }
+    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+        return false;
+    }
+
+    setInjectionResultLocked(entry, injectionResult);
+    if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+        return true;
+    }
+
+    // TODO: support sending secondary display events to input monitors
+    if (isMainDisplay(entry->displayId)) {
+        addMonitoringTargetsLocked(inputTargets);
+    }
+
+    // Dispatch the motion.
+    if (conflictingPointerActions) {
+        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+                "conflicting pointer actions");
+        synthesizeCancelationEventsForAllConnectionsLocked(options);
+    }
+    dispatchEventLocked(currentTime, entry, inputTargets);
+    return true;
+}
+
+
+void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
+            "action=0x%x, flags=0x%x, "
+            "metaState=0x%x, buttonState=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->buttonState,
+            entry->edgeFlags, entry->xPrecision, entry->yPrecision,
+            entry->downTime);
+
+    for (uint32_t i = 0; i < entry->pointerCount; i++) {
+        ALOGD("  Pointer %d: id=%d, toolType=%d, "
+                "x=%f, y=%f, pressure=%f, size=%f, "
+                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
+                "orientation=%f",
+                i, entry->pointerProperties[i].id,
+                entry->pointerProperties[i].toolType,
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
+    }
+#endif
+}
+
+void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
+        EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
+#if DEBUG_DISPATCH_CYCLE
+    ALOGD("dispatchEventToCurrentInputTargets");
+#endif
+
+    ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
+
+    pokeUserActivityLocked(eventEntry);
+
+    for (size_t i = 0; i < inputTargets.size(); i++) {
+        const InputTarget& inputTarget = inputTargets.itemAt(i);
+
+        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
+        if (connectionIndex >= 0) {
+            sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
+            prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
+        } else {
+#if DEBUG_FOCUS
+            ALOGD("Dropping event delivery to target with channel '%s' because it "
+                    "is no longer registered with the input dispatcher.",
+                    inputTarget.inputChannel->getName().string());
+#endif
+        }
+    }
+}
+
+int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
+        const EventEntry* entry,
+        const sp<InputApplicationHandle>& applicationHandle,
+        const sp<InputWindowHandle>& windowHandle,
+        nsecs_t* nextWakeupTime, const char* reason) {
+    if (applicationHandle == NULL && windowHandle == NULL) {
+        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
+#if DEBUG_FOCUS
+            ALOGD("Waiting for system to become ready for input.  Reason: %s", reason);
+#endif
+            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
+            mInputTargetWaitStartTime = currentTime;
+            mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
+            mInputTargetWaitTimeoutExpired = false;
+            mInputTargetWaitApplicationHandle.clear();
+        }
+    } else {
+        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
+#if DEBUG_FOCUS
+            ALOGD("Waiting for application to become ready for input: %s.  Reason: %s",
+                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
+                    reason);
+#endif
+            nsecs_t timeout;
+            if (windowHandle != NULL) {
+                timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
+            } else if (applicationHandle != NULL) {
+                timeout = applicationHandle->getDispatchingTimeout(
+                        DEFAULT_INPUT_DISPATCHING_TIMEOUT);
+            } else {
+                timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
+            }
+
+            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
+            mInputTargetWaitStartTime = currentTime;
+            mInputTargetWaitTimeoutTime = currentTime + timeout;
+            mInputTargetWaitTimeoutExpired = false;
+            mInputTargetWaitApplicationHandle.clear();
+
+            if (windowHandle != NULL) {
+                mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
+            }
+            if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
+                mInputTargetWaitApplicationHandle = applicationHandle;
+            }
+        }
+    }
+
+    if (mInputTargetWaitTimeoutExpired) {
+        return INPUT_EVENT_INJECTION_TIMED_OUT;
+    }
+
+    if (currentTime >= mInputTargetWaitTimeoutTime) {
+        onANRLocked(currentTime, applicationHandle, windowHandle,
+                entry->eventTime, mInputTargetWaitStartTime, reason);
+
+        // 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;
+
+        // 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 = mConnectionsByFd.valueAt(connectionIndex);
+                sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
+
+                if (windowHandle != NULL) {
+                    mTouchState.removeWindow(windowHandle);
+                }
+
+                if (connection->status == Connection::STATUS_NORMAL) {
+                    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
+                            "application not responding");
+                    synthesizeCancelationEventsForConnectionLocked(connection, options);
+                }
+            }
+        }
+    }
+}
+
+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
+        ALOGD("Resetting ANR timeouts.");
+#endif
+
+    // Reset input target wait timeout.
+    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
+    mInputTargetWaitApplicationHandle.clear();
+}
+
+int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
+        const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
+    int32_t injectionResult;
+
+    // If there is no currently focused window and no focused application
+    // then drop the event.
+    if (mFocusedWindowHandle == NULL) {
+        if (mFocusedApplicationHandle != NULL) {
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    mFocusedApplicationHandle, NULL, nextWakeupTime,
+                    "Waiting because no window has focus but there is a "
+                    "focused application that may eventually add a window "
+                    "when it finishes starting up.");
+            goto Unresponsive;
+        }
+
+        ALOGI("Dropping event because there is no focused window or focused application.");
+        injectionResult = INPUT_EVENT_INJECTION_FAILED;
+        goto Failed;
+    }
+
+    // Check permissions.
+    if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
+        injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+        goto Failed;
+    }
+
+    // If the currently focused window is paused then keep waiting.
+    if (mFocusedWindowHandle->getInfo()->paused) {
+        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
+                "Waiting because the focused window is paused.");
+        goto Unresponsive;
+    }
+
+    // If the currently focused window is still working on previous events then keep waiting.
+    if (!isWindowReadyForMoreInputLocked(currentTime, mFocusedWindowHandle, entry)) {
+        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
+                "Waiting because the focused window has not finished "
+                "processing the input events that were previously delivered to it.");
+        goto Unresponsive;
+    }
+
+    // Success!  Output targets.
+    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+    addWindowTargetLocked(mFocusedWindowHandle,
+            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
+            inputTargets);
+
+    // Done.
+Failed:
+Unresponsive:
+    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
+    updateDispatchStatisticsLocked(currentTime, entry,
+            injectionResult, timeSpentWaitingForApplication);
+#if DEBUG_FOCUS
+    ALOGD("findFocusedWindow finished: injectionResult=%d, "
+            "timeSpentWaitingForApplication=%0.1fms",
+            injectionResult, timeSpentWaitingForApplication / 1000000.0);
+#endif
+    return injectionResult;
+}
+
+int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
+        const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
+        bool* outConflictingPointerActions) {
+    enum InjectionPermission {
+        INJECTION_PERMISSION_UNKNOWN,
+        INJECTION_PERMISSION_GRANTED,
+        INJECTION_PERMISSION_DENIED
+    };
+
+    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 displayId = entry->displayId;
+    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;
+    sp<InputWindowHandle> newHoverWindowHandle;
+
+    bool isSplit = mTouchState.split;
+    bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0
+            && (mTouchState.deviceId != entry->deviceId
+                    || mTouchState.source != entry->source
+                    || mTouchState.displayId != displayId);
+    bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
+            || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
+            || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
+    bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
+            || maskedAction == AMOTION_EVENT_ACTION_SCROLL
+            || isHoverAction);
+    bool wrongDevice = false;
+    if (newGesture) {
+        bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
+        if (switchedDevice && mTouchState.down && !down) {
+#if DEBUG_FOCUS
+            ALOGD("Dropping event because a pointer for a different device is already down.");
+#endif
+            mTempTouchState.copyFrom(mTouchState);
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            switchedDevice = false;
+            wrongDevice = true;
+            goto Failed;
+        }
+        mTempTouchState.reset();
+        mTempTouchState.down = down;
+        mTempTouchState.deviceId = entry->deviceId;
+        mTempTouchState.source = entry->source;
+        mTempTouchState.displayId = displayId;
+        isSplit = false;
+    } else {
+        mTempTouchState.copyFrom(mTouchState);
+    }
+
+    if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
+        /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
+
+        int32_t pointerIndex = getMotionEventActionPointerIndex(action);
+        int32_t x = int32_t(entry->pointerCoords[pointerIndex].
+                getAxisValue(AMOTION_EVENT_AXIS_X));
+        int32_t y = int32_t(entry->pointerCoords[pointerIndex].
+                getAxisValue(AMOTION_EVENT_AXIS_Y));
+        sp<InputWindowHandle> newTouchedWindowHandle;
+        sp<InputWindowHandle> topErrorWindowHandle;
+        bool isTouchModal = false;
+
+        // Traverse windows from front to back to find touched window and outside targets.
+        size_t numWindows = mWindowHandles.size();
+        for (size_t i = 0; i < numWindows; i++) {
+            sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
+            const InputWindowInfo* windowInfo = windowHandle->getInfo();
+            if (windowInfo->displayId != displayId) {
+                continue; // wrong display
+            }
+
+            int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
+            if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
+                if (topErrorWindowHandle == NULL) {
+                    topErrorWindowHandle = windowHandle;
+                }
+            }
+
+            int32_t flags = windowInfo->layoutParamsFlags;
+            if (windowInfo->visible) {
+                if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
+                    isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
+                            | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
+                    if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
+                        if (! screenWasOff
+                                || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
+                            newTouchedWindowHandle = windowHandle;
+                        }
+                        break; // found touched window, exit window loop
+                    }
+                }
+
+                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+                        && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
+                    int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
+                    if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
+                        outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+                    }
+
+                    mTempTouchState.addOrUpdateWindow(
+                            windowHandle, 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 (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    NULL, NULL, nextWakeupTime,
+                    "Waiting because a system error window is about to be displayed.");
+            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
+            goto Unresponsive;
+        }
+
+        // Figure out whether splitting will be allowed for this window.
+        if (newTouchedWindowHandle != NULL
+                && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
+            // New window supports splitting.
+            isSplit = true;
+        } else if (isSplit) {
+            // New window does not support splitting but we have already split events.
+            // Ignore the new window.
+            newTouchedWindowHandle = NULL;
+        }
+
+        // Handle the case where we did not find a window.
+        if (newTouchedWindowHandle == NULL) {
+            // Try to assign the pointer to the first foreground window we find, if there is one.
+            newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
+            if (newTouchedWindowHandle == NULL) {
+                ALOGI("Dropping event because there is no touchable window at (%d, %d).", x, y);
+                injectionResult = INPUT_EVENT_INJECTION_FAILED;
+                goto Failed;
+            }
+        }
+
+        // Set target flags.
+        int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
+        if (isSplit) {
+            targetFlags |= InputTarget::FLAG_SPLIT;
+        }
+        if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
+            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+        }
+
+        // Update hover state.
+        if (isHoverAction) {
+            newHoverWindowHandle = newTouchedWindowHandle;
+        } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
+            newHoverWindowHandle = mLastHoverWindowHandle;
+        }
+
+        // Update the temporary touch state.
+        BitSet32 pointerIds;
+        if (isSplit) {
+            uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
+            pointerIds.markBit(pointerId);
+        }
+        mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, 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) {
+#if DEBUG_FOCUS
+            ALOGD("Dropping event because the pointer is not down or we previously "
+                    "dropped the pointer down event.");
+#endif
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            goto Failed;
+        }
+
+        // Check whether touches should slip outside of the current foreground window.
+        if (maskedAction == AMOTION_EVENT_ACTION_MOVE
+                && entry->pointerCount == 1
+                && mTempTouchState.isSlippery()) {
+            int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
+            int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
+
+            sp<InputWindowHandle> oldTouchedWindowHandle =
+                    mTempTouchState.getFirstForegroundWindowHandle();
+            sp<InputWindowHandle> newTouchedWindowHandle =
+                    findTouchedWindowAtLocked(displayId, x, y);
+            if (oldTouchedWindowHandle != newTouchedWindowHandle
+                    && newTouchedWindowHandle != NULL) {
+#if DEBUG_FOCUS
+                ALOGD("Touch is slipping out of window %s into window %s.",
+                        oldTouchedWindowHandle->getName().string(),
+                        newTouchedWindowHandle->getName().string());
+#endif
+                // Make a slippery exit from the old window.
+                mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
+                        InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
+
+                // Make a slippery entrance into the new window.
+                if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
+                    isSplit = true;
+                }
+
+                int32_t targetFlags = InputTarget::FLAG_FOREGROUND
+                        | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
+                if (isSplit) {
+                    targetFlags |= InputTarget::FLAG_SPLIT;
+                }
+                if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
+                    targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+                }
+
+                BitSet32 pointerIds;
+                if (isSplit) {
+                    pointerIds.markBit(entry->pointerProperties[0].id);
+                }
+                mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
+            }
+        }
+    }
+
+    if (newHoverWindowHandle != mLastHoverWindowHandle) {
+        // Let the previous window know that the hover sequence is over.
+        if (mLastHoverWindowHandle != NULL) {
+#if DEBUG_HOVER
+            ALOGD("Sending hover exit event to window %s.",
+                    mLastHoverWindowHandle->getName().string());
+#endif
+            mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
+                    InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
+        }
+
+        // Let the new window know that the hover sequence is starting.
+        if (newHoverWindowHandle != NULL) {
+#if DEBUG_HOVER
+            ALOGD("Sending hover enter event to window %s.",
+                    newHoverWindowHandle->getName().string());
+#endif
+            mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
+                    InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
+        }
+    }
+
+    // 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.windowHandle,
+                        entry->injectionState)) {
+                    injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+                    injectionPermission = INJECTION_PERMISSION_DENIED;
+                    goto Failed;
+                }
+            }
+        }
+        if (! haveForegroundWindow) {
+#if DEBUG_FOCUS
+            ALOGD("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;
+    }
+
+    // Check whether windows listening for outside touches are owned by the same UID. If it is
+    // set the policy flag that we will not reveal coordinate information to this window.
+    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+        sp<InputWindowHandle> foregroundWindowHandle =
+                mTempTouchState.getFirstForegroundWindowHandle();
+        const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
+        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
+            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+            if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
+                sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
+                if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
+                    mTempTouchState.addOrUpdateWindow(inputWindowHandle,
+                            InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
+                }
+            }
+        }
+    }
+
+    // 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.windowHandle->getInfo()->paused) {
+                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                        NULL, touchedWindow.windowHandle, nextWakeupTime,
+                        "Waiting because the touched window is paused.");
+                goto Unresponsive;
+            }
+
+            // If the touched window is still working on previous events then keep waiting.
+            if (!isWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry)) {
+                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                        NULL, touchedWindow.windowHandle, nextWakeupTime,
+                        "Waiting because the touched window has not finished "
+                        "processing the input events that were previously delivered to it.");
+                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.
+    // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
+    // engine only supports touch events.  We would need to add a mechanism similar
+    // to View.onGenericMotionEvent to enable wallpapers to handle these events.
+    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+        sp<InputWindowHandle> foregroundWindowHandle =
+                mTempTouchState.getFirstForegroundWindowHandle();
+        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
+            for (size_t i = 0; i < mWindowHandles.size(); i++) {
+                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
+                const InputWindowInfo* info = windowHandle->getInfo();
+                if (info->displayId == displayId
+                        && windowHandle->getInfo()->layoutParamsType
+                                == InputWindowInfo::TYPE_WALLPAPER) {
+                    mTempTouchState.addOrUpdateWindow(windowHandle,
+                            InputTarget::FLAG_WINDOW_IS_OBSCURED
+                                    | InputTarget::FLAG_DISPATCH_AS_IS,
+                            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.windowHandle, touchedWindow.targetFlags,
+                touchedWindow.pointerIds, inputTargets);
+    }
+
+    // Drop the outside or hover touch windows since we will not care about them
+    // in the next iteration.
+    mTempTouchState.filterNonAsIsTouchWindows();
+
+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 (!wrongDevice) {
+            if (switchedDevice) {
+#if DEBUG_FOCUS
+                ALOGD("Conflicting pointer actions: Switched to a different device.");
+#endif
+                *outConflictingPointerActions = true;
+            }
+
+            if (isHoverAction) {
+                // Started hovering, therefore no longer down.
+                if (mTouchState.down) {
+#if DEBUG_FOCUS
+                    ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
+#endif
+                    *outConflictingPointerActions = true;
+                }
+                mTouchState.reset();
+                if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
+                        || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+                    mTouchState.deviceId = entry->deviceId;
+                    mTouchState.source = entry->source;
+                    mTouchState.displayId = displayId;
+                }
+            } else if (maskedAction == AMOTION_EVENT_ACTION_UP
+                    || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
+                // All pointers up or canceled.
+                mTouchState.reset();
+            } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+                // First pointer went down.
+                if (mTouchState.down) {
+#if DEBUG_FOCUS
+                    ALOGD("Conflicting pointer actions: Down received while already down.");
+#endif
+                    *outConflictingPointerActions = true;
+                }
+                mTouchState.copyFrom(mTempTouchState);
+            } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
+                // One pointer went up.
+                if (isSplit) {
+                    int32_t pointerIndex = getMotionEventActionPointerIndex(action);
+                    uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
+
+                    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;
+                    }
+                }
+                mTouchState.copyFrom(mTempTouchState);
+            } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
+                // Discard temporary touch state since it was only valid for this action.
+            } else {
+                // Save changes to touch state as-is for all other actions.
+                mTouchState.copyFrom(mTempTouchState);
+            }
+
+            // Update hover state.
+            mLastHoverWindowHandle = newHoverWindowHandle;
+        }
+    } else {
+#if DEBUG_FOCUS
+        ALOGD("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
+    ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
+            "timeSpentWaitingForApplication=%0.1fms",
+            injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
+#endif
+    return injectionResult;
+}
+
+void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
+        int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
+    inputTargets.push();
+
+    const InputWindowInfo* windowInfo = windowHandle->getInfo();
+    InputTarget& target = inputTargets.editTop();
+    target.inputChannel = windowInfo->inputChannel;
+    target.flags = targetFlags;
+    target.xOffset = - windowInfo->frameLeft;
+    target.yOffset = - windowInfo->frameTop;
+    target.scaleFactor = windowInfo->scaleFactor;
+    target.pointerIds = pointerIds;
+}
+
+void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
+    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+        inputTargets.push();
+
+        InputTarget& target = inputTargets.editTop();
+        target.inputChannel = mMonitoringChannels[i];
+        target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
+        target.xOffset = 0;
+        target.yOffset = 0;
+        target.pointerIds.clear();
+        target.scaleFactor = 1.0f;
+    }
+}
+
+bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
+        const InjectionState* injectionState) {
+    if (injectionState
+            && (windowHandle == NULL
+                    || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
+            && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
+        if (windowHandle != NULL) {
+            ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
+                    "owned by uid %d",
+                    injectionState->injectorPid, injectionState->injectorUid,
+                    windowHandle->getName().string(),
+                    windowHandle->getInfo()->ownerUid);
+        } else {
+            ALOGW("Permission denied: injecting event from pid %d uid %d",
+                    injectionState->injectorPid, injectionState->injectorUid);
+        }
+        return false;
+    }
+    return true;
+}
+
+bool InputDispatcher::isWindowObscuredAtPointLocked(
+        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
+    int32_t displayId = windowHandle->getInfo()->displayId;
+    size_t numWindows = mWindowHandles.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
+        if (otherHandle == windowHandle) {
+            break;
+        }
+
+        const InputWindowInfo* otherInfo = otherHandle->getInfo();
+        if (otherInfo->displayId == displayId
+                && otherInfo->visible && !otherInfo->isTrustedOverlay()
+                && otherInfo->frameContainsPoint(x, y)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool InputDispatcher::isWindowReadyForMoreInputLocked(nsecs_t currentTime,
+        const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry) {
+    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
+    if (connectionIndex >= 0) {
+        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
+        if (connection->inputPublisherBlocked) {
+            return false;
+        }
+        if (eventEntry->type == EventEntry::TYPE_KEY) {
+            // If the event is a key event, then we must wait for all previous events to
+            // complete before delivering it because previous events may have the
+            // side-effect of transferring focus to a different window and we want to
+            // ensure that the following keys are sent to the new window.
+            //
+            // Suppose the user touches a button in a window then immediately presses "A".
+            // If the button causes a pop-up window to appear then we want to ensure that
+            // the "A" key is delivered to the new pop-up window.  This is because users
+            // often anticipate pending UI changes when typing on a keyboard.
+            // To obtain this behavior, we must serialize key events with respect to all
+            // prior input events.
+            return connection->outboundQueue.isEmpty()
+                    && connection->waitQueue.isEmpty();
+        }
+        // Touch events can always be sent to a window immediately because the user intended
+        // to touch whatever was visible at the time.  Even if focus changes or a new
+        // window appears moments later, the touch event was meant to be delivered to
+        // whatever window happened to be on screen at the time.
+        //
+        // Generic motion events, such as trackball or joystick events are a little trickier.
+        // Like key events, generic motion events are delivered to the focused window.
+        // Unlike key events, generic motion events don't tend to transfer focus to other
+        // windows and it is not important for them to be serialized.  So we prefer to deliver
+        // generic motion events as soon as possible to improve efficiency and reduce lag
+        // through batching.
+        //
+        // The one case where we pause input event delivery is when the wait queue is piling
+        // up with lots of events because the application is not responding.
+        // This condition ensures that ANRs are detected reliably.
+        if (!connection->waitQueue.isEmpty()
+                && currentTime >= connection->waitQueue.head->deliveryTime
+                        + STREAM_AHEAD_EVENT_TIMEOUT) {
+            return false;
+        }
+    }
+    return true;
+}
+
+String8 InputDispatcher::getApplicationWindowLabelLocked(
+        const sp<InputApplicationHandle>& applicationHandle,
+        const sp<InputWindowHandle>& windowHandle) {
+    if (applicationHandle != NULL) {
+        if (windowHandle != NULL) {
+            String8 label(applicationHandle->getName());
+            label.append(" - ");
+            label.append(windowHandle->getName());
+            return label;
+        } else {
+            return applicationHandle->getName();
+        }
+    } else if (windowHandle != NULL) {
+        return windowHandle->getName();
+    } else {
+        return String8("<unknown application or window>");
+    }
+}
+
+void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
+    if (mFocusedWindowHandle != NULL) {
+        const InputWindowInfo* info = mFocusedWindowHandle->getInfo();
+        if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
+#if DEBUG_DISPATCH_CYCLE
+            ALOGD("Not poking user activity: disabled by window '%s'.", info->name.string());
+#endif
+            return;
+        }
+    }
+
+    int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
+    switch (eventEntry->type) {
+    case EventEntry::TYPE_MOTION: {
+        const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
+        if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
+            return;
+        }
+
+        if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
+            eventType = USER_ACTIVITY_EVENT_TOUCH;
+        }
+        break;
+    }
+    case EventEntry::TYPE_KEY: {
+        const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
+        if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
+            return;
+        }
+        eventType = USER_ACTIVITY_EVENT_BUTTON;
+        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) {
+#if DEBUG_DISPATCH_CYCLE
+    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
+            "xOffset=%f, yOffset=%f, scaleFactor=%f, "
+            "pointerIds=0x%x",
+            connection->getInputChannelName(), inputTarget->flags,
+            inputTarget->xOffset, inputTarget->yOffset,
+            inputTarget->scaleFactor, inputTarget->pointerIds.value);
+#endif
+
+    // 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
+        ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
+                connection->getInputChannelName(), connection->getStatusLabel());
+#endif
+        return;
+    }
+
+    // Split a motion event if needed.
+    if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
+        ALOG_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 (!splitMotionEntry) {
+                return; // split event was dropped
+            }
+#if DEBUG_FOCUS
+            ALOGD("channel '%s' ~ Split motion event.",
+                    connection->getInputChannelName());
+            logOutboundMotionDetailsLocked("  ", splitMotionEntry);
+#endif
+            enqueueDispatchEntriesLocked(currentTime, connection,
+                    splitMotionEntry, inputTarget);
+            splitMotionEntry->release();
+            return;
+        }
+    }
+
+    // Not splitting.  Enqueue dispatch entries for the event as is.
+    enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
+}
+
+void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
+        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
+    bool wasEmpty = connection->outboundQueue.isEmpty();
+
+    // Enqueue dispatch entries for the requested modes.
+    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
+            InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
+    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
+            InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
+    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
+            InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
+    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
+            InputTarget::FLAG_DISPATCH_AS_IS);
+    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
+            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
+    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
+            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
+
+    // If the outbound queue was previously empty, start the dispatch cycle going.
+    if (wasEmpty && !connection->outboundQueue.isEmpty()) {
+        startDispatchCycleLocked(currentTime, connection);
+    }
+}
+
+void InputDispatcher::enqueueDispatchEntryLocked(
+        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
+        int32_t dispatchMode) {
+    int32_t inputTargetFlags = inputTarget->flags;
+    if (!(inputTargetFlags & dispatchMode)) {
+        return;
+    }
+    inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
+
+    // This is a new event.
+    // Enqueue a new dispatch entry onto the outbound queue for this connection.
+    DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
+            inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
+            inputTarget->scaleFactor);
+
+    // Apply target flags and update the connection's input state.
+    switch (eventEntry->type) {
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
+        dispatchEntry->resolvedAction = keyEntry->action;
+        dispatchEntry->resolvedFlags = keyEntry->flags;
+
+        if (!connection->inputState.trackKey(keyEntry,
+                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
+#if DEBUG_DISPATCH_CYCLE
+            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
+                    connection->getInputChannelName());
+#endif
+            delete dispatchEntry;
+            return; // skip the inconsistent event
+        }
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
+        if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
+            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
+        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
+            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
+        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
+            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
+        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
+            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
+        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
+            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
+        } else {
+            dispatchEntry->resolvedAction = motionEntry->action;
+        }
+        if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
+                && !connection->inputState.isHovering(
+                        motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
+#if DEBUG_DISPATCH_CYCLE
+        ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
+                connection->getInputChannelName());
+#endif
+            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
+        }
+
+        dispatchEntry->resolvedFlags = motionEntry->flags;
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
+            dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+        }
+
+        if (!connection->inputState.trackMotion(motionEntry,
+                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
+#if DEBUG_DISPATCH_CYCLE
+            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
+                    connection->getInputChannelName());
+#endif
+            delete dispatchEntry;
+            return; // skip the inconsistent event
+        }
+        break;
+    }
+    }
+
+    // Remember that we are waiting for this dispatch to complete.
+    if (dispatchEntry->hasForegroundTarget()) {
+        incrementPendingForegroundDispatchesLocked(eventEntry);
+    }
+
+    // Enqueue the dispatch entry.
+    connection->outboundQueue.enqueueAtTail(dispatchEntry);
+    traceOutboundQueueLengthLocked(connection);
+}
+
+void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection) {
+#if DEBUG_DISPATCH_CYCLE
+    ALOGD("channel '%s' ~ startDispatchCycle",
+            connection->getInputChannelName());
+#endif
+
+    while (connection->status == Connection::STATUS_NORMAL
+            && !connection->outboundQueue.isEmpty()) {
+        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
+        dispatchEntry->deliveryTime = currentTime;
+
+        // Publish the event.
+        status_t status;
+        EventEntry* eventEntry = dispatchEntry->eventEntry;
+        switch (eventEntry->type) {
+        case EventEntry::TYPE_KEY: {
+            KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
+
+            // Publish the key event.
+            status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
+                    keyEntry->deviceId, keyEntry->source,
+                    dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
+                    keyEntry->keyCode, keyEntry->scanCode,
+                    keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
+                    keyEntry->eventTime);
+            break;
+        }
+
+        case EventEntry::TYPE_MOTION: {
+            MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
+
+            PointerCoords scaledCoords[MAX_POINTERS];
+            const PointerCoords* usingCoords = motionEntry->pointerCoords;
+
+            // Set the X and Y offset depending on the input source.
+            float xOffset, yOffset, scaleFactor;
+            if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
+                    && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
+                scaleFactor = dispatchEntry->scaleFactor;
+                xOffset = dispatchEntry->xOffset * scaleFactor;
+                yOffset = dispatchEntry->yOffset * scaleFactor;
+                if (scaleFactor != 1.0f) {
+                    for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+                        scaledCoords[i] = motionEntry->pointerCoords[i];
+                        scaledCoords[i].scale(scaleFactor);
+                    }
+                    usingCoords = scaledCoords;
+                }
+            } else {
+                xOffset = 0.0f;
+                yOffset = 0.0f;
+                scaleFactor = 1.0f;
+
+                // We don't want the dispatch target to know.
+                if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
+                    for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+                        scaledCoords[i].clear();
+                    }
+                    usingCoords = scaledCoords;
+                }
+            }
+
+            // Publish the motion event.
+            status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
+                    motionEntry->deviceId, motionEntry->source,
+                    dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
+                    motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
+                    xOffset, yOffset,
+                    motionEntry->xPrecision, motionEntry->yPrecision,
+                    motionEntry->downTime, motionEntry->eventTime,
+                    motionEntry->pointerCount, motionEntry->pointerProperties,
+                    usingCoords);
+            break;
+        }
+
+        default:
+            ALOG_ASSERT(false);
+            return;
+        }
+
+        // Check the result.
+        if (status) {
+            if (status == WOULD_BLOCK) {
+                if (connection->waitQueue.isEmpty()) {
+                    ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
+                            "This is unexpected because the wait queue is empty, so the pipe "
+                            "should be empty and we shouldn't have any problems writing an "
+                            "event to it, status=%d", connection->getInputChannelName(), status);
+                    abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
+                } else {
+                    // Pipe is full and we are waiting for the app to finish process some events
+                    // before sending more events to it.
+#if DEBUG_DISPATCH_CYCLE
+                    ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
+                            "waiting for the application to catch up",
+                            connection->getInputChannelName());
+#endif
+                    connection->inputPublisherBlocked = true;
+                }
+            } else {
+                ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
+                        "status=%d", connection->getInputChannelName(), status);
+                abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
+            }
+            return;
+        }
+
+        // Re-enqueue the event on the wait queue.
+        connection->outboundQueue.dequeue(dispatchEntry);
+        traceOutboundQueueLengthLocked(connection);
+        connection->waitQueue.enqueueAtTail(dispatchEntry);
+        traceWaitQueueLengthLocked(connection);
+    }
+}
+
+void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection, uint32_t seq, bool handled) {
+#if DEBUG_DISPATCH_CYCLE
+    ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
+            connection->getInputChannelName(), seq, toString(handled));
+#endif
+
+    connection->inputPublisherBlocked = false;
+
+    if (connection->status == Connection::STATUS_BROKEN
+            || connection->status == Connection::STATUS_ZOMBIE) {
+        return;
+    }
+
+    // Notify other system components and prepare to start the next dispatch cycle.
+    onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
+}
+
+void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection, bool notify) {
+#if DEBUG_DISPATCH_CYCLE
+    ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
+            connection->getInputChannelName(), toString(notify));
+#endif
+
+    // Clear the dispatch queues.
+    drainDispatchQueueLocked(&connection->outboundQueue);
+    traceOutboundQueueLengthLocked(connection);
+    drainDispatchQueueLocked(&connection->waitQueue);
+    traceWaitQueueLengthLocked(connection);
+
+    // The connection appears to be unrecoverably broken.
+    // Ignore already broken or zombie connections.
+    if (connection->status == Connection::STATUS_NORMAL) {
+        connection->status = Connection::STATUS_BROKEN;
+
+        if (notify) {
+            // Notify other system components.
+            onDispatchCycleBrokenLocked(currentTime, connection);
+        }
+    }
+}
+
+void InputDispatcher::drainDispatchQueueLocked(Queue<DispatchEntry>* queue) {
+    while (!queue->isEmpty()) {
+        DispatchEntry* dispatchEntry = queue->dequeueAtHead();
+        releaseDispatchEntryLocked(dispatchEntry);
+    }
+}
+
+void InputDispatcher::releaseDispatchEntryLocked(DispatchEntry* dispatchEntry) {
+    if (dispatchEntry->hasForegroundTarget()) {
+        decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
+    }
+    delete dispatchEntry;
+}
+
+int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
+    InputDispatcher* d = static_cast<InputDispatcher*>(data);
+
+    { // acquire lock
+        AutoMutex _l(d->mLock);
+
+        ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
+        if (connectionIndex < 0) {
+            ALOGE("Received spurious receive callback for unknown input channel.  "
+                    "fd=%d, events=0x%x", fd, events);
+            return 0; // remove the callback
+        }
+
+        bool notify;
+        sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
+        if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
+            if (!(events & ALOOPER_EVENT_INPUT)) {
+                ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
+                        "events=0x%x", connection->getInputChannelName(), events);
+                return 1;
+            }
+
+            nsecs_t currentTime = now();
+            bool gotOne = false;
+            status_t status;
+            for (;;) {
+                uint32_t seq;
+                bool handled;
+                status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
+                if (status) {
+                    break;
+                }
+                d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
+                gotOne = true;
+            }
+            if (gotOne) {
+                d->runCommandsLockedInterruptible();
+                if (status == WOULD_BLOCK) {
+                    return 1;
+                }
+            }
+
+            notify = status != DEAD_OBJECT || !connection->monitor;
+            if (notify) {
+                ALOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
+                        connection->getInputChannelName(), status);
+            }
+        } else {
+            // Monitor channels are never explicitly unregistered.
+            // We do it automatically when the remote endpoint is closed so don't warn
+            // about them.
+            notify = !connection->monitor;
+            if (notify) {
+                ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred.  "
+                        "events=0x%x", connection->getInputChannelName(), events);
+            }
+        }
+
+        // Unregister the channel.
+        d->unregisterInputChannelLocked(connection->inputChannel, notify);
+        return 0; // remove the callback
+    } // release lock
+}
+
+void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
+        const CancelationOptions& options) {
+    for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
+        synthesizeCancelationEventsForConnectionLocked(
+                mConnectionsByFd.valueAt(i), options);
+    }
+}
+
+void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
+        const sp<InputChannel>& channel, const CancelationOptions& options) {
+    ssize_t index = getConnectionIndexLocked(channel);
+    if (index >= 0) {
+        synthesizeCancelationEventsForConnectionLocked(
+                mConnectionsByFd.valueAt(index), options);
+    }
+}
+
+void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
+        const sp<Connection>& connection, const CancelationOptions& options) {
+    if (connection->status == Connection::STATUS_BROKEN) {
+        return;
+    }
+
+    nsecs_t currentTime = now();
+
+    Vector<EventEntry*> cancelationEvents;
+    connection->inputState.synthesizeCancelationEvents(currentTime,
+            cancelationEvents, options);
+
+    if (!cancelationEvents.isEmpty()) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+        ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
+                "with reality: %s, mode=%d.",
+                connection->getInputChannelName(), cancelationEvents.size(),
+                options.reason, options.mode);
+#endif
+        for (size_t i = 0; i < cancelationEvents.size(); i++) {
+            EventEntry* cancelationEventEntry = cancelationEvents.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;
+            }
+
+            InputTarget target;
+            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
+            if (windowHandle != NULL) {
+                const InputWindowInfo* windowInfo = windowHandle->getInfo();
+                target.xOffset = -windowInfo->frameLeft;
+                target.yOffset = -windowInfo->frameTop;
+                target.scaleFactor = windowInfo->scaleFactor;
+            } else {
+                target.xOffset = 0;
+                target.yOffset = 0;
+                target.scaleFactor = 1.0f;
+            }
+            target.inputChannel = connection->inputChannel;
+            target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
+
+            enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
+                    &target, InputTarget::FLAG_DISPATCH_AS_IS);
+
+            cancelationEventEntry->release();
+        }
+
+        startDispatchCycleLocked(currentTime, connection);
+    }
+}
+
+InputDispatcher::MotionEntry*
+InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
+    ALOG_ASSERT(pointerIds.value != 0);
+
+    uint32_t splitPointerIndexMap[MAX_POINTERS];
+    PointerProperties splitPointerProperties[MAX_POINTERS];
+    PointerCoords splitPointerCoords[MAX_POINTERS];
+
+    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
+    uint32_t splitPointerCount = 0;
+
+    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
+            originalPointerIndex++) {
+        const PointerProperties& pointerProperties =
+                originalMotionEntry->pointerProperties[originalPointerIndex];
+        uint32_t pointerId = uint32_t(pointerProperties.id);
+        if (pointerIds.hasBit(pointerId)) {
+            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
+            splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
+            splitPointerCoords[splitPointerCount].copyFrom(
+                    originalMotionEntry->pointerCoords[originalPointerIndex]);
+            splitPointerCount += 1;
+        }
+    }
+
+    if (splitPointerCount != pointerIds.count()) {
+        // This is bad.  We are missing some of the pointers that we expected to deliver.
+        // Most likely this indicates that we received an ACTION_MOVE events that has
+        // different pointer ids than we expected based on the previous ACTION_DOWN
+        // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
+        // in this way.
+        ALOGW("Dropping split motion event because the pointer count is %d but "
+                "we expected there to be %d pointers.  This probably means we received "
+                "a broken sequence of pointer ids from the input device.",
+                splitPointerCount, pointerIds.count());
+        return NULL;
+    }
+
+    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);
+        const PointerProperties& pointerProperties =
+                originalMotionEntry->pointerProperties[originalPointerIndex];
+        uint32_t pointerId = uint32_t(pointerProperties.id);
+        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 != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
+                    splitPointerIndex += 1;
+                }
+                action = maskedAction | (splitPointerIndex
+                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+            }
+        } else {
+            // An unrelated pointer changed.
+            action = AMOTION_EVENT_ACTION_MOVE;
+        }
+    }
+
+    MotionEntry* splitMotionEntry = new MotionEntry(
+            originalMotionEntry->eventTime,
+            originalMotionEntry->deviceId,
+            originalMotionEntry->source,
+            originalMotionEntry->policyFlags,
+            action,
+            originalMotionEntry->flags,
+            originalMotionEntry->metaState,
+            originalMotionEntry->buttonState,
+            originalMotionEntry->edgeFlags,
+            originalMotionEntry->xPrecision,
+            originalMotionEntry->yPrecision,
+            originalMotionEntry->downTime,
+            originalMotionEntry->displayId,
+            splitPointerCount, splitPointerProperties, splitPointerCoords);
+
+    if (originalMotionEntry->injectionState) {
+        splitMotionEntry->injectionState = originalMotionEntry->injectionState;
+        splitMotionEntry->injectionState->refCount += 1;
+    }
+
+    return splitMotionEntry;
+}
+
+void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
+#endif
+
+    bool needWake;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
+        needWake = enqueueInboundEventLocked(newEntry);
+    } // release lock
+
+    if (needWake) {
+        mLooper->wake();
+    }
+}
+
+void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
+            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
+            args->eventTime, args->deviceId, args->source, args->policyFlags,
+            args->action, args->flags, args->keyCode, args->scanCode,
+            args->metaState, args->downTime);
+#endif
+    if (!validateKeyEvent(args->action)) {
+        return;
+    }
+
+    uint32_t policyFlags = args->policyFlags;
+    int32_t flags = args->flags;
+    int32_t metaState = args->metaState;
+    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
+        policyFlags |= POLICY_FLAG_VIRTUAL;
+        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
+    }
+    if (policyFlags & POLICY_FLAG_ALT) {
+        metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
+    }
+    if (policyFlags & POLICY_FLAG_ALT_GR) {
+        metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
+    }
+    if (policyFlags & POLICY_FLAG_SHIFT) {
+        metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
+    }
+    if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
+        metaState |= AMETA_CAPS_LOCK_ON;
+    }
+    if (policyFlags & POLICY_FLAG_FUNCTION) {
+        metaState |= AMETA_FUNCTION_ON;
+    }
+
+    policyFlags |= POLICY_FLAG_TRUSTED;
+
+    KeyEvent event;
+    event.initialize(args->deviceId, args->source, args->action,
+            flags, args->keyCode, args->scanCode, metaState, 0,
+            args->downTime, args->eventTime);
+
+    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
+
+    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
+        flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+    }
+
+    bool needWake;
+    { // acquire lock
+        mLock.lock();
+
+        if (shouldSendKeyToInputFilterLocked(args)) {
+            mLock.unlock();
+
+            policyFlags |= POLICY_FLAG_FILTERED;
+            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
+                return; // event was consumed by the filter
+            }
+
+            mLock.lock();
+        }
+
+        int32_t repeatCount = 0;
+        KeyEntry* newEntry = new KeyEntry(args->eventTime,
+                args->deviceId, args->source, policyFlags,
+                args->action, flags, args->keyCode, args->scanCode,
+                metaState, repeatCount, args->downTime);
+
+        needWake = enqueueInboundEventLocked(newEntry);
+        mLock.unlock();
+    } // release lock
+
+    if (needWake) {
+        mLooper->wake();
+    }
+}
+
+bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
+    return mInputFilterEnabled;
+}
+
+void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
+            "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
+            "xPrecision=%f, yPrecision=%f, downTime=%lld",
+            args->eventTime, args->deviceId, args->source, args->policyFlags,
+            args->action, args->flags, args->metaState, args->buttonState,
+            args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
+    for (uint32_t i = 0; i < args->pointerCount; i++) {
+        ALOGD("  Pointer %d: id=%d, toolType=%d, "
+                "x=%f, y=%f, pressure=%f, size=%f, "
+                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
+                "orientation=%f",
+                i, args->pointerProperties[i].id,
+                args->pointerProperties[i].toolType,
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
+    }
+#endif
+    if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
+        return;
+    }
+
+    uint32_t policyFlags = args->policyFlags;
+    policyFlags |= POLICY_FLAG_TRUSTED;
+    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
+
+    bool needWake;
+    { // acquire lock
+        mLock.lock();
+
+        if (shouldSendMotionToInputFilterLocked(args)) {
+            mLock.unlock();
+
+            MotionEvent event;
+            event.initialize(args->deviceId, args->source, args->action, args->flags,
+                    args->edgeFlags, args->metaState, args->buttonState, 0, 0,
+                    args->xPrecision, args->yPrecision,
+                    args->downTime, args->eventTime,
+                    args->pointerCount, args->pointerProperties, args->pointerCoords);
+
+            policyFlags |= POLICY_FLAG_FILTERED;
+            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
+                return; // event was consumed by the filter
+            }
+
+            mLock.lock();
+        }
+
+        // Just enqueue a new motion event.
+        MotionEntry* newEntry = new MotionEntry(args->eventTime,
+                args->deviceId, args->source, policyFlags,
+                args->action, args->flags, args->metaState, args->buttonState,
+                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
+                args->displayId,
+                args->pointerCount, args->pointerProperties, args->pointerCoords);
+
+        needWake = enqueueInboundEventLocked(newEntry);
+        mLock.unlock();
+    } // release lock
+
+    if (needWake) {
+        mLooper->wake();
+    }
+}
+
+bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
+    // TODO: support sending secondary display events to input filter
+    return mInputFilterEnabled && isMainDisplay(args->displayId);
+}
+
+void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchValues=0x%08x, switchMask=0x%08x",
+            args->eventTime, args->policyFlags,
+            args->switchValues, args->switchMask);
+#endif
+
+    uint32_t policyFlags = args->policyFlags;
+    policyFlags |= POLICY_FLAG_TRUSTED;
+    mPolicy->notifySwitch(args->eventTime,
+            args->switchValues, args->switchMask, policyFlags);
+}
+
+void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
+            args->eventTime, args->deviceId);
+#endif
+
+    bool needWake;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
+        needWake = enqueueInboundEventLocked(newEntry);
+    } // release lock
+
+    if (needWake) {
+        mLooper->wake();
+    }
+}
+
+int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
+        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
+        uint32_t policyFlags) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
+            "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
+            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
+#endif
+
+    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
+
+    policyFlags |= POLICY_FLAG_INJECTED;
+    if (hasInjectionPermission(injectorPid, injectorUid)) {
+        policyFlags |= POLICY_FLAG_TRUSTED;
+    }
+
+    EventEntry* firstInjectedEntry;
+    EventEntry* lastInjectedEntry;
+    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;
+        }
+
+        int32_t flags = keyEvent->getFlags();
+        if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
+            policyFlags |= POLICY_FLAG_VIRTUAL;
+        }
+
+        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
+            mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
+        }
+
+        if (policyFlags & POLICY_FLAG_WOKE_HERE) {
+            flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+        }
+
+        mLock.lock();
+        firstInjectedEntry = new KeyEntry(keyEvent->getEventTime(),
+                keyEvent->getDeviceId(), keyEvent->getSource(),
+                policyFlags, action, flags,
+                keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
+                keyEvent->getRepeatCount(), keyEvent->getDownTime());
+        lastInjectedEntry = firstInjectedEntry;
+        break;
+    }
+
+    case AINPUT_EVENT_TYPE_MOTION: {
+        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
+        int32_t displayId = ADISPLAY_ID_DEFAULT;
+        int32_t action = motionEvent->getAction();
+        size_t pointerCount = motionEvent->getPointerCount();
+        const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
+        if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
+            return INPUT_EVENT_INJECTION_FAILED;
+        }
+
+        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
+            nsecs_t eventTime = motionEvent->getEventTime();
+            mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
+        }
+
+        mLock.lock();
+        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
+        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
+        firstInjectedEntry = new MotionEntry(*sampleEventTimes,
+                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+                action, motionEvent->getFlags(),
+                motionEvent->getMetaState(), motionEvent->getButtonState(),
+                motionEvent->getEdgeFlags(),
+                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
+                motionEvent->getDownTime(), displayId,
+                uint32_t(pointerCount), pointerProperties, samplePointerCoords);
+        lastInjectedEntry = firstInjectedEntry;
+        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
+            sampleEventTimes += 1;
+            samplePointerCoords += pointerCount;
+            MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
+                    motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+                    action, motionEvent->getFlags(),
+                    motionEvent->getMetaState(), motionEvent->getButtonState(),
+                    motionEvent->getEdgeFlags(),
+                    motionEvent->getXPrecision(), motionEvent->getYPrecision(),
+                    motionEvent->getDownTime(), displayId,
+                    uint32_t(pointerCount), pointerProperties, samplePointerCoords);
+            lastInjectedEntry->next = nextInjectedEntry;
+            lastInjectedEntry = nextInjectedEntry;
+        }
+        break;
+    }
+
+    default:
+        ALOGW("Cannot inject event of type %d", event->getType());
+        return INPUT_EVENT_INJECTION_FAILED;
+    }
+
+    InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
+    if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+        injectionState->injectionIsAsync = true;
+    }
+
+    injectionState->refCount += 1;
+    lastInjectedEntry->injectionState = injectionState;
+
+    bool needWake = false;
+    for (EventEntry* entry = firstInjectedEntry; entry != NULL; ) {
+        EventEntry* nextEntry = entry->next;
+        needWake |= enqueueInboundEventLocked(entry);
+        entry = nextEntry;
+    }
+
+    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
+                    ALOGD("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
+                    ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
+                            injectionState->pendingForegroundDispatches);
+#endif
+                    nsecs_t remainingTimeout = endTime - now();
+                    if (remainingTimeout <= 0) {
+#if DEBUG_INJECTION
+                    ALOGD("injectInputEvent - Timed out waiting for pending foreground "
+                            "dispatches to finish.");
+#endif
+                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
+                        break;
+                    }
+
+                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
+                }
+            }
+        }
+
+        injectionState->release();
+    } // release lock
+
+#if DEBUG_INJECTION
+    ALOGD("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
+        ALOGD("Setting input event injection result to %d.  "
+                "injectorPid=%d, injectorUid=%d",
+                 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
+#endif
+
+        if (injectionState->injectionIsAsync
+                && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
+            // Log the outcome since the injector did not wait for the injection result.
+            switch (injectionResult) {
+            case INPUT_EVENT_INJECTION_SUCCEEDED:
+                ALOGV("Asynchronous input event injection succeeded.");
+                break;
+            case INPUT_EVENT_INJECTION_FAILED:
+                ALOGW("Asynchronous input event injection failed.");
+                break;
+            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+                ALOGW("Asynchronous input event injection permission denied.");
+                break;
+            case INPUT_EVENT_INJECTION_TIMED_OUT:
+                ALOGW("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();
+        }
+    }
+}
+
+sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
+        const sp<InputChannel>& inputChannel) const {
+    size_t numWindows = mWindowHandles.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
+        if (windowHandle->getInputChannel() == inputChannel) {
+            return windowHandle;
+        }
+    }
+    return NULL;
+}
+
+bool InputDispatcher::hasWindowHandleLocked(
+        const sp<InputWindowHandle>& windowHandle) const {
+    size_t numWindows = mWindowHandles.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        if (mWindowHandles.itemAt(i) == windowHandle) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
+#if DEBUG_FOCUS
+    ALOGD("setInputWindows");
+#endif
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
+        mWindowHandles = inputWindowHandles;
+
+        sp<InputWindowHandle> newFocusedWindowHandle;
+        bool foundHoveredWindow = false;
+        for (size_t i = 0; i < mWindowHandles.size(); i++) {
+            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
+            if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
+                mWindowHandles.removeAt(i--);
+                continue;
+            }
+            if (windowHandle->getInfo()->hasFocus) {
+                newFocusedWindowHandle = windowHandle;
+            }
+            if (windowHandle == mLastHoverWindowHandle) {
+                foundHoveredWindow = true;
+            }
+        }
+
+        if (!foundHoveredWindow) {
+            mLastHoverWindowHandle = NULL;
+        }
+
+        if (mFocusedWindowHandle != newFocusedWindowHandle) {
+            if (mFocusedWindowHandle != NULL) {
+#if DEBUG_FOCUS
+                ALOGD("Focus left window: %s",
+                        mFocusedWindowHandle->getName().string());
+#endif
+                sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
+                if (focusedInputChannel != NULL) {
+                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
+                            "focus left window");
+                    synthesizeCancelationEventsForInputChannelLocked(
+                            focusedInputChannel, options);
+                }
+            }
+            if (newFocusedWindowHandle != NULL) {
+#if DEBUG_FOCUS
+                ALOGD("Focus entered window: %s",
+                        newFocusedWindowHandle->getName().string());
+#endif
+            }
+            mFocusedWindowHandle = newFocusedWindowHandle;
+        }
+
+        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
+            TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
+            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
+#if DEBUG_FOCUS
+                ALOGD("Touched window was removed: %s",
+                        touchedWindow.windowHandle->getName().string());
+#endif
+                sp<InputChannel> touchedInputChannel =
+                        touchedWindow.windowHandle->getInputChannel();
+                if (touchedInputChannel != NULL) {
+                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+                            "touched window was removed");
+                    synthesizeCancelationEventsForInputChannelLocked(
+                            touchedInputChannel, options);
+                }
+                mTouchState.windows.removeAt(i--);
+            }
+        }
+
+        // Release information for windows that are no longer present.
+        // This ensures that unused input channels are released promptly.
+        // Otherwise, they might stick around until the window handle is destroyed
+        // which might not happen until the next GC.
+        for (size_t i = 0; i < oldWindowHandles.size(); i++) {
+            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
+            if (!hasWindowHandleLocked(oldWindowHandle)) {
+#if DEBUG_FOCUS
+                ALOGD("Window went away: %s", oldWindowHandle->getName().string());
+#endif
+                oldWindowHandle->releaseInfo();
+            }
+        }
+    } // release lock
+
+    // Wake up poll loop since it may need to make new input dispatching choices.
+    mLooper->wake();
+}
+
+void InputDispatcher::setFocusedApplication(
+        const sp<InputApplicationHandle>& inputApplicationHandle) {
+#if DEBUG_FOCUS
+    ALOGD("setFocusedApplication");
+#endif
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
+            if (mFocusedApplicationHandle != inputApplicationHandle) {
+                if (mFocusedApplicationHandle != NULL) {
+                    resetANRTimeoutsLocked();
+                    mFocusedApplicationHandle->releaseInfo();
+                }
+                mFocusedApplicationHandle = inputApplicationHandle;
+            }
+        } else if (mFocusedApplicationHandle != NULL) {
+            resetANRTimeoutsLocked();
+            mFocusedApplicationHandle->releaseInfo();
+            mFocusedApplicationHandle.clear();
+        }
+
+#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::setInputDispatchMode(bool enabled, bool frozen) {
+#if DEBUG_FOCUS
+    ALOGD("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::setInputFilterEnabled(bool enabled) {
+#if DEBUG_FOCUS
+    ALOGD("setInputFilterEnabled: enabled=%d", enabled);
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (mInputFilterEnabled == enabled) {
+            return;
+        }
+
+        mInputFilterEnabled = enabled;
+        resetAndDropEverythingLocked("input filter is being enabled or disabled");
+    } // release lock
+
+    // Wake up poll loop since there might be work to do to drop everything.
+    mLooper->wake();
+}
+
+bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
+        const sp<InputChannel>& toChannel) {
+#if DEBUG_FOCUS
+    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
+            fromChannel->getName().string(), toChannel->getName().string());
+#endif
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
+        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
+        if (fromWindowHandle == NULL || toWindowHandle == NULL) {
+#if DEBUG_FOCUS
+            ALOGD("Cannot transfer focus because from or to window not found.");
+#endif
+            return false;
+        }
+        if (fromWindowHandle == toWindowHandle) {
+#if DEBUG_FOCUS
+            ALOGD("Trivial transfer to same window.");
+#endif
+            return true;
+        }
+        if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
+#if DEBUG_FOCUS
+            ALOGD("Cannot transfer focus because windows are on different displays.");
+#endif
+            return false;
+        }
+
+        bool found = false;
+        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
+            const TouchedWindow& touchedWindow = mTouchState.windows[i];
+            if (touchedWindow.windowHandle == fromWindowHandle) {
+                int32_t oldTargetFlags = touchedWindow.targetFlags;
+                BitSet32 pointerIds = touchedWindow.pointerIds;
+
+                mTouchState.windows.removeAt(i);
+
+                int32_t newTargetFlags = oldTargetFlags
+                        & (InputTarget::FLAG_FOREGROUND
+                                | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
+                mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
+
+                found = true;
+                break;
+            }
+        }
+
+        if (! found) {
+#if DEBUG_FOCUS
+            ALOGD("Focus transfer failed because from window did not have focus.");
+#endif
+            return false;
+        }
+
+        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
+        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
+        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
+            sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
+            sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
+
+            fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
+            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+                    "transferring touch focus from this window to another window");
+            synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
+        }
+
+#if DEBUG_FOCUS
+        logDispatchStateLocked();
+#endif
+    } // release lock
+
+    // Wake up poll loop since it may need to make new input dispatching choices.
+    mLooper->wake();
+    return true;
+}
+
+void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
+#if DEBUG_FOCUS
+    ALOGD("Resetting and dropping all events (%s).", reason);
+#endif
+
+    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
+    synthesizeCancelationEventsForAllConnectionsLocked(options);
+
+    resetKeyRepeatLocked();
+    releasePendingEventLocked();
+    drainInboundQueueLocked();
+    resetANRTimeoutsLocked();
+
+    mTouchState.reset();
+    mLastHoverWindowHandle.clear();
+}
+
+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';
+        }
+        ALOGD("%s", start);
+        start = end;
+    }
+}
+
+void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
+    dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
+    dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
+
+    if (mFocusedApplicationHandle != NULL) {
+        dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
+                mFocusedApplicationHandle->getName().string(),
+                mFocusedApplicationHandle->getDispatchingTimeout(
+                        DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
+    } else {
+        dump.append(INDENT "FocusedApplication: <null>\n");
+    }
+    dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
+            mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
+
+    dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
+    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
+    dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
+    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
+    dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId);
+    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.windowHandle->getName().string(),
+                    touchedWindow.pointerIds.value,
+                    touchedWindow.targetFlags);
+        }
+    } else {
+        dump.append(INDENT "TouchedWindows: <none>\n");
+    }
+
+    if (!mWindowHandles.isEmpty()) {
+        dump.append(INDENT "Windows:\n");
+        for (size_t i = 0; i < mWindowHandles.size(); i++) {
+            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
+            const InputWindowInfo* windowInfo = windowHandle->getInfo();
+
+            dump.appendFormat(INDENT2 "%d: name='%s', displayId=%d, "
+                    "paused=%s, hasFocus=%s, hasWallpaper=%s, "
+                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
+                    "frame=[%d,%d][%d,%d], scale=%f, "
+                    "touchableRegion=",
+                    i, windowInfo->name.string(), windowInfo->displayId,
+                    toString(windowInfo->paused),
+                    toString(windowInfo->hasFocus),
+                    toString(windowInfo->hasWallpaper),
+                    toString(windowInfo->visible),
+                    toString(windowInfo->canReceiveKeys),
+                    windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
+                    windowInfo->layer,
+                    windowInfo->frameLeft, windowInfo->frameTop,
+                    windowInfo->frameRight, windowInfo->frameBottom,
+                    windowInfo->scaleFactor);
+            dumpRegion(dump, windowInfo->touchableRegion);
+            dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
+            dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
+                    windowInfo->ownerPid, windowInfo->ownerUid,
+                    windowInfo->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");
+    }
+
+    nsecs_t currentTime = now();
+
+    // Dump recently dispatched or dropped events from oldest to newest.
+    if (!mRecentQueue.isEmpty()) {
+        dump.appendFormat(INDENT "RecentQueue: length=%u\n", mRecentQueue.count());
+        for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) {
+            dump.append(INDENT2);
+            entry->appendDescription(dump);
+            dump.appendFormat(", age=%0.1fms\n",
+                    (currentTime - entry->eventTime) * 0.000001f);
+        }
+    } else {
+        dump.append(INDENT "RecentQueue: <empty>\n");
+    }
+
+    // Dump event currently being dispatched.
+    if (mPendingEvent) {
+        dump.append(INDENT "PendingEvent:\n");
+        dump.append(INDENT2);
+        mPendingEvent->appendDescription(dump);
+        dump.appendFormat(", age=%0.1fms\n",
+                (currentTime - mPendingEvent->eventTime) * 0.000001f);
+    } else {
+        dump.append(INDENT "PendingEvent: <none>\n");
+    }
+
+    // Dump inbound events from oldest to newest.
+    if (!mInboundQueue.isEmpty()) {
+        dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
+        for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
+            dump.append(INDENT2);
+            entry->appendDescription(dump);
+            dump.appendFormat(", age=%0.1fms\n",
+                    (currentTime - entry->eventTime) * 0.000001f);
+        }
+    } else {
+        dump.append(INDENT "InboundQueue: <empty>\n");
+    }
+
+    if (!mConnectionsByFd.isEmpty()) {
+        dump.append(INDENT "Connections:\n");
+        for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
+            const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
+            dump.appendFormat(INDENT2 "%d: channelName='%s', windowName='%s', "
+                    "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
+                    i, connection->getInputChannelName(), connection->getWindowName(),
+                    connection->getStatusLabel(), toString(connection->monitor),
+                    toString(connection->inputPublisherBlocked));
+
+            if (!connection->outboundQueue.isEmpty()) {
+                dump.appendFormat(INDENT3 "OutboundQueue: length=%u\n",
+                        connection->outboundQueue.count());
+                for (DispatchEntry* entry = connection->outboundQueue.head; entry;
+                        entry = entry->next) {
+                    dump.append(INDENT4);
+                    entry->eventEntry->appendDescription(dump);
+                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
+                            entry->targetFlags, entry->resolvedAction,
+                            (currentTime - entry->eventEntry->eventTime) * 0.000001f);
+                }
+            } else {
+                dump.append(INDENT3 "OutboundQueue: <empty>\n");
+            }
+
+            if (!connection->waitQueue.isEmpty()) {
+                dump.appendFormat(INDENT3 "WaitQueue: length=%u\n",
+                        connection->waitQueue.count());
+                for (DispatchEntry* entry = connection->waitQueue.head; entry;
+                        entry = entry->next) {
+                    dump.append(INDENT4);
+                    entry->eventEntry->appendDescription(dump);
+                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
+                            "age=%0.1fms, wait=%0.1fms\n",
+                            entry->targetFlags, entry->resolvedAction,
+                            (currentTime - entry->eventEntry->eventTime) * 0.000001f,
+                            (currentTime - entry->deliveryTime) * 0.000001f);
+                }
+            } else {
+                dump.append(INDENT3 "WaitQueue: <empty>\n");
+            }
+        }
+    } else {
+        dump.append(INDENT "Connections: <none>\n");
+    }
+
+    if (isAppSwitchPendingLocked()) {
+        dump.appendFormat(INDENT "AppSwitch: pending, due in %0.1fms\n",
+                (mAppSwitchDueTime - now()) / 1000000.0);
+    } else {
+        dump.append(INDENT "AppSwitch: not pending\n");
+    }
+
+    dump.append(INDENT "Configuration:\n");
+    dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n",
+            mConfig.keyRepeatDelay * 0.000001f);
+    dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
+            mConfig.keyRepeatTimeout * 0.000001f);
+}
+
+status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
+        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
+#if DEBUG_REGISTRATION
+    ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
+            toString(monitor));
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (getConnectionIndexLocked(inputChannel) >= 0) {
+            ALOGW("Attempted to register already registered input channel '%s'",
+                    inputChannel->getName().string());
+            return BAD_VALUE;
+        }
+
+        sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
+
+        int fd = inputChannel->getFd();
+        mConnectionsByFd.add(fd, connection);
+
+        if (monitor) {
+            mMonitoringChannels.push(inputChannel);
+        }
+
+        mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
+    } // release lock
+
+    // Wake the looper because some connections have changed.
+    mLooper->wake();
+    return OK;
+}
+
+status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
+#if DEBUG_REGISTRATION
+    ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
+        if (status) {
+            return status;
+        }
+    } // release lock
+
+    // Wake the poll loop because removing the connection may have changed the current
+    // synchronization state.
+    mLooper->wake();
+    return OK;
+}
+
+status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
+        bool notify) {
+    ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
+    if (connectionIndex < 0) {
+        ALOGW("Attempted to unregister already unregistered input channel '%s'",
+                inputChannel->getName().string());
+        return BAD_VALUE;
+    }
+
+    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
+    mConnectionsByFd.removeItemsAt(connectionIndex);
+
+    if (connection->monitor) {
+        removeMonitorChannelLocked(inputChannel);
+    }
+
+    mLooper->removeFd(inputChannel->getFd());
+
+    nsecs_t currentTime = now();
+    abortBrokenDispatchCycleLocked(currentTime, connection, notify);
+
+    connection->status = Connection::STATUS_ZOMBIE;
+    return OK;
+}
+
+void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
+    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+         if (mMonitoringChannels[i] == inputChannel) {
+             mMonitoringChannels.removeAt(i);
+             break;
+         }
+    }
+}
+
+ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
+    ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
+    if (connectionIndex >= 0) {
+        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
+        if (connection->inputChannel.get() == inputChannel.get()) {
+            return connectionIndex;
+        }
+    }
+
+    return -1;
+}
+
+void InputDispatcher::onDispatchCycleFinishedLocked(
+        nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
+    commandEntry->connection = connection;
+    commandEntry->eventTime = currentTime;
+    commandEntry->seq = seq;
+    commandEntry->handled = handled;
+}
+
+void InputDispatcher::onDispatchCycleBrokenLocked(
+        nsecs_t currentTime, const sp<Connection>& connection) {
+    ALOGE("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 sp<InputApplicationHandle>& applicationHandle,
+        const sp<InputWindowHandle>& windowHandle,
+        nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
+    float dispatchLatency = (currentTime - eventTime) * 0.000001f;
+    float waitDuration = (currentTime - waitStartTime) * 0.000001f;
+    ALOGI("Application is not responding: %s.  "
+            "It has been %0.1fms since event, %0.1fms since wait started.  Reason: %s",
+            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
+            dispatchLatency, waitDuration, reason);
+
+    // Capture a record of the InputDispatcher state at the time of the ANR.
+    time_t t = time(NULL);
+    struct tm tm;
+    localtime_r(&t, &tm);
+    char timestr[64];
+    strftime(timestr, sizeof(timestr), "%F %T", &tm);
+    mLastANRState.clear();
+    mLastANRState.append(INDENT "ANR:\n");
+    mLastANRState.appendFormat(INDENT2 "Time: %s\n", timestr);
+    mLastANRState.appendFormat(INDENT2 "Window: %s\n",
+            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
+    mLastANRState.appendFormat(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
+    mLastANRState.appendFormat(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
+    mLastANRState.appendFormat(INDENT2 "Reason: %s\n", reason);
+    dumpDispatchStateLocked(mLastANRState);
+
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doNotifyANRLockedInterruptible);
+    commandEntry->inputApplicationHandle = applicationHandle;
+    commandEntry->inputWindowHandle = windowHandle;
+    commandEntry->reason = reason;
+}
+
+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->inputWindowHandle);
+
+        mLock.lock();
+    }
+}
+
+void InputDispatcher::doNotifyANRLockedInterruptible(
+        CommandEntry* commandEntry) {
+    mLock.unlock();
+
+    nsecs_t newTimeout = mPolicy->notifyANR(
+            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle,
+            commandEntry->reason);
+
+    mLock.lock();
+
+    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
+            commandEntry->inputWindowHandle != NULL
+                    ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
+}
+
+void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
+        CommandEntry* commandEntry) {
+    KeyEntry* entry = commandEntry->keyEntry;
+
+    KeyEvent event;
+    initializeKeyEvent(&event, entry);
+
+    mLock.unlock();
+
+    nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
+            &event, entry->policyFlags);
+
+    mLock.lock();
+
+    if (delay < 0) {
+        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
+    } else if (!delay) {
+        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
+    } else {
+        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
+        entry->interceptKeyWakeupTime = now() + delay;
+    }
+    entry->release();
+}
+
+void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
+        CommandEntry* commandEntry) {
+    sp<Connection> connection = commandEntry->connection;
+    nsecs_t finishTime = commandEntry->eventTime;
+    uint32_t seq = commandEntry->seq;
+    bool handled = commandEntry->handled;
+
+    // Handle post-event policy actions.
+    DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
+    if (dispatchEntry) {
+        nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
+        if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
+            String8 msg;
+            msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
+                    connection->getWindowName(), eventDuration * 0.000001f);
+            dispatchEntry->eventEntry->appendDescription(msg);
+            ALOGI("%s", msg.string());
+        }
+
+        bool restartEvent;
+        if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
+            KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
+            restartEvent = afterKeyEventLockedInterruptible(connection,
+                    dispatchEntry, keyEntry, handled);
+        } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
+            MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
+            restartEvent = afterMotionEventLockedInterruptible(connection,
+                    dispatchEntry, motionEntry, handled);
+        } else {
+            restartEvent = false;
+        }
+
+        // Dequeue the event and start the next cycle.
+        // Note that because the lock might have been released, it is possible that the
+        // contents of the wait queue to have been drained, so we need to double-check
+        // a few things.
+        if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
+            connection->waitQueue.dequeue(dispatchEntry);
+            traceWaitQueueLengthLocked(connection);
+            if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
+                connection->outboundQueue.enqueueAtHead(dispatchEntry);
+                traceOutboundQueueLengthLocked(connection);
+            } else {
+                releaseDispatchEntryLocked(dispatchEntry);
+            }
+        }
+
+        // Start the next dispatch cycle for this connection.
+        startDispatchCycleLocked(now(), connection);
+    }
+}
+
+bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
+        DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
+    if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
+        // Get the fallback key state.
+        // Clear it out after dispatching the UP.
+        int32_t originalKeyCode = keyEntry->keyCode;
+        int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
+        if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
+            connection->inputState.removeFallbackKey(originalKeyCode);
+        }
+
+        if (handled || !dispatchEntry->hasForegroundTarget()) {
+            // If the application handles the original key for which we previously
+            // generated a fallback or if the window is not a foreground window,
+            // then cancel the associated fallback key, if any.
+            if (fallbackKeyCode != -1) {
+                // Dispatch the unhandled key to the policy with the cancel flag.
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+                ALOGD("Unhandled key event: Asking policy to cancel fallback action.  "
+                        "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
+                        keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
+                        keyEntry->policyFlags);
+#endif
+                KeyEvent event;
+                initializeKeyEvent(&event, keyEntry);
+                event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
+
+                mLock.unlock();
+
+                mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
+                        &event, keyEntry->policyFlags, &event);
+
+                mLock.lock();
+
+                // Cancel the fallback key.
+                if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
+                    CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
+                            "application handled the original non-fallback key "
+                            "or is no longer a foreground target, "
+                            "canceling previously dispatched fallback key");
+                    options.keyCode = fallbackKeyCode;
+                    synthesizeCancelationEventsForConnectionLocked(connection, options);
+                }
+                connection->inputState.removeFallbackKey(originalKeyCode);
+            }
+        } else {
+            // If the application did not handle a non-fallback key, first check
+            // that we are in a good state to perform unhandled key event processing
+            // Then ask the policy what to do with it.
+            bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
+                    && keyEntry->repeatCount == 0;
+            if (fallbackKeyCode == -1 && !initialDown) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+                ALOGD("Unhandled key event: Skipping unhandled key event processing "
+                        "since this is not an initial down.  "
+                        "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
+                        originalKeyCode, keyEntry->action, keyEntry->repeatCount,
+                        keyEntry->policyFlags);
+#endif
+                return false;
+            }
+
+            // Dispatch the unhandled key to the policy.
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+            ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
+                    "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
+                    keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
+                    keyEntry->policyFlags);
+#endif
+            KeyEvent event;
+            initializeKeyEvent(&event, keyEntry);
+
+            mLock.unlock();
+
+            bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
+                    &event, keyEntry->policyFlags, &event);
+
+            mLock.lock();
+
+            if (connection->status != Connection::STATUS_NORMAL) {
+                connection->inputState.removeFallbackKey(originalKeyCode);
+                return false;
+            }
+
+            // Latch the fallback keycode for this key on an initial down.
+            // The fallback keycode cannot change at any other point in the lifecycle.
+            if (initialDown) {
+                if (fallback) {
+                    fallbackKeyCode = event.getKeyCode();
+                } else {
+                    fallbackKeyCode = AKEYCODE_UNKNOWN;
+                }
+                connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
+            }
+
+            ALOG_ASSERT(fallbackKeyCode != -1);
+
+            // Cancel the fallback key if the policy decides not to send it anymore.
+            // We will continue to dispatch the key to the policy but we will no
+            // longer dispatch a fallback key to the application.
+            if (fallbackKeyCode != AKEYCODE_UNKNOWN
+                    && (!fallback || fallbackKeyCode != event.getKeyCode())) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+                if (fallback) {
+                    ALOGD("Unhandled key event: Policy requested to send key %d"
+                            "as a fallback for %d, but on the DOWN it had requested "
+                            "to send %d instead.  Fallback canceled.",
+                            event.getKeyCode(), originalKeyCode, fallbackKeyCode);
+                } else {
+                    ALOGD("Unhandled key event: Policy did not request fallback for %d, "
+                            "but on the DOWN it had requested to send %d.  "
+                            "Fallback canceled.",
+                            originalKeyCode, fallbackKeyCode);
+                }
+#endif
+
+                CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
+                        "canceling fallback, policy no longer desires it");
+                options.keyCode = fallbackKeyCode;
+                synthesizeCancelationEventsForConnectionLocked(connection, options);
+
+                fallback = false;
+                fallbackKeyCode = AKEYCODE_UNKNOWN;
+                if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
+                    connection->inputState.setFallbackKey(originalKeyCode,
+                            fallbackKeyCode);
+                }
+            }
+
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+            {
+                String8 msg;
+                const KeyedVector<int32_t, int32_t>& fallbackKeys =
+                        connection->inputState.getFallbackKeys();
+                for (size_t i = 0; i < fallbackKeys.size(); i++) {
+                    msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
+                            fallbackKeys.valueAt(i));
+                }
+                ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
+                        fallbackKeys.size(), msg.string());
+            }
+#endif
+
+            if (fallback) {
+                // Restart the dispatch cycle using the fallback key.
+                keyEntry->eventTime = event.getEventTime();
+                keyEntry->deviceId = event.getDeviceId();
+                keyEntry->source = event.getSource();
+                keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
+                keyEntry->keyCode = fallbackKeyCode;
+                keyEntry->scanCode = event.getScanCode();
+                keyEntry->metaState = event.getMetaState();
+                keyEntry->repeatCount = event.getRepeatCount();
+                keyEntry->downTime = event.getDownTime();
+                keyEntry->syntheticRepeat = false;
+
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+                ALOGD("Unhandled key event: Dispatching fallback key.  "
+                        "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
+                        originalKeyCode, fallbackKeyCode, keyEntry->metaState);
+#endif
+                return true; // restart the event
+            } else {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+                ALOGD("Unhandled key event: No fallback key.");
+#endif
+            }
+        }
+    }
+    return false;
+}
+
+bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
+        DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
+    return false;
+}
+
+void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
+    mLock.unlock();
+
+    mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
+
+    mLock.lock();
+}
+
+void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
+    event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
+            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
+            entry->downTime, entry->eventTime);
+}
+
+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::traceInboundQueueLengthLocked() {
+    if (ATRACE_ENABLED()) {
+        ATRACE_INT("iq", mInboundQueue.count());
+    }
+}
+
+void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
+    if (ATRACE_ENABLED()) {
+        char counterName[40];
+        snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName());
+        ATRACE_INT(counterName, connection->outboundQueue.count());
+    }
+}
+
+void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
+    if (ATRACE_ENABLED()) {
+        char counterName[40];
+        snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName());
+        ATRACE_INT(counterName, connection->waitQueue.count());
+    }
+}
+
+void InputDispatcher::dump(String8& dump) {
+    AutoMutex _l(mLock);
+
+    dump.append("Input Dispatcher State:\n");
+    dumpDispatchStateLocked(dump);
+
+    if (!mLastANRState.isEmpty()) {
+        dump.append("\nInput Dispatcher State at time of last ANR:\n");
+        dump.append(mLastANRState);
+    }
+}
+
+void InputDispatcher::monitor() {
+    // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
+    mLock.lock();
+    mLooper->wake();
+    mDispatcherIsAliveCondition.wait(mLock);
+    mLock.unlock();
+}
+
+
+// --- InputDispatcher::Queue ---
+
+template <typename T>
+uint32_t InputDispatcher::Queue<T>::count() const {
+    uint32_t result = 0;
+    for (const T* entry = head; entry; entry = entry->next) {
+        result += 1;
+    }
+    return result;
+}
+
+
+// --- InputDispatcher::InjectionState ---
+
+InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
+        refCount(1),
+        injectorPid(injectorPid), injectorUid(injectorUid),
+        injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
+        pendingForegroundDispatches(0) {
+}
+
+InputDispatcher::InjectionState::~InjectionState() {
+}
+
+void InputDispatcher::InjectionState::release() {
+    refCount -= 1;
+    if (refCount == 0) {
+        delete this;
+    } else {
+        ALOG_ASSERT(refCount > 0);
+    }
+}
+
+
+// --- InputDispatcher::EventEntry ---
+
+InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
+        refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
+        injectionState(NULL), dispatchInProgress(false) {
+}
+
+InputDispatcher::EventEntry::~EventEntry() {
+    releaseInjectionState();
+}
+
+void InputDispatcher::EventEntry::release() {
+    refCount -= 1;
+    if (refCount == 0) {
+        delete this;
+    } else {
+        ALOG_ASSERT(refCount > 0);
+    }
+}
+
+void InputDispatcher::EventEntry::releaseInjectionState() {
+    if (injectionState) {
+        injectionState->release();
+        injectionState = NULL;
+    }
+}
+
+
+// --- InputDispatcher::ConfigurationChangedEntry ---
+
+InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
+        EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
+}
+
+InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
+}
+
+void InputDispatcher::ConfigurationChangedEntry::appendDescription(String8& msg) const {
+    msg.append("ConfigurationChangedEvent(), policyFlags=0x%08x",
+            policyFlags);
+}
+
+
+// --- InputDispatcher::DeviceResetEntry ---
+
+InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
+        EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
+        deviceId(deviceId) {
+}
+
+InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
+}
+
+void InputDispatcher::DeviceResetEntry::appendDescription(String8& msg) const {
+    msg.appendFormat("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
+            deviceId, policyFlags);
+}
+
+
+// --- InputDispatcher::KeyEntry ---
+
+InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
+        int32_t deviceId, uint32_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) :
+        EventEntry(TYPE_KEY, eventTime, policyFlags),
+        deviceId(deviceId), source(source), action(action), flags(flags),
+        keyCode(keyCode), scanCode(scanCode), metaState(metaState),
+        repeatCount(repeatCount), downTime(downTime),
+        syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
+        interceptKeyWakeupTime(0) {
+}
+
+InputDispatcher::KeyEntry::~KeyEntry() {
+}
+
+void InputDispatcher::KeyEntry::appendDescription(String8& msg) const {
+    msg.appendFormat("KeyEvent(deviceId=%d, source=0x%08x, action=%d, "
+            "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
+            "repeatCount=%d), policyFlags=0x%08x",
+            deviceId, source, action, flags, keyCode, scanCode, metaState,
+            repeatCount, policyFlags);
+}
+
+void InputDispatcher::KeyEntry::recycle() {
+    releaseInjectionState();
+
+    dispatchInProgress = false;
+    syntheticRepeat = false;
+    interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+    interceptKeyWakeupTime = 0;
+}
+
+
+// --- InputDispatcher::MotionEntry ---
+
+InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
+        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
+        int32_t metaState, int32_t buttonState,
+        int32_t edgeFlags, float xPrecision, float yPrecision,
+        nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
+        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
+        EventEntry(TYPE_MOTION, eventTime, policyFlags),
+        eventTime(eventTime),
+        deviceId(deviceId), source(source), action(action), flags(flags),
+        metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
+        xPrecision(xPrecision), yPrecision(yPrecision),
+        downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        this->pointerProperties[i].copyFrom(pointerProperties[i]);
+        this->pointerCoords[i].copyFrom(pointerCoords[i]);
+    }
+}
+
+InputDispatcher::MotionEntry::~MotionEntry() {
+}
+
+void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
+    msg.appendFormat("MotionEvent(deviceId=%d, source=0x%08x, action=%d, "
+            "flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, edgeFlags=0x%08x, "
+            "xPrecision=%.1f, yPrecision=%.1f, displayId=%d, pointers=[",
+            deviceId, source, action, flags, metaState, buttonState, edgeFlags,
+            xPrecision, yPrecision, displayId);
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        if (i) {
+            msg.append(", ");
+        }
+        msg.appendFormat("%d: (%.1f, %.1f)", pointerProperties[i].id,
+                pointerCoords[i].getX(), pointerCoords[i].getY());
+    }
+    msg.appendFormat("]), policyFlags=0x%08x", policyFlags);
+}
+
+
+// --- InputDispatcher::DispatchEntry ---
+
+volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
+
+InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
+        int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
+        seq(nextSeq()),
+        eventEntry(eventEntry), targetFlags(targetFlags),
+        xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
+        deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
+    eventEntry->refCount += 1;
+}
+
+InputDispatcher::DispatchEntry::~DispatchEntry() {
+    eventEntry->release();
+}
+
+uint32_t InputDispatcher::DispatchEntry::nextSeq() {
+    // Sequence number 0 is reserved and will never be returned.
+    uint32_t seq;
+    do {
+        seq = android_atomic_inc(&sNextSeqAtomic);
+    } while (!seq);
+    return seq;
+}
+
+
+// --- InputDispatcher::InputState ---
+
+InputDispatcher::InputState::InputState() {
+}
+
+InputDispatcher::InputState::~InputState() {
+}
+
+bool InputDispatcher::InputState::isNeutral() const {
+    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
+}
+
+bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
+        int32_t displayId) const {
+    for (size_t i = 0; i < mMotionMementos.size(); i++) {
+        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        if (memento.deviceId == deviceId
+                && memento.source == source
+                && memento.displayId == displayId
+                && memento.hovering) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
+        int32_t action, int32_t flags) {
+    switch (action) {
+    case AKEY_EVENT_ACTION_UP: {
+        if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
+            for (size_t i = 0; i < mFallbackKeys.size(); ) {
+                if (mFallbackKeys.valueAt(i) == entry->keyCode) {
+                    mFallbackKeys.removeItemsAt(i);
+                } else {
+                    i += 1;
+                }
+            }
+        }
+        ssize_t index = findKeyMemento(entry);
+        if (index >= 0) {
+            mKeyMementos.removeAt(index);
+            return true;
+        }
+        /* FIXME: We can't just drop the key up event because that prevents creating
+         * popup windows that are automatically shown when a key is held and then
+         * dismissed when the key is released.  The problem is that the popup will
+         * not have received the original key down, so the key up will be considered
+         * to be inconsistent with its observed state.  We could perhaps handle this
+         * by synthesizing a key down but that will cause other problems.
+         *
+         * So for now, allow inconsistent key up events to be dispatched.
+         *
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+        ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
+                "keyCode=%d, scanCode=%d",
+                entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
+#endif
+        return false;
+        */
+        return true;
+    }
+
+    case AKEY_EVENT_ACTION_DOWN: {
+        ssize_t index = findKeyMemento(entry);
+        if (index >= 0) {
+            mKeyMementos.removeAt(index);
+        }
+        addKeyMemento(entry, flags);
+        return true;
+    }
+
+    default:
+        return true;
+    }
+}
+
+bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
+        int32_t action, int32_t flags) {
+    int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
+    switch (actionMasked) {
+    case AMOTION_EVENT_ACTION_UP:
+    case AMOTION_EVENT_ACTION_CANCEL: {
+        ssize_t index = findMotionMemento(entry, false /*hovering*/);
+        if (index >= 0) {
+            mMotionMementos.removeAt(index);
+            return true;
+        }
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+        ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
+                "actionMasked=%d",
+                entry->deviceId, entry->source, actionMasked);
+#endif
+        return false;
+    }
+
+    case AMOTION_EVENT_ACTION_DOWN: {
+        ssize_t index = findMotionMemento(entry, false /*hovering*/);
+        if (index >= 0) {
+            mMotionMementos.removeAt(index);
+        }
+        addMotionMemento(entry, flags, false /*hovering*/);
+        return true;
+    }
+
+    case AMOTION_EVENT_ACTION_POINTER_UP:
+    case AMOTION_EVENT_ACTION_POINTER_DOWN:
+    case AMOTION_EVENT_ACTION_MOVE: {
+        ssize_t index = findMotionMemento(entry, false /*hovering*/);
+        if (index >= 0) {
+            MotionMemento& memento = mMotionMementos.editItemAt(index);
+            memento.setPointers(entry);
+            return true;
+        }
+        if (actionMasked == AMOTION_EVENT_ACTION_MOVE
+                && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
+                        | AINPUT_SOURCE_CLASS_NAVIGATION))) {
+            // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
+            return true;
+        }
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+        ALOGD("Dropping inconsistent motion pointer up/down or move event: "
+                "deviceId=%d, source=%08x, actionMasked=%d",
+                entry->deviceId, entry->source, actionMasked);
+#endif
+        return false;
+    }
+
+    case AMOTION_EVENT_ACTION_HOVER_EXIT: {
+        ssize_t index = findMotionMemento(entry, true /*hovering*/);
+        if (index >= 0) {
+            mMotionMementos.removeAt(index);
+            return true;
+        }
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+        ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
+                entry->deviceId, entry->source);
+#endif
+        return false;
+    }
+
+    case AMOTION_EVENT_ACTION_HOVER_ENTER:
+    case AMOTION_EVENT_ACTION_HOVER_MOVE: {
+        ssize_t index = findMotionMemento(entry, true /*hovering*/);
+        if (index >= 0) {
+            mMotionMementos.removeAt(index);
+        }
+        addMotionMemento(entry, flags, true /*hovering*/);
+        return true;
+    }
+
+    default:
+        return true;
+    }
+}
+
+ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
+    for (size_t i = 0; i < mKeyMementos.size(); i++) {
+        const KeyMemento& memento = mKeyMementos.itemAt(i);
+        if (memento.deviceId == entry->deviceId
+                && memento.source == entry->source
+                && memento.keyCode == entry->keyCode
+                && memento.scanCode == entry->scanCode) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
+        bool hovering) const {
+    for (size_t i = 0; i < mMotionMementos.size(); i++) {
+        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        if (memento.deviceId == entry->deviceId
+                && memento.source == entry->source
+                && memento.displayId == entry->displayId
+                && memento.hovering == hovering) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
+    mKeyMementos.push();
+    KeyMemento& memento = mKeyMementos.editTop();
+    memento.deviceId = entry->deviceId;
+    memento.source = entry->source;
+    memento.keyCode = entry->keyCode;
+    memento.scanCode = entry->scanCode;
+    memento.metaState = entry->metaState;
+    memento.flags = flags;
+    memento.downTime = entry->downTime;
+    memento.policyFlags = entry->policyFlags;
+}
+
+void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
+        int32_t flags, bool hovering) {
+    mMotionMementos.push();
+    MotionMemento& memento = mMotionMementos.editTop();
+    memento.deviceId = entry->deviceId;
+    memento.source = entry->source;
+    memento.flags = flags;
+    memento.xPrecision = entry->xPrecision;
+    memento.yPrecision = entry->yPrecision;
+    memento.downTime = entry->downTime;
+    memento.displayId = entry->displayId;
+    memento.setPointers(entry);
+    memento.hovering = hovering;
+    memento.policyFlags = entry->policyFlags;
+}
+
+void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
+    pointerCount = entry->pointerCount;
+    for (uint32_t i = 0; i < entry->pointerCount; i++) {
+        pointerProperties[i].copyFrom(entry->pointerProperties[i]);
+        pointerCoords[i].copyFrom(entry->pointerCoords[i]);
+    }
+}
+
+void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
+        Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
+    for (size_t i = 0; i < mKeyMementos.size(); i++) {
+        const KeyMemento& memento = mKeyMementos.itemAt(i);
+        if (shouldCancelKey(memento, options)) {
+            outEvents.push(new KeyEntry(currentTime,
+                    memento.deviceId, memento.source, memento.policyFlags,
+                    AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
+                    memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
+        }
+    }
+
+    for (size_t i = 0; i < mMotionMementos.size(); i++) {
+        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        if (shouldCancelMotion(memento, options)) {
+            outEvents.push(new MotionEntry(currentTime,
+                    memento.deviceId, memento.source, memento.policyFlags,
+                    memento.hovering
+                            ? AMOTION_EVENT_ACTION_HOVER_EXIT
+                            : AMOTION_EVENT_ACTION_CANCEL,
+                    memento.flags, 0, 0, 0,
+                    memento.xPrecision, memento.yPrecision, memento.downTime,
+                    memento.displayId,
+                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
+        }
+    }
+}
+
+void InputDispatcher::InputState::clear() {
+    mKeyMementos.clear();
+    mMotionMementos.clear();
+    mFallbackKeys.clear();
+}
+
+void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
+    for (size_t i = 0; i < mMotionMementos.size(); i++) {
+        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
+            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
+                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
+                if (memento.deviceId == otherMemento.deviceId
+                        && memento.source == otherMemento.source
+                        && memento.displayId == otherMemento.displayId) {
+                    other.mMotionMementos.removeAt(j);
+                } else {
+                    j += 1;
+                }
+            }
+            other.mMotionMementos.push(memento);
+        }
+    }
+}
+
+int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
+    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
+    return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
+}
+
+void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
+        int32_t fallbackKeyCode) {
+    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
+    if (index >= 0) {
+        mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
+    } else {
+        mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
+    }
+}
+
+void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
+    mFallbackKeys.removeItem(originalKeyCode);
+}
+
+bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
+        const CancelationOptions& options) {
+    if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
+        return false;
+    }
+
+    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
+        return false;
+    }
+
+    switch (options.mode) {
+    case CancelationOptions::CANCEL_ALL_EVENTS:
+    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
+        return true;
+    case CancelationOptions::CANCEL_FALLBACK_EVENTS:
+        return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
+    default:
+        return false;
+    }
+}
+
+bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
+        const CancelationOptions& options) {
+    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
+        return false;
+    }
+
+    switch (options.mode) {
+    case CancelationOptions::CANCEL_ALL_EVENTS:
+        return true;
+    case CancelationOptions::CANCEL_POINTER_EVENTS:
+        return memento.source & AINPUT_SOURCE_CLASS_POINTER;
+    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
+        return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
+    default:
+        return false;
+    }
+}
+
+
+// --- InputDispatcher::Connection ---
+
+InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
+        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
+        status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
+        monitor(monitor),
+        inputPublisher(inputChannel), inputPublisherBlocked(false) {
+}
+
+InputDispatcher::Connection::~Connection() {
+}
+
+const char* InputDispatcher::Connection::getWindowName() const {
+    if (inputWindowHandle != NULL) {
+        return inputWindowHandle->getName().string();
+    }
+    if (monitor) {
+        return "monitor";
+    }
+    return "?";
+}
+
+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::findWaitQueueEntry(uint32_t seq) {
+    for (DispatchEntry* entry = waitQueue.head; entry != NULL; entry = entry->next) {
+        if (entry->seq == seq) {
+            return entry;
+        }
+    }
+    return NULL;
+}
+
+
+// --- InputDispatcher::CommandEntry ---
+
+InputDispatcher::CommandEntry::CommandEntry(Command command) :
+    command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0),
+    seq(0), handled(false) {
+}
+
+InputDispatcher::CommandEntry::~CommandEntry() {
+}
+
+
+// --- InputDispatcher::TouchState ---
+
+InputDispatcher::TouchState::TouchState() :
+    down(false), split(false), deviceId(-1), source(0), displayId(-1) {
+}
+
+InputDispatcher::TouchState::~TouchState() {
+}
+
+void InputDispatcher::TouchState::reset() {
+    down = false;
+    split = false;
+    deviceId = -1;
+    source = 0;
+    displayId = -1;
+    windows.clear();
+}
+
+void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
+    down = other.down;
+    split = other.split;
+    deviceId = other.deviceId;
+    source = other.source;
+    displayId = other.displayId;
+    windows = other.windows;
+}
+
+void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
+        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.windowHandle == windowHandle) {
+            touchedWindow.targetFlags |= targetFlags;
+            if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
+                touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
+            }
+            touchedWindow.pointerIds.value |= pointerIds.value;
+            return;
+        }
+    }
+
+    windows.push();
+
+    TouchedWindow& touchedWindow = windows.editTop();
+    touchedWindow.windowHandle = windowHandle;
+    touchedWindow.targetFlags = targetFlags;
+    touchedWindow.pointerIds = pointerIds;
+}
+
+void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
+    for (size_t i = 0; i < windows.size(); i++) {
+        if (windows.itemAt(i).windowHandle == windowHandle) {
+            windows.removeAt(i);
+            return;
+        }
+    }
+}
+
+void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
+    for (size_t i = 0 ; i < windows.size(); ) {
+        TouchedWindow& window = windows.editItemAt(i);
+        if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
+                | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
+            window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
+            window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
+            i += 1;
+        } else {
+            windows.removeAt(i);
+        }
+    }
+}
+
+sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
+    for (size_t i = 0; i < windows.size(); i++) {
+        const TouchedWindow& window = windows.itemAt(i);
+        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
+            return window.windowHandle;
+        }
+    }
+    return NULL;
+}
+
+bool InputDispatcher::TouchState::isSlippery() const {
+    // Must have exactly one foreground window.
+    bool haveSlipperyForegroundWindow = false;
+    for (size_t i = 0; i < windows.size(); i++) {
+        const TouchedWindow& window = windows.itemAt(i);
+        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
+            if (haveSlipperyForegroundWindow
+                    || !(window.windowHandle->getInfo()->layoutParamsFlags
+                            & InputWindowInfo::FLAG_SLIPPERY)) {
+                return false;
+            }
+            haveSlipperyForegroundWindow = true;
+        }
+    }
+    return haveSlipperyForegroundWindow;
+}
+
+
+// --- 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/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
new file mode 100644
index 0000000..190e7b2
--- /dev/null
+++ b/services/inputflinger/InputDispatcher.h
@@ -0,0 +1,1123 @@
+/*
+ * 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 <input/Input.h>
+#include <input/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/BitSet.h>
+#include <cutils/atomic.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include "InputWindow.h"
+#include "InputApplication.h"
+#include "InputListener.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 = 1 << 0,
+
+        /* 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 = 1 << 1,
+
+        /* This flag indicates that a motion event is being split across multiple windows. */
+        FLAG_SPLIT = 1 << 2,
+
+        /* This flag indicates that the pointer coordinates dispatched to the application
+         * will be zeroed out to avoid revealing information to an application. This is
+         * used in conjunction with FLAG_DISPATCH_AS_OUTSIDE to prevent apps not sharing
+         * the same UID from watching all touches. */
+        FLAG_ZERO_COORDS = 1 << 3,
+
+        /* This flag indicates that the event should be sent as is.
+         * Should always be set unless the event is to be transmuted. */
+        FLAG_DISPATCH_AS_IS = 1 << 8,
+
+        /* 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_DISPATCH_AS_OUTSIDE = 1 << 9,
+
+        /* This flag indicates that a hover sequence is starting in the given window.
+         * The event is transmuted into ACTION_HOVER_ENTER. */
+        FLAG_DISPATCH_AS_HOVER_ENTER = 1 << 10,
+
+        /* This flag indicates that a hover event happened outside of a window which handled
+         * previous hover events, signifying the end of the current hover sequence for that
+         * window.
+         * The event is transmuted into ACTION_HOVER_ENTER. */
+        FLAG_DISPATCH_AS_HOVER_EXIT = 1 << 11,
+
+        /* This flag indicates that the event should be canceled.
+         * It is used to transmute ACTION_MOVE into ACTION_CANCEL when a touch slips
+         * outside of a window. */
+        FLAG_DISPATCH_AS_SLIPPERY_EXIT = 1 << 12,
+
+        /* This flag indicates that the event should be dispatched as an initial down.
+         * It is used to transmute ACTION_MOVE into ACTION_DOWN when a touch slips
+         * into a new window. */
+        FLAG_DISPATCH_AS_SLIPPERY_ENTER = 1 << 13,
+
+        /* Mask for all dispatch modes. */
+        FLAG_DISPATCH_MASK = FLAG_DISPATCH_AS_IS
+                | FLAG_DISPATCH_AS_OUTSIDE
+                | FLAG_DISPATCH_AS_HOVER_ENTER
+                | FLAG_DISPATCH_AS_HOVER_EXIT
+                | FLAG_DISPATCH_AS_SLIPPERY_EXIT
+                | FLAG_DISPATCH_AS_SLIPPERY_ENTER,
+    };
+
+    // 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;
+
+    // Scaling factor to apply to MotionEvent as it is delivered.
+    // (ignored for KeyEvents)
+    float scaleFactor;
+
+    // The subset of pointer ids to include in motion events dispatched to this input target
+    // if FLAG_SPLIT is set.
+    BitSet32 pointerIds;
+};
+
+
+/*
+ * Input dispatcher configuration.
+ *
+ * Specifies various options that modify the behavior of the input dispatcher.
+ * The values provided here are merely defaults. The actual values will come from ViewConfiguration
+ * and are passed into the dispatcher during initialization.
+ */
+struct InputDispatcherConfiguration {
+    // The key repeat initial timeout.
+    nsecs_t keyRepeatTimeout;
+
+    // The key repeat inter-key delay.
+    nsecs_t keyRepeatDelay;
+
+    InputDispatcherConfiguration() :
+            keyRepeatTimeout(500 * 1000000LL),
+            keyRepeatDelay(50 * 1000000LL) { }
+};
+
+
+/*
+ * 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<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) = 0;
+
+    /* Notifies the system that an input channel is unrecoverably broken. */
+    virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
+
+    /* Gets the input dispatcher configuration. */
+    virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) = 0;
+
+    /* Returns true if automatic key repeating is enabled. */
+    virtual bool isKeyRepeatEnabled() = 0;
+
+    /* Filters an input event.
+     * Return true to dispatch the event unmodified, false to consume the event.
+     * A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED
+     * to injectInputEvent.
+     */
+    virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) = 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(const KeyEvent* keyEvent, uint32_t& policyFlags) = 0;
+
+    /* Intercepts a touch, trackball or other motion 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 interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
+
+    /* Allows the policy a chance to intercept a key before dispatching. */
+    virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
+            const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
+
+    /* Allows the policy a chance to perform default processing for an unhandled key.
+     * Returns an alternate keycode to redispatch as a fallback, or 0 to give up. */
+    virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
+            const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) = 0;
+
+    /* Notifies the policy about switch events.
+     */
+    virtual void notifySwitch(nsecs_t when,
+            uint32_t switchValues, uint32_t switchMask, 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, public InputListenerInterface {
+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;
+
+    /* Called by the heatbeat to ensures that the dispatcher has not deadlocked. */
+    virtual void monitor() = 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;
+
+    /* 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,
+            uint32_t policyFlags) = 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<sp<InputWindowHandle> >& inputWindowHandles) = 0;
+
+    /* Sets the focused application.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void setFocusedApplication(
+            const sp<InputApplicationHandle>& inputApplicationHandle) = 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;
+
+    /* Sets whether input event filtering is enabled.
+     * When enabled, incoming input events are sent to the policy's filterInputEvent
+     * method instead of being dispatched.  The filter is expected to use
+     * injectInputEvent to inject the events it would like to have dispatched.
+     * It should include POLICY_FLAG_FILTERED in the policy flags during injection.
+     */
+    virtual void setInputFilterEnabled(bool enabled) = 0;
+
+    /* Transfers touch focus from the window associated with one channel to the
+     * window associated with the other channel.
+     *
+     * Returns true on success.  False if the window did not actually have touch focus.
+     */
+    virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
+            const sp<InputChannel>& toChannel) = 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,
+            const sp<InputWindowHandle>& inputWindowHandle, 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 monitor();
+
+    virtual void dispatchOnce();
+
+    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
+    virtual void notifyKey(const NotifyKeyArgs* args);
+    virtual void notifyMotion(const NotifyMotionArgs* args);
+    virtual void notifySwitch(const NotifySwitchArgs* args);
+    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
+
+    virtual int32_t injectInputEvent(const InputEvent* event,
+            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
+            uint32_t policyFlags);
+
+    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
+    virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
+    virtual void setInputDispatchMode(bool enabled, bool frozen);
+    virtual void setInputFilterEnabled(bool enabled);
+
+    virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
+            const sp<InputChannel>& toChannel);
+
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
+            const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+private:
+    template <typename T>
+    struct Link {
+        T* next;
+        T* prev;
+
+    protected:
+        inline Link() : next(NULL), prev(NULL) { }
+    };
+
+    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
+
+        InjectionState(int32_t injectorPid, int32_t injectorUid);
+        void release();
+
+    private:
+        ~InjectionState();
+    };
+
+    struct EventEntry : Link<EventEntry> {
+        enum {
+            TYPE_CONFIGURATION_CHANGED,
+            TYPE_DEVICE_RESET,
+            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() const { return injectionState != NULL; }
+
+        void release();
+
+        virtual void appendDescription(String8& msg) const = 0;
+
+    protected:
+        EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
+        virtual ~EventEntry();
+        void releaseInjectionState();
+    };
+
+    struct ConfigurationChangedEntry : EventEntry {
+        ConfigurationChangedEntry(nsecs_t eventTime);
+        virtual void appendDescription(String8& msg) const;
+
+    protected:
+        virtual ~ConfigurationChangedEntry();
+    };
+
+    struct DeviceResetEntry : EventEntry {
+        int32_t deviceId;
+
+        DeviceResetEntry(nsecs_t eventTime, int32_t deviceId);
+        virtual void appendDescription(String8& msg) const;
+
+    protected:
+        virtual ~DeviceResetEntry();
+    };
+
+    struct KeyEntry : EventEntry {
+        int32_t deviceId;
+        uint32_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,
+            INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
+        };
+        InterceptKeyResult interceptKeyResult; // set based on the interception result
+        nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
+
+        KeyEntry(nsecs_t eventTime,
+                int32_t deviceId, uint32_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);
+        virtual void appendDescription(String8& msg) const;
+        void recycle();
+
+    protected:
+        virtual ~KeyEntry();
+    };
+
+    struct MotionEntry : EventEntry {
+        nsecs_t eventTime;
+        int32_t deviceId;
+        uint32_t source;
+        int32_t action;
+        int32_t flags;
+        int32_t metaState;
+        int32_t buttonState;
+        int32_t edgeFlags;
+        float xPrecision;
+        float yPrecision;
+        nsecs_t downTime;
+        int32_t displayId;
+        uint32_t pointerCount;
+        PointerProperties pointerProperties[MAX_POINTERS];
+        PointerCoords pointerCoords[MAX_POINTERS];
+
+        MotionEntry(nsecs_t eventTime,
+                int32_t deviceId, uint32_t source, uint32_t policyFlags,
+                int32_t action, int32_t flags,
+                int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+                float xPrecision, float yPrecision,
+                nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
+                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
+        virtual void appendDescription(String8& msg) const;
+
+    protected:
+        virtual ~MotionEntry();
+    };
+
+    // Tracks the progress of dispatching a particular event to a particular connection.
+    struct DispatchEntry : Link<DispatchEntry> {
+        const uint32_t seq; // unique sequence number, never 0
+
+        EventEntry* eventEntry; // the event to dispatch
+        int32_t targetFlags;
+        float xOffset;
+        float yOffset;
+        float scaleFactor;
+        nsecs_t deliveryTime; // time when the event was actually delivered
+
+        // Set to the resolved action and flags when the event is enqueued.
+        int32_t resolvedAction;
+        int32_t resolvedFlags;
+
+        DispatchEntry(EventEntry* eventEntry,
+                int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
+        ~DispatchEntry();
+
+        inline bool hasForegroundTarget() const {
+            return targetFlags & InputTarget::FLAG_FOREGROUND;
+        }
+
+        inline bool isSplit() const {
+            return targetFlags & InputTarget::FLAG_SPLIT;
+        }
+
+    private:
+        static volatile int32_t sNextSeqAtomic;
+
+        static uint32_t nextSeq();
+    };
+
+    // 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(Command command);
+        ~CommandEntry();
+
+        Command command;
+
+        // parameters for the command (usage varies by command)
+        sp<Connection> connection;
+        nsecs_t eventTime;
+        KeyEntry* keyEntry;
+        sp<InputApplicationHandle> inputApplicationHandle;
+        sp<InputWindowHandle> inputWindowHandle;
+        String8 reason;
+        int32_t userActivityEventType;
+        uint32_t seq;
+        bool handled;
+    };
+
+    // Generic queue implementation.
+    template <typename T>
+    struct Queue {
+        T* head;
+        T* tail;
+
+        inline Queue() : head(NULL), tail(NULL) {
+        }
+
+        inline bool isEmpty() const {
+            return !head;
+        }
+
+        inline void enqueueAtTail(T* entry) {
+            entry->prev = tail;
+            if (tail) {
+                tail->next = entry;
+            } else {
+                head = entry;
+            }
+            entry->next = NULL;
+            tail = entry;
+        }
+
+        inline void enqueueAtHead(T* entry) {
+            entry->next = head;
+            if (head) {
+                head->prev = entry;
+            } else {
+                tail = entry;
+            }
+            entry->prev = NULL;
+            head = entry;
+        }
+
+        inline void dequeue(T* entry) {
+            if (entry->prev) {
+                entry->prev->next = entry->next;
+            } else {
+                head = entry->next;
+            }
+            if (entry->next) {
+                entry->next->prev = entry->prev;
+            } else {
+                tail = entry->prev;
+            }
+        }
+
+        inline T* dequeueAtHead() {
+            T* entry = head;
+            head = entry->next;
+            if (head) {
+                head->prev = NULL;
+            } else {
+                tail = NULL;
+            }
+            return entry;
+        }
+
+        uint32_t count() const;
+    };
+
+    /* Specifies which events are to be canceled and why. */
+    struct CancelationOptions {
+        enum Mode {
+            CANCEL_ALL_EVENTS = 0,
+            CANCEL_POINTER_EVENTS = 1,
+            CANCEL_NON_POINTER_EVENTS = 2,
+            CANCEL_FALLBACK_EVENTS = 3,
+        };
+
+        // The criterion to use to determine which events should be canceled.
+        Mode mode;
+
+        // Descriptive reason for the cancelation.
+        const char* reason;
+
+        // The specific keycode of the key event to cancel, or -1 to cancel any key event.
+        int32_t keyCode;
+
+        // The specific device id of events to cancel, or -1 to cancel events from any device.
+        int32_t deviceId;
+
+        CancelationOptions(Mode mode, const char* reason) :
+                mode(mode), reason(reason), keyCode(-1), deviceId(-1) { }
+    };
+
+    /* Tracks dispatched key and motion event state so that cancelation events can be
+     * synthesized when events are dropped. */
+    class InputState {
+    public:
+        InputState();
+        ~InputState();
+
+        // Returns true if there is no state to be canceled.
+        bool isNeutral() const;
+
+        // Returns true if the specified source is known to have received a hover enter
+        // motion event.
+        bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;
+
+        // Records tracking information for a key event that has just been published.
+        // Returns true if the event should be delivered, false if it is inconsistent
+        // and should be skipped.
+        bool trackKey(const KeyEntry* entry, int32_t action, int32_t flags);
+
+        // Records tracking information for a motion event that has just been published.
+        // Returns true if the event should be delivered, false if it is inconsistent
+        // and should be skipped.
+        bool trackMotion(const MotionEntry* entry, int32_t action, int32_t flags);
+
+        // Synthesizes cancelation events for the current state and resets the tracked state.
+        void synthesizeCancelationEvents(nsecs_t currentTime,
+                Vector<EventEntry*>& outEvents, const CancelationOptions& options);
+
+        // Clears the current state.
+        void clear();
+
+        // Copies pointer-related parts of the input state to another instance.
+        void copyPointerStateTo(InputState& other) const;
+
+        // Gets the fallback key associated with a keycode.
+        // Returns -1 if none.
+        // Returns AKEYCODE_UNKNOWN if we are only dispatching the unhandled key to the policy.
+        int32_t getFallbackKey(int32_t originalKeyCode);
+
+        // Sets the fallback key for a particular keycode.
+        void setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode);
+
+        // Removes the fallback key for a particular keycode.
+        void removeFallbackKey(int32_t originalKeyCode);
+
+        inline const KeyedVector<int32_t, int32_t>& getFallbackKeys() const {
+            return mFallbackKeys;
+        }
+
+    private:
+        struct KeyMemento {
+            int32_t deviceId;
+            uint32_t source;
+            int32_t keyCode;
+            int32_t scanCode;
+            int32_t metaState;
+            int32_t flags;
+            nsecs_t downTime;
+            uint32_t policyFlags;
+        };
+
+        struct MotionMemento {
+            int32_t deviceId;
+            uint32_t source;
+            int32_t flags;
+            float xPrecision;
+            float yPrecision;
+            nsecs_t downTime;
+            int32_t displayId;
+            uint32_t pointerCount;
+            PointerProperties pointerProperties[MAX_POINTERS];
+            PointerCoords pointerCoords[MAX_POINTERS];
+            bool hovering;
+            uint32_t policyFlags;
+
+            void setPointers(const MotionEntry* entry);
+        };
+
+        Vector<KeyMemento> mKeyMementos;
+        Vector<MotionMemento> mMotionMementos;
+        KeyedVector<int32_t, int32_t> mFallbackKeys;
+
+        ssize_t findKeyMemento(const KeyEntry* entry) const;
+        ssize_t findMotionMemento(const MotionEntry* entry, bool hovering) const;
+
+        void addKeyMemento(const KeyEntry* entry, int32_t flags);
+        void addMotionMemento(const MotionEntry* entry, int32_t flags, bool hovering);
+
+        static bool shouldCancelKey(const KeyMemento& memento,
+                const CancelationOptions& options);
+        static bool shouldCancelMotion(const MotionMemento& memento,
+                const 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; // never null
+        sp<InputWindowHandle> inputWindowHandle; // may be null
+        bool monitor;
+        InputPublisher inputPublisher;
+        InputState inputState;
+
+        // True if the socket is full and no further events can be published until
+        // the application consumes some of the input.
+        bool inputPublisherBlocked;
+
+        // Queue of events that need to be published to the connection.
+        Queue<DispatchEntry> outboundQueue;
+
+        // Queue of events that have been published to the connection but that have not
+        // yet received a "finished" response from the application.
+        Queue<DispatchEntry> waitQueue;
+
+        explicit Connection(const sp<InputChannel>& inputChannel,
+                const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
+
+        inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
+
+        const char* getWindowName() const;
+        const char* getStatusLabel() const;
+
+        DispatchEntry* findWaitQueueEntry(uint32_t seq);
+    };
+
+    enum DropReason {
+        DROP_REASON_NOT_DROPPED = 0,
+        DROP_REASON_POLICY = 1,
+        DROP_REASON_APP_SWITCH = 2,
+        DROP_REASON_DISABLED = 3,
+        DROP_REASON_BLOCKED = 4,
+        DROP_REASON_STALE = 5,
+    };
+
+    sp<InputDispatcherPolicyInterface> mPolicy;
+    InputDispatcherConfiguration mConfig;
+
+    Mutex mLock;
+
+    Condition mDispatcherIsAliveCondition;
+
+    sp<Looper> mLooper;
+
+    EventEntry* mPendingEvent;
+    Queue<EventEntry> mInboundQueue;
+    Queue<EventEntry> mRecentQueue;
+    Queue<CommandEntry> mCommandQueue;
+
+    void dispatchOnceInnerLocked(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);
+
+    // Adds an event to a queue of recent events for debugging purposes.
+    void addRecentEventLocked(EventEntry* entry);
+
+    // 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);
+
+    // Stale event latency optimization.
+    static bool isStaleEventLocked(nsecs_t currentTime, EventEntry* entry);
+
+    // Blocked event latency optimization.  Drops old events when the user intends
+    // to transfer focus to a new application.
+    EventEntry* mNextUnblockedEvent;
+
+    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y);
+
+    // All registered connections mapped by channel file descriptor.
+    KeyedVector<int, sp<Connection> > mConnectionsByFd;
+
+    ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel);
+
+    // Input channels that will receive a copy of all input events.
+    Vector<sp<InputChannel> > mMonitoringChannels;
+
+    // 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);
+
+    // Key repeat tracking.
+    struct KeyRepeatState {
+        KeyEntry* lastKeyEntry; // or null if no repeat
+        nsecs_t nextRepeatTime;
+    } mKeyRepeatState;
+
+    void resetKeyRepeatLocked();
+    KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime);
+
+    // Deferred command processing.
+    bool haveCommandsLocked() const;
+    bool runCommandsLockedInterruptible();
+    CommandEntry* postCommandLocked(Command command);
+
+    // Input filter processing.
+    bool shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args);
+    bool shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args);
+
+    // Inbound event processing.
+    void drainInboundQueueLocked();
+    void releasePendingEventLocked();
+    void releaseInboundEventLocked(EventEntry* entry);
+
+    // Dispatch state.
+    bool mDispatchEnabled;
+    bool mDispatchFrozen;
+    bool mInputFilterEnabled;
+
+    Vector<sp<InputWindowHandle> > mWindowHandles;
+
+    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
+    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
+
+    // Focus tracking for keys, trackball, etc.
+    sp<InputWindowHandle> mFocusedWindowHandle;
+
+    // Focus tracking for touch.
+    struct TouchedWindow {
+        sp<InputWindowHandle> windowHandle;
+        int32_t targetFlags;
+        BitSet32 pointerIds;        // zero unless target flag FLAG_SPLIT is set
+    };
+    struct TouchState {
+        bool down;
+        bool split;
+        int32_t deviceId; // id of the device that is currently down, others are rejected
+        uint32_t source;  // source of the device that is current down, others are rejected
+        int32_t displayId; // id to the display that currently has a touch, others are rejected
+        Vector<TouchedWindow> windows;
+
+        TouchState();
+        ~TouchState();
+        void reset();
+        void copyFrom(const TouchState& other);
+        void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
+                int32_t targetFlags, BitSet32 pointerIds);
+        void removeWindow(const sp<InputWindowHandle>& windowHandle);
+        void filterNonAsIsTouchWindows();
+        sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
+        bool isSlippery() const;
+    };
+
+    TouchState mTouchState;
+    TouchState mTempTouchState;
+
+    // Focused application.
+    sp<InputApplicationHandle> mFocusedApplicationHandle;
+
+    // Dispatcher state at time of last ANR.
+    String8 mLastANRState;
+
+    // Dispatch inbound events.
+    bool dispatchConfigurationChangedLocked(
+            nsecs_t currentTime, ConfigurationChangedEntry* entry);
+    bool dispatchDeviceResetLocked(
+            nsecs_t currentTime, DeviceResetEntry* entry);
+    bool dispatchKeyLocked(
+            nsecs_t currentTime, KeyEntry* entry,
+            DropReason* dropReason, nsecs_t* nextWakeupTime);
+    bool dispatchMotionLocked(
+            nsecs_t currentTime, MotionEntry* entry,
+            DropReason* dropReason, nsecs_t* nextWakeupTime);
+    void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
+            const Vector<InputTarget>& inputTargets);
+
+    void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
+    void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
+
+    // Keeping track of ANR timeouts.
+    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;
+    sp<InputApplicationHandle> mInputTargetWaitApplicationHandle;
+
+    // Contains the last window which received a hover event.
+    sp<InputWindowHandle> mLastHoverWindowHandle;
+
+    // Finding targets for input events.
+    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
+            const sp<InputApplicationHandle>& applicationHandle,
+            const sp<InputWindowHandle>& windowHandle,
+            nsecs_t* nextWakeupTime, const char* reason);
+    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,
+            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime);
+    int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
+            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
+            bool* outConflictingPointerActions);
+
+    void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
+            int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets);
+    void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets);
+
+    void pokeUserActivityLocked(const EventEntry* eventEntry);
+    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
+            const InjectionState* injectionState);
+    bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
+            int32_t x, int32_t y) const;
+    bool isWindowReadyForMoreInputLocked(nsecs_t currentTime,
+            const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry);
+    String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
+            const sp<InputWindowHandle>& windowHandle);
+
+    // 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);
+    void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
+            EventEntry* eventEntry, const InputTarget* inputTarget);
+    void enqueueDispatchEntryLocked(const sp<Connection>& connection,
+            EventEntry* eventEntry, const InputTarget* inputTarget, int32_t dispatchMode);
+    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
+    void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
+            uint32_t seq, bool handled);
+    void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
+            bool notify);
+    void drainDispatchQueueLocked(Queue<DispatchEntry>* queue);
+    void releaseDispatchEntryLocked(DispatchEntry* dispatchEntry);
+    static int handleReceiveCallback(int fd, int events, void* data);
+
+    void synthesizeCancelationEventsForAllConnectionsLocked(
+            const CancelationOptions& options);
+    void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
+            const CancelationOptions& options);
+    void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
+            const CancelationOptions& options);
+
+    // 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();
+
+    // Registration.
+    void removeMonitorChannelLocked(const sp<InputChannel>& inputChannel);
+    status_t unregisterInputChannelLocked(const sp<InputChannel>& inputChannel, bool notify);
+
+    // 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 onDispatchCycleFinishedLocked(
+            nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled);
+    void onDispatchCycleBrokenLocked(
+            nsecs_t currentTime, const sp<Connection>& connection);
+    void onANRLocked(
+            nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
+            const sp<InputWindowHandle>& windowHandle,
+            nsecs_t eventTime, nsecs_t waitStartTime, const char* reason);
+
+    // Outbound policy interactions.
+    void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
+    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
+    void doNotifyANRLockedInterruptible(CommandEntry* commandEntry);
+    void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry);
+    void doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry);
+    bool afterKeyEventLockedInterruptible(const sp<Connection>& connection,
+            DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled);
+    bool afterMotionEventLockedInterruptible(const sp<Connection>& connection,
+            DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled);
+    void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry);
+    void initializeKeyEvent(KeyEvent* event, const KeyEntry* entry);
+
+    // Statistics gathering.
+    void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
+            int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
+    void traceInboundQueueLengthLocked();
+    void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
+    void traceWaitQueueLengthLocked(const sp<Connection>& connection);
+};
+
+/* 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/services/inputflinger/InputFlinger.cpp b/services/inputflinger/InputFlinger.cpp
new file mode 100644
index 0000000..9ea6ce5
--- /dev/null
+++ b/services/inputflinger/InputFlinger.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 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 "InputFlinger"
+
+#include "InputFlinger.h"
+
+#include <stdint.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
+#include <cutils/log.h>
+#include <private/android_filesystem_config.h>
+
+namespace android {
+
+const String16 sAccessInputFlingerPermission("android.permission.ACCESS_INPUT_FLINGER");
+const String16 sDumpPermission("android.permission.DUMP");
+
+
+InputFlinger::InputFlinger() :
+        BnInputFlinger() {
+    ALOGI("InputFlinger is starting");
+}
+
+InputFlinger::~InputFlinger() {
+}
+
+status_t InputFlinger::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    switch (code) {
+    case DO_SOMETHING_TRANSACTION:
+        const IPCThreadState* ipc = IPCThreadState::self();
+        const int pid = ipc->getCallingPid();
+        const int uid = ipc->getCallingUid();
+        if (!PermissionCache::checkPermission(sAccessInputFlingerPermission, pid, uid)) {
+            ALOGE("Permission Denial: "
+                    "can't access InputFlinger from pid=%d, uid=%d", pid, uid);
+            return PERMISSION_DENIED;
+        }
+        break;
+    }
+
+    return BnInputFlinger::onTransact(code, data, reply, flags);
+}
+
+status_t InputFlinger::dump(int fd, const Vector<String16>& args) {
+    String8 result;
+    const IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int uid = ipc->getCallingUid();
+    if ((uid != AID_SHELL)
+            && !PermissionCache::checkPermission(sDumpPermission, pid, uid)) {
+        result.appendFormat("Permission Denial: "
+                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
+    } else {
+        dumpInternal(result);
+    }
+    write(fd, result.string(), result.size());
+    return OK;
+}
+
+void InputFlinger::dumpInternal(String8& result) {
+    result.append("INPUT FLINGER (dumpsys inputflinger)\n");
+    result.append("... nothing here yet...\n");
+}
+
+status_t InputFlinger::doSomething() {
+    ALOGI("Did something...");
+    return OK;
+}
+
+}; // namespace android
diff --git a/services/inputflinger/InputFlinger.h b/services/inputflinger/InputFlinger.h
new file mode 100644
index 0000000..731ab17
--- /dev/null
+++ b/services/inputflinger/InputFlinger.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 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_INPUT_FLINGER_H
+#define ANDROID_INPUT_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/compiler.h>
+#include <input/IInputFlinger.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+
+class InputFlinger : public BnInputFlinger {
+public:
+    static char const* getServiceName() ANDROID_API {
+        return "inputflinger";
+    }
+
+    InputFlinger() ANDROID_API;
+
+    // IBinder interface
+    virtual status_t onTransact(uint32_t code,
+            const Parcel& data, Parcel* reply, uint32_t flags);
+    virtual status_t dump(int fd, const Vector<String16>& args);
+
+    // IInputFlinger interface
+    virtual status_t doSomething();
+
+private:
+    virtual ~InputFlinger();
+
+    void dumpInternal(String8& result);
+};
+
+} // namespace android
+
+#endif // ANDROID_INPUT_FLINGER_H
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
new file mode 100644
index 0000000..85bb0ed
--- /dev/null
+++ b/services/inputflinger/InputListener.cpp
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "InputListener"
+
+//#define LOG_NDEBUG 0
+
+#include "InputListener.h"
+
+#include <cutils/log.h>
+
+namespace android {
+
+// --- NotifyConfigurationChangedArgs ---
+
+NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(nsecs_t eventTime) :
+        eventTime(eventTime) {
+}
+
+NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(
+        const NotifyConfigurationChangedArgs& other) :
+        eventTime(other.eventTime) {
+}
+
+void NotifyConfigurationChangedArgs::notify(const sp<InputListenerInterface>& listener) const {
+    listener->notifyConfigurationChanged(this);
+}
+
+
+// --- NotifyKeyArgs ---
+
+NotifyKeyArgs::NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
+        uint32_t policyFlags,
+        int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
+        int32_t metaState, nsecs_t downTime) :
+        eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+        action(action), flags(flags), keyCode(keyCode), scanCode(scanCode),
+        metaState(metaState), downTime(downTime) {
+}
+
+NotifyKeyArgs::NotifyKeyArgs(const NotifyKeyArgs& other) :
+        eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
+        policyFlags(other.policyFlags),
+        action(other.action), flags(other.flags),
+        keyCode(other.keyCode), scanCode(other.scanCode),
+        metaState(other.metaState), downTime(other.downTime) {
+}
+
+void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
+    listener->notifyKey(this);
+}
+
+
+// --- NotifyMotionArgs ---
+
+NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
+        uint32_t policyFlags,
+        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+        int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
+        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+        float xPrecision, float yPrecision, nsecs_t downTime) :
+        eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+        action(action), flags(flags), metaState(metaState), buttonState(buttonState),
+        edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
+        xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        this->pointerProperties[i].copyFrom(pointerProperties[i]);
+        this->pointerCoords[i].copyFrom(pointerCoords[i]);
+    }
+}
+
+NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
+        eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
+        policyFlags(other.policyFlags),
+        action(other.action), flags(other.flags),
+        metaState(other.metaState), buttonState(other.buttonState),
+        edgeFlags(other.edgeFlags), displayId(other.displayId),
+        pointerCount(other.pointerCount),
+        xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        pointerProperties[i].copyFrom(other.pointerProperties[i]);
+        pointerCoords[i].copyFrom(other.pointerCoords[i]);
+    }
+}
+
+void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
+    listener->notifyMotion(this);
+}
+
+
+// --- NotifySwitchArgs ---
+
+NotifySwitchArgs::NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
+        uint32_t switchValues, uint32_t switchMask) :
+        eventTime(eventTime), policyFlags(policyFlags),
+        switchValues(switchValues), switchMask(switchMask) {
+}
+
+NotifySwitchArgs::NotifySwitchArgs(const NotifySwitchArgs& other) :
+        eventTime(other.eventTime), policyFlags(other.policyFlags),
+        switchValues(other.switchValues), switchMask(other.switchMask) {
+}
+
+void NotifySwitchArgs::notify(const sp<InputListenerInterface>& listener) const {
+    listener->notifySwitch(this);
+}
+
+
+// --- NotifyDeviceResetArgs ---
+
+NotifyDeviceResetArgs::NotifyDeviceResetArgs(nsecs_t eventTime, int32_t deviceId) :
+        eventTime(eventTime), deviceId(deviceId) {
+}
+
+NotifyDeviceResetArgs::NotifyDeviceResetArgs(const NotifyDeviceResetArgs& other) :
+        eventTime(other.eventTime), deviceId(other.deviceId) {
+}
+
+void NotifyDeviceResetArgs::notify(const sp<InputListenerInterface>& listener) const {
+    listener->notifyDeviceReset(this);
+}
+
+
+// --- QueuedInputListener ---
+
+QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
+        mInnerListener(innerListener) {
+}
+
+QueuedInputListener::~QueuedInputListener() {
+    size_t count = mArgsQueue.size();
+    for (size_t i = 0; i < count; i++) {
+        delete mArgsQueue[i];
+    }
+}
+
+void QueuedInputListener::notifyConfigurationChanged(
+        const NotifyConfigurationChangedArgs* args) {
+    mArgsQueue.push(new NotifyConfigurationChangedArgs(*args));
+}
+
+void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
+    mArgsQueue.push(new NotifyKeyArgs(*args));
+}
+
+void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
+    mArgsQueue.push(new NotifyMotionArgs(*args));
+}
+
+void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) {
+    mArgsQueue.push(new NotifySwitchArgs(*args));
+}
+
+void QueuedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
+    mArgsQueue.push(new NotifyDeviceResetArgs(*args));
+}
+
+void QueuedInputListener::flush() {
+    size_t count = mArgsQueue.size();
+    for (size_t i = 0; i < count; i++) {
+        NotifyArgs* args = mArgsQueue[i];
+        args->notify(mInnerListener);
+        delete args;
+    }
+    mArgsQueue.clear();
+}
+
+
+} // namespace android
diff --git a/services/inputflinger/InputListener.h b/services/inputflinger/InputListener.h
new file mode 100644
index 0000000..78ae10f
--- /dev/null
+++ b/services/inputflinger/InputListener.h
@@ -0,0 +1,196 @@
+/*
+ * 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 _UI_INPUT_LISTENER_H
+#define _UI_INPUT_LISTENER_H
+
+#include <input/Input.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class InputListenerInterface;
+
+
+/* Superclass of all input event argument objects */
+struct NotifyArgs {
+    virtual ~NotifyArgs() { }
+
+    virtual void notify(const sp<InputListenerInterface>& listener) const = 0;
+};
+
+
+/* Describes a configuration change event. */
+struct NotifyConfigurationChangedArgs : public NotifyArgs {
+    nsecs_t eventTime;
+
+    inline NotifyConfigurationChangedArgs() { }
+
+    NotifyConfigurationChangedArgs(nsecs_t eventTime);
+
+    NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other);
+
+    virtual ~NotifyConfigurationChangedArgs() { }
+
+    virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a key event. */
+struct NotifyKeyArgs : public NotifyArgs {
+    nsecs_t eventTime;
+    int32_t deviceId;
+    uint32_t source;
+    uint32_t policyFlags;
+    int32_t action;
+    int32_t flags;
+    int32_t keyCode;
+    int32_t scanCode;
+    int32_t metaState;
+    nsecs_t downTime;
+
+    inline NotifyKeyArgs() { }
+
+    NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
+            int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
+            int32_t metaState, nsecs_t downTime);
+
+    NotifyKeyArgs(const NotifyKeyArgs& other);
+
+    virtual ~NotifyKeyArgs() { }
+
+    virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a motion event. */
+struct NotifyMotionArgs : public NotifyArgs {
+    nsecs_t eventTime;
+    int32_t deviceId;
+    uint32_t source;
+    uint32_t policyFlags;
+    int32_t action;
+    int32_t flags;
+    int32_t metaState;
+    int32_t buttonState;
+    int32_t edgeFlags;
+    int32_t displayId;
+    uint32_t pointerCount;
+    PointerProperties pointerProperties[MAX_POINTERS];
+    PointerCoords pointerCoords[MAX_POINTERS];
+    float xPrecision;
+    float yPrecision;
+    nsecs_t downTime;
+
+    inline NotifyMotionArgs() { }
+
+    NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
+            int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+            int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
+            const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+            float xPrecision, float yPrecision, nsecs_t downTime);
+
+    NotifyMotionArgs(const NotifyMotionArgs& other);
+
+    virtual ~NotifyMotionArgs() { }
+
+    virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a switch event. */
+struct NotifySwitchArgs : public NotifyArgs {
+    nsecs_t eventTime;
+    uint32_t policyFlags;
+    uint32_t switchValues;
+    uint32_t switchMask;
+
+    inline NotifySwitchArgs() { }
+
+    NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
+            uint32_t switchValues, uint32_t switchMask);
+
+    NotifySwitchArgs(const NotifySwitchArgs& other);
+
+    virtual ~NotifySwitchArgs() { }
+
+    virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a device reset event, such as when a device is added,
+ * reconfigured, or removed. */
+struct NotifyDeviceResetArgs : public NotifyArgs {
+    nsecs_t eventTime;
+    int32_t deviceId;
+
+    inline NotifyDeviceResetArgs() { }
+
+    NotifyDeviceResetArgs(nsecs_t eventTime, int32_t deviceId);
+
+    NotifyDeviceResetArgs(const NotifyDeviceResetArgs& other);
+
+    virtual ~NotifyDeviceResetArgs() { }
+
+    virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/*
+ * The interface used by the InputReader to notify the InputListener about input events.
+ */
+class InputListenerInterface : public virtual RefBase {
+protected:
+    InputListenerInterface() { }
+    virtual ~InputListenerInterface() { }
+
+public:
+    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) = 0;
+    virtual void notifyKey(const NotifyKeyArgs* args) = 0;
+    virtual void notifyMotion(const NotifyMotionArgs* args) = 0;
+    virtual void notifySwitch(const NotifySwitchArgs* args) = 0;
+    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) = 0;
+};
+
+
+/*
+ * An implementation of the listener interface that queues up and defers dispatch
+ * of decoded events until flushed.
+ */
+class QueuedInputListener : public InputListenerInterface {
+protected:
+    virtual ~QueuedInputListener();
+
+public:
+    QueuedInputListener(const sp<InputListenerInterface>& innerListener);
+
+    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
+    virtual void notifyKey(const NotifyKeyArgs* args);
+    virtual void notifyMotion(const NotifyMotionArgs* args);
+    virtual void notifySwitch(const NotifySwitchArgs* args);
+    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
+
+    void flush();
+
+private:
+    sp<InputListenerInterface> mInnerListener;
+    Vector<NotifyArgs*> mArgsQueue;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_LISTENER_H
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
new file mode 100644
index 0000000..6a6547b
--- /dev/null
+++ b/services/inputflinger/InputManager.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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 "InputManager"
+
+//#define LOG_NDEBUG 0
+
+#include "InputManager.h"
+
+#include <cutils/log.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) {
+        ALOGE("Could not start InputDispatcher thread due to error %d.", result);
+        return result;
+    }
+
+    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
+    if (result) {
+        ALOGE("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) {
+        ALOGW("Could not stop InputReader thread due to error %d.", result);
+    }
+
+    result = mDispatcherThread->requestExitAndWait();
+    if (result) {
+        ALOGW("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/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
new file mode 100644
index 0000000..a213b2d
--- /dev/null
+++ b/services/inputflinger/InputManager.h
@@ -0,0 +1,109 @@
+/*
+ * 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 "EventHub.h"
+#include "InputReader.h"
+#include "InputDispatcher.h"
+
+#include <input/Input.h>
+#include <input/InputTransport.h>
+#include <utils/Errors.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/*
+ * 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/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
new file mode 100644
index 0000000..94e2a80
--- /dev/null
+++ b/services/inputflinger/InputReader.cpp
@@ -0,0 +1,6530 @@
+/*
+ * 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 "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
+
+// Log debug messages about gesture detection.
+#define DEBUG_GESTURES 0
+
+// Log debug messages about the vibrator.
+#define DEBUG_VIBRATOR 0
+
+#include "InputReader.h"
+
+#include <cutils/log.h>
+#include <input/Keyboard.h>
+#include <input/VirtualKeyMap.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 "        "
+#define INDENT5 "          "
+
+namespace android {
+
+// --- Constants ---
+
+// Maximum number of slots supported when using the slot-based Multitouch Protocol B.
+static const size_t MAX_SLOTS = 32;
+
+// --- 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 distance(float x1, float y1, float x2, float y2) {
+    return hypotf(x1 - x2, y1 - y2);
+}
+
+inline static int32_t signExtendNybble(int32_t value) {
+    return value >= 8 ? value - 16 : value;
+}
+
+static inline const char* toString(bool value) {
+    return value ? "true" : "false";
+}
+
+static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
+        const int32_t map[][4], size_t mapSize) {
+    if (orientation != DISPLAY_ORIENTATION_0) {
+        for (size_t i = 0; i < mapSize; i++) {
+            if (value == map[i][0]) {
+                return map[i][orientation];
+            }
+        }
+    }
+    return value;
+}
+
+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 size_t keyCodeRotationMapSize =
+        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
+
+static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
+    return rotateValueUsingRotationMap(keyCode, orientation,
+            keyCodeRotationMap, keyCodeRotationMapSize);
+}
+
+static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
+    float temp;
+    switch (orientation) {
+    case DISPLAY_ORIENTATION_90:
+        temp = *deltaX;
+        *deltaX = *deltaY;
+        *deltaY = -temp;
+        break;
+
+    case DISPLAY_ORIENTATION_180:
+        *deltaX = -*deltaX;
+        *deltaY = -*deltaY;
+        break;
+
+    case DISPLAY_ORIENTATION_270:
+        temp = *deltaX;
+        *deltaX = -*deltaY;
+        *deltaY = temp;
+        break;
+    }
+}
+
+static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
+    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
+}
+
+// Returns true if the pointer should be reported as being down given the specified
+// button states.  This determines whether the event is reported as a touch event.
+static bool isPointerDown(int32_t buttonState) {
+    return buttonState &
+            (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
+                    | AMOTION_EVENT_BUTTON_TERTIARY);
+}
+
+static float calculateCommonVector(float a, float b) {
+    if (a > 0 && b > 0) {
+        return a < b ? a : b;
+    } else if (a < 0 && b < 0) {
+        return a > b ? a : b;
+    } else {
+        return 0;
+    }
+}
+
+static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
+        nsecs_t when, int32_t deviceId, uint32_t source,
+        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
+        int32_t buttonState, int32_t keyCode) {
+    if (
+            (action == AKEY_EVENT_ACTION_DOWN
+                    && !(lastButtonState & buttonState)
+                    && (currentButtonState & buttonState))
+            || (action == AKEY_EVENT_ACTION_UP
+                    && (lastButtonState & buttonState)
+                    && !(currentButtonState & buttonState))) {
+        NotifyKeyArgs args(when, deviceId, source, policyFlags,
+                action, 0, keyCode, 0, context->getGlobalMetaState(), when);
+        context->getListener()->notifyKey(&args);
+    }
+}
+
+static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
+        nsecs_t when, int32_t deviceId, uint32_t source,
+        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
+    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
+            lastButtonState, currentButtonState,
+            AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
+    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
+            lastButtonState, currentButtonState,
+            AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
+}
+
+
+// --- InputReaderConfiguration ---
+
+bool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
+    const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
+    if (viewport.displayId >= 0) {
+        *outViewport = viewport;
+        return true;
+    }
+    return false;
+}
+
+void InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
+    DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
+    v = viewport;
+}
+
+
+// --- InputReader ---
+
+InputReader::InputReader(const sp<EventHubInterface>& eventHub,
+        const sp<InputReaderPolicyInterface>& policy,
+        const sp<InputListenerInterface>& listener) :
+        mContext(this), mEventHub(eventHub), mPolicy(policy),
+        mGlobalMetaState(0), mGeneration(1),
+        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
+        mConfigurationChangesToRefresh(0) {
+    mQueuedListener = new QueuedInputListener(listener);
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        refreshConfigurationLocked(0);
+        updateGlobalMetaStateLocked();
+    } // release lock
+}
+
+InputReader::~InputReader() {
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        delete mDevices.valueAt(i);
+    }
+}
+
+void InputReader::loopOnce() {
+    int32_t oldGeneration;
+    int32_t timeoutMillis;
+    bool inputDevicesChanged = false;
+    Vector<InputDeviceInfo> inputDevices;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        oldGeneration = mGeneration;
+        timeoutMillis = -1;
+
+        uint32_t changes = mConfigurationChangesToRefresh;
+        if (changes) {
+            mConfigurationChangesToRefresh = 0;
+            timeoutMillis = 0;
+            refreshConfigurationLocked(changes);
+        } else if (mNextTimeout != LLONG_MAX) {
+            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
+        }
+    } // release lock
+
+    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+        mReaderIsAliveCondition.broadcast();
+
+        if (count) {
+            processEventsLocked(mEventBuffer, count);
+        }
+
+        if (mNextTimeout != LLONG_MAX) {
+            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+            if (now >= mNextTimeout) {
+#if DEBUG_RAW_EVENTS
+                ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
+#endif
+                mNextTimeout = LLONG_MAX;
+                timeoutExpiredLocked(now);
+            }
+        }
+
+        if (oldGeneration != mGeneration) {
+            inputDevicesChanged = true;
+            getInputDevicesLocked(inputDevices);
+        }
+    } // release lock
+
+    // Send out a message that the describes the changed input devices.
+    if (inputDevicesChanged) {
+        mPolicy->notifyInputDevicesChanged(inputDevices);
+    }
+
+    // Flush queued events out to the listener.
+    // This must happen outside of the lock because the listener could potentially call
+    // back into the InputReader's methods, such as getScanCodeState, or become blocked
+    // on another thread similarly waiting to acquire the InputReader lock thereby
+    // resulting in a deadlock.  This situation is actually quite plausible because the
+    // listener is actually the input dispatcher, which calls into the window manager,
+    // which occasionally calls into the input reader.
+    mQueuedListener->flush();
+}
+
+void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
+    for (const RawEvent* rawEvent = rawEvents; count;) {
+        int32_t type = rawEvent->type;
+        size_t batchSize = 1;
+        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
+            int32_t deviceId = rawEvent->deviceId;
+            while (batchSize < count) {
+                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
+                        || rawEvent[batchSize].deviceId != deviceId) {
+                    break;
+                }
+                batchSize += 1;
+            }
+#if DEBUG_RAW_EVENTS
+            ALOGD("BatchSize: %d Count: %d", batchSize, count);
+#endif
+            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
+        } else {
+            switch (rawEvent->type) {
+            case EventHubInterface::DEVICE_ADDED:
+                addDeviceLocked(rawEvent->when, rawEvent->deviceId);
+                break;
+            case EventHubInterface::DEVICE_REMOVED:
+                removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
+                break;
+            case EventHubInterface::FINISHED_DEVICE_SCAN:
+                handleConfigurationChangedLocked(rawEvent->when);
+                break;
+            default:
+                ALOG_ASSERT(false); // can't happen
+                break;
+            }
+        }
+        count -= batchSize;
+        rawEvent += batchSize;
+    }
+}
+
+void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex >= 0) {
+        ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
+        return;
+    }
+
+    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
+    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+    int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
+
+    InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
+    device->configure(when, &mConfig, 0);
+    device->reset(when);
+
+    if (device->isIgnored()) {
+        ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
+                identifier.name.string());
+    } else {
+        ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
+                identifier.name.string(), device->getSources());
+    }
+
+    mDevices.add(deviceId, device);
+    bumpGenerationLocked();
+}
+
+void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
+    InputDevice* device = NULL;
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex < 0) {
+        ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
+        return;
+    }
+
+    device = mDevices.valueAt(deviceIndex);
+    mDevices.removeItemsAt(deviceIndex, 1);
+    bumpGenerationLocked();
+
+    if (device->isIgnored()) {
+        ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
+                device->getId(), device->getName().string());
+    } else {
+        ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
+                device->getId(), device->getName().string(), device->getSources());
+    }
+
+    device->reset(when);
+    delete device;
+}
+
+InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
+        const InputDeviceIdentifier& identifier, uint32_t classes) {
+    InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
+            controllerNumber, identifier, classes);
+
+    // External devices.
+    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
+        device->setExternal(true);
+    }
+
+    // Switch-like devices.
+    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
+        device->addMapper(new SwitchInputMapper(device));
+    }
+
+    // Vibrator-like devices.
+    if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
+        device->addMapper(new VibratorInputMapper(device));
+    }
+
+    // Keyboard-like devices.
+    uint32_t keyboardSource = 0;
+    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
+    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
+        keyboardSource |= AINPUT_SOURCE_KEYBOARD;
+    }
+    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
+        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
+    }
+    if (classes & INPUT_DEVICE_CLASS_DPAD) {
+        keyboardSource |= AINPUT_SOURCE_DPAD;
+    }
+    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
+        keyboardSource |= AINPUT_SOURCE_GAMEPAD;
+    }
+
+    if (keyboardSource != 0) {
+        device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
+    }
+
+    // Cursor-like devices.
+    if (classes & INPUT_DEVICE_CLASS_CURSOR) {
+        device->addMapper(new CursorInputMapper(device));
+    }
+
+    // Touchscreens and touchpad devices.
+    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
+        device->addMapper(new MultiTouchInputMapper(device));
+    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
+        device->addMapper(new SingleTouchInputMapper(device));
+    }
+
+    // Joystick-like devices.
+    if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
+        device->addMapper(new JoystickInputMapper(device));
+    }
+
+    return device;
+}
+
+void InputReader::processEventsForDeviceLocked(int32_t deviceId,
+        const RawEvent* rawEvents, size_t count) {
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex < 0) {
+        ALOGW("Discarding event for unknown deviceId %d.", deviceId);
+        return;
+    }
+
+    InputDevice* device = mDevices.valueAt(deviceIndex);
+    if (device->isIgnored()) {
+        //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
+        return;
+    }
+
+    device->process(rawEvents, count);
+}
+
+void InputReader::timeoutExpiredLocked(nsecs_t when) {
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        InputDevice* device = mDevices.valueAt(i);
+        if (!device->isIgnored()) {
+            device->timeoutExpired(when);
+        }
+    }
+}
+
+void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
+    // Reset global meta state because it depends on the list of all configured devices.
+    updateGlobalMetaStateLocked();
+
+    // Enqueue configuration changed.
+    NotifyConfigurationChangedArgs args(when);
+    mQueuedListener->notifyConfigurationChanged(&args);
+}
+
+void InputReader::refreshConfigurationLocked(uint32_t changes) {
+    mPolicy->getReaderConfiguration(&mConfig);
+    mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
+
+    if (changes) {
+        ALOGI("Reconfiguring input devices.  changes=0x%08x", changes);
+        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+
+        if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
+            mEventHub->requestReopenDevices();
+        } else {
+            for (size_t i = 0; i < mDevices.size(); i++) {
+                InputDevice* device = mDevices.valueAt(i);
+                device->configure(now, &mConfig, changes);
+            }
+        }
+    }
+}
+
+void InputReader::updateGlobalMetaStateLocked() {
+    mGlobalMetaState = 0;
+
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        InputDevice* device = mDevices.valueAt(i);
+        mGlobalMetaState |= device->getMetaState();
+    }
+}
+
+int32_t InputReader::getGlobalMetaStateLocked() {
+    return mGlobalMetaState;
+}
+
+void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
+    mDisableVirtualKeysTimeout = time;
+}
+
+bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
+        InputDevice* device, int32_t keyCode, int32_t scanCode) {
+    if (now < mDisableVirtualKeysTimeout) {
+        ALOGI("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::fadePointerLocked() {
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        InputDevice* device = mDevices.valueAt(i);
+        device->fadePointer();
+    }
+}
+
+void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
+    if (when < mNextTimeout) {
+        mNextTimeout = when;
+        mEventHub->wake();
+    }
+}
+
+int32_t InputReader::bumpGenerationLocked() {
+    return ++mGeneration;
+}
+
+void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
+    AutoMutex _l(mLock);
+    getInputDevicesLocked(outInputDevices);
+}
+
+void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
+    outInputDevices.clear();
+
+    size_t numDevices = mDevices.size();
+    for (size_t i = 0; i < numDevices; i++) {
+        InputDevice* device = mDevices.valueAt(i);
+        if (!device->isIgnored()) {
+            outInputDevices.push();
+            device->getDeviceInfo(&outInputDevices.editTop());
+        }
+    }
+}
+
+int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+        int32_t keyCode) {
+    AutoMutex _l(mLock);
+
+    return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
+}
+
+int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+        int32_t scanCode) {
+    AutoMutex _l(mLock);
+
+    return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
+}
+
+int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
+    AutoMutex _l(mLock);
+
+    return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
+}
+
+int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
+        GetStateFunc getStateFunc) {
+    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)) {
+                // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
+                // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
+                int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
+                if (currentResult >= AKEY_STATE_DOWN) {
+                    return currentResult;
+                } else if (currentResult == AKEY_STATE_UP) {
+                    result = currentResult;
+                }
+            }
+        }
+    }
+    return result;
+}
+
+bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
+        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+    AutoMutex _l(mLock);
+
+    memset(outFlags, 0, numCodes);
+    return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
+}
+
+bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
+        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+    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;
+}
+
+void InputReader::requestRefreshConfiguration(uint32_t changes) {
+    AutoMutex _l(mLock);
+
+    if (changes) {
+        bool needWake = !mConfigurationChangesToRefresh;
+        mConfigurationChangesToRefresh |= changes;
+
+        if (needWake) {
+            mEventHub->wake();
+        }
+    }
+}
+
+void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
+        ssize_t repeat, int32_t token) {
+    AutoMutex _l(mLock);
+
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex >= 0) {
+        InputDevice* device = mDevices.valueAt(deviceIndex);
+        device->vibrate(pattern, patternSize, repeat, token);
+    }
+}
+
+void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
+    AutoMutex _l(mLock);
+
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex >= 0) {
+        InputDevice* device = mDevices.valueAt(deviceIndex);
+        device->cancelVibrate(token);
+    }
+}
+
+void InputReader::dump(String8& dump) {
+    AutoMutex _l(mLock);
+
+    mEventHub->dump(dump);
+    dump.append("\n");
+
+    dump.append("Input Reader State:\n");
+
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        mDevices.valueAt(i)->dump(dump);
+    }
+
+    dump.append(INDENT "Configuration:\n");
+    dump.append(INDENT2 "ExcludedDeviceNames: [");
+    for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
+        if (i != 0) {
+            dump.append(", ");
+        }
+        dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
+    }
+    dump.append("]\n");
+    dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
+            mConfig.virtualKeyQuietTime * 0.000001f);
+
+    dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
+            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
+            mConfig.pointerVelocityControlParameters.scale,
+            mConfig.pointerVelocityControlParameters.lowThreshold,
+            mConfig.pointerVelocityControlParameters.highThreshold,
+            mConfig.pointerVelocityControlParameters.acceleration);
+
+    dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
+            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
+            mConfig.wheelVelocityControlParameters.scale,
+            mConfig.wheelVelocityControlParameters.lowThreshold,
+            mConfig.wheelVelocityControlParameters.highThreshold,
+            mConfig.wheelVelocityControlParameters.acceleration);
+
+    dump.appendFormat(INDENT2 "PointerGesture:\n");
+    dump.appendFormat(INDENT3 "Enabled: %s\n",
+            toString(mConfig.pointerGesturesEnabled));
+    dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
+            mConfig.pointerGestureQuietInterval * 0.000001f);
+    dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
+            mConfig.pointerGestureDragMinSwitchSpeed);
+    dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
+            mConfig.pointerGestureTapInterval * 0.000001f);
+    dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
+            mConfig.pointerGestureTapDragInterval * 0.000001f);
+    dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
+            mConfig.pointerGestureTapSlop);
+    dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
+            mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
+    dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
+            mConfig.pointerGestureMultitouchMinDistance);
+    dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
+            mConfig.pointerGestureSwipeTransitionAngleCosine);
+    dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
+            mConfig.pointerGestureSwipeMaxWidthRatio);
+    dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
+            mConfig.pointerGestureMovementSpeedRatio);
+    dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
+            mConfig.pointerGestureZoomSpeedRatio);
+}
+
+void InputReader::monitor() {
+    // Acquire and release the lock to ensure that the reader has not deadlocked.
+    mLock.lock();
+    mEventHub->wake();
+    mReaderIsAliveCondition.wait(mLock);
+    mLock.unlock();
+
+    // Check the EventHub
+    mEventHub->monitor();
+}
+
+
+// --- InputReader::ContextImpl ---
+
+InputReader::ContextImpl::ContextImpl(InputReader* reader) :
+        mReader(reader) {
+}
+
+void InputReader::ContextImpl::updateGlobalMetaState() {
+    // lock is already held by the input loop
+    mReader->updateGlobalMetaStateLocked();
+}
+
+int32_t InputReader::ContextImpl::getGlobalMetaState() {
+    // lock is already held by the input loop
+    return mReader->getGlobalMetaStateLocked();
+}
+
+void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
+    // lock is already held by the input loop
+    mReader->disableVirtualKeysUntilLocked(time);
+}
+
+bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
+        InputDevice* device, int32_t keyCode, int32_t scanCode) {
+    // lock is already held by the input loop
+    return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
+}
+
+void InputReader::ContextImpl::fadePointer() {
+    // lock is already held by the input loop
+    mReader->fadePointerLocked();
+}
+
+void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
+    // lock is already held by the input loop
+    mReader->requestTimeoutAtTimeLocked(when);
+}
+
+int32_t InputReader::ContextImpl::bumpGeneration() {
+    // lock is already held by the input loop
+    return mReader->bumpGenerationLocked();
+}
+
+InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
+    return mReader->mPolicy.get();
+}
+
+InputListenerInterface* InputReader::ContextImpl::getListener() {
+    return mReader->mQueuedListener.get();
+}
+
+EventHubInterface* InputReader::ContextImpl::getEventHub() {
+    return mReader->mEventHub.get();
+}
+
+
+// --- 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, int32_t generation,
+        int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
+        mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
+        mIdentifier(identifier), mClasses(classes),
+        mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
+}
+
+InputDevice::~InputDevice() {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        delete mMappers[i];
+    }
+    mMappers.clear();
+}
+
+void InputDevice::dump(String8& dump) {
+    InputDeviceInfo deviceInfo;
+    getDeviceInfo(& deviceInfo);
+
+    dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
+            deviceInfo.getDisplayName().string());
+    dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
+    dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
+    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
+    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
+
+    const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
+    if (!ranges.isEmpty()) {
+        dump.append(INDENT2 "Motion Ranges:\n");
+        for (size_t i = 0; i < ranges.size(); i++) {
+            const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
+            const char* label = getAxisLabel(range.axis);
+            char name[32];
+            if (label) {
+                strncpy(name, label, sizeof(name));
+                name[sizeof(name) - 1] = '\0';
+            } else {
+                snprintf(name, sizeof(name), "%d", range.axis);
+            }
+            dump.appendFormat(INDENT3 "%s: source=0x%08x, "
+                    "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
+                    name, range.source, range.min, range.max, range.flat, range.fuzz,
+                    range.resolution);
+        }
+    }
+
+    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(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
+    mSources = 0;
+
+    if (!isIgnored()) {
+        if (!changes) { // first time only
+            mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
+        }
+
+        if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
+            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
+                sp<KeyCharacterMap> keyboardLayout =
+                        mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
+                if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
+                    bumpGeneration();
+                }
+            }
+        }
+
+        if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
+            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
+                String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
+                if (mAlias != alias) {
+                    mAlias = alias;
+                    bumpGeneration();
+                }
+            }
+        }
+
+        size_t numMappers = mMappers.size();
+        for (size_t i = 0; i < numMappers; i++) {
+            InputMapper* mapper = mMappers[i];
+            mapper->configure(when, config, changes);
+            mSources |= mapper->getSources();
+        }
+    }
+}
+
+void InputDevice::reset(nsecs_t when) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->reset(when);
+    }
+
+    mContext->updateGlobalMetaState();
+
+    notifyReset(when);
+}
+
+void InputDevice::process(const RawEvent* rawEvents, size_t count) {
+    // Process all of the events in order for each mapper.
+    // We cannot simply ask each mapper to process them in bulk because mappers may
+    // have side-effects that must be interleaved.  For example, joystick movement events and
+    // gamepad button presses are handled by different mappers but they should be dispatched
+    // in the order received.
+    size_t numMappers = mMappers.size();
+    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
+#if DEBUG_RAW_EVENTS
+        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
+                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
+                rawEvent->when);
+#endif
+
+        if (mDropUntilNextSync) {
+            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
+                mDropUntilNextSync = false;
+#if DEBUG_RAW_EVENTS
+                ALOGD("Recovered from input event buffer overrun.");
+#endif
+            } else {
+#if DEBUG_RAW_EVENTS
+                ALOGD("Dropped input event while waiting for next input sync.");
+#endif
+            }
+        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
+            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
+            mDropUntilNextSync = true;
+            reset(rawEvent->when);
+        } else {
+            for (size_t i = 0; i < numMappers; i++) {
+                InputMapper* mapper = mMappers[i];
+                mapper->process(rawEvent);
+            }
+        }
+    }
+}
+
+void InputDevice::timeoutExpired(nsecs_t when) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->timeoutExpired(when);
+    }
+}
+
+void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
+    outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
+            mIsExternal);
+
+    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)) {
+            // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
+            // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
+            int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
+            if (currentResult >= AKEY_STATE_DOWN) {
+                return currentResult;
+            } else if (currentResult == AKEY_STATE_UP) {
+                result = currentResult;
+            }
+        }
+    }
+    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;
+}
+
+void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+        int32_t token) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->vibrate(pattern, patternSize, repeat, token);
+    }
+}
+
+void InputDevice::cancelVibrate(int32_t token) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->cancelVibrate(token);
+    }
+}
+
+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;
+}
+
+void InputDevice::fadePointer() {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->fadePointer();
+    }
+}
+
+void InputDevice::bumpGeneration() {
+    mGeneration = mContext->bumpGeneration();
+}
+
+void InputDevice::notifyReset(nsecs_t when) {
+    NotifyDeviceResetArgs args(when, mId);
+    mContext->getListener()->notifyDeviceReset(&args);
+}
+
+
+// --- CursorButtonAccumulator ---
+
+CursorButtonAccumulator::CursorButtonAccumulator() {
+    clearButtons();
+}
+
+void CursorButtonAccumulator::reset(InputDevice* device) {
+    mBtnLeft = device->isKeyPressed(BTN_LEFT);
+    mBtnRight = device->isKeyPressed(BTN_RIGHT);
+    mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
+    mBtnBack = device->isKeyPressed(BTN_BACK);
+    mBtnSide = device->isKeyPressed(BTN_SIDE);
+    mBtnForward = device->isKeyPressed(BTN_FORWARD);
+    mBtnExtra = device->isKeyPressed(BTN_EXTRA);
+    mBtnTask = device->isKeyPressed(BTN_TASK);
+}
+
+void CursorButtonAccumulator::clearButtons() {
+    mBtnLeft = 0;
+    mBtnRight = 0;
+    mBtnMiddle = 0;
+    mBtnBack = 0;
+    mBtnSide = 0;
+    mBtnForward = 0;
+    mBtnExtra = 0;
+    mBtnTask = 0;
+}
+
+void CursorButtonAccumulator::process(const RawEvent* rawEvent) {
+    if (rawEvent->type == EV_KEY) {
+        switch (rawEvent->code) {
+        case BTN_LEFT:
+            mBtnLeft = rawEvent->value;
+            break;
+        case BTN_RIGHT:
+            mBtnRight = rawEvent->value;
+            break;
+        case BTN_MIDDLE:
+            mBtnMiddle = rawEvent->value;
+            break;
+        case BTN_BACK:
+            mBtnBack = rawEvent->value;
+            break;
+        case BTN_SIDE:
+            mBtnSide = rawEvent->value;
+            break;
+        case BTN_FORWARD:
+            mBtnForward = rawEvent->value;
+            break;
+        case BTN_EXTRA:
+            mBtnExtra = rawEvent->value;
+            break;
+        case BTN_TASK:
+            mBtnTask = rawEvent->value;
+            break;
+        }
+    }
+}
+
+uint32_t CursorButtonAccumulator::getButtonState() const {
+    uint32_t result = 0;
+    if (mBtnLeft) {
+        result |= AMOTION_EVENT_BUTTON_PRIMARY;
+    }
+    if (mBtnRight) {
+        result |= AMOTION_EVENT_BUTTON_SECONDARY;
+    }
+    if (mBtnMiddle) {
+        result |= AMOTION_EVENT_BUTTON_TERTIARY;
+    }
+    if (mBtnBack || mBtnSide) {
+        result |= AMOTION_EVENT_BUTTON_BACK;
+    }
+    if (mBtnForward || mBtnExtra) {
+        result |= AMOTION_EVENT_BUTTON_FORWARD;
+    }
+    return result;
+}
+
+
+// --- CursorMotionAccumulator ---
+
+CursorMotionAccumulator::CursorMotionAccumulator() {
+    clearRelativeAxes();
+}
+
+void CursorMotionAccumulator::reset(InputDevice* device) {
+    clearRelativeAxes();
+}
+
+void CursorMotionAccumulator::clearRelativeAxes() {
+    mRelX = 0;
+    mRelY = 0;
+}
+
+void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
+    if (rawEvent->type == EV_REL) {
+        switch (rawEvent->code) {
+        case REL_X:
+            mRelX = rawEvent->value;
+            break;
+        case REL_Y:
+            mRelY = rawEvent->value;
+            break;
+        }
+    }
+}
+
+void CursorMotionAccumulator::finishSync() {
+    clearRelativeAxes();
+}
+
+
+// --- CursorScrollAccumulator ---
+
+CursorScrollAccumulator::CursorScrollAccumulator() :
+        mHaveRelWheel(false), mHaveRelHWheel(false) {
+    clearRelativeAxes();
+}
+
+void CursorScrollAccumulator::configure(InputDevice* device) {
+    mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
+    mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
+}
+
+void CursorScrollAccumulator::reset(InputDevice* device) {
+    clearRelativeAxes();
+}
+
+void CursorScrollAccumulator::clearRelativeAxes() {
+    mRelWheel = 0;
+    mRelHWheel = 0;
+}
+
+void CursorScrollAccumulator::process(const RawEvent* rawEvent) {
+    if (rawEvent->type == EV_REL) {
+        switch (rawEvent->code) {
+        case REL_WHEEL:
+            mRelWheel = rawEvent->value;
+            break;
+        case REL_HWHEEL:
+            mRelHWheel = rawEvent->value;
+            break;
+        }
+    }
+}
+
+void CursorScrollAccumulator::finishSync() {
+    clearRelativeAxes();
+}
+
+
+// --- TouchButtonAccumulator ---
+
+TouchButtonAccumulator::TouchButtonAccumulator() :
+        mHaveBtnTouch(false), mHaveStylus(false) {
+    clearButtons();
+}
+
+void TouchButtonAccumulator::configure(InputDevice* device) {
+    mHaveBtnTouch = device->hasKey(BTN_TOUCH);
+    mHaveStylus = device->hasKey(BTN_TOOL_PEN)
+            || device->hasKey(BTN_TOOL_RUBBER)
+            || device->hasKey(BTN_TOOL_BRUSH)
+            || device->hasKey(BTN_TOOL_PENCIL)
+            || device->hasKey(BTN_TOOL_AIRBRUSH);
+}
+
+void TouchButtonAccumulator::reset(InputDevice* device) {
+    mBtnTouch = device->isKeyPressed(BTN_TOUCH);
+    mBtnStylus = device->isKeyPressed(BTN_STYLUS);
+    mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
+    mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
+    mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
+    mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
+    mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
+    mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
+    mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
+    mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
+    mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
+    mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
+    mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
+    mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
+}
+
+void TouchButtonAccumulator::clearButtons() {
+    mBtnTouch = 0;
+    mBtnStylus = 0;
+    mBtnStylus2 = 0;
+    mBtnToolFinger = 0;
+    mBtnToolPen = 0;
+    mBtnToolRubber = 0;
+    mBtnToolBrush = 0;
+    mBtnToolPencil = 0;
+    mBtnToolAirbrush = 0;
+    mBtnToolMouse = 0;
+    mBtnToolLens = 0;
+    mBtnToolDoubleTap = 0;
+    mBtnToolTripleTap = 0;
+    mBtnToolQuadTap = 0;
+}
+
+void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
+    if (rawEvent->type == EV_KEY) {
+        switch (rawEvent->code) {
+        case BTN_TOUCH:
+            mBtnTouch = rawEvent->value;
+            break;
+        case BTN_STYLUS:
+            mBtnStylus = rawEvent->value;
+            break;
+        case BTN_STYLUS2:
+            mBtnStylus2 = rawEvent->value;
+            break;
+        case BTN_TOOL_FINGER:
+            mBtnToolFinger = rawEvent->value;
+            break;
+        case BTN_TOOL_PEN:
+            mBtnToolPen = rawEvent->value;
+            break;
+        case BTN_TOOL_RUBBER:
+            mBtnToolRubber = rawEvent->value;
+            break;
+        case BTN_TOOL_BRUSH:
+            mBtnToolBrush = rawEvent->value;
+            break;
+        case BTN_TOOL_PENCIL:
+            mBtnToolPencil = rawEvent->value;
+            break;
+        case BTN_TOOL_AIRBRUSH:
+            mBtnToolAirbrush = rawEvent->value;
+            break;
+        case BTN_TOOL_MOUSE:
+            mBtnToolMouse = rawEvent->value;
+            break;
+        case BTN_TOOL_LENS:
+            mBtnToolLens = rawEvent->value;
+            break;
+        case BTN_TOOL_DOUBLETAP:
+            mBtnToolDoubleTap = rawEvent->value;
+            break;
+        case BTN_TOOL_TRIPLETAP:
+            mBtnToolTripleTap = rawEvent->value;
+            break;
+        case BTN_TOOL_QUADTAP:
+            mBtnToolQuadTap = rawEvent->value;
+            break;
+        }
+    }
+}
+
+uint32_t TouchButtonAccumulator::getButtonState() const {
+    uint32_t result = 0;
+    if (mBtnStylus) {
+        result |= AMOTION_EVENT_BUTTON_SECONDARY;
+    }
+    if (mBtnStylus2) {
+        result |= AMOTION_EVENT_BUTTON_TERTIARY;
+    }
+    return result;
+}
+
+int32_t TouchButtonAccumulator::getToolType() const {
+    if (mBtnToolMouse || mBtnToolLens) {
+        return AMOTION_EVENT_TOOL_TYPE_MOUSE;
+    }
+    if (mBtnToolRubber) {
+        return AMOTION_EVENT_TOOL_TYPE_ERASER;
+    }
+    if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
+        return AMOTION_EVENT_TOOL_TYPE_STYLUS;
+    }
+    if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
+        return AMOTION_EVENT_TOOL_TYPE_FINGER;
+    }
+    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+}
+
+bool TouchButtonAccumulator::isToolActive() const {
+    return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
+            || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
+            || mBtnToolMouse || mBtnToolLens
+            || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
+}
+
+bool TouchButtonAccumulator::isHovering() const {
+    return mHaveBtnTouch && !mBtnTouch;
+}
+
+bool TouchButtonAccumulator::hasStylus() const {
+    return mHaveStylus;
+}
+
+
+// --- RawPointerAxes ---
+
+RawPointerAxes::RawPointerAxes() {
+    clear();
+}
+
+void RawPointerAxes::clear() {
+    x.clear();
+    y.clear();
+    pressure.clear();
+    touchMajor.clear();
+    touchMinor.clear();
+    toolMajor.clear();
+    toolMinor.clear();
+    orientation.clear();
+    distance.clear();
+    tiltX.clear();
+    tiltY.clear();
+    trackingId.clear();
+    slot.clear();
+}
+
+
+// --- RawPointerData ---
+
+RawPointerData::RawPointerData() {
+    clear();
+}
+
+void RawPointerData::clear() {
+    pointerCount = 0;
+    clearIdBits();
+}
+
+void RawPointerData::copyFrom(const RawPointerData& other) {
+    pointerCount = other.pointerCount;
+    hoveringIdBits = other.hoveringIdBits;
+    touchingIdBits = other.touchingIdBits;
+
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        pointers[i] = other.pointers[i];
+
+        int id = pointers[i].id;
+        idToIndex[id] = other.idToIndex[id];
+    }
+}
+
+void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
+    float x = 0, y = 0;
+    uint32_t count = touchingIdBits.count();
+    if (count) {
+        for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
+            uint32_t id = idBits.clearFirstMarkedBit();
+            const Pointer& pointer = pointerForId(id);
+            x += pointer.x;
+            y += pointer.y;
+        }
+        x /= count;
+        y /= count;
+    }
+    *outX = x;
+    *outY = y;
+}
+
+
+// --- CookedPointerData ---
+
+CookedPointerData::CookedPointerData() {
+    clear();
+}
+
+void CookedPointerData::clear() {
+    pointerCount = 0;
+    hoveringIdBits.clear();
+    touchingIdBits.clear();
+}
+
+void CookedPointerData::copyFrom(const CookedPointerData& other) {
+    pointerCount = other.pointerCount;
+    hoveringIdBits = other.hoveringIdBits;
+    touchingIdBits = other.touchingIdBits;
+
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        pointerProperties[i].copyFrom(other.pointerProperties[i]);
+        pointerCoords[i].copyFrom(other.pointerCoords[i]);
+
+        int id = pointerProperties[i].id;
+        idToIndex[id] = other.idToIndex[id];
+    }
+}
+
+
+// --- SingleTouchMotionAccumulator ---
+
+SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
+    clearAbsoluteAxes();
+}
+
+void SingleTouchMotionAccumulator::reset(InputDevice* device) {
+    mAbsX = device->getAbsoluteAxisValue(ABS_X);
+    mAbsY = device->getAbsoluteAxisValue(ABS_Y);
+    mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
+    mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
+    mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
+    mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
+    mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
+}
+
+void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
+    mAbsX = 0;
+    mAbsY = 0;
+    mAbsPressure = 0;
+    mAbsToolWidth = 0;
+    mAbsDistance = 0;
+    mAbsTiltX = 0;
+    mAbsTiltY = 0;
+}
+
+void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
+    if (rawEvent->type == EV_ABS) {
+        switch (rawEvent->code) {
+        case ABS_X:
+            mAbsX = rawEvent->value;
+            break;
+        case ABS_Y:
+            mAbsY = rawEvent->value;
+            break;
+        case ABS_PRESSURE:
+            mAbsPressure = rawEvent->value;
+            break;
+        case ABS_TOOL_WIDTH:
+            mAbsToolWidth = rawEvent->value;
+            break;
+        case ABS_DISTANCE:
+            mAbsDistance = rawEvent->value;
+            break;
+        case ABS_TILT_X:
+            mAbsTiltX = rawEvent->value;
+            break;
+        case ABS_TILT_Y:
+            mAbsTiltY = rawEvent->value;
+            break;
+        }
+    }
+}
+
+
+// --- MultiTouchMotionAccumulator ---
+
+MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
+        mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
+        mHaveStylus(false) {
+}
+
+MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
+    delete[] mSlots;
+}
+
+void MultiTouchMotionAccumulator::configure(InputDevice* device,
+        size_t slotCount, bool usingSlotsProtocol) {
+    mSlotCount = slotCount;
+    mUsingSlotsProtocol = usingSlotsProtocol;
+    mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
+
+    delete[] mSlots;
+    mSlots = new Slot[slotCount];
+}
+
+void MultiTouchMotionAccumulator::reset(InputDevice* device) {
+    // Unfortunately there is no way to read the initial contents of the slots.
+    // So when we reset the accumulator, we must assume they are all zeroes.
+    if (mUsingSlotsProtocol) {
+        // Query the driver for the current slot index and use it as the initial slot
+        // before we start reading events from the device.  It is possible that the
+        // current slot index will not be the same as it was when the first event was
+        // written into the evdev buffer, which means the input mapper could start
+        // out of sync with the initial state of the events in the evdev buffer.
+        // In the extremely unlikely case that this happens, the data from
+        // two slots will be confused until the next ABS_MT_SLOT event is received.
+        // This can cause the touch point to "jump", but at least there will be
+        // no stuck touches.
+        int32_t initialSlot;
+        status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
+                ABS_MT_SLOT, &initialSlot);
+        if (status) {
+            ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
+            initialSlot = -1;
+        }
+        clearSlots(initialSlot);
+    } else {
+        clearSlots(-1);
+    }
+}
+
+void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
+    if (mSlots) {
+        for (size_t i = 0; i < mSlotCount; i++) {
+            mSlots[i].clear();
+        }
+    }
+    mCurrentSlot = initialSlot;
+}
+
+void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
+    if (rawEvent->type == EV_ABS) {
+        bool newSlot = false;
+        if (mUsingSlotsProtocol) {
+            if (rawEvent->code == ABS_MT_SLOT) {
+                mCurrentSlot = rawEvent->value;
+                newSlot = true;
+            }
+        } else if (mCurrentSlot < 0) {
+            mCurrentSlot = 0;
+        }
+
+        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
+#if DEBUG_POINTERS
+            if (newSlot) {
+                ALOGW("MultiTouch device emitted invalid slot index %d but it "
+                        "should be between 0 and %d; ignoring this slot.",
+                        mCurrentSlot, mSlotCount - 1);
+            }
+#endif
+        } else {
+            Slot* slot = &mSlots[mCurrentSlot];
+
+            switch (rawEvent->code) {
+            case ABS_MT_POSITION_X:
+                slot->mInUse = true;
+                slot->mAbsMTPositionX = rawEvent->value;
+                break;
+            case ABS_MT_POSITION_Y:
+                slot->mInUse = true;
+                slot->mAbsMTPositionY = rawEvent->value;
+                break;
+            case ABS_MT_TOUCH_MAJOR:
+                slot->mInUse = true;
+                slot->mAbsMTTouchMajor = rawEvent->value;
+                break;
+            case ABS_MT_TOUCH_MINOR:
+                slot->mInUse = true;
+                slot->mAbsMTTouchMinor = rawEvent->value;
+                slot->mHaveAbsMTTouchMinor = true;
+                break;
+            case ABS_MT_WIDTH_MAJOR:
+                slot->mInUse = true;
+                slot->mAbsMTWidthMajor = rawEvent->value;
+                break;
+            case ABS_MT_WIDTH_MINOR:
+                slot->mInUse = true;
+                slot->mAbsMTWidthMinor = rawEvent->value;
+                slot->mHaveAbsMTWidthMinor = true;
+                break;
+            case ABS_MT_ORIENTATION:
+                slot->mInUse = true;
+                slot->mAbsMTOrientation = rawEvent->value;
+                break;
+            case ABS_MT_TRACKING_ID:
+                if (mUsingSlotsProtocol && rawEvent->value < 0) {
+                    // The slot is no longer in use but it retains its previous contents,
+                    // which may be reused for subsequent touches.
+                    slot->mInUse = false;
+                } else {
+                    slot->mInUse = true;
+                    slot->mAbsMTTrackingId = rawEvent->value;
+                }
+                break;
+            case ABS_MT_PRESSURE:
+                slot->mInUse = true;
+                slot->mAbsMTPressure = rawEvent->value;
+                break;
+            case ABS_MT_DISTANCE:
+                slot->mInUse = true;
+                slot->mAbsMTDistance = rawEvent->value;
+                break;
+            case ABS_MT_TOOL_TYPE:
+                slot->mInUse = true;
+                slot->mAbsMTToolType = rawEvent->value;
+                slot->mHaveAbsMTToolType = true;
+                break;
+            }
+        }
+    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
+        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
+        mCurrentSlot += 1;
+    }
+}
+
+void MultiTouchMotionAccumulator::finishSync() {
+    if (!mUsingSlotsProtocol) {
+        clearSlots(-1);
+    }
+}
+
+bool MultiTouchMotionAccumulator::hasStylus() const {
+    return mHaveStylus;
+}
+
+
+// --- MultiTouchMotionAccumulator::Slot ---
+
+MultiTouchMotionAccumulator::Slot::Slot() {
+    clear();
+}
+
+void MultiTouchMotionAccumulator::Slot::clear() {
+    mInUse = false;
+    mHaveAbsMTTouchMinor = false;
+    mHaveAbsMTWidthMinor = false;
+    mHaveAbsMTToolType = false;
+    mAbsMTPositionX = 0;
+    mAbsMTPositionY = 0;
+    mAbsMTTouchMajor = 0;
+    mAbsMTTouchMinor = 0;
+    mAbsMTWidthMajor = 0;
+    mAbsMTWidthMinor = 0;
+    mAbsMTOrientation = 0;
+    mAbsMTTrackingId = -1;
+    mAbsMTPressure = 0;
+    mAbsMTDistance = 0;
+    mAbsMTToolType = 0;
+}
+
+int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
+    if (mHaveAbsMTToolType) {
+        switch (mAbsMTToolType) {
+        case MT_TOOL_FINGER:
+            return AMOTION_EVENT_TOOL_TYPE_FINGER;
+        case MT_TOOL_PEN:
+            return AMOTION_EVENT_TOOL_TYPE_STYLUS;
+        }
+    }
+    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+}
+
+
+// --- 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(nsecs_t when,
+        const InputReaderConfiguration* config, uint32_t changes) {
+}
+
+void InputMapper::reset(nsecs_t when) {
+}
+
+void InputMapper::timeoutExpired(nsecs_t when) {
+}
+
+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;
+}
+
+void InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+        int32_t token) {
+}
+
+void InputMapper::cancelVibrate(int32_t token) {
+}
+
+int32_t InputMapper::getMetaState() {
+    return 0;
+}
+
+void InputMapper::fadePointer() {
+}
+
+status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
+    return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
+}
+
+void InputMapper::bumpGeneration() {
+    mDevice->bumpGeneration();
+}
+
+void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
+        const RawAbsoluteAxisInfo& axis, const char* name) {
+    if (axis.valid) {
+        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
+                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
+    } else {
+        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
+    }
+}
+
+
+// --- SwitchInputMapper ---
+
+SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
+        InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
+}
+
+SwitchInputMapper::~SwitchInputMapper() {
+}
+
+uint32_t SwitchInputMapper::getSources() {
+    return AINPUT_SOURCE_SWITCH;
+}
+
+void SwitchInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_SW:
+        processSwitch(rawEvent->code, rawEvent->value);
+        break;
+
+    case EV_SYN:
+        if (rawEvent->code == SYN_REPORT) {
+            sync(rawEvent->when);
+        }
+    }
+}
+
+void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
+    if (switchCode >= 0 && switchCode < 32) {
+        if (switchValue) {
+            mUpdatedSwitchValues |= 1 << switchCode;
+        }
+        mUpdatedSwitchMask |= 1 << switchCode;
+    }
+}
+
+void SwitchInputMapper::sync(nsecs_t when) {
+    if (mUpdatedSwitchMask) {
+        NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
+        getListener()->notifySwitch(&args);
+
+        mUpdatedSwitchValues = 0;
+        mUpdatedSwitchMask = 0;
+    }
+}
+
+int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
+}
+
+
+// --- VibratorInputMapper ---
+
+VibratorInputMapper::VibratorInputMapper(InputDevice* device) :
+        InputMapper(device), mVibrating(false) {
+}
+
+VibratorInputMapper::~VibratorInputMapper() {
+}
+
+uint32_t VibratorInputMapper::getSources() {
+    return 0;
+}
+
+void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    info->setVibrator(true);
+}
+
+void VibratorInputMapper::process(const RawEvent* rawEvent) {
+    // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
+}
+
+void VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+        int32_t token) {
+#if DEBUG_VIBRATOR
+    String8 patternStr;
+    for (size_t i = 0; i < patternSize; i++) {
+        if (i != 0) {
+            patternStr.append(", ");
+        }
+        patternStr.appendFormat("%lld", pattern[i]);
+    }
+    ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
+            getDeviceId(), patternStr.string(), repeat, token);
+#endif
+
+    mVibrating = true;
+    memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
+    mPatternSize = patternSize;
+    mRepeat = repeat;
+    mToken = token;
+    mIndex = -1;
+
+    nextStep();
+}
+
+void VibratorInputMapper::cancelVibrate(int32_t token) {
+#if DEBUG_VIBRATOR
+    ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
+#endif
+
+    if (mVibrating && mToken == token) {
+        stopVibrating();
+    }
+}
+
+void VibratorInputMapper::timeoutExpired(nsecs_t when) {
+    if (mVibrating) {
+        if (when >= mNextStepTime) {
+            nextStep();
+        } else {
+            getContext()->requestTimeoutAtTime(mNextStepTime);
+        }
+    }
+}
+
+void VibratorInputMapper::nextStep() {
+    mIndex += 1;
+    if (size_t(mIndex) >= mPatternSize) {
+        if (mRepeat < 0) {
+            // We are done.
+            stopVibrating();
+            return;
+        }
+        mIndex = mRepeat;
+    }
+
+    bool vibratorOn = mIndex & 1;
+    nsecs_t duration = mPattern[mIndex];
+    if (vibratorOn) {
+#if DEBUG_VIBRATOR
+        ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
+                getDeviceId(), duration);
+#endif
+        getEventHub()->vibrate(getDeviceId(), duration);
+    } else {
+#if DEBUG_VIBRATOR
+        ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
+#endif
+        getEventHub()->cancelVibrate(getDeviceId());
+    }
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    mNextStepTime = now + duration;
+    getContext()->requestTimeoutAtTime(mNextStepTime);
+#if DEBUG_VIBRATOR
+    ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
+#endif
+}
+
+void VibratorInputMapper::stopVibrating() {
+    mVibrating = false;
+#if DEBUG_VIBRATOR
+    ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
+#endif
+    getEventHub()->cancelVibrate(getDeviceId());
+}
+
+void VibratorInputMapper::dump(String8& dump) {
+    dump.append(INDENT2 "Vibrator Input Mapper:\n");
+    dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
+}
+
+
+// --- KeyboardInputMapper ---
+
+KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
+        uint32_t source, int32_t keyboardType) :
+        InputMapper(device), mSource(source),
+        mKeyboardType(keyboardType) {
+}
+
+KeyboardInputMapper::~KeyboardInputMapper() {
+}
+
+uint32_t KeyboardInputMapper::getSources() {
+    return mSource;
+}
+
+void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    info->setKeyboardType(mKeyboardType);
+    info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
+}
+
+void KeyboardInputMapper::dump(String8& dump) {
+    dump.append(INDENT2 "Keyboard Input Mapper:\n");
+    dumpParameters(dump);
+    dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
+    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
+    dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
+    dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
+    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
+}
+
+
+void KeyboardInputMapper::configure(nsecs_t when,
+        const InputReaderConfiguration* config, uint32_t changes) {
+    InputMapper::configure(when, config, changes);
+
+    if (!changes) { // first time only
+        // Configure basic parameters.
+        configureParameters();
+    }
+
+    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
+            DisplayViewport v;
+            if (config->getDisplayInfo(false /*external*/, &v)) {
+                mOrientation = v.orientation;
+            } else {
+                mOrientation = DISPLAY_ORIENTATION_0;
+            }
+        } else {
+            mOrientation = DISPLAY_ORIENTATION_0;
+        }
+    }
+}
+
+void KeyboardInputMapper::configureParameters() {
+    mParameters.orientationAware = false;
+    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
+            mParameters.orientationAware);
+
+    mParameters.hasAssociatedDisplay = false;
+    if (mParameters.orientationAware) {
+        mParameters.hasAssociatedDisplay = true;
+    }
+}
+
+void KeyboardInputMapper::dumpParameters(String8& dump) {
+    dump.append(INDENT3 "Parameters:\n");
+    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
+            toString(mParameters.hasAssociatedDisplay));
+    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
+            toString(mParameters.orientationAware));
+}
+
+void KeyboardInputMapper::reset(nsecs_t when) {
+    mMetaState = AMETA_NONE;
+    mDownTime = 0;
+    mKeyDowns.clear();
+    mCurrentHidUsage = 0;
+
+    resetLedState();
+
+    InputMapper::reset(when);
+}
+
+void KeyboardInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_KEY: {
+        int32_t scanCode = rawEvent->code;
+        int32_t usageCode = mCurrentHidUsage;
+        mCurrentHidUsage = 0;
+
+        if (isKeyboardOrGamepadKey(scanCode)) {
+            int32_t keyCode;
+            uint32_t flags;
+            if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
+                keyCode = AKEYCODE_UNKNOWN;
+                flags = 0;
+            }
+            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
+        }
+        break;
+    }
+    case EV_MSC: {
+        if (rawEvent->code == MSC_SCAN) {
+            mCurrentHidUsage = rawEvent->value;
+        }
+        break;
+    }
+    case EV_SYN: {
+        if (rawEvent->code == SYN_REPORT) {
+            mCurrentHidUsage = 0;
+        }
+    }
+    }
+}
+
+bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
+    return scanCode < BTN_MOUSE
+        || scanCode >= KEY_OK
+        || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
+        || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
+}
+
+void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
+        int32_t scanCode, uint32_t policyFlags) {
+
+    if (down) {
+        // Rotate key codes according to orientation if needed.
+        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
+            keyCode = rotateKeyCode(keyCode, mOrientation);
+        }
+
+        // Add key down.
+        ssize_t keyDownIndex = findKeyDown(scanCode);
+        if (keyDownIndex >= 0) {
+            // key repeat, be sure to use same keycode as before in case of rotation
+            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
+        } else {
+            // key down
+            if ((policyFlags & POLICY_FLAG_VIRTUAL)
+                    && mContext->shouldDropVirtualKey(when,
+                            getDevice(), keyCode, scanCode)) {
+                return;
+            }
+
+            mKeyDowns.push();
+            KeyDown& keyDown = mKeyDowns.editTop();
+            keyDown.keyCode = keyCode;
+            keyDown.scanCode = scanCode;
+        }
+
+        mDownTime = when;
+    } else {
+        // Remove key down.
+        ssize_t keyDownIndex = findKeyDown(scanCode);
+        if (keyDownIndex >= 0) {
+            // key up, be sure to use same keycode as before in case of rotation
+            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
+            mKeyDowns.removeAt(size_t(keyDownIndex));
+        } else {
+            // key was not actually down
+            ALOGI("Dropping key up from device %s because the key was not down.  "
+                    "keyCode=%d, scanCode=%d",
+                    getDeviceName().string(), keyCode, scanCode);
+            return;
+        }
+    }
+
+    int32_t oldMetaState = mMetaState;
+    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
+    bool metaStateChanged = oldMetaState != newMetaState;
+    if (metaStateChanged) {
+        mMetaState = newMetaState;
+        updateLedState(false);
+    }
+
+    nsecs_t downTime = mDownTime;
+
+    // Key down on external an keyboard should wake the device.
+    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
+    // For internal keyboards, the key layout file should specify the policy flags for
+    // each wake key individually.
+    // TODO: Use the input device configuration to control this behavior more finely.
+    if (down && getDevice()->isExternal()
+            && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
+        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
+    }
+
+    if (metaStateChanged) {
+        getContext()->updateGlobalMetaState();
+    }
+
+    if (down && !isMetaKey(keyCode)) {
+        getContext()->fadePointer();
+    }
+
+    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
+            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
+            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
+    getListener()->notifyKey(&args);
+}
+
+ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
+    size_t n = mKeyDowns.size();
+    for (size_t i = 0; i < n; i++) {
+        if (mKeyDowns[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() {
+    return mMetaState;
+}
+
+void KeyboardInputMapper::resetLedState() {
+    initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
+    initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
+    initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
+
+    updateLedState(true);
+}
+
+void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
+    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
+    ledState.on = false;
+}
+
+void KeyboardInputMapper::updateLedState(bool reset) {
+    updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK,
+            AMETA_CAPS_LOCK_ON, reset);
+    updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK,
+            AMETA_NUM_LOCK_ON, reset);
+    updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK,
+            AMETA_SCROLL_LOCK_ON, reset);
+}
+
+void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
+        int32_t led, int32_t modifier, bool reset) {
+    if (ledState.avail) {
+        bool desiredState = (mMetaState & modifier) != 0;
+        if (reset || ledState.on != desiredState) {
+            getEventHub()->setLedState(getDeviceId(), led, desiredState);
+            ledState.on = desiredState;
+        }
+    }
+}
+
+
+// --- CursorInputMapper ---
+
+CursorInputMapper::CursorInputMapper(InputDevice* device) :
+        InputMapper(device) {
+}
+
+CursorInputMapper::~CursorInputMapper() {
+}
+
+uint32_t CursorInputMapper::getSources() {
+    return mSource;
+}
+
+void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    if (mParameters.mode == Parameters::MODE_POINTER) {
+        float minX, minY, maxX, maxY;
+        if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
+            info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
+            info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
+        }
+    } else {
+        info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
+        info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
+    }
+    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+
+    if (mCursorScrollAccumulator.haveRelativeVWheel()) {
+        info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+    }
+    if (mCursorScrollAccumulator.haveRelativeHWheel()) {
+        info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+    }
+}
+
+void CursorInputMapper::dump(String8& dump) {
+    dump.append(INDENT2 "Cursor Input Mapper:\n");
+    dumpParameters(dump);
+    dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
+    dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
+    dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
+    dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
+    dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
+            toString(mCursorScrollAccumulator.haveRelativeVWheel()));
+    dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
+            toString(mCursorScrollAccumulator.haveRelativeHWheel()));
+    dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
+    dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
+    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
+    dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
+    dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
+    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
+}
+
+void CursorInputMapper::configure(nsecs_t when,
+        const InputReaderConfiguration* config, uint32_t changes) {
+    InputMapper::configure(when, config, changes);
+
+    if (!changes) { // first time only
+        mCursorScrollAccumulator.configure(getDevice());
+
+        // Configure basic parameters.
+        configureParameters();
+
+        // Configure device mode.
+        switch (mParameters.mode) {
+        case Parameters::MODE_POINTER:
+            mSource = AINPUT_SOURCE_MOUSE;
+            mXPrecision = 1.0f;
+            mYPrecision = 1.0f;
+            mXScale = 1.0f;
+            mYScale = 1.0f;
+            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
+            break;
+        case Parameters::MODE_NAVIGATION:
+            mSource = AINPUT_SOURCE_TRACKBALL;
+            mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+            mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+            mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+            mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+            break;
+        }
+
+        mVWheelScale = 1.0f;
+        mHWheelScale = 1.0f;
+    }
+
+    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
+        mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
+        mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
+        mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
+    }
+
+    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
+            DisplayViewport v;
+            if (config->getDisplayInfo(false /*external*/, &v)) {
+                mOrientation = v.orientation;
+            } else {
+                mOrientation = DISPLAY_ORIENTATION_0;
+            }
+        } else {
+            mOrientation = DISPLAY_ORIENTATION_0;
+        }
+        bumpGeneration();
+    }
+}
+
+void CursorInputMapper::configureParameters() {
+    mParameters.mode = Parameters::MODE_POINTER;
+    String8 cursorModeString;
+    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
+        if (cursorModeString == "navigation") {
+            mParameters.mode = Parameters::MODE_NAVIGATION;
+        } else if (cursorModeString != "pointer" && cursorModeString != "default") {
+            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
+        }
+    }
+
+    mParameters.orientationAware = false;
+    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
+            mParameters.orientationAware);
+
+    mParameters.hasAssociatedDisplay = false;
+    if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
+        mParameters.hasAssociatedDisplay = true;
+    }
+}
+
+void CursorInputMapper::dumpParameters(String8& dump) {
+    dump.append(INDENT3 "Parameters:\n");
+    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
+            toString(mParameters.hasAssociatedDisplay));
+
+    switch (mParameters.mode) {
+    case Parameters::MODE_POINTER:
+        dump.append(INDENT4 "Mode: pointer\n");
+        break;
+    case Parameters::MODE_NAVIGATION:
+        dump.append(INDENT4 "Mode: navigation\n");
+        break;
+    default:
+        ALOG_ASSERT(false);
+    }
+
+    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
+            toString(mParameters.orientationAware));
+}
+
+void CursorInputMapper::reset(nsecs_t when) {
+    mButtonState = 0;
+    mDownTime = 0;
+
+    mPointerVelocityControl.reset();
+    mWheelXVelocityControl.reset();
+    mWheelYVelocityControl.reset();
+
+    mCursorButtonAccumulator.reset(getDevice());
+    mCursorMotionAccumulator.reset(getDevice());
+    mCursorScrollAccumulator.reset(getDevice());
+
+    InputMapper::reset(when);
+}
+
+void CursorInputMapper::process(const RawEvent* rawEvent) {
+    mCursorButtonAccumulator.process(rawEvent);
+    mCursorMotionAccumulator.process(rawEvent);
+    mCursorScrollAccumulator.process(rawEvent);
+
+    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
+        sync(rawEvent->when);
+    }
+}
+
+void CursorInputMapper::sync(nsecs_t when) {
+    int32_t lastButtonState = mButtonState;
+    int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
+    mButtonState = currentButtonState;
+
+    bool wasDown = isPointerDown(lastButtonState);
+    bool down = isPointerDown(currentButtonState);
+    bool downChanged;
+    if (!wasDown && down) {
+        mDownTime = when;
+        downChanged = true;
+    } else if (wasDown && !down) {
+        downChanged = true;
+    } else {
+        downChanged = false;
+    }
+    nsecs_t downTime = mDownTime;
+    bool buttonsChanged = currentButtonState != lastButtonState;
+    bool buttonsPressed = currentButtonState & ~lastButtonState;
+
+    float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
+    float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+    bool moved = deltaX != 0 || deltaY != 0;
+
+    // Rotate delta according to orientation if needed.
+    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
+            && (deltaX != 0.0f || deltaY != 0.0f)) {
+        rotateDelta(mOrientation, &deltaX, &deltaY);
+    }
+
+    // Move the pointer.
+    PointerProperties pointerProperties;
+    pointerProperties.clear();
+    pointerProperties.id = 0;
+    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
+
+    PointerCoords pointerCoords;
+    pointerCoords.clear();
+
+    float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
+    float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
+    bool scrolled = vscroll != 0 || hscroll != 0;
+
+    mWheelYVelocityControl.move(when, NULL, &vscroll);
+    mWheelXVelocityControl.move(when, &hscroll, NULL);
+
+    mPointerVelocityControl.move(when, &deltaX, &deltaY);
+
+    int32_t displayId;
+    if (mPointerController != NULL) {
+        if (moved || scrolled || buttonsChanged) {
+            mPointerController->setPresentation(
+                    PointerControllerInterface::PRESENTATION_POINTER);
+
+            if (moved) {
+                mPointerController->move(deltaX, deltaY);
+            }
+
+            if (buttonsChanged) {
+                mPointerController->setButtonState(currentButtonState);
+            }
+
+            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+        }
+
+        float x, y;
+        mPointerController->getPosition(&x, &y);
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        displayId = ADISPLAY_ID_DEFAULT;
+    } else {
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+        displayId = ADISPLAY_ID_NONE;
+    }
+
+    pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
+
+    // Moving an external trackball or mouse should wake the device.
+    // We don't do this for internal cursor devices to prevent them from waking up
+    // the device in your pocket.
+    // TODO: Use the input device configuration to control this behavior more finely.
+    uint32_t policyFlags = 0;
+    if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
+        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
+    }
+
+    // Synthesize key down from buttons if needed.
+    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
+            policyFlags, lastButtonState, currentButtonState);
+
+    // Send motion event.
+    if (downChanged || moved || scrolled || buttonsChanged) {
+        int32_t metaState = mContext->getGlobalMetaState();
+        int32_t motionEventAction;
+        if (downChanged) {
+            motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+        } else if (down || mPointerController == NULL) {
+            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+        } else {
+            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
+        }
+
+        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                motionEventAction, 0, metaState, currentButtonState, 0,
+                displayId, 1, &pointerProperties, &pointerCoords,
+                mXPrecision, mYPrecision, downTime);
+        getListener()->notifyMotion(&args);
+
+        // Send hover move after UP to tell the application that the mouse is hovering now.
+        if (motionEventAction == AMOTION_EVENT_ACTION_UP
+                && mPointerController != NULL) {
+            NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
+                    AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+                    metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+                    displayId, 1, &pointerProperties, &pointerCoords,
+                    mXPrecision, mYPrecision, downTime);
+            getListener()->notifyMotion(&hoverArgs);
+        }
+
+        // Send scroll events.
+        if (scrolled) {
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
+            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
+
+            NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+                    AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
+                    AMOTION_EVENT_EDGE_FLAG_NONE,
+                    displayId, 1, &pointerProperties, &pointerCoords,
+                    mXPrecision, mYPrecision, downTime);
+            getListener()->notifyMotion(&scrollArgs);
+        }
+    }
+
+    // Synthesize key up from buttons if needed.
+    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
+            policyFlags, lastButtonState, currentButtonState);
+
+    mCursorMotionAccumulator.finishSync();
+    mCursorScrollAccumulator.finishSync();
+}
+
+int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
+        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+    } else {
+        return AKEY_STATE_UNKNOWN;
+    }
+}
+
+void CursorInputMapper::fadePointer() {
+    if (mPointerController != NULL) {
+        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+    }
+}
+
+
+// --- TouchInputMapper ---
+
+TouchInputMapper::TouchInputMapper(InputDevice* device) :
+        InputMapper(device),
+        mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
+        mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
+        mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
+}
+
+TouchInputMapper::~TouchInputMapper() {
+}
+
+uint32_t TouchInputMapper::getSources() {
+    return mSource;
+}
+
+void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    if (mDeviceMode != DEVICE_MODE_DISABLED) {
+        info->addMotionRange(mOrientedRanges.x);
+        info->addMotionRange(mOrientedRanges.y);
+        info->addMotionRange(mOrientedRanges.pressure);
+
+        if (mOrientedRanges.haveSize) {
+            info->addMotionRange(mOrientedRanges.size);
+        }
+
+        if (mOrientedRanges.haveTouchSize) {
+            info->addMotionRange(mOrientedRanges.touchMajor);
+            info->addMotionRange(mOrientedRanges.touchMinor);
+        }
+
+        if (mOrientedRanges.haveToolSize) {
+            info->addMotionRange(mOrientedRanges.toolMajor);
+            info->addMotionRange(mOrientedRanges.toolMinor);
+        }
+
+        if (mOrientedRanges.haveOrientation) {
+            info->addMotionRange(mOrientedRanges.orientation);
+        }
+
+        if (mOrientedRanges.haveDistance) {
+            info->addMotionRange(mOrientedRanges.distance);
+        }
+
+        if (mOrientedRanges.haveTilt) {
+            info->addMotionRange(mOrientedRanges.tilt);
+        }
+
+        if (mCursorScrollAccumulator.haveRelativeVWheel()) {
+            info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
+                    0.0f);
+        }
+        if (mCursorScrollAccumulator.haveRelativeHWheel()) {
+            info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
+                    0.0f);
+        }
+        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
+            const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
+            const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
+            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat,
+                    x.fuzz, x.resolution);
+            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat,
+                    y.fuzz, y.resolution);
+            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat,
+                    x.fuzz, x.resolution);
+            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
+                    y.fuzz, y.resolution);
+        }
+        info->setButtonUnderPad(mParameters.hasButtonUnderPad);
+    }
+}
+
+void TouchInputMapper::dump(String8& dump) {
+    dump.append(INDENT2 "Touch Input Mapper:\n");
+    dumpParameters(dump);
+    dumpVirtualKeys(dump);
+    dumpRawPointerAxes(dump);
+    dumpCalibration(dump);
+    dumpSurface(dump);
+
+    dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
+    dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
+    dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
+    dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
+    dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
+    dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
+    dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
+    dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
+    dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
+    dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
+    dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
+    dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
+    dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
+    dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
+    dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
+    dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
+    dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
+
+    dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
+
+    dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
+            mLastRawPointerData.pointerCount);
+    for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
+        const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
+        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
+                "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
+                "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
+                "toolType=%d, isHovering=%s\n", i,
+                pointer.id, pointer.x, pointer.y, pointer.pressure,
+                pointer.touchMajor, pointer.touchMinor,
+                pointer.toolMajor, pointer.toolMinor,
+                pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
+                pointer.toolType, toString(pointer.isHovering));
+    }
+
+    dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
+            mLastCookedPointerData.pointerCount);
+    for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
+        const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
+        const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
+        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
+                "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
+                "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
+                "toolType=%d, isHovering=%s\n", i,
+                pointerProperties.id,
+                pointerCoords.getX(),
+                pointerCoords.getY(),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
+                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
+                pointerProperties.toolType,
+                toString(mLastCookedPointerData.isHovering(i)));
+    }
+
+    if (mDeviceMode == DEVICE_MODE_POINTER) {
+        dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
+        dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
+                mPointerXMovementScale);
+        dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
+                mPointerYMovementScale);
+        dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
+                mPointerXZoomScale);
+        dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
+                mPointerYZoomScale);
+        dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
+                mPointerGestureMaxSwipeWidth);
+    }
+}
+
+void TouchInputMapper::configure(nsecs_t when,
+        const InputReaderConfiguration* config, uint32_t changes) {
+    InputMapper::configure(when, config, changes);
+
+    mConfig = *config;
+
+    if (!changes) { // first time only
+        // Configure basic parameters.
+        configureParameters();
+
+        // Configure common accumulators.
+        mCursorScrollAccumulator.configure(getDevice());
+        mTouchButtonAccumulator.configure(getDevice());
+
+        // Configure absolute axis information.
+        configureRawPointerAxes();
+
+        // Prepare input device calibration.
+        parseCalibration();
+        resolveCalibration();
+    }
+
+    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
+        // Update pointer speed.
+        mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
+        mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
+        mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
+    }
+
+    bool resetNeeded = false;
+    if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
+            | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
+            | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
+        // Configure device sources, surface dimensions, orientation and
+        // scaling factors.
+        configureSurface(when, &resetNeeded);
+    }
+
+    if (changes && resetNeeded) {
+        // Send reset, unless this is the first time the device has been configured,
+        // in which case the reader will call reset itself after all mappers are ready.
+        getDevice()->notifyReset(when);
+    }
+}
+
+void TouchInputMapper::configureParameters() {
+    // Use the pointer presentation mode for devices that do not support distinct
+    // multitouch.  The spot-based presentation relies on being able to accurately
+    // locate two or more fingers on the touch pad.
+    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
+            ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
+
+    String8 gestureModeString;
+    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
+            gestureModeString)) {
+        if (gestureModeString == "pointer") {
+            mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
+        } else if (gestureModeString == "spots") {
+            mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
+        } else if (gestureModeString != "default") {
+            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
+        }
+    }
+
+    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
+        // The device is a touch screen.
+        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
+    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
+        // The device is a pointing device like a track pad.
+        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
+    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
+            || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
+        // The device is a cursor device with a touch pad attached.
+        // By default don't use the touch pad to move the pointer.
+        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
+    } else {
+        // The device is a touch pad of unknown purpose.
+        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
+    }
+
+    mParameters.hasButtonUnderPad=
+            getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
+
+    String8 deviceTypeString;
+    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
+            deviceTypeString)) {
+        if (deviceTypeString == "touchScreen") {
+            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
+        } else if (deviceTypeString == "touchPad") {
+            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
+        } else if (deviceTypeString == "touchNavigation") {
+            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
+        } else if (deviceTypeString == "pointer") {
+            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
+        } else if (deviceTypeString != "default") {
+            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
+        }
+    }
+
+    mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
+    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
+            mParameters.orientationAware);
+
+    mParameters.hasAssociatedDisplay = false;
+    mParameters.associatedDisplayIsExternal = false;
+    if (mParameters.orientationAware
+            || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
+            || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
+        mParameters.hasAssociatedDisplay = true;
+        mParameters.associatedDisplayIsExternal =
+                mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
+                        && getDevice()->isExternal();
+    }
+}
+
+void TouchInputMapper::dumpParameters(String8& dump) {
+    dump.append(INDENT3 "Parameters:\n");
+
+    switch (mParameters.gestureMode) {
+    case Parameters::GESTURE_MODE_POINTER:
+        dump.append(INDENT4 "GestureMode: pointer\n");
+        break;
+    case Parameters::GESTURE_MODE_SPOTS:
+        dump.append(INDENT4 "GestureMode: spots\n");
+        break;
+    default:
+        assert(false);
+    }
+
+    switch (mParameters.deviceType) {
+    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
+        dump.append(INDENT4 "DeviceType: touchScreen\n");
+        break;
+    case Parameters::DEVICE_TYPE_TOUCH_PAD:
+        dump.append(INDENT4 "DeviceType: touchPad\n");
+        break;
+    case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
+        dump.append(INDENT4 "DeviceType: touchNavigation\n");
+        break;
+    case Parameters::DEVICE_TYPE_POINTER:
+        dump.append(INDENT4 "DeviceType: pointer\n");
+        break;
+    default:
+        ALOG_ASSERT(false);
+    }
+
+    dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
+            toString(mParameters.hasAssociatedDisplay),
+            toString(mParameters.associatedDisplayIsExternal));
+    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
+            toString(mParameters.orientationAware));
+}
+
+void TouchInputMapper::configureRawPointerAxes() {
+    mRawPointerAxes.clear();
+}
+
+void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
+    dump.append(INDENT3 "Raw Touch Axes:\n");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
+    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
+}
+
+void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
+    int32_t oldDeviceMode = mDeviceMode;
+
+    // Determine device mode.
+    if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
+            && mConfig.pointerGesturesEnabled) {
+        mSource = AINPUT_SOURCE_MOUSE;
+        mDeviceMode = DEVICE_MODE_POINTER;
+        if (hasStylus()) {
+            mSource |= AINPUT_SOURCE_STYLUS;
+        }
+    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
+            && mParameters.hasAssociatedDisplay) {
+        mSource = AINPUT_SOURCE_TOUCHSCREEN;
+        mDeviceMode = DEVICE_MODE_DIRECT;
+        if (hasStylus()) {
+            mSource |= AINPUT_SOURCE_STYLUS;
+        }
+    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
+        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
+        mDeviceMode = DEVICE_MODE_NAVIGATION;
+    } else {
+        mSource = AINPUT_SOURCE_TOUCHPAD;
+        mDeviceMode = DEVICE_MODE_UNSCALED;
+    }
+
+    // Ensure we have valid X and Y axes.
+    if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
+        ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
+                "The device will be inoperable.", getDeviceName().string());
+        mDeviceMode = DEVICE_MODE_DISABLED;
+        return;
+    }
+
+    // Raw width and height in the natural orientation.
+    int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
+
+    // Get associated display dimensions.
+    DisplayViewport newViewport;
+    if (mParameters.hasAssociatedDisplay) {
+        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
+            ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
+                    "display.  The device will be inoperable until the display size "
+                    "becomes available.",
+                    getDeviceName().string());
+            mDeviceMode = DEVICE_MODE_DISABLED;
+            return;
+        }
+    } else {
+        newViewport.setNonDisplayViewport(rawWidth, rawHeight);
+    }
+    bool viewportChanged = mViewport != newViewport;
+    if (viewportChanged) {
+        mViewport = newViewport;
+
+        if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
+            // Convert rotated viewport to natural surface coordinates.
+            int32_t naturalLogicalWidth, naturalLogicalHeight;
+            int32_t naturalPhysicalWidth, naturalPhysicalHeight;
+            int32_t naturalPhysicalLeft, naturalPhysicalTop;
+            int32_t naturalDeviceWidth, naturalDeviceHeight;
+            switch (mViewport.orientation) {
+            case DISPLAY_ORIENTATION_90:
+                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
+                naturalPhysicalTop = mViewport.physicalLeft;
+                naturalDeviceWidth = mViewport.deviceHeight;
+                naturalDeviceHeight = mViewport.deviceWidth;
+                break;
+            case DISPLAY_ORIENTATION_180:
+                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
+                naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
+                naturalDeviceWidth = mViewport.deviceWidth;
+                naturalDeviceHeight = mViewport.deviceHeight;
+                break;
+            case DISPLAY_ORIENTATION_270:
+                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalLeft = mViewport.physicalTop;
+                naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
+                naturalDeviceWidth = mViewport.deviceHeight;
+                naturalDeviceHeight = mViewport.deviceWidth;
+                break;
+            case DISPLAY_ORIENTATION_0:
+            default:
+                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
+                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
+                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
+                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
+                naturalPhysicalLeft = mViewport.physicalLeft;
+                naturalPhysicalTop = mViewport.physicalTop;
+                naturalDeviceWidth = mViewport.deviceWidth;
+                naturalDeviceHeight = mViewport.deviceHeight;
+                break;
+            }
+
+            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
+            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
+            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
+            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
+
+            mSurfaceOrientation = mParameters.orientationAware ?
+                    mViewport.orientation : DISPLAY_ORIENTATION_0;
+        } else {
+            mSurfaceWidth = rawWidth;
+            mSurfaceHeight = rawHeight;
+            mSurfaceLeft = 0;
+            mSurfaceTop = 0;
+            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
+        }
+    }
+
+    // If moving between pointer modes, need to reset some state.
+    bool deviceModeChanged = mDeviceMode != oldDeviceMode;
+    if (deviceModeChanged) {
+        mOrientedRanges.clear();
+    }
+
+    // Create pointer controller if needed.
+    if (mDeviceMode == DEVICE_MODE_POINTER ||
+            (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
+        if (mPointerController == NULL) {
+            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
+        }
+    } else {
+        mPointerController.clear();
+    }
+
+    if (viewportChanged || deviceModeChanged) {
+        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
+                "display id %d",
+                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
+                mSurfaceOrientation, mDeviceMode, mViewport.displayId);
+
+        // Configure X and Y factors.
+        mXScale = float(mSurfaceWidth) / rawWidth;
+        mYScale = float(mSurfaceHeight) / rawHeight;
+        mXTranslate = -mSurfaceLeft;
+        mYTranslate = -mSurfaceTop;
+        mXPrecision = 1.0f / mXScale;
+        mYPrecision = 1.0f / mYScale;
+
+        mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
+        mOrientedRanges.x.source = mSource;
+        mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
+        mOrientedRanges.y.source = mSource;
+
+        configureVirtualKeys();
+
+        // 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.
+        mGeometricScale = avg(mXScale, mYScale);
+
+        // Size of diagonal axis.
+        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
+
+        // Size factors.
+        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
+            if (mRawPointerAxes.touchMajor.valid
+                    && mRawPointerAxes.touchMajor.maxValue != 0) {
+                mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
+            } else if (mRawPointerAxes.toolMajor.valid
+                    && mRawPointerAxes.toolMajor.maxValue != 0) {
+                mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
+            } else {
+                mSizeScale = 0.0f;
+            }
+
+            mOrientedRanges.haveTouchSize = true;
+            mOrientedRanges.haveToolSize = true;
+            mOrientedRanges.haveSize = true;
+
+            mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
+            mOrientedRanges.touchMajor.source = mSource;
+            mOrientedRanges.touchMajor.min = 0;
+            mOrientedRanges.touchMajor.max = diagonalSize;
+            mOrientedRanges.touchMajor.flat = 0;
+            mOrientedRanges.touchMajor.fuzz = 0;
+            mOrientedRanges.touchMajor.resolution = 0;
+
+            mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
+            mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
+
+            mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
+            mOrientedRanges.toolMajor.source = mSource;
+            mOrientedRanges.toolMajor.min = 0;
+            mOrientedRanges.toolMajor.max = diagonalSize;
+            mOrientedRanges.toolMajor.flat = 0;
+            mOrientedRanges.toolMajor.fuzz = 0;
+            mOrientedRanges.toolMajor.resolution = 0;
+
+            mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
+            mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
+
+            mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
+            mOrientedRanges.size.source = mSource;
+            mOrientedRanges.size.min = 0;
+            mOrientedRanges.size.max = 1.0;
+            mOrientedRanges.size.flat = 0;
+            mOrientedRanges.size.fuzz = 0;
+            mOrientedRanges.size.resolution = 0;
+        } else {
+            mSizeScale = 0.0f;
+        }
+
+        // Pressure factors.
+        mPressureScale = 0;
+        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
+                || mCalibration.pressureCalibration
+                        == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
+            if (mCalibration.havePressureScale) {
+                mPressureScale = mCalibration.pressureScale;
+            } else if (mRawPointerAxes.pressure.valid
+                    && mRawPointerAxes.pressure.maxValue != 0) {
+                mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
+            }
+        }
+
+        mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
+        mOrientedRanges.pressure.source = mSource;
+        mOrientedRanges.pressure.min = 0;
+        mOrientedRanges.pressure.max = 1.0;
+        mOrientedRanges.pressure.flat = 0;
+        mOrientedRanges.pressure.fuzz = 0;
+        mOrientedRanges.pressure.resolution = 0;
+
+        // Tilt
+        mTiltXCenter = 0;
+        mTiltXScale = 0;
+        mTiltYCenter = 0;
+        mTiltYScale = 0;
+        mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
+        if (mHaveTilt) {
+            mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
+                    mRawPointerAxes.tiltX.maxValue);
+            mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
+                    mRawPointerAxes.tiltY.maxValue);
+            mTiltXScale = M_PI / 180;
+            mTiltYScale = M_PI / 180;
+
+            mOrientedRanges.haveTilt = true;
+
+            mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
+            mOrientedRanges.tilt.source = mSource;
+            mOrientedRanges.tilt.min = 0;
+            mOrientedRanges.tilt.max = M_PI_2;
+            mOrientedRanges.tilt.flat = 0;
+            mOrientedRanges.tilt.fuzz = 0;
+            mOrientedRanges.tilt.resolution = 0;
+        }
+
+        // Orientation
+        mOrientationScale = 0;
+        if (mHaveTilt) {
+            mOrientedRanges.haveOrientation = true;
+
+            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
+            mOrientedRanges.orientation.source = mSource;
+            mOrientedRanges.orientation.min = -M_PI;
+            mOrientedRanges.orientation.max = M_PI;
+            mOrientedRanges.orientation.flat = 0;
+            mOrientedRanges.orientation.fuzz = 0;
+            mOrientedRanges.orientation.resolution = 0;
+        } else if (mCalibration.orientationCalibration !=
+                Calibration::ORIENTATION_CALIBRATION_NONE) {
+            if (mCalibration.orientationCalibration
+                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
+                if (mRawPointerAxes.orientation.valid) {
+                    if (mRawPointerAxes.orientation.maxValue > 0) {
+                        mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
+                    } else if (mRawPointerAxes.orientation.minValue < 0) {
+                        mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
+                    } else {
+                        mOrientationScale = 0;
+                    }
+                }
+            }
+
+            mOrientedRanges.haveOrientation = true;
+
+            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
+            mOrientedRanges.orientation.source = mSource;
+            mOrientedRanges.orientation.min = -M_PI_2;
+            mOrientedRanges.orientation.max = M_PI_2;
+            mOrientedRanges.orientation.flat = 0;
+            mOrientedRanges.orientation.fuzz = 0;
+            mOrientedRanges.orientation.resolution = 0;
+        }
+
+        // Distance
+        mDistanceScale = 0;
+        if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
+            if (mCalibration.distanceCalibration
+                    == Calibration::DISTANCE_CALIBRATION_SCALED) {
+                if (mCalibration.haveDistanceScale) {
+                    mDistanceScale = mCalibration.distanceScale;
+                } else {
+                    mDistanceScale = 1.0f;
+                }
+            }
+
+            mOrientedRanges.haveDistance = true;
+
+            mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
+            mOrientedRanges.distance.source = mSource;
+            mOrientedRanges.distance.min =
+                    mRawPointerAxes.distance.minValue * mDistanceScale;
+            mOrientedRanges.distance.max =
+                    mRawPointerAxes.distance.maxValue * mDistanceScale;
+            mOrientedRanges.distance.flat = 0;
+            mOrientedRanges.distance.fuzz =
+                    mRawPointerAxes.distance.fuzz * mDistanceScale;
+            mOrientedRanges.distance.resolution = 0;
+        }
+
+        // Compute oriented precision, scales and ranges.
+        // Note that the maximum value reported is an inclusive maximum value so it is one
+        // unit less than the total width or height of surface.
+        switch (mSurfaceOrientation) {
+        case DISPLAY_ORIENTATION_90:
+        case DISPLAY_ORIENTATION_270:
+            mOrientedXPrecision = mYPrecision;
+            mOrientedYPrecision = mXPrecision;
+
+            mOrientedRanges.x.min = mYTranslate;
+            mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
+            mOrientedRanges.x.flat = 0;
+            mOrientedRanges.x.fuzz = 0;
+            mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
+
+            mOrientedRanges.y.min = mXTranslate;
+            mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
+            mOrientedRanges.y.flat = 0;
+            mOrientedRanges.y.fuzz = 0;
+            mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
+            break;
+
+        default:
+            mOrientedXPrecision = mXPrecision;
+            mOrientedYPrecision = mYPrecision;
+
+            mOrientedRanges.x.min = mXTranslate;
+            mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
+            mOrientedRanges.x.flat = 0;
+            mOrientedRanges.x.fuzz = 0;
+            mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
+
+            mOrientedRanges.y.min = mYTranslate;
+            mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
+            mOrientedRanges.y.flat = 0;
+            mOrientedRanges.y.fuzz = 0;
+            mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
+            break;
+        }
+
+        if (mDeviceMode == DEVICE_MODE_POINTER) {
+            // Compute pointer gesture detection parameters.
+            float rawDiagonal = hypotf(rawWidth, rawHeight);
+            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
+
+            // Scale movements such that one whole swipe of the touch pad covers a
+            // given area relative to the diagonal size of the display when no acceleration
+            // is applied.
+            // Assume that the touch pad has a square aspect ratio such that movements in
+            // X and Y of the same number of raw units cover the same physical distance.
+            mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
+                    * displayDiagonal / rawDiagonal;
+            mPointerYMovementScale = mPointerXMovementScale;
+
+            // Scale zooms to cover a smaller range of the display than movements do.
+            // This value determines the area around the pointer that is affected by freeform
+            // pointer gestures.
+            mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
+                    * displayDiagonal / rawDiagonal;
+            mPointerYZoomScale = mPointerXZoomScale;
+
+            // Max width between pointers to detect a swipe gesture is more than some fraction
+            // of the diagonal axis of the touch pad.  Touches that are wider than this are
+            // translated into freeform gestures.
+            mPointerGestureMaxSwipeWidth =
+                    mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
+
+            // Abort current pointer usages because the state has changed.
+            abortPointerUsage(when, 0 /*policyFlags*/);
+        }
+
+        // Inform the dispatcher about the changes.
+        *outResetNeeded = true;
+        bumpGeneration();
+    }
+}
+
+void TouchInputMapper::dumpSurface(String8& dump) {
+    dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
+            "logicalFrame=[%d, %d, %d, %d], "
+            "physicalFrame=[%d, %d, %d, %d], "
+            "deviceSize=[%d, %d]\n",
+            mViewport.displayId, mViewport.orientation,
+            mViewport.logicalLeft, mViewport.logicalTop,
+            mViewport.logicalRight, mViewport.logicalBottom,
+            mViewport.physicalLeft, mViewport.physicalTop,
+            mViewport.physicalRight, mViewport.physicalBottom,
+            mViewport.deviceWidth, mViewport.deviceHeight);
+
+    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
+    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
+    dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
+    dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
+    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
+}
+
+void TouchInputMapper::configureVirtualKeys() {
+    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
+    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
+
+    mVirtualKeys.clear();
+
+    if (virtualKeyDefinitions.size() == 0) {
+        return;
+    }
+
+    mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
+
+    int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
+    int32_t touchScreenTop = mRawPointerAxes.y.minValue;
+    int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+    int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
+
+    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
+        const VirtualKeyDefinition& virtualKeyDefinition =
+                virtualKeyDefinitions[i];
+
+        mVirtualKeys.add();
+        VirtualKey& virtualKey = mVirtualKeys.editTop();
+
+        virtualKey.scanCode = virtualKeyDefinition.scanCode;
+        int32_t keyCode;
+        uint32_t flags;
+        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
+            ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
+                    virtualKey.scanCode);
+            mVirtualKeys.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 / mSurfaceWidth + touchScreenLeft;
+        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
+                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
+        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
+                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
+        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
+                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
+    }
+}
+
+void TouchInputMapper::dumpVirtualKeys(String8& dump) {
+    if (!mVirtualKeys.isEmpty()) {
+        dump.append(INDENT3 "Virtual Keys:\n");
+
+        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
+            const VirtualKey& virtualKey = mVirtualKeys.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 PropertyMap& in = getDevice()->getConfiguration();
+    Calibration& out = mCalibration;
+
+    // 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 == "geometric") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
+        } else if (sizeCalibrationString == "diameter") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
+        } else if (sizeCalibrationString == "box") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
+        } else if (sizeCalibrationString == "area") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
+        } else if (sizeCalibrationString != "default") {
+            ALOGW("Invalid value for touch.size.calibration: '%s'",
+                    sizeCalibrationString.string());
+        }
+    }
+
+    out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
+            out.sizeScale);
+    out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
+            out.sizeBias);
+    out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
+            out.sizeIsSummed);
+
+    // 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") {
+            ALOGW("Invalid value for touch.pressure.calibration: '%s'",
+                    pressureCalibrationString.string());
+        }
+    }
+
+    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
+            out.pressureScale);
+
+    // 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 == "vector") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
+        } else if (orientationCalibrationString != "default") {
+            ALOGW("Invalid value for touch.orientation.calibration: '%s'",
+                    orientationCalibrationString.string());
+        }
+    }
+
+    // Distance
+    out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
+    String8 distanceCalibrationString;
+    if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
+        if (distanceCalibrationString == "none") {
+            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
+        } else if (distanceCalibrationString == "scaled") {
+            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
+        } else if (distanceCalibrationString != "default") {
+            ALOGW("Invalid value for touch.distance.calibration: '%s'",
+                    distanceCalibrationString.string());
+        }
+    }
+
+    out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
+            out.distanceScale);
+
+    out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_DEFAULT;
+    String8 coverageCalibrationString;
+    if (in.tryGetProperty(String8("touch.coverage.calibration"), coverageCalibrationString)) {
+        if (coverageCalibrationString == "none") {
+            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
+        } else if (coverageCalibrationString == "box") {
+            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_BOX;
+        } else if (coverageCalibrationString != "default") {
+            ALOGW("Invalid value for touch.coverage.calibration: '%s'",
+                    coverageCalibrationString.string());
+        }
+    }
+}
+
+void TouchInputMapper::resolveCalibration() {
+    // Size
+    if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
+        if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
+            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
+        }
+    } else {
+        mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+    }
+
+    // Pressure
+    if (mRawPointerAxes.pressure.valid) {
+        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
+            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
+        }
+    } else {
+        mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+    }
+
+    // Orientation
+    if (mRawPointerAxes.orientation.valid) {
+        if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
+            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        }
+    } else {
+        mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+    }
+
+    // Distance
+    if (mRawPointerAxes.distance.valid) {
+        if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
+            mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
+        }
+    } else {
+        mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
+    }
+
+    // Coverage
+    if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_DEFAULT) {
+        mCalibration.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
+    }
+}
+
+void TouchInputMapper::dumpCalibration(String8& dump) {
+    dump.append(INDENT3 "Calibration:\n");
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.size.calibration: none\n");
+        break;
+    case Calibration::SIZE_CALIBRATION_GEOMETRIC:
+        dump.append(INDENT4 "touch.size.calibration: geometric\n");
+        break;
+    case Calibration::SIZE_CALIBRATION_DIAMETER:
+        dump.append(INDENT4 "touch.size.calibration: diameter\n");
+        break;
+    case Calibration::SIZE_CALIBRATION_BOX:
+        dump.append(INDENT4 "touch.size.calibration: box\n");
+        break;
+    case Calibration::SIZE_CALIBRATION_AREA:
+        dump.append(INDENT4 "touch.size.calibration: area\n");
+        break;
+    default:
+        ALOG_ASSERT(false);
+    }
+
+    if (mCalibration.haveSizeScale) {
+        dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
+                mCalibration.sizeScale);
+    }
+
+    if (mCalibration.haveSizeBias) {
+        dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
+                mCalibration.sizeBias);
+    }
+
+    if (mCalibration.haveSizeIsSummed) {
+        dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
+                toString(mCalibration.sizeIsSummed));
+    }
+
+    // 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:
+        ALOG_ASSERT(false);
+    }
+
+    if (mCalibration.havePressureScale) {
+        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
+                mCalibration.pressureScale);
+    }
+
+    // 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;
+    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
+        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
+        break;
+    default:
+        ALOG_ASSERT(false);
+    }
+
+    // Distance
+    switch (mCalibration.distanceCalibration) {
+    case Calibration::DISTANCE_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.distance.calibration: none\n");
+        break;
+    case Calibration::DISTANCE_CALIBRATION_SCALED:
+        dump.append(INDENT4 "touch.distance.calibration: scaled\n");
+        break;
+    default:
+        ALOG_ASSERT(false);
+    }
+
+    if (mCalibration.haveDistanceScale) {
+        dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
+                mCalibration.distanceScale);
+    }
+
+    switch (mCalibration.coverageCalibration) {
+    case Calibration::COVERAGE_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.coverage.calibration: none\n");
+        break;
+    case Calibration::COVERAGE_CALIBRATION_BOX:
+        dump.append(INDENT4 "touch.coverage.calibration: box\n");
+        break;
+    default:
+        ALOG_ASSERT(false);
+    }
+}
+
+void TouchInputMapper::reset(nsecs_t when) {
+    mCursorButtonAccumulator.reset(getDevice());
+    mCursorScrollAccumulator.reset(getDevice());
+    mTouchButtonAccumulator.reset(getDevice());
+
+    mPointerVelocityControl.reset();
+    mWheelXVelocityControl.reset();
+    mWheelYVelocityControl.reset();
+
+    mCurrentRawPointerData.clear();
+    mLastRawPointerData.clear();
+    mCurrentCookedPointerData.clear();
+    mLastCookedPointerData.clear();
+    mCurrentButtonState = 0;
+    mLastButtonState = 0;
+    mCurrentRawVScroll = 0;
+    mCurrentRawHScroll = 0;
+    mCurrentFingerIdBits.clear();
+    mLastFingerIdBits.clear();
+    mCurrentStylusIdBits.clear();
+    mLastStylusIdBits.clear();
+    mCurrentMouseIdBits.clear();
+    mLastMouseIdBits.clear();
+    mPointerUsage = POINTER_USAGE_NONE;
+    mSentHoverEnter = false;
+    mDownTime = 0;
+
+    mCurrentVirtualKey.down = false;
+
+    mPointerGesture.reset();
+    mPointerSimple.reset();
+
+    if (mPointerController != NULL) {
+        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        mPointerController->clearSpots();
+    }
+
+    InputMapper::reset(when);
+}
+
+void TouchInputMapper::process(const RawEvent* rawEvent) {
+    mCursorButtonAccumulator.process(rawEvent);
+    mCursorScrollAccumulator.process(rawEvent);
+    mTouchButtonAccumulator.process(rawEvent);
+
+    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
+        sync(rawEvent->when);
+    }
+}
+
+void TouchInputMapper::sync(nsecs_t when) {
+    // Sync button state.
+    mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
+            | mCursorButtonAccumulator.getButtonState();
+
+    // Sync scroll state.
+    mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
+    mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
+    mCursorScrollAccumulator.finishSync();
+
+    // Sync touch state.
+    bool havePointerIds = true;
+    mCurrentRawPointerData.clear();
+    syncTouch(when, &havePointerIds);
+
+#if DEBUG_RAW_EVENTS
+    if (!havePointerIds) {
+        ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
+                mLastRawPointerData.pointerCount,
+                mCurrentRawPointerData.pointerCount);
+    } else {
+        ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
+                "hovering ids 0x%08x -> 0x%08x",
+                mLastRawPointerData.pointerCount,
+                mCurrentRawPointerData.pointerCount,
+                mLastRawPointerData.touchingIdBits.value,
+                mCurrentRawPointerData.touchingIdBits.value,
+                mLastRawPointerData.hoveringIdBits.value,
+                mCurrentRawPointerData.hoveringIdBits.value);
+    }
+#endif
+
+    // Reset state that we will compute below.
+    mCurrentFingerIdBits.clear();
+    mCurrentStylusIdBits.clear();
+    mCurrentMouseIdBits.clear();
+    mCurrentCookedPointerData.clear();
+
+    if (mDeviceMode == DEVICE_MODE_DISABLED) {
+        // Drop all input if the device is disabled.
+        mCurrentRawPointerData.clear();
+        mCurrentButtonState = 0;
+    } else {
+        // Preprocess pointer data.
+        if (!havePointerIds) {
+            assignPointerIds();
+        }
+
+        // Handle policy on initial down or hover events.
+        uint32_t policyFlags = 0;
+        bool initialDown = mLastRawPointerData.pointerCount == 0
+                && mCurrentRawPointerData.pointerCount != 0;
+        bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
+        if (initialDown || buttonsPressed) {
+            // If this is a touch screen, hide the pointer on an initial down.
+            if (mDeviceMode == DEVICE_MODE_DIRECT) {
+                getContext()->fadePointer();
+            }
+
+            // Initial downs on external touch devices should wake the device.
+            // We don't do this for internal touch screens to prevent them from waking
+            // up in your pocket.
+            // TODO: Use the input device configuration to control this behavior more finely.
+            if (getDevice()->isExternal()) {
+                policyFlags |= POLICY_FLAG_WAKE_DROPPED;
+            }
+        }
+
+        // Synthesize key down from raw buttons if needed.
+        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
+                policyFlags, mLastButtonState, mCurrentButtonState);
+
+        // Consume raw off-screen touches before cooking pointer data.
+        // If touches are consumed, subsequent code will not receive any pointer data.
+        if (consumeRawTouches(when, policyFlags)) {
+            mCurrentRawPointerData.clear();
+        }
+
+        // Cook pointer data.  This call populates the mCurrentCookedPointerData structure
+        // with cooked pointer data that has the same ids and indices as the raw data.
+        // The following code can use either the raw or cooked data, as needed.
+        cookPointerData();
+
+        // Dispatch the touches either directly or by translation through a pointer on screen.
+        if (mDeviceMode == DEVICE_MODE_POINTER) {
+            for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
+                uint32_t id = idBits.clearFirstMarkedBit();
+                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
+                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
+                    mCurrentStylusIdBits.markBit(id);
+                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
+                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
+                    mCurrentFingerIdBits.markBit(id);
+                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
+                    mCurrentMouseIdBits.markBit(id);
+                }
+            }
+            for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
+                uint32_t id = idBits.clearFirstMarkedBit();
+                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
+                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
+                    mCurrentStylusIdBits.markBit(id);
+                }
+            }
+
+            // Stylus takes precedence over all tools, then mouse, then finger.
+            PointerUsage pointerUsage = mPointerUsage;
+            if (!mCurrentStylusIdBits.isEmpty()) {
+                mCurrentMouseIdBits.clear();
+                mCurrentFingerIdBits.clear();
+                pointerUsage = POINTER_USAGE_STYLUS;
+            } else if (!mCurrentMouseIdBits.isEmpty()) {
+                mCurrentFingerIdBits.clear();
+                pointerUsage = POINTER_USAGE_MOUSE;
+            } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
+                pointerUsage = POINTER_USAGE_GESTURES;
+            }
+
+            dispatchPointerUsage(when, policyFlags, pointerUsage);
+        } else {
+            if (mDeviceMode == DEVICE_MODE_DIRECT
+                    && mConfig.showTouches && mPointerController != NULL) {
+                mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
+                mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+
+                mPointerController->setButtonState(mCurrentButtonState);
+                mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
+                        mCurrentCookedPointerData.idToIndex,
+                        mCurrentCookedPointerData.touchingIdBits);
+            }
+
+            dispatchHoverExit(when, policyFlags);
+            dispatchTouches(when, policyFlags);
+            dispatchHoverEnterAndMove(when, policyFlags);
+        }
+
+        // Synthesize key up from raw buttons if needed.
+        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
+                policyFlags, mLastButtonState, mCurrentButtonState);
+    }
+
+    // Copy current touch to last touch in preparation for the next cycle.
+    mLastRawPointerData.copyFrom(mCurrentRawPointerData);
+    mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
+    mLastButtonState = mCurrentButtonState;
+    mLastFingerIdBits = mCurrentFingerIdBits;
+    mLastStylusIdBits = mCurrentStylusIdBits;
+    mLastMouseIdBits = mCurrentMouseIdBits;
+
+    // Clear some transient state.
+    mCurrentRawVScroll = 0;
+    mCurrentRawHScroll = 0;
+}
+
+void TouchInputMapper::timeoutExpired(nsecs_t when) {
+    if (mDeviceMode == DEVICE_MODE_POINTER) {
+        if (mPointerUsage == POINTER_USAGE_GESTURES) {
+            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
+        }
+    }
+}
+
+bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
+    // Check for release of a virtual key.
+    if (mCurrentVirtualKey.down) {
+        if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+            // Pointer went up while virtual key was down.
+            mCurrentVirtualKey.down = false;
+            if (!mCurrentVirtualKey.ignored) {
+#if DEBUG_VIRTUAL_KEYS
+                ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
+                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+                dispatchVirtualKey(when, policyFlags,
+                        AKEY_EVENT_ACTION_UP,
+                        AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
+            }
+            return true;
+        }
+
+        if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+            uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+            const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+            if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
+                // Pointer is still within the space of the virtual key.
+                return true;
+            }
+        }
+
+        // Pointer left virtual key area or another pointer also went down.
+        // Send key cancellation but do not consume the touch yet.
+        // This is useful when the user swipes through from the virtual key area
+        // into the main display surface.
+        mCurrentVirtualKey.down = false;
+        if (!mCurrentVirtualKey.ignored) {
+#if DEBUG_VIRTUAL_KEYS
+            ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
+                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+            dispatchVirtualKey(when, policyFlags,
+                    AKEY_EVENT_ACTION_UP,
+                    AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+                            | AKEY_EVENT_FLAG_CANCELED);
+        }
+    }
+
+    if (mLastRawPointerData.touchingIdBits.isEmpty()
+            && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+        // Pointer just went down.  Check for virtual key press or off-screen touches.
+        uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+        const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+        if (!isPointInsideSurface(pointer.x, pointer.y)) {
+            // If exactly one pointer went down, check for virtual key hit.
+            // Otherwise we will drop the entire stroke.
+            if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+                const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+                if (virtualKey) {
+                    mCurrentVirtualKey.down = true;
+                    mCurrentVirtualKey.downTime = when;
+                    mCurrentVirtualKey.keyCode = virtualKey->keyCode;
+                    mCurrentVirtualKey.scanCode = virtualKey->scanCode;
+                    mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
+                            when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
+
+                    if (!mCurrentVirtualKey.ignored) {
+#if DEBUG_VIRTUAL_KEYS
+                        ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
+                                mCurrentVirtualKey.keyCode,
+                                mCurrentVirtualKey.scanCode);
+#endif
+                        dispatchVirtualKey(when, policyFlags,
+                                AKEY_EVENT_ACTION_DOWN,
+                                AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    // Disable all virtual key touches that happen within a short time interval of the
+    // most recent touch within the screen area.  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 (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+        mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
+    }
+    return false;
+}
+
+void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+        int32_t keyEventAction, int32_t keyEventFlags) {
+    int32_t keyCode = mCurrentVirtualKey.keyCode;
+    int32_t scanCode = mCurrentVirtualKey.scanCode;
+    nsecs_t downTime = mCurrentVirtualKey.downTime;
+    int32_t metaState = mContext->getGlobalMetaState();
+    policyFlags |= POLICY_FLAG_VIRTUAL;
+
+    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+    getListener()->notifyKey(&args);
+}
+
+void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
+    BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
+    BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
+    int32_t metaState = getContext()->getGlobalMetaState();
+    int32_t buttonState = mCurrentButtonState;
+
+    if (currentIdBits == lastIdBits) {
+        if (!currentIdBits.isEmpty()) {
+            // No pointer id changes so this is a move event.
+            // The listener takes care of batching moves so we don't have to deal with that here.
+            dispatchMotion(when, policyFlags, mSource,
+                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
+                    AMOTION_EVENT_EDGE_FLAG_NONE,
+                    mCurrentCookedPointerData.pointerProperties,
+                    mCurrentCookedPointerData.pointerCoords,
+                    mCurrentCookedPointerData.idToIndex,
+                    currentIdBits, -1,
+                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+        }
+    } 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 moveIdBits(lastIdBits.value & currentIdBits.value);
+        BitSet32 dispatchedIdBits(lastIdBits.value);
+
+        // Update last coordinates of pointers that have moved so that we observe the new
+        // pointer positions at the same time as other pointers that have just gone up.
+        bool moveNeeded = updateMovedPointers(
+                mCurrentCookedPointerData.pointerProperties,
+                mCurrentCookedPointerData.pointerCoords,
+                mCurrentCookedPointerData.idToIndex,
+                mLastCookedPointerData.pointerProperties,
+                mLastCookedPointerData.pointerCoords,
+                mLastCookedPointerData.idToIndex,
+                moveIdBits);
+        if (buttonState != mLastButtonState) {
+            moveNeeded = true;
+        }
+
+        // Dispatch pointer up events.
+        while (!upIdBits.isEmpty()) {
+            uint32_t upId = upIdBits.clearFirstMarkedBit();
+
+            dispatchMotion(when, policyFlags, mSource,
+                    AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
+                    mLastCookedPointerData.pointerProperties,
+                    mLastCookedPointerData.pointerCoords,
+                    mLastCookedPointerData.idToIndex,
+                    dispatchedIdBits, upId,
+                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+            dispatchedIdBits.clearBit(upId);
+        }
+
+        // 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) {
+            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
+            dispatchMotion(when, policyFlags, mSource,
+                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
+                    mCurrentCookedPointerData.pointerProperties,
+                    mCurrentCookedPointerData.pointerCoords,
+                    mCurrentCookedPointerData.idToIndex,
+                    dispatchedIdBits, -1,
+                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+        }
+
+        // Dispatch pointer down events using the new pointer locations.
+        while (!downIdBits.isEmpty()) {
+            uint32_t downId = downIdBits.clearFirstMarkedBit();
+            dispatchedIdBits.markBit(downId);
+
+            if (dispatchedIdBits.count() == 1) {
+                // First pointer is going down.  Set down time.
+                mDownTime = when;
+            }
+
+            dispatchMotion(when, policyFlags, mSource,
+                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
+                    mCurrentCookedPointerData.pointerProperties,
+                    mCurrentCookedPointerData.pointerCoords,
+                    mCurrentCookedPointerData.idToIndex,
+                    dispatchedIdBits, downId,
+                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+        }
+    }
+}
+
+void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
+    if (mSentHoverEnter &&
+            (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
+                    || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
+        int32_t metaState = getContext()->getGlobalMetaState();
+        dispatchMotion(when, policyFlags, mSource,
+                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
+                mLastCookedPointerData.pointerProperties,
+                mLastCookedPointerData.pointerCoords,
+                mLastCookedPointerData.idToIndex,
+                mLastCookedPointerData.hoveringIdBits, -1,
+                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+        mSentHoverEnter = false;
+    }
+}
+
+void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
+    if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
+            && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
+        int32_t metaState = getContext()->getGlobalMetaState();
+        if (!mSentHoverEnter) {
+            dispatchMotion(when, policyFlags, mSource,
+                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
+                    mCurrentCookedPointerData.pointerProperties,
+                    mCurrentCookedPointerData.pointerCoords,
+                    mCurrentCookedPointerData.idToIndex,
+                    mCurrentCookedPointerData.hoveringIdBits, -1,
+                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+            mSentHoverEnter = true;
+        }
+
+        dispatchMotion(when, policyFlags, mSource,
+                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
+                mCurrentCookedPointerData.pointerProperties,
+                mCurrentCookedPointerData.pointerCoords,
+                mCurrentCookedPointerData.idToIndex,
+                mCurrentCookedPointerData.hoveringIdBits, -1,
+                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+    }
+}
+
+void TouchInputMapper::cookPointerData() {
+    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+
+    mCurrentCookedPointerData.clear();
+    mCurrentCookedPointerData.pointerCount = currentPointerCount;
+    mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
+    mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
+
+    // Walk through the the active pointers and map device coordinates onto
+    // surface coordinates and adjust for display orientation.
+    for (uint32_t i = 0; i < currentPointerCount; i++) {
+        const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
+
+        // Size
+        float touchMajor, touchMinor, toolMajor, toolMinor, size;
+        switch (mCalibration.sizeCalibration) {
+        case Calibration::SIZE_CALIBRATION_GEOMETRIC:
+        case Calibration::SIZE_CALIBRATION_DIAMETER:
+        case Calibration::SIZE_CALIBRATION_BOX:
+        case Calibration::SIZE_CALIBRATION_AREA:
+            if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
+                touchMajor = in.touchMajor;
+                touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
+                toolMajor = in.toolMajor;
+                toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
+                size = mRawPointerAxes.touchMinor.valid
+                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
+            } else if (mRawPointerAxes.touchMajor.valid) {
+                toolMajor = touchMajor = in.touchMajor;
+                toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
+                        ? in.touchMinor : in.touchMajor;
+                size = mRawPointerAxes.touchMinor.valid
+                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
+            } else if (mRawPointerAxes.toolMajor.valid) {
+                touchMajor = toolMajor = in.toolMajor;
+                touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
+                        ? in.toolMinor : in.toolMajor;
+                size = mRawPointerAxes.toolMinor.valid
+                        ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
+            } else {
+                ALOG_ASSERT(false, "No touch or tool axes.  "
+                        "Size calibration should have been resolved to NONE.");
+                touchMajor = 0;
+                touchMinor = 0;
+                toolMajor = 0;
+                toolMinor = 0;
+                size = 0;
+            }
+
+            if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
+                uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
+                if (touchingCount > 1) {
+                    touchMajor /= touchingCount;
+                    touchMinor /= touchingCount;
+                    toolMajor /= touchingCount;
+                    toolMinor /= touchingCount;
+                    size /= touchingCount;
+                }
+            }
+
+            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
+                touchMajor *= mGeometricScale;
+                touchMinor *= mGeometricScale;
+                toolMajor *= mGeometricScale;
+                toolMinor *= mGeometricScale;
+            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
+                touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
+                touchMinor = touchMajor;
+                toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
+                toolMinor = toolMajor;
+            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
+                touchMinor = touchMajor;
+                toolMinor = toolMajor;
+            }
+
+            mCalibration.applySizeScaleAndBias(&touchMajor);
+            mCalibration.applySizeScaleAndBias(&touchMinor);
+            mCalibration.applySizeScaleAndBias(&toolMajor);
+            mCalibration.applySizeScaleAndBias(&toolMinor);
+            size *= mSizeScale;
+            break;
+        default:
+            touchMajor = 0;
+            touchMinor = 0;
+            toolMajor = 0;
+            toolMinor = 0;
+            size = 0;
+            break;
+        }
+
+        // Pressure
+        float pressure;
+        switch (mCalibration.pressureCalibration) {
+        case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+        case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+            pressure = in.pressure * mPressureScale;
+            break;
+        default:
+            pressure = in.isHovering ? 0 : 1;
+            break;
+        }
+
+        // Tilt and Orientation
+        float tilt;
+        float orientation;
+        if (mHaveTilt) {
+            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
+            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
+            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
+            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
+        } else {
+            tilt = 0;
+
+            switch (mCalibration.orientationCalibration) {
+            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+                orientation = in.orientation * mOrientationScale;
+                break;
+            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
+                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
+                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
+                if (c1 != 0 || c2 != 0) {
+                    orientation = atan2f(c1, c2) * 0.5f;
+                    float confidence = hypotf(c1, c2);
+                    float scale = 1.0f + confidence / 16.0f;
+                    touchMajor *= scale;
+                    touchMinor /= scale;
+                    toolMajor *= scale;
+                    toolMinor /= scale;
+                } else {
+                    orientation = 0;
+                }
+                break;
+            }
+            default:
+                orientation = 0;
+            }
+        }
+
+        // Distance
+        float distance;
+        switch (mCalibration.distanceCalibration) {
+        case Calibration::DISTANCE_CALIBRATION_SCALED:
+            distance = in.distance * mDistanceScale;
+            break;
+        default:
+            distance = 0;
+        }
+
+        // Coverage
+        int32_t rawLeft, rawTop, rawRight, rawBottom;
+        switch (mCalibration.coverageCalibration) {
+        case Calibration::COVERAGE_CALIBRATION_BOX:
+            rawLeft = (in.toolMinor & 0xffff0000) >> 16;
+            rawRight = in.toolMinor & 0x0000ffff;
+            rawBottom = in.toolMajor & 0x0000ffff;
+            rawTop = (in.toolMajor & 0xffff0000) >> 16;
+            break;
+        default:
+            rawLeft = rawTop = rawRight = rawBottom = 0;
+            break;
+        }
+
+        // X, Y, and the bounding box for coverage information
+        // Adjust coords for surface orientation.
+        float x, y, left, top, right, bottom;
+        switch (mSurfaceOrientation) {
+        case DISPLAY_ORIENTATION_90:
+            x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+            y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
+            left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+            right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+            bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
+            top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
+            orientation -= M_PI_2;
+            if (orientation < mOrientedRanges.orientation.min) {
+                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
+            }
+            break;
+        case DISPLAY_ORIENTATION_180:
+            x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
+            y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
+            left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
+            right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
+            bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
+            top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
+            orientation -= M_PI;
+            if (orientation < mOrientedRanges.orientation.min) {
+                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
+            }
+            break;
+        case DISPLAY_ORIENTATION_270:
+            x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
+            y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+            left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
+            right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
+            bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+            top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+            orientation += M_PI_2;
+            if (orientation > mOrientedRanges.orientation.max) {
+                orientation -= (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
+            }
+            break;
+        default:
+            x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+            y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+            left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+            right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+            bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+            top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+            break;
+        }
+
+        // Write output coords.
+        PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
+        out.clear();
+        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
+        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
+        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
+        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
+        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
+        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
+        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
+        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
+            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
+            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
+            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
+            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
+        } else {
+            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
+            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
+        }
+
+        // Write output properties.
+        PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
+        uint32_t id = in.id;
+        properties.clear();
+        properties.id = id;
+        properties.toolType = in.toolType;
+
+        // Write id index.
+        mCurrentCookedPointerData.idToIndex[id] = i;
+    }
+}
+
+void TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
+        PointerUsage pointerUsage) {
+    if (pointerUsage != mPointerUsage) {
+        abortPointerUsage(when, policyFlags);
+        mPointerUsage = pointerUsage;
+    }
+
+    switch (mPointerUsage) {
+    case POINTER_USAGE_GESTURES:
+        dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
+        break;
+    case POINTER_USAGE_STYLUS:
+        dispatchPointerStylus(when, policyFlags);
+        break;
+    case POINTER_USAGE_MOUSE:
+        dispatchPointerMouse(when, policyFlags);
+        break;
+    default:
+        break;
+    }
+}
+
+void TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
+    switch (mPointerUsage) {
+    case POINTER_USAGE_GESTURES:
+        abortPointerGestures(when, policyFlags);
+        break;
+    case POINTER_USAGE_STYLUS:
+        abortPointerStylus(when, policyFlags);
+        break;
+    case POINTER_USAGE_MOUSE:
+        abortPointerMouse(when, policyFlags);
+        break;
+    default:
+        break;
+    }
+
+    mPointerUsage = POINTER_USAGE_NONE;
+}
+
+void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
+        bool isTimeout) {
+    // Update current gesture coordinates.
+    bool cancelPreviousGesture, finishPreviousGesture;
+    bool sendEvents = preparePointerGestures(when,
+            &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
+    if (!sendEvents) {
+        return;
+    }
+    if (finishPreviousGesture) {
+        cancelPreviousGesture = false;
+    }
+
+    // Update the pointer presentation and spots.
+    if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
+        if (finishPreviousGesture || cancelPreviousGesture) {
+            mPointerController->clearSpots();
+        }
+        mPointerController->setSpots(mPointerGesture.currentGestureCoords,
+                mPointerGesture.currentGestureIdToIndex,
+                mPointerGesture.currentGestureIdBits);
+    } else {
+        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+    }
+
+    // Show or hide the pointer if needed.
+    switch (mPointerGesture.currentGestureMode) {
+    case PointerGesture::NEUTRAL:
+    case PointerGesture::QUIET:
+        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
+                && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
+                        || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
+            // Remind the user of where the pointer is after finishing a gesture with spots.
+            mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
+        }
+        break;
+    case PointerGesture::TAP:
+    case PointerGesture::TAP_DRAG:
+    case PointerGesture::BUTTON_CLICK_OR_DRAG:
+    case PointerGesture::HOVER:
+    case PointerGesture::PRESS:
+        // Unfade the pointer when the current gesture manipulates the
+        // area directly under the pointer.
+        mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+        break;
+    case PointerGesture::SWIPE:
+    case PointerGesture::FREEFORM:
+        // Fade the pointer when the current gesture manipulates a different
+        // area and there are spots to guide the user experience.
+        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        } else {
+            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+        }
+        break;
+    }
+
+    // Send events!
+    int32_t metaState = getContext()->getGlobalMetaState();
+    int32_t buttonState = mCurrentButtonState;
+
+    // Update last coordinates of pointers that have moved so that we observe the new
+    // pointer positions at the same time as other pointers that have just gone up.
+    bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
+            || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
+            || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
+            || mPointerGesture.currentGestureMode == PointerGesture::PRESS
+            || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
+            || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
+    bool moveNeeded = false;
+    if (down && !cancelPreviousGesture && !finishPreviousGesture
+            && !mPointerGesture.lastGestureIdBits.isEmpty()
+            && !mPointerGesture.currentGestureIdBits.isEmpty()) {
+        BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
+                & mPointerGesture.lastGestureIdBits.value);
+        moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
+                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
+                mPointerGesture.lastGestureProperties,
+                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
+                movedGestureIdBits);
+        if (buttonState != mLastButtonState) {
+            moveNeeded = true;
+        }
+    }
+
+    // Send motion events for all pointers that went up or were canceled.
+    BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
+    if (!dispatchedGestureIdBits.isEmpty()) {
+        if (cancelPreviousGesture) {
+            dispatchMotion(when, policyFlags, mSource,
+                    AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
+                    AMOTION_EVENT_EDGE_FLAG_NONE,
+                    mPointerGesture.lastGestureProperties,
+                    mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
+                    dispatchedGestureIdBits, -1,
+                    0, 0, mPointerGesture.downTime);
+
+            dispatchedGestureIdBits.clear();
+        } else {
+            BitSet32 upGestureIdBits;
+            if (finishPreviousGesture) {
+                upGestureIdBits = dispatchedGestureIdBits;
+            } else {
+                upGestureIdBits.value = dispatchedGestureIdBits.value
+                        & ~mPointerGesture.currentGestureIdBits.value;
+            }
+            while (!upGestureIdBits.isEmpty()) {
+                uint32_t id = upGestureIdBits.clearFirstMarkedBit();
+
+                dispatchMotion(when, policyFlags, mSource,
+                        AMOTION_EVENT_ACTION_POINTER_UP, 0,
+                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+                        mPointerGesture.lastGestureProperties,
+                        mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
+                        dispatchedGestureIdBits, id,
+                        0, 0, mPointerGesture.downTime);
+
+                dispatchedGestureIdBits.clearBit(id);
+            }
+        }
+    }
+
+    // Send motion events for all pointers that moved.
+    if (moveNeeded) {
+        dispatchMotion(when, policyFlags, mSource,
+                AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+                mPointerGesture.currentGestureProperties,
+                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
+                dispatchedGestureIdBits, -1,
+                0, 0, mPointerGesture.downTime);
+    }
+
+    // Send motion events for all pointers that went down.
+    if (down) {
+        BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
+                & ~dispatchedGestureIdBits.value);
+        while (!downGestureIdBits.isEmpty()) {
+            uint32_t id = downGestureIdBits.clearFirstMarkedBit();
+            dispatchedGestureIdBits.markBit(id);
+
+            if (dispatchedGestureIdBits.count() == 1) {
+                mPointerGesture.downTime = when;
+            }
+
+            dispatchMotion(when, policyFlags, mSource,
+                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
+                    mPointerGesture.currentGestureProperties,
+                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
+                    dispatchedGestureIdBits, id,
+                    0, 0, mPointerGesture.downTime);
+        }
+    }
+
+    // Send motion events for hover.
+    if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
+        dispatchMotion(when, policyFlags, mSource,
+                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+                mPointerGesture.currentGestureProperties,
+                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
+                mPointerGesture.currentGestureIdBits, -1,
+                0, 0, mPointerGesture.downTime);
+    } else if (dispatchedGestureIdBits.isEmpty()
+            && !mPointerGesture.lastGestureIdBits.isEmpty()) {
+        // Synthesize a hover move event after all pointers go up to indicate that
+        // the pointer is hovering again even if the user is not currently touching
+        // the touch pad.  This ensures that a view will receive a fresh hover enter
+        // event after a tap.
+        float x, y;
+        mPointerController->getPosition(&x, &y);
+
+        PointerProperties pointerProperties;
+        pointerProperties.clear();
+        pointerProperties.id = 0;
+        pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+
+        PointerCoords pointerCoords;
+        pointerCoords.clear();
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+
+        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+                mViewport.displayId, 1, &pointerProperties, &pointerCoords,
+                0, 0, mPointerGesture.downTime);
+        getListener()->notifyMotion(&args);
+    }
+
+    // Update state.
+    mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
+    if (!down) {
+        mPointerGesture.lastGestureIdBits.clear();
+    } else {
+        mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
+        for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
+            uint32_t id = idBits.clearFirstMarkedBit();
+            uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
+            mPointerGesture.lastGestureProperties[index].copyFrom(
+                    mPointerGesture.currentGestureProperties[index]);
+            mPointerGesture.lastGestureCoords[index].copyFrom(
+                    mPointerGesture.currentGestureCoords[index]);
+            mPointerGesture.lastGestureIdToIndex[id] = index;
+        }
+    }
+}
+
+void TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
+    // Cancel previously dispatches pointers.
+    if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
+        int32_t metaState = getContext()->getGlobalMetaState();
+        int32_t buttonState = mCurrentButtonState;
+        dispatchMotion(when, policyFlags, mSource,
+                AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
+                AMOTION_EVENT_EDGE_FLAG_NONE,
+                mPointerGesture.lastGestureProperties,
+                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
+                mPointerGesture.lastGestureIdBits, -1,
+                0, 0, mPointerGesture.downTime);
+    }
+
+    // Reset the current pointer gesture.
+    mPointerGesture.reset();
+    mPointerVelocityControl.reset();
+
+    // Remove any current spots.
+    if (mPointerController != NULL) {
+        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        mPointerController->clearSpots();
+    }
+}
+
+bool TouchInputMapper::preparePointerGestures(nsecs_t when,
+        bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
+    *outCancelPreviousGesture = false;
+    *outFinishPreviousGesture = false;
+
+    // Handle TAP timeout.
+    if (isTimeout) {
+#if DEBUG_GESTURES
+        ALOGD("Gestures: Processing timeout");
+#endif
+
+        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
+            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
+                // The tap/drag timeout has not yet expired.
+                getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
+                        + mConfig.pointerGestureTapDragInterval);
+            } else {
+                // The tap is finished.
+#if DEBUG_GESTURES
+                ALOGD("Gestures: TAP finished");
+#endif
+                *outFinishPreviousGesture = true;
+
+                mPointerGesture.activeGestureId = -1;
+                mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
+                mPointerGesture.currentGestureIdBits.clear();
+
+                mPointerVelocityControl.reset();
+                return true;
+            }
+        }
+
+        // We did not handle this timeout.
+        return false;
+    }
+
+    const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
+    const uint32_t lastFingerCount = mLastFingerIdBits.count();
+
+    // Update the velocity tracker.
+    {
+        VelocityTracker::Position positions[MAX_POINTERS];
+        uint32_t count = 0;
+        for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
+            uint32_t id = idBits.clearFirstMarkedBit();
+            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+            positions[count].x = pointer.x * mPointerXMovementScale;
+            positions[count].y = pointer.y * mPointerYMovementScale;
+        }
+        mPointerGesture.velocityTracker.addMovement(when,
+                mCurrentFingerIdBits, positions);
+    }
+
+    // If the gesture ever enters a mode other than TAP, HOVER or TAP_DRAG, without first returning
+    // to NEUTRAL, then we should not generate tap event.
+    if (mPointerGesture.lastGestureMode != PointerGesture::HOVER
+            && mPointerGesture.lastGestureMode != PointerGesture::TAP
+            && mPointerGesture.lastGestureMode != PointerGesture::TAP_DRAG) {
+        mPointerGesture.resetTap();
+    }
+
+    // Pick a new active touch id if needed.
+    // Choose an arbitrary pointer that just went down, if there is one.
+    // Otherwise choose an arbitrary remaining pointer.
+    // This guarantees we always have an active touch id when there is at least one pointer.
+    // We keep the same active touch id for as long as possible.
+    bool activeTouchChanged = false;
+    int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
+    int32_t activeTouchId = lastActiveTouchId;
+    if (activeTouchId < 0) {
+        if (!mCurrentFingerIdBits.isEmpty()) {
+            activeTouchChanged = true;
+            activeTouchId = mPointerGesture.activeTouchId =
+                    mCurrentFingerIdBits.firstMarkedBit();
+            mPointerGesture.firstTouchTime = when;
+        }
+    } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
+        activeTouchChanged = true;
+        if (!mCurrentFingerIdBits.isEmpty()) {
+            activeTouchId = mPointerGesture.activeTouchId =
+                    mCurrentFingerIdBits.firstMarkedBit();
+        } else {
+            activeTouchId = mPointerGesture.activeTouchId = -1;
+        }
+    }
+
+    // Determine whether we are in quiet time.
+    bool isQuietTime = false;
+    if (activeTouchId < 0) {
+        mPointerGesture.resetQuietTime();
+    } else {
+        isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
+        if (!isQuietTime) {
+            if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
+                    || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
+                    || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
+                    && currentFingerCount < 2) {
+                // Enter quiet time when exiting swipe or freeform state.
+                // This is to prevent accidentally entering the hover state and flinging the
+                // pointer when finishing a swipe and there is still one pointer left onscreen.
+                isQuietTime = true;
+            } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
+                    && currentFingerCount >= 2
+                    && !isPointerDown(mCurrentButtonState)) {
+                // Enter quiet time when releasing the button and there are still two or more
+                // fingers down.  This may indicate that one finger was used to press the button
+                // but it has not gone up yet.
+                isQuietTime = true;
+            }
+            if (isQuietTime) {
+                mPointerGesture.quietTime = when;
+            }
+        }
+    }
+
+    // Switch states based on button and pointer state.
+    if (isQuietTime) {
+        // Case 1: Quiet time. (QUIET)
+#if DEBUG_GESTURES
+        ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
+                + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
+#endif
+        if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
+            *outFinishPreviousGesture = true;
+        }
+
+        mPointerGesture.activeGestureId = -1;
+        mPointerGesture.currentGestureMode = PointerGesture::QUIET;
+        mPointerGesture.currentGestureIdBits.clear();
+
+        mPointerVelocityControl.reset();
+    } else if (isPointerDown(mCurrentButtonState)) {
+        // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
+        // The pointer follows the active touch point.
+        // Emit DOWN, MOVE, UP events at the pointer location.
+        //
+        // Only the active touch matters; other fingers are ignored.  This policy helps
+        // to handle the case where the user places a second finger on the touch pad
+        // to apply the necessary force to depress an integrated button below the surface.
+        // We don't want the second finger to be delivered to applications.
+        //
+        // For this to work well, we need to make sure to track the pointer that is really
+        // active.  If the user first puts one finger down to click then adds another
+        // finger to drag then the active pointer should switch to the finger that is
+        // being dragged.
+#if DEBUG_GESTURES
+        ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
+                "currentFingerCount=%d", activeTouchId, currentFingerCount);
+#endif
+        // Reset state when just starting.
+        if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
+            *outFinishPreviousGesture = true;
+            mPointerGesture.activeGestureId = 0;
+        }
+
+        // Switch pointers if needed.
+        // Find the fastest pointer and follow it.
+        if (activeTouchId >= 0 && currentFingerCount > 1) {
+            int32_t bestId = -1;
+            float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
+            for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
+                uint32_t id = idBits.clearFirstMarkedBit();
+                float vx, vy;
+                if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
+                    float speed = hypotf(vx, vy);
+                    if (speed > bestSpeed) {
+                        bestId = id;
+                        bestSpeed = speed;
+                    }
+                }
+            }
+            if (bestId >= 0 && bestId != activeTouchId) {
+                mPointerGesture.activeTouchId = activeTouchId = bestId;
+                activeTouchChanged = true;
+#if DEBUG_GESTURES
+                ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
+                        "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
+#endif
+            }
+        }
+
+        if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
+            const RawPointerData::Pointer& currentPointer =
+                    mCurrentRawPointerData.pointerForId(activeTouchId);
+            const RawPointerData::Pointer& lastPointer =
+                    mLastRawPointerData.pointerForId(activeTouchId);
+            float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
+            float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
+
+            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
+            mPointerVelocityControl.move(when, &deltaX, &deltaY);
+
+            // Move the pointer using a relative motion.
+            // When using spots, the click will occur at the position of the anchor
+            // spot and all other spots will move there.
+            mPointerController->move(deltaX, deltaY);
+        } else {
+            mPointerVelocityControl.reset();
+        }
+
+        float x, y;
+        mPointerController->getPosition(&x, &y);
+
+        mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
+        mPointerGesture.currentGestureIdBits.clear();
+        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
+        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
+        mPointerGesture.currentGestureProperties[0].clear();
+        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
+        mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+        mPointerGesture.currentGestureCoords[0].clear();
+        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
+        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
+    } else if (currentFingerCount == 0) {
+        // Case 3. No fingers down and button is not pressed. (NEUTRAL)
+        if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
+            *outFinishPreviousGesture = true;
+        }
+
+        // Watch for taps coming out of HOVER or TAP_DRAG mode.
+        // Checking for taps after TAP_DRAG allows us to detect double-taps.
+        bool tapped = false;
+        if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
+                || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
+                && lastFingerCount == 1) {
+            if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
+                float x, y;
+                mPointerController->getPosition(&x, &y);
+                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
+                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
+#if DEBUG_GESTURES
+                    ALOGD("Gestures: TAP");
+#endif
+
+                    mPointerGesture.tapUpTime = when;
+                    getContext()->requestTimeoutAtTime(when
+                            + mConfig.pointerGestureTapDragInterval);
+
+                    mPointerGesture.activeGestureId = 0;
+                    mPointerGesture.currentGestureMode = PointerGesture::TAP;
+                    mPointerGesture.currentGestureIdBits.clear();
+                    mPointerGesture.currentGestureIdBits.markBit(
+                            mPointerGesture.activeGestureId);
+                    mPointerGesture.currentGestureIdToIndex[
+                            mPointerGesture.activeGestureId] = 0;
+                    mPointerGesture.currentGestureProperties[0].clear();
+                    mPointerGesture.currentGestureProperties[0].id =
+                            mPointerGesture.activeGestureId;
+                    mPointerGesture.currentGestureProperties[0].toolType =
+                            AMOTION_EVENT_TOOL_TYPE_FINGER;
+                    mPointerGesture.currentGestureCoords[0].clear();
+                    mPointerGesture.currentGestureCoords[0].setAxisValue(
+                            AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
+                    mPointerGesture.currentGestureCoords[0].setAxisValue(
+                            AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
+                    mPointerGesture.currentGestureCoords[0].setAxisValue(
+                            AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
+
+                    tapped = true;
+                } else {
+#if DEBUG_GESTURES
+                    ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
+                            x - mPointerGesture.tapX,
+                            y - mPointerGesture.tapY);
+#endif
+                }
+            } else {
+#if DEBUG_GESTURES
+                if (mPointerGesture.tapDownTime != LLONG_MIN) {
+                    ALOGD("Gestures: Not a TAP, %0.3fms since down",
+                            (when - mPointerGesture.tapDownTime) * 0.000001f);
+                } else {
+                    ALOGD("Gestures: Not a TAP, incompatible mode transitions");
+                }
+#endif
+            }
+        }
+
+        mPointerVelocityControl.reset();
+
+        if (!tapped) {
+#if DEBUG_GESTURES
+            ALOGD("Gestures: NEUTRAL");
+#endif
+            mPointerGesture.activeGestureId = -1;
+            mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
+            mPointerGesture.currentGestureIdBits.clear();
+        }
+    } else if (currentFingerCount == 1) {
+        // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
+        // The pointer follows the active touch point.
+        // When in HOVER, emit HOVER_MOVE events at the pointer location.
+        // When in TAP_DRAG, emit MOVE events at the pointer location.
+        ALOG_ASSERT(activeTouchId >= 0);
+
+        mPointerGesture.currentGestureMode = PointerGesture::HOVER;
+        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
+            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
+                float x, y;
+                mPointerController->getPosition(&x, &y);
+                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
+                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
+                    mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
+                } else {
+#if DEBUG_GESTURES
+                    ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
+                            x - mPointerGesture.tapX,
+                            y - mPointerGesture.tapY);
+#endif
+                }
+            } else {
+#if DEBUG_GESTURES
+                ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
+                        (when - mPointerGesture.tapUpTime) * 0.000001f);
+#endif
+            }
+        } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
+            mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
+        }
+
+        if (mLastFingerIdBits.hasBit(activeTouchId)) {
+            const RawPointerData::Pointer& currentPointer =
+                    mCurrentRawPointerData.pointerForId(activeTouchId);
+            const RawPointerData::Pointer& lastPointer =
+                    mLastRawPointerData.pointerForId(activeTouchId);
+            float deltaX = (currentPointer.x - lastPointer.x)
+                    * mPointerXMovementScale;
+            float deltaY = (currentPointer.y - lastPointer.y)
+                    * mPointerYMovementScale;
+
+            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
+            mPointerVelocityControl.move(when, &deltaX, &deltaY);
+
+            // Move the pointer using a relative motion.
+            // When using spots, the hover or drag will occur at the position of the anchor spot.
+            mPointerController->move(deltaX, deltaY);
+        } else {
+            mPointerVelocityControl.reset();
+        }
+
+        bool down;
+        if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
+#if DEBUG_GESTURES
+            ALOGD("Gestures: TAP_DRAG");
+#endif
+            down = true;
+        } else {
+#if DEBUG_GESTURES
+            ALOGD("Gestures: HOVER");
+#endif
+            if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
+                *outFinishPreviousGesture = true;
+            }
+            mPointerGesture.activeGestureId = 0;
+            down = false;
+        }
+
+        float x, y;
+        mPointerController->getPosition(&x, &y);
+
+        mPointerGesture.currentGestureIdBits.clear();
+        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
+        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
+        mPointerGesture.currentGestureProperties[0].clear();
+        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
+        mPointerGesture.currentGestureProperties[0].toolType =
+                AMOTION_EVENT_TOOL_TYPE_FINGER;
+        mPointerGesture.currentGestureCoords[0].clear();
+        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
+        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
+                down ? 1.0f : 0.0f);
+
+        if (lastFingerCount == 0 && currentFingerCount != 0) {
+            mPointerGesture.resetTap();
+            mPointerGesture.tapDownTime = when;
+            mPointerGesture.tapX = x;
+            mPointerGesture.tapY = y;
+        }
+    } else {
+        // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
+        // We need to provide feedback for each finger that goes down so we cannot wait
+        // for the fingers to move before deciding what to do.
+        //
+        // The ambiguous case is deciding what to do when there are two fingers down but they
+        // have not moved enough to determine whether they are part of a drag or part of a
+        // freeform gesture, or just a press or long-press at the pointer location.
+        //
+        // When there are two fingers we start with the PRESS hypothesis and we generate a
+        // down at the pointer location.
+        //
+        // When the two fingers move enough or when additional fingers are added, we make
+        // a decision to transition into SWIPE or FREEFORM mode accordingly.
+        ALOG_ASSERT(activeTouchId >= 0);
+
+        bool settled = when >= mPointerGesture.firstTouchTime
+                + mConfig.pointerGestureMultitouchSettleInterval;
+        if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
+                && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
+                && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
+            *outFinishPreviousGesture = true;
+        } else if (!settled && currentFingerCount > lastFingerCount) {
+            // Additional pointers have gone down but not yet settled.
+            // Reset the gesture.
+#if DEBUG_GESTURES
+            ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
+                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
+                            + mConfig.pointerGestureMultitouchSettleInterval - when)
+                            * 0.000001f);
+#endif
+            *outCancelPreviousGesture = true;
+        } else {
+            // Continue previous gesture.
+            mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
+        }
+
+        if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
+            mPointerGesture.currentGestureMode = PointerGesture::PRESS;
+            mPointerGesture.activeGestureId = 0;
+            mPointerGesture.referenceIdBits.clear();
+            mPointerVelocityControl.reset();
+
+            // Use the centroid and pointer location as the reference points for the gesture.
+#if DEBUG_GESTURES
+            ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
+                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
+                            + mConfig.pointerGestureMultitouchSettleInterval - when)
+                            * 0.000001f);
+#endif
+            mCurrentRawPointerData.getCentroidOfTouchingPointers(
+                    &mPointerGesture.referenceTouchX,
+                    &mPointerGesture.referenceTouchY);
+            mPointerController->getPosition(&mPointerGesture.referenceGestureX,
+                    &mPointerGesture.referenceGestureY);
+        }
+
+        // Clear the reference deltas for fingers not yet included in the reference calculation.
+        for (BitSet32 idBits(mCurrentFingerIdBits.value
+                & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
+            uint32_t id = idBits.clearFirstMarkedBit();
+            mPointerGesture.referenceDeltas[id].dx = 0;
+            mPointerGesture.referenceDeltas[id].dy = 0;
+        }
+        mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
+
+        // Add delta for all fingers and calculate a common movement delta.
+        float commonDeltaX = 0, commonDeltaY = 0;
+        BitSet32 commonIdBits(mLastFingerIdBits.value
+                & mCurrentFingerIdBits.value);
+        for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
+            bool first = (idBits == commonIdBits);
+            uint32_t id = idBits.clearFirstMarkedBit();
+            const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
+            const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
+            PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
+            delta.dx += cpd.x - lpd.x;
+            delta.dy += cpd.y - lpd.y;
+
+            if (first) {
+                commonDeltaX = delta.dx;
+                commonDeltaY = delta.dy;
+            } else {
+                commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
+                commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
+            }
+        }
+
+        // Consider transitions from PRESS to SWIPE or MULTITOUCH.
+        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
+            float dist[MAX_POINTER_ID + 1];
+            int32_t distOverThreshold = 0;
+            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
+                uint32_t id = idBits.clearFirstMarkedBit();
+                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
+                dist[id] = hypotf(delta.dx * mPointerXZoomScale,
+                        delta.dy * mPointerYZoomScale);
+                if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
+                    distOverThreshold += 1;
+                }
+            }
+
+            // Only transition when at least two pointers have moved further than
+            // the minimum distance threshold.
+            if (distOverThreshold >= 2) {
+                if (currentFingerCount > 2) {
+                    // There are more than two pointers, switch to FREEFORM.
+#if DEBUG_GESTURES
+                    ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
+                            currentFingerCount);
+#endif
+                    *outCancelPreviousGesture = true;
+                    mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+                } else {
+                    // There are exactly two pointers.
+                    BitSet32 idBits(mCurrentFingerIdBits);
+                    uint32_t id1 = idBits.clearFirstMarkedBit();
+                    uint32_t id2 = idBits.firstMarkedBit();
+                    const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
+                    const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
+                    float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
+                    if (mutualDistance > mPointerGestureMaxSwipeWidth) {
+                        // There are two pointers but they are too far apart for a SWIPE,
+                        // switch to FREEFORM.
+#if DEBUG_GESTURES
+                        ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
+                                mutualDistance, mPointerGestureMaxSwipeWidth);
+#endif
+                        *outCancelPreviousGesture = true;
+                        mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+                    } else {
+                        // There are two pointers.  Wait for both pointers to start moving
+                        // before deciding whether this is a SWIPE or FREEFORM gesture.
+                        float dist1 = dist[id1];
+                        float dist2 = dist[id2];
+                        if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
+                                && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
+                            // Calculate the dot product of the displacement vectors.
+                            // When the vectors are oriented in approximately the same direction,
+                            // the angle betweeen them is near zero and the cosine of the angle
+                            // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
+                            PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
+                            PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
+                            float dx1 = delta1.dx * mPointerXZoomScale;
+                            float dy1 = delta1.dy * mPointerYZoomScale;
+                            float dx2 = delta2.dx * mPointerXZoomScale;
+                            float dy2 = delta2.dy * mPointerYZoomScale;
+                            float dot = dx1 * dx2 + dy1 * dy2;
+                            float cosine = dot / (dist1 * dist2); // denominator always > 0
+                            if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
+                                // Pointers are moving in the same direction.  Switch to SWIPE.
+#if DEBUG_GESTURES
+                                ALOGD("Gestures: PRESS transitioned to SWIPE, "
+                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+                                        "cosine %0.3f >= %0.3f",
+                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
+                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
+                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
+#endif
+                                mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
+                            } else {
+                                // Pointers are moving in different directions.  Switch to FREEFORM.
+#if DEBUG_GESTURES
+                                ALOGD("Gestures: PRESS transitioned to FREEFORM, "
+                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+                                        "cosine %0.3f < %0.3f",
+                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
+                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
+                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
+#endif
+                                *outCancelPreviousGesture = true;
+                                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+                            }
+                        }
+                    }
+                }
+            }
+        } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
+            // Switch from SWIPE to FREEFORM if additional pointers go down.
+            // Cancel previous gesture.
+            if (currentFingerCount > 2) {
+#if DEBUG_GESTURES
+                ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
+                        currentFingerCount);
+#endif
+                *outCancelPreviousGesture = true;
+                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+            }
+        }
+
+        // Move the reference points based on the overall group motion of the fingers
+        // except in PRESS mode while waiting for a transition to occur.
+        if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
+                && (commonDeltaX || commonDeltaY)) {
+            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
+                uint32_t id = idBits.clearFirstMarkedBit();
+                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
+                delta.dx = 0;
+                delta.dy = 0;
+            }
+
+            mPointerGesture.referenceTouchX += commonDeltaX;
+            mPointerGesture.referenceTouchY += commonDeltaY;
+
+            commonDeltaX *= mPointerXMovementScale;
+            commonDeltaY *= mPointerYMovementScale;
+
+            rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
+            mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
+
+            mPointerGesture.referenceGestureX += commonDeltaX;
+            mPointerGesture.referenceGestureY += commonDeltaY;
+        }
+
+        // Report gestures.
+        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
+                || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
+            // PRESS or SWIPE mode.
+#if DEBUG_GESTURES
+            ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
+                    "activeGestureId=%d, currentTouchPointerCount=%d",
+                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
+#endif
+            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
+
+            mPointerGesture.currentGestureIdBits.clear();
+            mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
+            mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
+            mPointerGesture.currentGestureProperties[0].clear();
+            mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
+            mPointerGesture.currentGestureProperties[0].toolType =
+                    AMOTION_EVENT_TOOL_TYPE_FINGER;
+            mPointerGesture.currentGestureCoords[0].clear();
+            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
+                    mPointerGesture.referenceGestureX);
+            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
+                    mPointerGesture.referenceGestureY);
+            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
+        } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
+            // FREEFORM mode.
+#if DEBUG_GESTURES
+            ALOGD("Gestures: FREEFORM activeTouchId=%d,"
+                    "activeGestureId=%d, currentTouchPointerCount=%d",
+                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
+#endif
+            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
+
+            mPointerGesture.currentGestureIdBits.clear();
+
+            BitSet32 mappedTouchIdBits;
+            BitSet32 usedGestureIdBits;
+            if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
+                // Initially, assign the active gesture id to the active touch point
+                // if there is one.  No other touch id bits are mapped yet.
+                if (!*outCancelPreviousGesture) {
+                    mappedTouchIdBits.markBit(activeTouchId);
+                    usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
+                    mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
+                            mPointerGesture.activeGestureId;
+                } else {
+                    mPointerGesture.activeGestureId = -1;
+                }
+            } else {
+                // Otherwise, assume we mapped all touches from the previous frame.
+                // Reuse all mappings that are still applicable.
+                mappedTouchIdBits.value = mLastFingerIdBits.value
+                        & mCurrentFingerIdBits.value;
+                usedGestureIdBits = mPointerGesture.lastGestureIdBits;
+
+                // Check whether we need to choose a new active gesture id because the
+                // current went went up.
+                for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
+                        & ~mCurrentFingerIdBits.value);
+                        !upTouchIdBits.isEmpty(); ) {
+                    uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
+                    uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
+                    if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
+                        mPointerGesture.activeGestureId = -1;
+                        break;
+                    }
+                }
+            }
+
+#if DEBUG_GESTURES
+            ALOGD("Gestures: FREEFORM follow up "
+                    "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
+                    "activeGestureId=%d",
+                    mappedTouchIdBits.value, usedGestureIdBits.value,
+                    mPointerGesture.activeGestureId);
+#endif
+
+            BitSet32 idBits(mCurrentFingerIdBits);
+            for (uint32_t i = 0; i < currentFingerCount; i++) {
+                uint32_t touchId = idBits.clearFirstMarkedBit();
+                uint32_t gestureId;
+                if (!mappedTouchIdBits.hasBit(touchId)) {
+                    gestureId = usedGestureIdBits.markFirstUnmarkedBit();
+                    mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
+#if DEBUG_GESTURES
+                    ALOGD("Gestures: FREEFORM "
+                            "new mapping for touch id %d -> gesture id %d",
+                            touchId, gestureId);
+#endif
+                } else {
+                    gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
+#if DEBUG_GESTURES
+                    ALOGD("Gestures: FREEFORM "
+                            "existing mapping for touch id %d -> gesture id %d",
+                            touchId, gestureId);
+#endif
+                }
+                mPointerGesture.currentGestureIdBits.markBit(gestureId);
+                mPointerGesture.currentGestureIdToIndex[gestureId] = i;
+
+                const RawPointerData::Pointer& pointer =
+                        mCurrentRawPointerData.pointerForId(touchId);
+                float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
+                        * mPointerXZoomScale;
+                float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
+                        * mPointerYZoomScale;
+                rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
+
+                mPointerGesture.currentGestureProperties[i].clear();
+                mPointerGesture.currentGestureProperties[i].id = gestureId;
+                mPointerGesture.currentGestureProperties[i].toolType =
+                        AMOTION_EVENT_TOOL_TYPE_FINGER;
+                mPointerGesture.currentGestureCoords[i].clear();
+                mPointerGesture.currentGestureCoords[i].setAxisValue(
+                        AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
+                mPointerGesture.currentGestureCoords[i].setAxisValue(
+                        AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
+                mPointerGesture.currentGestureCoords[i].setAxisValue(
+                        AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
+            }
+
+            if (mPointerGesture.activeGestureId < 0) {
+                mPointerGesture.activeGestureId =
+                        mPointerGesture.currentGestureIdBits.firstMarkedBit();
+#if DEBUG_GESTURES
+                ALOGD("Gestures: FREEFORM new "
+                        "activeGestureId=%d", mPointerGesture.activeGestureId);
+#endif
+            }
+        }
+    }
+
+    mPointerController->setButtonState(mCurrentButtonState);
+
+#if DEBUG_GESTURES
+    ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
+            "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
+            "lastGestureMode=%d, lastGestureIdBits=0x%08x",
+            toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
+            mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
+            mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
+    for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
+        uint32_t id = idBits.clearFirstMarkedBit();
+        uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
+        const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
+        const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
+        ALOGD("  currentGesture[%d]: index=%d, toolType=%d, "
+                "x=%0.3f, y=%0.3f, pressure=%0.3f",
+                id, index, properties.toolType,
+                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
+                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
+                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
+    }
+    for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
+        uint32_t id = idBits.clearFirstMarkedBit();
+        uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
+        const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
+        const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
+        ALOGD("  lastGesture[%d]: index=%d, toolType=%d, "
+                "x=%0.3f, y=%0.3f, pressure=%0.3f",
+                id, index, properties.toolType,
+                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
+                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
+                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
+    }
+#endif
+    return true;
+}
+
+void TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
+    mPointerSimple.currentCoords.clear();
+    mPointerSimple.currentProperties.clear();
+
+    bool down, hovering;
+    if (!mCurrentStylusIdBits.isEmpty()) {
+        uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
+        uint32_t index = mCurrentCookedPointerData.idToIndex[id];
+        float x = mCurrentCookedPointerData.pointerCoords[index].getX();
+        float y = mCurrentCookedPointerData.pointerCoords[index].getY();
+        mPointerController->setPosition(x, y);
+
+        hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
+        down = !hovering;
+
+        mPointerController->getPosition(&x, &y);
+        mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
+        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        mPointerSimple.currentProperties.id = 0;
+        mPointerSimple.currentProperties.toolType =
+                mCurrentCookedPointerData.pointerProperties[index].toolType;
+    } else {
+        down = false;
+        hovering = false;
+    }
+
+    dispatchPointerSimple(when, policyFlags, down, hovering);
+}
+
+void TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
+    abortPointerSimple(when, policyFlags);
+}
+
+void TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
+    mPointerSimple.currentCoords.clear();
+    mPointerSimple.currentProperties.clear();
+
+    bool down, hovering;
+    if (!mCurrentMouseIdBits.isEmpty()) {
+        uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
+        uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
+        if (mLastMouseIdBits.hasBit(id)) {
+            uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
+            float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
+                    - mLastRawPointerData.pointers[lastIndex].x)
+                    * mPointerXMovementScale;
+            float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
+                    - mLastRawPointerData.pointers[lastIndex].y)
+                    * mPointerYMovementScale;
+
+            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
+            mPointerVelocityControl.move(when, &deltaX, &deltaY);
+
+            mPointerController->move(deltaX, deltaY);
+        } else {
+            mPointerVelocityControl.reset();
+        }
+
+        down = isPointerDown(mCurrentButtonState);
+        hovering = !down;
+
+        float x, y;
+        mPointerController->getPosition(&x, &y);
+        mPointerSimple.currentCoords.copyFrom(
+                mCurrentCookedPointerData.pointerCoords[currentIndex]);
+        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
+                hovering ? 0.0f : 1.0f);
+        mPointerSimple.currentProperties.id = 0;
+        mPointerSimple.currentProperties.toolType =
+                mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
+    } else {
+        mPointerVelocityControl.reset();
+
+        down = false;
+        hovering = false;
+    }
+
+    dispatchPointerSimple(when, policyFlags, down, hovering);
+}
+
+void TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
+    abortPointerSimple(when, policyFlags);
+
+    mPointerVelocityControl.reset();
+}
+
+void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
+        bool down, bool hovering) {
+    int32_t metaState = getContext()->getGlobalMetaState();
+
+    if (mPointerController != NULL) {
+        if (down || hovering) {
+            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+            mPointerController->clearSpots();
+            mPointerController->setButtonState(mCurrentButtonState);
+            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+        } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
+            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+        }
+    }
+
+    if (mPointerSimple.down && !down) {
+        mPointerSimple.down = false;
+
+        // Send up.
+        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                 AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
+                 mViewport.displayId,
+                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
+                 mOrientedXPrecision, mOrientedYPrecision,
+                 mPointerSimple.downTime);
+        getListener()->notifyMotion(&args);
+    }
+
+    if (mPointerSimple.hovering && !hovering) {
+        mPointerSimple.hovering = false;
+
+        // Send hover exit.
+        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
+                mViewport.displayId,
+                1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
+                mOrientedXPrecision, mOrientedYPrecision,
+                mPointerSimple.downTime);
+        getListener()->notifyMotion(&args);
+    }
+
+    if (down) {
+        if (!mPointerSimple.down) {
+            mPointerSimple.down = true;
+            mPointerSimple.downTime = when;
+
+            // Send down.
+            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                    AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
+                    mViewport.displayId,
+                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
+                    mOrientedXPrecision, mOrientedYPrecision,
+                    mPointerSimple.downTime);
+            getListener()->notifyMotion(&args);
+        }
+
+        // Send move.
+        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
+                mViewport.displayId,
+                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
+                mOrientedXPrecision, mOrientedYPrecision,
+                mPointerSimple.downTime);
+        getListener()->notifyMotion(&args);
+    }
+
+    if (hovering) {
+        if (!mPointerSimple.hovering) {
+            mPointerSimple.hovering = true;
+
+            // Send hover enter.
+            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
+                    mViewport.displayId,
+                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
+                    mOrientedXPrecision, mOrientedYPrecision,
+                    mPointerSimple.downTime);
+            getListener()->notifyMotion(&args);
+        }
+
+        // Send hover move.
+        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
+                mViewport.displayId,
+                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
+                mOrientedXPrecision, mOrientedYPrecision,
+                mPointerSimple.downTime);
+        getListener()->notifyMotion(&args);
+    }
+
+    if (mCurrentRawVScroll || mCurrentRawHScroll) {
+        float vscroll = mCurrentRawVScroll;
+        float hscroll = mCurrentRawHScroll;
+        mWheelYVelocityControl.move(when, NULL, &vscroll);
+        mWheelXVelocityControl.move(when, &hscroll, NULL);
+
+        // Send scroll.
+        PointerCoords pointerCoords;
+        pointerCoords.copyFrom(mPointerSimple.currentCoords);
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
+        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
+
+        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+                AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
+                mViewport.displayId,
+                1, &mPointerSimple.currentProperties, &pointerCoords,
+                mOrientedXPrecision, mOrientedYPrecision,
+                mPointerSimple.downTime);
+        getListener()->notifyMotion(&args);
+    }
+
+    // Save state.
+    if (down || hovering) {
+        mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
+        mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
+    } else {
+        mPointerSimple.reset();
+    }
+}
+
+void TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
+    mPointerSimple.currentCoords.clear();
+    mPointerSimple.currentProperties.clear();
+
+    dispatchPointerSimple(when, policyFlags, false, false);
+}
+
+void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
+        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+        const PointerProperties* properties, const PointerCoords* coords,
+        const uint32_t* idToIndex, BitSet32 idBits,
+        int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
+    PointerCoords pointerCoords[MAX_POINTERS];
+    PointerProperties pointerProperties[MAX_POINTERS];
+    uint32_t pointerCount = 0;
+    while (!idBits.isEmpty()) {
+        uint32_t id = idBits.clearFirstMarkedBit();
+        uint32_t index = idToIndex[id];
+        pointerProperties[pointerCount].copyFrom(properties[index]);
+        pointerCoords[pointerCount].copyFrom(coords[index]);
+
+        if (changedId >= 0 && id == uint32_t(changedId)) {
+            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+        }
+
+        pointerCount += 1;
+    }
+
+    ALOG_ASSERT(pointerCount != 0);
+
+    if (changedId >= 0 && pointerCount == 1) {
+        // Replace initial down and final up action.
+        // We can compare the action without masking off the changed pointer index
+        // because we know the index is 0.
+        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
+            action = AMOTION_EVENT_ACTION_DOWN;
+        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
+            action = AMOTION_EVENT_ACTION_UP;
+        } else {
+            // Can't happen.
+            ALOG_ASSERT(false);
+        }
+    }
+
+    NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
+            action, flags, metaState, buttonState, edgeFlags,
+            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
+            xPrecision, yPrecision, downTime);
+    getListener()->notifyMotion(&args);
+}
+
+bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
+        const PointerCoords* inCoords, const uint32_t* inIdToIndex,
+        PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
+        BitSet32 idBits) const {
+    bool changed = false;
+    while (!idBits.isEmpty()) {
+        uint32_t id = idBits.clearFirstMarkedBit();
+        uint32_t inIndex = inIdToIndex[id];
+        uint32_t outIndex = outIdToIndex[id];
+
+        const PointerProperties& curInProperties = inProperties[inIndex];
+        const PointerCoords& curInCoords = inCoords[inIndex];
+        PointerProperties& curOutProperties = outProperties[outIndex];
+        PointerCoords& curOutCoords = outCoords[outIndex];
+
+        if (curInProperties != curOutProperties) {
+            curOutProperties.copyFrom(curInProperties);
+            changed = true;
+        }
+
+        if (curInCoords != curOutCoords) {
+            curOutCoords.copyFrom(curInCoords);
+            changed = true;
+        }
+    }
+    return changed;
+}
+
+void TouchInputMapper::fadePointer() {
+    if (mPointerController != NULL) {
+        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+    }
+}
+
+bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
+            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
+}
+
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
+        int32_t x, int32_t y) {
+    size_t numVirtualKeys = mVirtualKeys.size();
+    for (size_t i = 0; i < numVirtualKeys; i++) {
+        const VirtualKey& virtualKey = mVirtualKeys[i];
+
+#if DEBUG_VIRTUAL_KEYS
+        ALOGD("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::assignPointerIds() {
+    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+    uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
+
+    mCurrentRawPointerData.clearIdBits();
+
+    if (currentPointerCount == 0) {
+        // No pointers to assign.
+        return;
+    }
+
+    if (lastPointerCount == 0) {
+        // All pointers are new.
+        for (uint32_t i = 0; i < currentPointerCount; i++) {
+            uint32_t id = i;
+            mCurrentRawPointerData.pointers[i].id = id;
+            mCurrentRawPointerData.idToIndex[id] = i;
+            mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
+        }
+        return;
+    }
+
+    if (currentPointerCount == 1 && lastPointerCount == 1
+            && mCurrentRawPointerData.pointers[0].toolType
+                    == mLastRawPointerData.pointers[0].toolType) {
+        // Only one pointer and no change in count so it must have the same id as before.
+        uint32_t id = mLastRawPointerData.pointers[0].id;
+        mCurrentRawPointerData.pointers[0].id = id;
+        mCurrentRawPointerData.idToIndex[id] = 0;
+        mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
+        return;
+    }
+
+    // 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.
+    // The pointers must have the same tool type but it is possible for them to
+    // transition from hovering to touching or vice-versa while retaining the same id.
+    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++) {
+            const RawPointerData::Pointer& currentPointer =
+                    mCurrentRawPointerData.pointers[currentPointerIndex];
+            const RawPointerData::Pointer& lastPointer =
+                    mLastRawPointerData.pointers[lastPointerIndex];
+            if (currentPointer.toolType == lastPointer.toolType) {
+                int64_t deltaX = currentPointer.x - lastPointer.x;
+                int64_t deltaY = currentPointer.y - lastPointer.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
+    ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
+    for (size_t i = 0; i < heapSize; i++) {
+        ALOGD("  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); heapSize > 0 && i > 0; i--) {
+        while (heapSize > 0) {
+            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).
+                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
+                ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
+                for (size_t i = 0; i < heapSize; i++) {
+                    ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
+                            i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+                            heap[i].distance);
+                }
+#endif
+            }
+
+            heapSize -= 1;
+
+            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 = mLastRawPointerData.pointers[lastPointerIndex].id;
+            mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+            mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+            mCurrentRawPointerData.markIdBit(id,
+                    mCurrentRawPointerData.isHovering(currentPointerIndex));
+            usedIdBits.markBit(id);
+
+#if DEBUG_POINTER_ASSIGNMENT
+            ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
+                    lastPointerIndex, currentPointerIndex, id, heap[0].distance);
+#endif
+            break;
+        }
+    }
+
+    // Assign fresh ids to pointers that were not matched in the process.
+    for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
+        uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
+        uint32_t id = usedIdBits.markFirstUnmarkedBit();
+
+        mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+        mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+        mCurrentRawPointerData.markIdBit(id,
+                mCurrentRawPointerData.isHovering(currentPointerIndex));
+
+#if DEBUG_POINTER_ASSIGNMENT
+        ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
+                currentPointerIndex, id);
+#endif
+    }
+}
+
+int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
+        return AKEY_STATE_VIRTUAL;
+    }
+
+    size_t numVirtualKeys = mVirtualKeys.size();
+    for (size_t i = 0; i < numVirtualKeys; i++) {
+        const VirtualKey& virtualKey = mVirtualKeys[i];
+        if (virtualKey.keyCode == keyCode) {
+            return AKEY_STATE_UP;
+        }
+    }
+
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
+        return AKEY_STATE_VIRTUAL;
+    }
+
+    size_t numVirtualKeys = mVirtualKeys.size();
+    for (size_t i = 0; i < numVirtualKeys; i++) {
+        const VirtualKey& virtualKey = mVirtualKeys[i];
+        if (virtualKey.scanCode == scanCode) {
+            return AKEY_STATE_UP;
+        }
+    }
+
+    return AKEY_STATE_UNKNOWN;
+}
+
+bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    size_t numVirtualKeys = mVirtualKeys.size();
+    for (size_t i = 0; i < numVirtualKeys; i++) {
+        const VirtualKey& virtualKey = mVirtualKeys[i];
+
+        for (size_t i = 0; i < numCodes; i++) {
+            if (virtualKey.keyCode == keyCodes[i]) {
+                outFlags[i] = 1;
+            }
+        }
+    }
+
+    return true;
+}
+
+
+// --- SingleTouchInputMapper ---
+
+SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
+        TouchInputMapper(device) {
+}
+
+SingleTouchInputMapper::~SingleTouchInputMapper() {
+}
+
+void SingleTouchInputMapper::reset(nsecs_t when) {
+    mSingleTouchMotionAccumulator.reset(getDevice());
+
+    TouchInputMapper::reset(when);
+}
+
+void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
+    TouchInputMapper::process(rawEvent);
+
+    mSingleTouchMotionAccumulator.process(rawEvent);
+}
+
+void SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
+    if (mTouchButtonAccumulator.isToolActive()) {
+        mCurrentRawPointerData.pointerCount = 1;
+        mCurrentRawPointerData.idToIndex[0] = 0;
+
+        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
+                && (mTouchButtonAccumulator.isHovering()
+                        || (mRawPointerAxes.pressure.valid
+                                && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
+        mCurrentRawPointerData.markIdBit(0, isHovering);
+
+        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
+        outPointer.id = 0;
+        outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
+        outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
+        outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
+        outPointer.touchMajor = 0;
+        outPointer.touchMinor = 0;
+        outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
+        outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
+        outPointer.orientation = 0;
+        outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
+        outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
+        outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
+        outPointer.toolType = mTouchButtonAccumulator.getToolType();
+        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
+            outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+        }
+        outPointer.isHovering = isHovering;
+    }
+}
+
+void SingleTouchInputMapper::configureRawPointerAxes() {
+    TouchInputMapper::configureRawPointerAxes();
+
+    getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
+    getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
+    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
+    getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
+    getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
+    getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
+    getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
+}
+
+bool SingleTouchInputMapper::hasStylus() const {
+    return mTouchButtonAccumulator.hasStylus();
+}
+
+
+// --- MultiTouchInputMapper ---
+
+MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
+        TouchInputMapper(device) {
+}
+
+MultiTouchInputMapper::~MultiTouchInputMapper() {
+}
+
+void MultiTouchInputMapper::reset(nsecs_t when) {
+    mMultiTouchMotionAccumulator.reset(getDevice());
+
+    mPointerIdBits.clear();
+
+    TouchInputMapper::reset(when);
+}
+
+void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
+    TouchInputMapper::process(rawEvent);
+
+    mMultiTouchMotionAccumulator.process(rawEvent);
+}
+
+void MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
+    size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
+    size_t outCount = 0;
+    BitSet32 newPointerIdBits;
+
+    for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
+        const MultiTouchMotionAccumulator::Slot* inSlot =
+                mMultiTouchMotionAccumulator.getSlot(inIndex);
+        if (!inSlot->isInUse()) {
+            continue;
+        }
+
+        if (outCount >= MAX_POINTERS) {
+#if DEBUG_POINTERS
+            ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
+                    "ignoring the rest.",
+                    getDeviceName().string(), MAX_POINTERS);
+#endif
+            break; // too many fingers!
+        }
+
+        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
+        outPointer.x = inSlot->getX();
+        outPointer.y = inSlot->getY();
+        outPointer.pressure = inSlot->getPressure();
+        outPointer.touchMajor = inSlot->getTouchMajor();
+        outPointer.touchMinor = inSlot->getTouchMinor();
+        outPointer.toolMajor = inSlot->getToolMajor();
+        outPointer.toolMinor = inSlot->getToolMinor();
+        outPointer.orientation = inSlot->getOrientation();
+        outPointer.distance = inSlot->getDistance();
+        outPointer.tiltX = 0;
+        outPointer.tiltY = 0;
+
+        outPointer.toolType = inSlot->getToolType();
+        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
+            outPointer.toolType = mTouchButtonAccumulator.getToolType();
+            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
+                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+            }
+        }
+
+        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
+                && (mTouchButtonAccumulator.isHovering()
+                        || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
+        outPointer.isHovering = isHovering;
+
+        // Assign pointer id using tracking id if available.
+        if (*outHavePointerIds) {
+            int32_t trackingId = inSlot->getTrackingId();
+            int32_t id = -1;
+            if (trackingId >= 0) {
+                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
+                    uint32_t n = idBits.clearFirstMarkedBit();
+                    if (mPointerTrackingIdMap[n] == trackingId) {
+                        id = n;
+                    }
+                }
+
+                if (id < 0 && !mPointerIdBits.isFull()) {
+                    id = mPointerIdBits.markFirstUnmarkedBit();
+                    mPointerTrackingIdMap[id] = trackingId;
+                }
+            }
+            if (id < 0) {
+                *outHavePointerIds = false;
+                mCurrentRawPointerData.clearIdBits();
+                newPointerIdBits.clear();
+            } else {
+                outPointer.id = id;
+                mCurrentRawPointerData.idToIndex[id] = outCount;
+                mCurrentRawPointerData.markIdBit(id, isHovering);
+                newPointerIdBits.markBit(id);
+            }
+        }
+
+        outCount += 1;
+    }
+
+    mCurrentRawPointerData.pointerCount = outCount;
+    mPointerIdBits = newPointerIdBits;
+
+    mMultiTouchMotionAccumulator.finishSync();
+}
+
+void MultiTouchInputMapper::configureRawPointerAxes() {
+    TouchInputMapper::configureRawPointerAxes();
+
+    getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
+    getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
+    getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
+    getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
+    getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
+    getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
+    getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
+    getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
+    getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
+    getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
+    getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
+
+    if (mRawPointerAxes.trackingId.valid
+            && mRawPointerAxes.slot.valid
+            && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
+        size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
+        if (slotCount > MAX_SLOTS) {
+            ALOGW("MultiTouch Device %s reported %d slots but the framework "
+                    "only supports a maximum of %d slots at this time.",
+                    getDeviceName().string(), slotCount, MAX_SLOTS);
+            slotCount = MAX_SLOTS;
+        }
+        mMultiTouchMotionAccumulator.configure(getDevice(),
+                slotCount, true /*usingSlotsProtocol*/);
+    } else {
+        mMultiTouchMotionAccumulator.configure(getDevice(),
+                MAX_POINTERS, false /*usingSlotsProtocol*/);
+    }
+}
+
+bool MultiTouchInputMapper::hasStylus() const {
+    return mMultiTouchMotionAccumulator.hasStylus()
+            || mTouchButtonAccumulator.hasStylus();
+}
+
+
+// --- JoystickInputMapper ---
+
+JoystickInputMapper::JoystickInputMapper(InputDevice* device) :
+        InputMapper(device) {
+}
+
+JoystickInputMapper::~JoystickInputMapper() {
+}
+
+uint32_t JoystickInputMapper::getSources() {
+    return AINPUT_SOURCE_JOYSTICK;
+}
+
+void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    for (size_t i = 0; i < mAxes.size(); i++) {
+        const Axis& axis = mAxes.valueAt(i);
+        addMotionRange(axis.axisInfo.axis, axis, info);
+
+        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+            addMotionRange(axis.axisInfo.highAxis, axis, info);
+
+        }
+    }
+}
+
+void JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis,
+        InputDeviceInfo* info) {
+    info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK,
+            axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
+    /* In order to ease the transition for developers from using the old axes
+     * to the newer, more semantically correct axes, we'll continue to register
+     * the old axes as duplicates of their corresponding new ones.  */
+    int32_t compatAxis = getCompatAxis(axisId);
+    if (compatAxis >= 0) {
+        info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK,
+                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
+    }
+}
+
+/* A mapping from axes the joystick actually has to the axes that should be
+ * artificially created for compatibility purposes.
+ * Returns -1 if no compatibility axis is needed. */
+int32_t JoystickInputMapper::getCompatAxis(int32_t axis) {
+    switch(axis) {
+    case AMOTION_EVENT_AXIS_LTRIGGER:
+        return AMOTION_EVENT_AXIS_BRAKE;
+    case AMOTION_EVENT_AXIS_RTRIGGER:
+        return AMOTION_EVENT_AXIS_GAS;
+    }
+    return -1;
+}
+
+void JoystickInputMapper::dump(String8& dump) {
+    dump.append(INDENT2 "Joystick Input Mapper:\n");
+
+    dump.append(INDENT3 "Axes:\n");
+    size_t numAxes = mAxes.size();
+    for (size_t i = 0; i < numAxes; i++) {
+        const Axis& axis = mAxes.valueAt(i);
+        const char* label = getAxisLabel(axis.axisInfo.axis);
+        if (label) {
+            dump.appendFormat(INDENT4 "%s", label);
+        } else {
+            dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
+        }
+        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+            label = getAxisLabel(axis.axisInfo.highAxis);
+            if (label) {
+                dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
+            } else {
+                dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
+                        axis.axisInfo.splitValue);
+            }
+        } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
+            dump.append(" (invert)");
+        }
+
+        dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
+                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
+        dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
+                "highScale=%0.5f, highOffset=%0.5f\n",
+                axis.scale, axis.offset, axis.highScale, axis.highOffset);
+        dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, "
+                "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
+                mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
+                axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
+    }
+}
+
+void JoystickInputMapper::configure(nsecs_t when,
+        const InputReaderConfiguration* config, uint32_t changes) {
+    InputMapper::configure(when, config, changes);
+
+    if (!changes) { // first time only
+        // Collect all axes.
+        for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
+            if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
+                    & INPUT_DEVICE_CLASS_JOYSTICK)) {
+                continue; // axis must be claimed by a different device
+            }
+
+            RawAbsoluteAxisInfo rawAxisInfo;
+            getAbsoluteAxisInfo(abs, &rawAxisInfo);
+            if (rawAxisInfo.valid) {
+                // Map axis.
+                AxisInfo axisInfo;
+                bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
+                if (!explicitlyMapped) {
+                    // Axis is not explicitly mapped, will choose a generic axis later.
+                    axisInfo.mode = AxisInfo::MODE_NORMAL;
+                    axisInfo.axis = -1;
+                }
+
+                // Apply flat override.
+                int32_t rawFlat = axisInfo.flatOverride < 0
+                        ? rawAxisInfo.flat : axisInfo.flatOverride;
+
+                // Calculate scaling factors and limits.
+                Axis axis;
+                if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
+                    float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
+                    float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
+                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+                            scale, 0.0f, highScale, 0.0f,
+                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
+                            rawAxisInfo.resolution * scale);
+                } else if (isCenteredAxis(axisInfo.axis)) {
+                    float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+                    float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
+                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+                            scale, offset, scale, offset,
+                            -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
+                            rawAxisInfo.resolution * scale);
+                } else {
+                    float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+                            scale, 0.0f, scale, 0.0f,
+                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
+                            rawAxisInfo.resolution * scale);
+                }
+
+                // To eliminate noise while the joystick is at rest, filter out small variations
+                // in axis values up front.
+                axis.filter = axis.fuzz ? axis.fuzz : axis.flat * 0.25f;
+
+                mAxes.add(abs, axis);
+            }
+        }
+
+        // If there are too many axes, start dropping them.
+        // Prefer to keep explicitly mapped axes.
+        if (mAxes.size() > PointerCoords::MAX_AXES) {
+            ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
+                    getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
+            pruneAxes(true);
+            pruneAxes(false);
+        }
+
+        // Assign generic axis ids to remaining axes.
+        int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
+        size_t numAxes = mAxes.size();
+        for (size_t i = 0; i < numAxes; i++) {
+            Axis& axis = mAxes.editValueAt(i);
+            if (axis.axisInfo.axis < 0) {
+                while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
+                        && haveAxis(nextGenericAxisId)) {
+                    nextGenericAxisId += 1;
+                }
+
+                if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
+                    axis.axisInfo.axis = nextGenericAxisId;
+                    nextGenericAxisId += 1;
+                } else {
+                    ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
+                            "have already been assigned to other axes.",
+                            getDeviceName().string(), mAxes.keyAt(i));
+                    mAxes.removeItemsAt(i--);
+                    numAxes -= 1;
+                }
+            }
+        }
+    }
+}
+
+bool JoystickInputMapper::haveAxis(int32_t axisId) {
+    size_t numAxes = mAxes.size();
+    for (size_t i = 0; i < numAxes; i++) {
+        const Axis& axis = mAxes.valueAt(i);
+        if (axis.axisInfo.axis == axisId
+                || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
+                        && axis.axisInfo.highAxis == axisId)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
+    size_t i = mAxes.size();
+    while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
+        if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
+            continue;
+        }
+        ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
+                getDeviceName().string(), mAxes.keyAt(i));
+        mAxes.removeItemsAt(i);
+    }
+}
+
+bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
+    switch (axis) {
+    case AMOTION_EVENT_AXIS_X:
+    case AMOTION_EVENT_AXIS_Y:
+    case AMOTION_EVENT_AXIS_Z:
+    case AMOTION_EVENT_AXIS_RX:
+    case AMOTION_EVENT_AXIS_RY:
+    case AMOTION_EVENT_AXIS_RZ:
+    case AMOTION_EVENT_AXIS_HAT_X:
+    case AMOTION_EVENT_AXIS_HAT_Y:
+    case AMOTION_EVENT_AXIS_ORIENTATION:
+    case AMOTION_EVENT_AXIS_RUDDER:
+    case AMOTION_EVENT_AXIS_WHEEL:
+        return true;
+    default:
+        return false;
+    }
+}
+
+void JoystickInputMapper::reset(nsecs_t when) {
+    // Recenter all axes.
+    size_t numAxes = mAxes.size();
+    for (size_t i = 0; i < numAxes; i++) {
+        Axis& axis = mAxes.editValueAt(i);
+        axis.resetValue();
+    }
+
+    InputMapper::reset(when);
+}
+
+void JoystickInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_ABS: {
+        ssize_t index = mAxes.indexOfKey(rawEvent->code);
+        if (index >= 0) {
+            Axis& axis = mAxes.editValueAt(index);
+            float newValue, highNewValue;
+            switch (axis.axisInfo.mode) {
+            case AxisInfo::MODE_INVERT:
+                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
+                        * axis.scale + axis.offset;
+                highNewValue = 0.0f;
+                break;
+            case AxisInfo::MODE_SPLIT:
+                if (rawEvent->value < axis.axisInfo.splitValue) {
+                    newValue = (axis.axisInfo.splitValue - rawEvent->value)
+                            * axis.scale + axis.offset;
+                    highNewValue = 0.0f;
+                } else if (rawEvent->value > axis.axisInfo.splitValue) {
+                    newValue = 0.0f;
+                    highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
+                            * axis.highScale + axis.highOffset;
+                } else {
+                    newValue = 0.0f;
+                    highNewValue = 0.0f;
+                }
+                break;
+            default:
+                newValue = rawEvent->value * axis.scale + axis.offset;
+                highNewValue = 0.0f;
+                break;
+            }
+            axis.newValue = newValue;
+            axis.highNewValue = highNewValue;
+        }
+        break;
+    }
+
+    case EV_SYN:
+        switch (rawEvent->code) {
+        case SYN_REPORT:
+            sync(rawEvent->when, false /*force*/);
+            break;
+        }
+        break;
+    }
+}
+
+void JoystickInputMapper::sync(nsecs_t when, bool force) {
+    if (!filterAxes(force)) {
+        return;
+    }
+
+    int32_t metaState = mContext->getGlobalMetaState();
+    int32_t buttonState = 0;
+
+    PointerProperties pointerProperties;
+    pointerProperties.clear();
+    pointerProperties.id = 0;
+    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+
+    PointerCoords pointerCoords;
+    pointerCoords.clear();
+
+    size_t numAxes = mAxes.size();
+    for (size_t i = 0; i < numAxes; i++) {
+        const Axis& axis = mAxes.valueAt(i);
+        setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.axis, axis.currentValue);
+        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+            setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.highAxis,
+                    axis.highCurrentValue);
+        }
+    }
+
+    // Moving a joystick axis should not wake the device because joysticks can
+    // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
+    // button will likely wake the device.
+    // TODO: Use the input device configuration to control this behavior more finely.
+    uint32_t policyFlags = 0;
+
+    NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
+            AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+            ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
+    getListener()->notifyMotion(&args);
+}
+
+void JoystickInputMapper::setPointerCoordsAxisValue(PointerCoords* pointerCoords,
+        int32_t axis, float value) {
+    pointerCoords->setAxisValue(axis, value);
+    /* In order to ease the transition for developers from using the old axes
+     * to the newer, more semantically correct axes, we'll continue to produce
+     * values for the old axes as mirrors of the value of their corresponding
+     * new axes. */
+    int32_t compatAxis = getCompatAxis(axis);
+    if (compatAxis >= 0) {
+        pointerCoords->setAxisValue(compatAxis, value);
+    }
+}
+
+bool JoystickInputMapper::filterAxes(bool force) {
+    bool atLeastOneSignificantChange = force;
+    size_t numAxes = mAxes.size();
+    for (size_t i = 0; i < numAxes; i++) {
+        Axis& axis = mAxes.editValueAt(i);
+        if (force || hasValueChangedSignificantly(axis.filter,
+                axis.newValue, axis.currentValue, axis.min, axis.max)) {
+            axis.currentValue = axis.newValue;
+            atLeastOneSignificantChange = true;
+        }
+        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
+            if (force || hasValueChangedSignificantly(axis.filter,
+                    axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
+                axis.highCurrentValue = axis.highNewValue;
+                atLeastOneSignificantChange = true;
+            }
+        }
+    }
+    return atLeastOneSignificantChange;
+}
+
+bool JoystickInputMapper::hasValueChangedSignificantly(
+        float filter, float newValue, float currentValue, float min, float max) {
+    if (newValue != currentValue) {
+        // Filter out small changes in value unless the value is converging on the axis
+        // bounds or center point.  This is intended to reduce the amount of information
+        // sent to applications by particularly noisy joysticks (such as PS3).
+        if (fabs(newValue - currentValue) > filter
+                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
+                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
+                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
+        float filter, float newValue, float currentValue, float thresholdValue) {
+    float newDistance = fabs(newValue - thresholdValue);
+    if (newDistance < filter) {
+        float oldDistance = fabs(currentValue - thresholdValue);
+        if (newDistance < oldDistance) {
+            return true;
+        }
+    }
+    return false;
+}
+
+} // namespace android
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
new file mode 100644
index 0000000..6c4c927
--- /dev/null
+++ b/services/inputflinger/InputReader.h
@@ -0,0 +1,1818 @@
+/*
+ * 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 "EventHub.h"
+#include "PointerControllerInterface.h"
+#include "InputListener.h"
+
+#include <input/Input.h>
+#include <input/VelocityControl.h>
+#include <input/VelocityTracker.h>
+#include <ui/DisplayInfo.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>
+
+// Maximum supported size of a vibration pattern.
+// Must be at least 2.
+#define MAX_VIBRATE_PATTERN_SIZE 100
+
+// Maximum allowable delay value in a vibration pattern before
+// which the delay will be truncated.
+#define MAX_VIBRATE_PATTERN_DELAY_NSECS (1000000 * 1000000000LL)
+
+namespace android {
+
+class InputDevice;
+class InputMapper;
+
+/*
+ * Describes how coordinates are mapped on a physical display.
+ * See com.android.server.display.DisplayViewport.
+ */
+struct DisplayViewport {
+    int32_t displayId; // -1 if invalid
+    int32_t orientation;
+    int32_t logicalLeft;
+    int32_t logicalTop;
+    int32_t logicalRight;
+    int32_t logicalBottom;
+    int32_t physicalLeft;
+    int32_t physicalTop;
+    int32_t physicalRight;
+    int32_t physicalBottom;
+    int32_t deviceWidth;
+    int32_t deviceHeight;
+
+    DisplayViewport() :
+            displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
+            logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
+            physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
+            deviceWidth(0), deviceHeight(0) {
+    }
+
+    bool operator==(const DisplayViewport& other) const {
+        return displayId == other.displayId
+                && orientation == other.orientation
+                && logicalLeft == other.logicalLeft
+                && logicalTop == other.logicalTop
+                && logicalRight == other.logicalRight
+                && logicalBottom == other.logicalBottom
+                && physicalLeft == other.physicalLeft
+                && physicalTop == other.physicalTop
+                && physicalRight == other.physicalRight
+                && physicalBottom == other.physicalBottom
+                && deviceWidth == other.deviceWidth
+                && deviceHeight == other.deviceHeight;
+    }
+
+    bool operator!=(const DisplayViewport& other) const {
+        return !(*this == other);
+    }
+
+    inline bool isValid() const {
+        return displayId >= 0;
+    }
+
+    void setNonDisplayViewport(int32_t width, int32_t height) {
+        displayId = ADISPLAY_ID_NONE;
+        orientation = DISPLAY_ORIENTATION_0;
+        logicalLeft = 0;
+        logicalTop = 0;
+        logicalRight = width;
+        logicalBottom = height;
+        physicalLeft = 0;
+        physicalTop = 0;
+        physicalRight = width;
+        physicalBottom = height;
+        deviceWidth = width;
+        deviceHeight = height;
+    }
+};
+
+/*
+ * Input reader configuration.
+ *
+ * Specifies various options that modify the behavior of the input reader.
+ */
+struct InputReaderConfiguration {
+    // Describes changes that have occurred.
+    enum {
+        // The pointer speed changed.
+        CHANGE_POINTER_SPEED = 1 << 0,
+
+        // The pointer gesture control changed.
+        CHANGE_POINTER_GESTURE_ENABLEMENT = 1 << 1,
+
+        // The display size or orientation changed.
+        CHANGE_DISPLAY_INFO = 1 << 2,
+
+        // The visible touches option changed.
+        CHANGE_SHOW_TOUCHES = 1 << 3,
+
+        // The keyboard layouts must be reloaded.
+        CHANGE_KEYBOARD_LAYOUTS = 1 << 4,
+
+        // The device name alias supplied by the may have changed for some devices.
+        CHANGE_DEVICE_ALIAS = 1 << 5,
+
+        // All devices must be reopened.
+        CHANGE_MUST_REOPEN = 1 << 31,
+    };
+
+    // 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.
+    nsecs_t virtualKeyQuietTime;
+
+    // The excluded device names for the platform.
+    // Devices with these names will be ignored.
+    Vector<String8> excludedDeviceNames;
+
+    // Velocity control parameters for mouse pointer movements.
+    VelocityControlParameters pointerVelocityControlParameters;
+
+    // Velocity control parameters for mouse wheel movements.
+    VelocityControlParameters wheelVelocityControlParameters;
+
+    // True if pointer gestures are enabled.
+    bool pointerGesturesEnabled;
+
+    // Quiet time between certain pointer gesture transitions.
+    // Time to allow for all fingers or buttons to settle into a stable state before
+    // starting a new gesture.
+    nsecs_t pointerGestureQuietInterval;
+
+    // The minimum speed that a pointer must travel for us to consider switching the active
+    // touch pointer to it during a drag.  This threshold is set to avoid switching due
+    // to noise from a finger resting on the touch pad (perhaps just pressing it down).
+    float pointerGestureDragMinSwitchSpeed; // in pixels per second
+
+    // Tap gesture delay time.
+    // The time between down and up must be less than this to be considered a tap.
+    nsecs_t pointerGestureTapInterval;
+
+    // Tap drag gesture delay time.
+    // The time between the previous tap's up and the next down must be less than
+    // this to be considered a drag.  Otherwise, the previous tap is finished and a
+    // new tap begins.
+    //
+    // Note that the previous tap will be held down for this entire duration so this
+    // interval must be shorter than the long press timeout.
+    nsecs_t pointerGestureTapDragInterval;
+
+    // The distance in pixels that the pointer is allowed to move from initial down
+    // to up and still be called a tap.
+    float pointerGestureTapSlop; // in pixels
+
+    // Time after the first touch points go down to settle on an initial centroid.
+    // This is intended to be enough time to handle cases where the user puts down two
+    // fingers at almost but not quite exactly the same time.
+    nsecs_t pointerGestureMultitouchSettleInterval;
+
+    // The transition from PRESS to SWIPE or FREEFORM gesture mode is made when
+    // at least two pointers have moved at least this far from their starting place.
+    float pointerGestureMultitouchMinDistance; // in pixels
+
+    // The transition from PRESS to SWIPE gesture mode can only occur when the
+    // cosine of the angle between the two vectors is greater than or equal to than this value
+    // which indicates that the vectors are oriented in the same direction.
+    // When the vectors are oriented in the exactly same direction, the cosine is 1.0.
+    // (In exactly opposite directions, the cosine is -1.0.)
+    float pointerGestureSwipeTransitionAngleCosine;
+
+    // The transition from PRESS to SWIPE gesture mode can only occur when the
+    // fingers are no more than this far apart relative to the diagonal size of
+    // the touch pad.  For example, a ratio of 0.5 means that the fingers must be
+    // no more than half the diagonal size of the touch pad apart.
+    float pointerGestureSwipeMaxWidthRatio;
+
+    // The gesture movement speed factor relative to the size of the display.
+    // Movement speed applies when the fingers are moving in the same direction.
+    // Without acceleration, a full swipe of the touch pad diagonal in movement mode
+    // will cover this portion of the display diagonal.
+    float pointerGestureMovementSpeedRatio;
+
+    // The gesture zoom speed factor relative to the size of the display.
+    // Zoom speed applies when the fingers are mostly moving relative to each other
+    // to execute a scale gesture or similar.
+    // Without acceleration, a full swipe of the touch pad diagonal in zoom mode
+    // will cover this portion of the display diagonal.
+    float pointerGestureZoomSpeedRatio;
+
+    // True to show the location of touches on the touch screen as spots.
+    bool showTouches;
+
+    InputReaderConfiguration() :
+            virtualKeyQuietTime(0),
+            pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
+            wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
+            pointerGesturesEnabled(true),
+            pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
+            pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second
+            pointerGestureTapInterval(150 * 1000000LL), // 150 ms
+            pointerGestureTapDragInterval(150 * 1000000LL), // 150 ms
+            pointerGestureTapSlop(10.0f), // 10 pixels
+            pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms
+            pointerGestureMultitouchMinDistance(15), // 15 pixels
+            pointerGestureSwipeTransitionAngleCosine(0.2588f), // cosine of 75 degrees
+            pointerGestureSwipeMaxWidthRatio(0.25f),
+            pointerGestureMovementSpeedRatio(0.8f),
+            pointerGestureZoomSpeedRatio(0.3f),
+            showTouches(false) { }
+
+    bool getDisplayInfo(bool external, DisplayViewport* outViewport) const;
+    void setDisplayInfo(bool external, const DisplayViewport& viewport);
+
+private:
+    DisplayViewport mInternalDisplay;
+    DisplayViewport mExternalDisplay;
+};
+
+
+/*
+ * 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.
+ *
+ * These methods must NOT re-enter the input reader since they may be called while
+ * holding the input reader lock.
+ */
+class InputReaderPolicyInterface : public virtual RefBase {
+protected:
+    InputReaderPolicyInterface() { }
+    virtual ~InputReaderPolicyInterface() { }
+
+public:
+    /* Gets the input reader configuration. */
+    virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0;
+
+    /* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
+    virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
+
+    /* Notifies the input reader policy that some input devices have changed
+     * and provides information about all current input devices.
+     */
+    virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0;
+
+    /* Gets the keyboard layout for a particular input device. */
+    virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(
+            const InputDeviceIdentifier& identifier) = 0;
+
+    /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
+    virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
+};
+
+
+/* Processes raw input events and sends cooked event data to an input listener. */
+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;
+
+    /* Called by the heatbeat to ensures that the reader has not deadlocked. */
+    virtual void monitor() = 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 information about all input devices.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices) = 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;
+
+    /* Requests that a reconfiguration of all input devices.
+     * The changes flag is a bitfield that indicates what has changed and whether
+     * the input devices must all be reopened. */
+    virtual void requestRefreshConfiguration(uint32_t changes) = 0;
+
+    /* Controls the vibrator of a particular input device. */
+    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
+            ssize_t repeat, int32_t token) = 0;
+    virtual void cancelVibrate(int32_t deviceId, int32_t token) = 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 void fadePointer() = 0;
+
+    virtual void requestTimeoutAtTime(nsecs_t when) = 0;
+    virtual int32_t bumpGeneration() = 0;
+
+    virtual InputReaderPolicyInterface* getPolicy() = 0;
+    virtual InputListenerInterface* getListener() = 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 listener.  Some functions of the input reader, such as early
+ * event filtering in low power states, are controlled by a separate policy object.
+ *
+ * The InputReader owns a collection of InputMappers.  Most of the work it does happens
+ * on the input reader thread but the InputReader can receive queries from other system
+ * components running on arbitrary threads.  To keep things manageable, the InputReader
+ * uses a single Mutex to guard its state.  The Mutex may be held while calling into the
+ * EventHub or the InputReaderPolicy but it is never held while calling into the
+ * InputListener.
+ */
+class InputReader : public InputReaderInterface {
+public:
+    InputReader(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputListenerInterface>& listener);
+    virtual ~InputReader();
+
+    virtual void dump(String8& dump);
+    virtual void monitor();
+
+    virtual void loopOnce();
+
+    virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices);
+
+    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);
+
+    virtual void requestRefreshConfiguration(uint32_t changes);
+
+    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
+            ssize_t repeat, int32_t token);
+    virtual void cancelVibrate(int32_t deviceId, int32_t token);
+
+protected:
+    // These members are protected so they can be instrumented by test cases.
+    virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
+            const InputDeviceIdentifier& identifier, uint32_t classes);
+
+    class ContextImpl : public InputReaderContext {
+        InputReader* mReader;
+
+    public:
+        ContextImpl(InputReader* reader);
+
+        virtual void updateGlobalMetaState();
+        virtual int32_t getGlobalMetaState();
+        virtual void disableVirtualKeysUntil(nsecs_t time);
+        virtual bool shouldDropVirtualKey(nsecs_t now,
+                InputDevice* device, int32_t keyCode, int32_t scanCode);
+        virtual void fadePointer();
+        virtual void requestTimeoutAtTime(nsecs_t when);
+        virtual int32_t bumpGeneration();
+        virtual InputReaderPolicyInterface* getPolicy();
+        virtual InputListenerInterface* getListener();
+        virtual EventHubInterface* getEventHub();
+    } mContext;
+
+    friend class ContextImpl;
+
+private:
+    Mutex mLock;
+
+    Condition mReaderIsAliveCondition;
+
+    sp<EventHubInterface> mEventHub;
+    sp<InputReaderPolicyInterface> mPolicy;
+    sp<QueuedInputListener> mQueuedListener;
+
+    InputReaderConfiguration mConfig;
+
+    // The event queue.
+    static const int EVENT_BUFFER_SIZE = 256;
+    RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
+
+    KeyedVector<int32_t, InputDevice*> mDevices;
+
+    // low-level input event decoding and device management
+    void processEventsLocked(const RawEvent* rawEvents, size_t count);
+
+    void addDeviceLocked(nsecs_t when, int32_t deviceId);
+    void removeDeviceLocked(nsecs_t when, int32_t deviceId);
+    void processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count);
+    void timeoutExpiredLocked(nsecs_t when);
+
+    void handleConfigurationChangedLocked(nsecs_t when);
+
+    int32_t mGlobalMetaState;
+    void updateGlobalMetaStateLocked();
+    int32_t getGlobalMetaStateLocked();
+
+    void fadePointerLocked();
+
+    int32_t mGeneration;
+    int32_t bumpGenerationLocked();
+
+    void getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices);
+
+    nsecs_t mDisableVirtualKeysTimeout;
+    void disableVirtualKeysUntilLocked(nsecs_t time);
+    bool shouldDropVirtualKeyLocked(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode);
+
+    nsecs_t mNextTimeout;
+    void requestTimeoutAtTimeLocked(nsecs_t when);
+
+    uint32_t mConfigurationChangesToRefresh;
+    void refreshConfigurationLocked(uint32_t changes);
+
+    // state queries
+    typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+    int32_t getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
+            GetStateFunc getStateFunc);
+    bool markSupportedKeyCodesLocked(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, int32_t generation, int32_t
+            controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes);
+    ~InputDevice();
+
+    inline InputReaderContext* getContext() { return mContext; }
+    inline int32_t getId() const { return mId; }
+    inline int32_t getControllerNumber() const { return mControllerNumber; }
+    inline int32_t getGeneration() const { return mGeneration; }
+    inline const String8& getName() const { return mIdentifier.name; }
+    inline uint32_t getClasses() const { return mClasses; }
+    inline uint32_t getSources() const { return mSources; }
+
+    inline bool isExternal() { return mIsExternal; }
+    inline void setExternal(bool external) { mIsExternal = external; }
+
+    inline bool isIgnored() { return mMappers.isEmpty(); }
+
+    void dump(String8& dump);
+    void addMapper(InputMapper* mapper);
+    void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+    void reset(nsecs_t when);
+    void process(const RawEvent* rawEvents, size_t count);
+    void timeoutExpired(nsecs_t when);
+
+    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);
+    void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat, int32_t token);
+    void cancelVibrate(int32_t token);
+
+    int32_t getMetaState();
+
+    void fadePointer();
+
+    void bumpGeneration();
+
+    void notifyReset(nsecs_t when);
+
+    inline const PropertyMap& getConfiguration() { return mConfiguration; }
+    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
+
+    bool hasKey(int32_t code) {
+        return getEventHub()->hasScanCode(mId, code);
+    }
+
+    bool hasAbsoluteAxis(int32_t code) {
+        RawAbsoluteAxisInfo info;
+        getEventHub()->getAbsoluteAxisInfo(mId, code, &info);
+        return info.valid;
+    }
+
+    bool isKeyPressed(int32_t code) {
+        return getEventHub()->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
+    }
+
+    int32_t getAbsoluteAxisValue(int32_t code) {
+        int32_t value;
+        getEventHub()->getAbsoluteAxisValue(mId, code, &value);
+        return value;
+    }
+
+private:
+    InputReaderContext* mContext;
+    int32_t mId;
+    int32_t mGeneration;
+    int32_t mControllerNumber;
+    InputDeviceIdentifier mIdentifier;
+    String8 mAlias;
+    uint32_t mClasses;
+
+    Vector<InputMapper*> mMappers;
+
+    uint32_t mSources;
+    bool mIsExternal;
+    bool mDropUntilNextSync;
+
+    typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+    int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
+
+    PropertyMap mConfiguration;
+};
+
+
+/* Keeps track of the state of mouse or touch pad buttons. */
+class CursorButtonAccumulator {
+public:
+    CursorButtonAccumulator();
+    void reset(InputDevice* device);
+
+    void process(const RawEvent* rawEvent);
+
+    uint32_t getButtonState() const;
+
+private:
+    bool mBtnLeft;
+    bool mBtnRight;
+    bool mBtnMiddle;
+    bool mBtnBack;
+    bool mBtnSide;
+    bool mBtnForward;
+    bool mBtnExtra;
+    bool mBtnTask;
+
+    void clearButtons();
+};
+
+
+/* Keeps track of cursor movements. */
+
+class CursorMotionAccumulator {
+public:
+    CursorMotionAccumulator();
+    void reset(InputDevice* device);
+
+    void process(const RawEvent* rawEvent);
+    void finishSync();
+
+    inline int32_t getRelativeX() const { return mRelX; }
+    inline int32_t getRelativeY() const { return mRelY; }
+
+private:
+    int32_t mRelX;
+    int32_t mRelY;
+
+    void clearRelativeAxes();
+};
+
+
+/* Keeps track of cursor scrolling motions. */
+
+class CursorScrollAccumulator {
+public:
+    CursorScrollAccumulator();
+    void configure(InputDevice* device);
+    void reset(InputDevice* device);
+
+    void process(const RawEvent* rawEvent);
+    void finishSync();
+
+    inline bool haveRelativeVWheel() const { return mHaveRelWheel; }
+    inline bool haveRelativeHWheel() const { return mHaveRelHWheel; }
+
+    inline int32_t getRelativeX() const { return mRelX; }
+    inline int32_t getRelativeY() const { return mRelY; }
+    inline int32_t getRelativeVWheel() const { return mRelWheel; }
+    inline int32_t getRelativeHWheel() const { return mRelHWheel; }
+
+private:
+    bool mHaveRelWheel;
+    bool mHaveRelHWheel;
+
+    int32_t mRelX;
+    int32_t mRelY;
+    int32_t mRelWheel;
+    int32_t mRelHWheel;
+
+    void clearRelativeAxes();
+};
+
+
+/* Keeps track of the state of touch, stylus and tool buttons. */
+class TouchButtonAccumulator {
+public:
+    TouchButtonAccumulator();
+    void configure(InputDevice* device);
+    void reset(InputDevice* device);
+
+    void process(const RawEvent* rawEvent);
+
+    uint32_t getButtonState() const;
+    int32_t getToolType() const;
+    bool isToolActive() const;
+    bool isHovering() const;
+    bool hasStylus() const;
+
+private:
+    bool mHaveBtnTouch;
+    bool mHaveStylus;
+
+    bool mBtnTouch;
+    bool mBtnStylus;
+    bool mBtnStylus2;
+    bool mBtnToolFinger;
+    bool mBtnToolPen;
+    bool mBtnToolRubber;
+    bool mBtnToolBrush;
+    bool mBtnToolPencil;
+    bool mBtnToolAirbrush;
+    bool mBtnToolMouse;
+    bool mBtnToolLens;
+    bool mBtnToolDoubleTap;
+    bool mBtnToolTripleTap;
+    bool mBtnToolQuadTap;
+
+    void clearButtons();
+};
+
+
+/* Raw axis information from the driver. */
+struct RawPointerAxes {
+    RawAbsoluteAxisInfo x;
+    RawAbsoluteAxisInfo y;
+    RawAbsoluteAxisInfo pressure;
+    RawAbsoluteAxisInfo touchMajor;
+    RawAbsoluteAxisInfo touchMinor;
+    RawAbsoluteAxisInfo toolMajor;
+    RawAbsoluteAxisInfo toolMinor;
+    RawAbsoluteAxisInfo orientation;
+    RawAbsoluteAxisInfo distance;
+    RawAbsoluteAxisInfo tiltX;
+    RawAbsoluteAxisInfo tiltY;
+    RawAbsoluteAxisInfo trackingId;
+    RawAbsoluteAxisInfo slot;
+
+    RawPointerAxes();
+    void clear();
+};
+
+
+/* Raw data for a collection of pointers including a pointer id mapping table. */
+struct RawPointerData {
+    struct Pointer {
+        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;
+        int32_t distance;
+        int32_t tiltX;
+        int32_t tiltY;
+        int32_t toolType; // a fully decoded AMOTION_EVENT_TOOL_TYPE constant
+        bool isHovering;
+    };
+
+    uint32_t pointerCount;
+    Pointer pointers[MAX_POINTERS];
+    BitSet32 hoveringIdBits, touchingIdBits;
+    uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+    RawPointerData();
+    void clear();
+    void copyFrom(const RawPointerData& other);
+    void getCentroidOfTouchingPointers(float* outX, float* outY) const;
+
+    inline void markIdBit(uint32_t id, bool isHovering) {
+        if (isHovering) {
+            hoveringIdBits.markBit(id);
+        } else {
+            touchingIdBits.markBit(id);
+        }
+    }
+
+    inline void clearIdBits() {
+        hoveringIdBits.clear();
+        touchingIdBits.clear();
+    }
+
+    inline const Pointer& pointerForId(uint32_t id) const {
+        return pointers[idToIndex[id]];
+    }
+
+    inline bool isHovering(uint32_t pointerIndex) {
+        return pointers[pointerIndex].isHovering;
+    }
+};
+
+
+/* Cooked data for a collection of pointers including a pointer id mapping table. */
+struct CookedPointerData {
+    uint32_t pointerCount;
+    PointerProperties pointerProperties[MAX_POINTERS];
+    PointerCoords pointerCoords[MAX_POINTERS];
+    BitSet32 hoveringIdBits, touchingIdBits;
+    uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+    CookedPointerData();
+    void clear();
+    void copyFrom(const CookedPointerData& other);
+
+    inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
+        return pointerCoords[idToIndex[id]];
+    }
+
+    inline bool isHovering(uint32_t pointerIndex) {
+        return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
+    }
+};
+
+
+/* Keeps track of the state of single-touch protocol. */
+class SingleTouchMotionAccumulator {
+public:
+    SingleTouchMotionAccumulator();
+
+    void process(const RawEvent* rawEvent);
+    void reset(InputDevice* device);
+
+    inline int32_t getAbsoluteX() const { return mAbsX; }
+    inline int32_t getAbsoluteY() const { return mAbsY; }
+    inline int32_t getAbsolutePressure() const { return mAbsPressure; }
+    inline int32_t getAbsoluteToolWidth() const { return mAbsToolWidth; }
+    inline int32_t getAbsoluteDistance() const { return mAbsDistance; }
+    inline int32_t getAbsoluteTiltX() const { return mAbsTiltX; }
+    inline int32_t getAbsoluteTiltY() const { return mAbsTiltY; }
+
+private:
+    int32_t mAbsX;
+    int32_t mAbsY;
+    int32_t mAbsPressure;
+    int32_t mAbsToolWidth;
+    int32_t mAbsDistance;
+    int32_t mAbsTiltX;
+    int32_t mAbsTiltY;
+
+    void clearAbsoluteAxes();
+};
+
+
+/* Keeps track of the state of multi-touch protocol. */
+class MultiTouchMotionAccumulator {
+public:
+    class Slot {
+    public:
+        inline bool isInUse() const { return mInUse; }
+        inline int32_t getX() const { return mAbsMTPositionX; }
+        inline int32_t getY() const { return mAbsMTPositionY; }
+        inline int32_t getTouchMajor() const { return mAbsMTTouchMajor; }
+        inline int32_t getTouchMinor() const {
+            return mHaveAbsMTTouchMinor ? mAbsMTTouchMinor : mAbsMTTouchMajor; }
+        inline int32_t getToolMajor() const { return mAbsMTWidthMajor; }
+        inline int32_t getToolMinor() const {
+            return mHaveAbsMTWidthMinor ? mAbsMTWidthMinor : mAbsMTWidthMajor; }
+        inline int32_t getOrientation() const { return mAbsMTOrientation; }
+        inline int32_t getTrackingId() const { return mAbsMTTrackingId; }
+        inline int32_t getPressure() const { return mAbsMTPressure; }
+        inline int32_t getDistance() const { return mAbsMTDistance; }
+        inline int32_t getToolType() const;
+
+    private:
+        friend class MultiTouchMotionAccumulator;
+
+        bool mInUse;
+        bool mHaveAbsMTTouchMinor;
+        bool mHaveAbsMTWidthMinor;
+        bool mHaveAbsMTToolType;
+
+        int32_t mAbsMTPositionX;
+        int32_t mAbsMTPositionY;
+        int32_t mAbsMTTouchMajor;
+        int32_t mAbsMTTouchMinor;
+        int32_t mAbsMTWidthMajor;
+        int32_t mAbsMTWidthMinor;
+        int32_t mAbsMTOrientation;
+        int32_t mAbsMTTrackingId;
+        int32_t mAbsMTPressure;
+        int32_t mAbsMTDistance;
+        int32_t mAbsMTToolType;
+
+        Slot();
+        void clear();
+    };
+
+    MultiTouchMotionAccumulator();
+    ~MultiTouchMotionAccumulator();
+
+    void configure(InputDevice* device, size_t slotCount, bool usingSlotsProtocol);
+    void reset(InputDevice* device);
+    void process(const RawEvent* rawEvent);
+    void finishSync();
+    bool hasStylus() const;
+
+    inline size_t getSlotCount() const { return mSlotCount; }
+    inline const Slot* getSlot(size_t index) const { return &mSlots[index]; }
+
+private:
+    int32_t mCurrentSlot;
+    Slot* mSlots;
+    size_t mSlotCount;
+    bool mUsingSlotsProtocol;
+    bool mHaveStylus;
+
+    void clearSlots(int32_t initialSlot);
+};
+
+
+/* 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.
+ *
+ * InputMapper lifecycle:
+ * - create
+ * - configure with 0 changes
+ * - reset
+ * - process, process, process (may occasionally reconfigure with non-zero changes or reset)
+ * - reset
+ * - destroy
+ */
+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 InputListenerInterface* getListener() { return mContext->getListener(); }
+    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
+
+    virtual uint32_t getSources() = 0;
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void dump(String8& dump);
+    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+    virtual void reset(nsecs_t when);
+    virtual void process(const RawEvent* rawEvent) = 0;
+    virtual void timeoutExpired(nsecs_t when);
+
+    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 void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+            int32_t token);
+    virtual void cancelVibrate(int32_t token);
+
+    virtual int32_t getMetaState();
+
+    virtual void fadePointer();
+
+protected:
+    InputDevice* mDevice;
+    InputReaderContext* mContext;
+
+    status_t getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo);
+    void bumpGeneration();
+
+    static void dumpRawAbsoluteAxisInfo(String8& dump,
+            const RawAbsoluteAxisInfo& axis, const char* name);
+};
+
+
+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:
+    uint32_t mUpdatedSwitchValues;
+    uint32_t mUpdatedSwitchMask;
+
+    void processSwitch(int32_t switchCode, int32_t switchValue);
+    void sync(nsecs_t when);
+};
+
+
+class VibratorInputMapper : public InputMapper {
+public:
+    VibratorInputMapper(InputDevice* device);
+    virtual ~VibratorInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
+            int32_t token);
+    virtual void cancelVibrate(int32_t token);
+    virtual void timeoutExpired(nsecs_t when);
+    virtual void dump(String8& dump);
+
+private:
+    bool mVibrating;
+    nsecs_t mPattern[MAX_VIBRATE_PATTERN_SIZE];
+    size_t mPatternSize;
+    ssize_t mRepeat;
+    int32_t mToken;
+    ssize_t mIndex;
+    nsecs_t mNextStepTime;
+
+    void nextStep();
+    void stopVibrating();
+};
+
+
+class KeyboardInputMapper : public InputMapper {
+public:
+    KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
+    virtual ~KeyboardInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void dump(String8& dump);
+    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+    virtual void reset(nsecs_t when);
+    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:
+    struct KeyDown {
+        int32_t keyCode;
+        int32_t scanCode;
+    };
+
+    uint32_t mSource;
+    int32_t mKeyboardType;
+
+    int32_t mOrientation; // orientation for dpad keys
+
+    Vector<KeyDown> mKeyDowns; // keys that are down
+    int32_t mMetaState;
+    nsecs_t mDownTime; // time of most recent key down
+
+    int32_t mCurrentHidUsage; // most recent HID usage seen this packet, or 0 if none
+
+    struct LedState {
+        bool avail; // led is available
+        bool on;    // we think the led is currently on
+    };
+    LedState mCapsLockLedState;
+    LedState mNumLockLedState;
+    LedState mScrollLockLedState;
+
+    // Immutable configuration parameters.
+    struct Parameters {
+        bool hasAssociatedDisplay;
+        bool orientationAware;
+    } mParameters;
+
+    void configureParameters();
+    void dumpParameters(String8& dump);
+
+    bool isKeyboardOrGamepadKey(int32_t scanCode);
+
+    void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
+            uint32_t policyFlags);
+
+    ssize_t findKeyDown(int32_t scanCode);
+
+    void resetLedState();
+    void initializeLedState(LedState& ledState, int32_t led);
+    void updateLedState(bool reset);
+    void updateLedStateForModifier(LedState& ledState, int32_t led,
+            int32_t modifier, bool reset);
+};
+
+
+class CursorInputMapper : public InputMapper {
+public:
+    CursorInputMapper(InputDevice* device);
+    virtual ~CursorInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void dump(String8& dump);
+    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+    virtual void reset(nsecs_t when);
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+
+    virtual void fadePointer();
+
+private:
+    // Amount that trackball needs to move in order to generate a key event.
+    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
+
+    // Immutable configuration parameters.
+    struct Parameters {
+        enum Mode {
+            MODE_POINTER,
+            MODE_NAVIGATION,
+        };
+
+        Mode mode;
+        bool hasAssociatedDisplay;
+        bool orientationAware;
+    } mParameters;
+
+    CursorButtonAccumulator mCursorButtonAccumulator;
+    CursorMotionAccumulator mCursorMotionAccumulator;
+    CursorScrollAccumulator mCursorScrollAccumulator;
+
+    int32_t mSource;
+    float mXScale;
+    float mYScale;
+    float mXPrecision;
+    float mYPrecision;
+
+    float mVWheelScale;
+    float mHWheelScale;
+
+    // Velocity controls for mouse pointer and wheel movements.
+    // The controls for X and Y wheel movements are separate to keep them decoupled.
+    VelocityControl mPointerVelocityControl;
+    VelocityControl mWheelXVelocityControl;
+    VelocityControl mWheelYVelocityControl;
+
+    int32_t mOrientation;
+
+    sp<PointerControllerInterface> mPointerController;
+
+    int32_t mButtonState;
+    nsecs_t mDownTime;
+
+    void configureParameters();
+    void dumpParameters(String8& dump);
+
+    void sync(nsecs_t when);
+};
+
+
+class TouchInputMapper : public InputMapper {
+public:
+    TouchInputMapper(InputDevice* device);
+    virtual ~TouchInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void dump(String8& dump);
+    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+    virtual void reset(nsecs_t when);
+    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 void fadePointer();
+    virtual void timeoutExpired(nsecs_t when);
+
+protected:
+    CursorButtonAccumulator mCursorButtonAccumulator;
+    CursorScrollAccumulator mCursorScrollAccumulator;
+    TouchButtonAccumulator mTouchButtonAccumulator;
+
+    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;
+        }
+    };
+
+    // Input sources and device mode.
+    uint32_t mSource;
+
+    enum DeviceMode {
+        DEVICE_MODE_DISABLED, // input is disabled
+        DEVICE_MODE_DIRECT, // direct mapping (touchscreen)
+        DEVICE_MODE_UNSCALED, // unscaled mapping (touchpad)
+        DEVICE_MODE_NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
+        DEVICE_MODE_POINTER, // pointer mapping (pointer)
+    };
+    DeviceMode mDeviceMode;
+
+    // The reader's configuration.
+    InputReaderConfiguration mConfig;
+
+    // Immutable configuration parameters.
+    struct Parameters {
+        enum DeviceType {
+            DEVICE_TYPE_TOUCH_SCREEN,
+            DEVICE_TYPE_TOUCH_PAD,
+            DEVICE_TYPE_TOUCH_NAVIGATION,
+            DEVICE_TYPE_POINTER,
+        };
+
+        DeviceType deviceType;
+        bool hasAssociatedDisplay;
+        bool associatedDisplayIsExternal;
+        bool orientationAware;
+        bool hasButtonUnderPad;
+
+        enum GestureMode {
+            GESTURE_MODE_POINTER,
+            GESTURE_MODE_SPOTS,
+        };
+        GestureMode gestureMode;
+    } mParameters;
+
+    // Immutable calibration parameters in parsed form.
+    struct Calibration {
+        // Size
+        enum SizeCalibration {
+            SIZE_CALIBRATION_DEFAULT,
+            SIZE_CALIBRATION_NONE,
+            SIZE_CALIBRATION_GEOMETRIC,
+            SIZE_CALIBRATION_DIAMETER,
+            SIZE_CALIBRATION_BOX,
+            SIZE_CALIBRATION_AREA,
+        };
+
+        SizeCalibration sizeCalibration;
+
+        bool haveSizeScale;
+        float sizeScale;
+        bool haveSizeBias;
+        float sizeBias;
+        bool haveSizeIsSummed;
+        bool sizeIsSummed;
+
+        // Pressure
+        enum PressureCalibration {
+            PRESSURE_CALIBRATION_DEFAULT,
+            PRESSURE_CALIBRATION_NONE,
+            PRESSURE_CALIBRATION_PHYSICAL,
+            PRESSURE_CALIBRATION_AMPLITUDE,
+        };
+
+        PressureCalibration pressureCalibration;
+        bool havePressureScale;
+        float pressureScale;
+
+        // Orientation
+        enum OrientationCalibration {
+            ORIENTATION_CALIBRATION_DEFAULT,
+            ORIENTATION_CALIBRATION_NONE,
+            ORIENTATION_CALIBRATION_INTERPOLATED,
+            ORIENTATION_CALIBRATION_VECTOR,
+        };
+
+        OrientationCalibration orientationCalibration;
+
+        // Distance
+        enum DistanceCalibration {
+            DISTANCE_CALIBRATION_DEFAULT,
+            DISTANCE_CALIBRATION_NONE,
+            DISTANCE_CALIBRATION_SCALED,
+        };
+
+        DistanceCalibration distanceCalibration;
+        bool haveDistanceScale;
+        float distanceScale;
+
+        enum CoverageCalibration {
+            COVERAGE_CALIBRATION_DEFAULT,
+            COVERAGE_CALIBRATION_NONE,
+            COVERAGE_CALIBRATION_BOX,
+        };
+
+        CoverageCalibration coverageCalibration;
+
+        inline void applySizeScaleAndBias(float* outSize) const {
+            if (haveSizeScale) {
+                *outSize *= sizeScale;
+            }
+            if (haveSizeBias) {
+                *outSize += sizeBias;
+            }
+            if (*outSize < 0) {
+                *outSize = 0;
+            }
+        }
+    } mCalibration;
+
+    // Raw pointer axis information from the driver.
+    RawPointerAxes mRawPointerAxes;
+
+    // Raw pointer sample data.
+    RawPointerData mCurrentRawPointerData;
+    RawPointerData mLastRawPointerData;
+
+    // Cooked pointer sample data.
+    CookedPointerData mCurrentCookedPointerData;
+    CookedPointerData mLastCookedPointerData;
+
+    // Button state.
+    int32_t mCurrentButtonState;
+    int32_t mLastButtonState;
+
+    // Scroll state.
+    int32_t mCurrentRawVScroll;
+    int32_t mCurrentRawHScroll;
+
+    // Id bits used to differentiate fingers, stylus and mouse tools.
+    BitSet32 mCurrentFingerIdBits; // finger or unknown
+    BitSet32 mLastFingerIdBits;
+    BitSet32 mCurrentStylusIdBits; // stylus or eraser
+    BitSet32 mLastStylusIdBits;
+    BitSet32 mCurrentMouseIdBits; // mouse or lens
+    BitSet32 mLastMouseIdBits;
+
+    // True if we sent a HOVER_ENTER event.
+    bool mSentHoverEnter;
+
+    // The time the primary pointer last went down.
+    nsecs_t mDownTime;
+
+    // The pointer controller, or null if the device is not a pointer.
+    sp<PointerControllerInterface> mPointerController;
+
+    Vector<VirtualKey> mVirtualKeys;
+
+    virtual void configureParameters();
+    virtual void dumpParameters(String8& dump);
+    virtual void configureRawPointerAxes();
+    virtual void dumpRawPointerAxes(String8& dump);
+    virtual void configureSurface(nsecs_t when, bool* outResetNeeded);
+    virtual void dumpSurface(String8& dump);
+    virtual void configureVirtualKeys();
+    virtual void dumpVirtualKeys(String8& dump);
+    virtual void parseCalibration();
+    virtual void resolveCalibration();
+    virtual void dumpCalibration(String8& dump);
+    virtual bool hasStylus() const = 0;
+
+    virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
+
+private:
+    // The current viewport.
+    // The components of the viewport are specified in the display's rotated orientation.
+    DisplayViewport mViewport;
+
+    // The surface orientation, width and height set by configureSurface().
+    // The width and height are derived from the viewport but are specified
+    // in the natural orientation.
+    // The surface origin specifies how the surface coordinates should be translated
+    // to align with the logical display coordinate space.
+    // The orientation may be different from the viewport orientation as it specifies
+    // the rotation of the surface coordinates required to produce the viewport's
+    // requested orientation, so it will depend on whether the device is orientation aware.
+    int32_t mSurfaceWidth;
+    int32_t mSurfaceHeight;
+    int32_t mSurfaceLeft;
+    int32_t mSurfaceTop;
+    int32_t mSurfaceOrientation;
+
+    // Translation and scaling factors, orientation-independent.
+    float mXTranslate;
+    float mXScale;
+    float mXPrecision;
+
+    float mYTranslate;
+    float mYScale;
+    float mYPrecision;
+
+    float mGeometricScale;
+
+    float mPressureScale;
+
+    float mSizeScale;
+
+    float mOrientationScale;
+
+    float mDistanceScale;
+
+    bool mHaveTilt;
+    float mTiltXCenter;
+    float mTiltXScale;
+    float mTiltYCenter;
+    float mTiltYScale;
+
+    // Oriented motion ranges for input device info.
+    struct OrientedRanges {
+        InputDeviceInfo::MotionRange x;
+        InputDeviceInfo::MotionRange y;
+        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;
+
+        bool haveDistance;
+        InputDeviceInfo::MotionRange distance;
+
+        bool haveTilt;
+        InputDeviceInfo::MotionRange tilt;
+
+        OrientedRanges() {
+            clear();
+        }
+
+        void clear() {
+            haveSize = false;
+            haveTouchSize = false;
+            haveToolSize = false;
+            haveOrientation = false;
+            haveDistance = false;
+            haveTilt = false;
+        }
+    } mOrientedRanges;
+
+    // Oriented dimensions and precision.
+    float mOrientedXPrecision;
+    float mOrientedYPrecision;
+
+    struct CurrentVirtualKeyState {
+        bool down;
+        bool ignored;
+        nsecs_t downTime;
+        int32_t keyCode;
+        int32_t scanCode;
+    } mCurrentVirtualKey;
+
+    // Scale factor for gesture or mouse based pointer movements.
+    float mPointerXMovementScale;
+    float mPointerYMovementScale;
+
+    // Scale factor for gesture based zooming and other freeform motions.
+    float mPointerXZoomScale;
+    float mPointerYZoomScale;
+
+    // The maximum swipe width.
+    float mPointerGestureMaxSwipeWidth;
+
+    struct PointerDistanceHeapElement {
+        uint32_t currentPointerIndex : 8;
+        uint32_t lastPointerIndex : 8;
+        uint64_t distance : 48; // squared distance
+    };
+
+    enum PointerUsage {
+        POINTER_USAGE_NONE,
+        POINTER_USAGE_GESTURES,
+        POINTER_USAGE_STYLUS,
+        POINTER_USAGE_MOUSE,
+    };
+    PointerUsage mPointerUsage;
+
+    struct PointerGesture {
+        enum Mode {
+            // No fingers, button is not pressed.
+            // Nothing happening.
+            NEUTRAL,
+
+            // No fingers, button is not pressed.
+            // Tap detected.
+            // Emits DOWN and UP events at the pointer location.
+            TAP,
+
+            // Exactly one finger dragging following a tap.
+            // Pointer follows the active finger.
+            // Emits DOWN, MOVE and UP events at the pointer location.
+            //
+            // Detect double-taps when the finger goes up while in TAP_DRAG mode.
+            TAP_DRAG,
+
+            // Button is pressed.
+            // Pointer follows the active finger if there is one.  Other fingers are ignored.
+            // Emits DOWN, MOVE and UP events at the pointer location.
+            BUTTON_CLICK_OR_DRAG,
+
+            // Exactly one finger, button is not pressed.
+            // Pointer follows the active finger.
+            // Emits HOVER_MOVE events at the pointer location.
+            //
+            // Detect taps when the finger goes up while in HOVER mode.
+            HOVER,
+
+            // Exactly two fingers but neither have moved enough to clearly indicate
+            // whether a swipe or freeform gesture was intended.  We consider the
+            // pointer to be pressed so this enables clicking or long-pressing on buttons.
+            // Pointer does not move.
+            // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
+            PRESS,
+
+            // Exactly two fingers moving in the same direction, button is not pressed.
+            // Pointer does not move.
+            // Emits DOWN, MOVE and UP events with a single pointer coordinate that
+            // follows the midpoint between both fingers.
+            SWIPE,
+
+            // Two or more fingers moving in arbitrary directions, button is not pressed.
+            // Pointer does not move.
+            // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
+            // each finger individually relative to the initial centroid of the finger.
+            FREEFORM,
+
+            // Waiting for quiet time to end before starting the next gesture.
+            QUIET,
+        };
+
+        // Time the first finger went down.
+        nsecs_t firstTouchTime;
+
+        // The active pointer id from the raw touch data.
+        int32_t activeTouchId; // -1 if none
+
+        // The active pointer id from the gesture last delivered to the application.
+        int32_t activeGestureId; // -1 if none
+
+        // Pointer coords and ids for the current and previous pointer gesture.
+        Mode currentGestureMode;
+        BitSet32 currentGestureIdBits;
+        uint32_t currentGestureIdToIndex[MAX_POINTER_ID + 1];
+        PointerProperties currentGestureProperties[MAX_POINTERS];
+        PointerCoords currentGestureCoords[MAX_POINTERS];
+
+        Mode lastGestureMode;
+        BitSet32 lastGestureIdBits;
+        uint32_t lastGestureIdToIndex[MAX_POINTER_ID + 1];
+        PointerProperties lastGestureProperties[MAX_POINTERS];
+        PointerCoords lastGestureCoords[MAX_POINTERS];
+
+        // Time the pointer gesture last went down.
+        nsecs_t downTime;
+
+        // Time when the pointer went down for a TAP.
+        nsecs_t tapDownTime;
+
+        // Time when the pointer went up for a TAP.
+        nsecs_t tapUpTime;
+
+        // Location of initial tap.
+        float tapX, tapY;
+
+        // Time we started waiting for quiescence.
+        nsecs_t quietTime;
+
+        // Reference points for multitouch gestures.
+        float referenceTouchX;    // reference touch X/Y coordinates in surface units
+        float referenceTouchY;
+        float referenceGestureX;  // reference gesture X/Y coordinates in pixels
+        float referenceGestureY;
+
+        // Distance that each pointer has traveled which has not yet been
+        // subsumed into the reference gesture position.
+        BitSet32 referenceIdBits;
+        struct Delta {
+            float dx, dy;
+        };
+        Delta referenceDeltas[MAX_POINTER_ID + 1];
+
+        // Describes how touch ids are mapped to gesture ids for freeform gestures.
+        uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
+
+        // A velocity tracker for determining whether to switch active pointers during drags.
+        VelocityTracker velocityTracker;
+
+        void reset() {
+            firstTouchTime = LLONG_MIN;
+            activeTouchId = -1;
+            activeGestureId = -1;
+            currentGestureMode = NEUTRAL;
+            currentGestureIdBits.clear();
+            lastGestureMode = NEUTRAL;
+            lastGestureIdBits.clear();
+            downTime = 0;
+            velocityTracker.clear();
+            resetTap();
+            resetQuietTime();
+        }
+
+        void resetTap() {
+            tapDownTime = LLONG_MIN;
+            tapUpTime = LLONG_MIN;
+        }
+
+        void resetQuietTime() {
+            quietTime = LLONG_MIN;
+        }
+    } mPointerGesture;
+
+    struct PointerSimple {
+        PointerCoords currentCoords;
+        PointerProperties currentProperties;
+        PointerCoords lastCoords;
+        PointerProperties lastProperties;
+
+        // True if the pointer is down.
+        bool down;
+
+        // True if the pointer is hovering.
+        bool hovering;
+
+        // Time the pointer last went down.
+        nsecs_t downTime;
+
+        void reset() {
+            currentCoords.clear();
+            currentProperties.clear();
+            lastCoords.clear();
+            lastProperties.clear();
+            down = false;
+            hovering = false;
+            downTime = 0;
+        }
+    } mPointerSimple;
+
+    // The pointer and scroll velocity controls.
+    VelocityControl mPointerVelocityControl;
+    VelocityControl mWheelXVelocityControl;
+    VelocityControl mWheelYVelocityControl;
+
+    void sync(nsecs_t when);
+
+    bool consumeRawTouches(nsecs_t when, uint32_t policyFlags);
+    void dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+            int32_t keyEventAction, int32_t keyEventFlags);
+
+    void dispatchTouches(nsecs_t when, uint32_t policyFlags);
+    void dispatchHoverExit(nsecs_t when, uint32_t policyFlags);
+    void dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags);
+    void cookPointerData();
+
+    void dispatchPointerUsage(nsecs_t when, uint32_t policyFlags, PointerUsage pointerUsage);
+    void abortPointerUsage(nsecs_t when, uint32_t policyFlags);
+
+    void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
+    void abortPointerGestures(nsecs_t when, uint32_t policyFlags);
+    bool preparePointerGestures(nsecs_t when,
+            bool* outCancelPreviousGesture, bool* outFinishPreviousGesture,
+            bool isTimeout);
+
+    void dispatchPointerStylus(nsecs_t when, uint32_t policyFlags);
+    void abortPointerStylus(nsecs_t when, uint32_t policyFlags);
+
+    void dispatchPointerMouse(nsecs_t when, uint32_t policyFlags);
+    void abortPointerMouse(nsecs_t when, uint32_t policyFlags);
+
+    void dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
+            bool down, bool hovering);
+    void abortPointerSimple(nsecs_t when, uint32_t policyFlags);
+
+    // Dispatches a motion event.
+    // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
+    // method will take care of setting the index and transmuting the action to DOWN or UP
+    // it is the first / last pointer to go down / up.
+    void dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
+            int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+            int32_t edgeFlags,
+            const PointerProperties* properties, const PointerCoords* coords,
+            const uint32_t* idToIndex, BitSet32 idBits,
+            int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime);
+
+    // Updates pointer coords and properties for pointers with specified ids that have moved.
+    // Returns true if any of them changed.
+    bool updateMovedPointers(const PointerProperties* inProperties,
+            const PointerCoords* inCoords, const uint32_t* inIdToIndex,
+            PointerProperties* outProperties, PointerCoords* outCoords,
+            const uint32_t* outIdToIndex, BitSet32 idBits) const;
+
+    bool isPointInsideSurface(int32_t x, int32_t y);
+    const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
+
+    void assignPointerIds();
+};
+
+
+class SingleTouchInputMapper : public TouchInputMapper {
+public:
+    SingleTouchInputMapper(InputDevice* device);
+    virtual ~SingleTouchInputMapper();
+
+    virtual void reset(nsecs_t when);
+    virtual void process(const RawEvent* rawEvent);
+
+protected:
+    virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
+    virtual void configureRawPointerAxes();
+    virtual bool hasStylus() const;
+
+private:
+    SingleTouchMotionAccumulator mSingleTouchMotionAccumulator;
+};
+
+
+class MultiTouchInputMapper : public TouchInputMapper {
+public:
+    MultiTouchInputMapper(InputDevice* device);
+    virtual ~MultiTouchInputMapper();
+
+    virtual void reset(nsecs_t when);
+    virtual void process(const RawEvent* rawEvent);
+
+protected:
+    virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
+    virtual void configureRawPointerAxes();
+    virtual bool hasStylus() const;
+
+private:
+    MultiTouchMotionAccumulator mMultiTouchMotionAccumulator;
+
+    // Specifies the pointer id bits that are in use, and their associated tracking id.
+    BitSet32 mPointerIdBits;
+    int32_t mPointerTrackingIdMap[MAX_POINTER_ID + 1];
+};
+
+
+class JoystickInputMapper : public InputMapper {
+public:
+    JoystickInputMapper(InputDevice* device);
+    virtual ~JoystickInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void dump(String8& dump);
+    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+    virtual void reset(nsecs_t when);
+    virtual void process(const RawEvent* rawEvent);
+
+private:
+    struct Axis {
+        RawAbsoluteAxisInfo rawAxisInfo;
+        AxisInfo axisInfo;
+
+        bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
+
+        float scale;   // scale factor from raw to normalized values
+        float offset;  // offset to add after scaling for normalization
+        float highScale;  // scale factor from raw to normalized values of high split
+        float highOffset; // offset to add after scaling for normalization of high split
+
+        float min;        // normalized inclusive minimum
+        float max;        // normalized inclusive maximum
+        float flat;       // normalized flat region size
+        float fuzz;       // normalized error tolerance
+        float resolution; // normalized resolution in units/mm
+
+        float filter;  // filter out small variations of this size
+        float currentValue; // current value
+        float newValue; // most recent value
+        float highCurrentValue; // current value of high split
+        float highNewValue; // most recent value of high split
+
+        void initialize(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo,
+                bool explicitlyMapped, float scale, float offset,
+                float highScale, float highOffset,
+                float min, float max, float flat, float fuzz, float resolution) {
+            this->rawAxisInfo = rawAxisInfo;
+            this->axisInfo = axisInfo;
+            this->explicitlyMapped = explicitlyMapped;
+            this->scale = scale;
+            this->offset = offset;
+            this->highScale = highScale;
+            this->highOffset = highOffset;
+            this->min = min;
+            this->max = max;
+            this->flat = flat;
+            this->fuzz = fuzz;
+            this->resolution = resolution;
+            this->filter = 0;
+            resetValue();
+        }
+
+        void resetValue() {
+            this->currentValue = 0;
+            this->newValue = 0;
+            this->highCurrentValue = 0;
+            this->highNewValue = 0;
+        }
+    };
+
+    // Axes indexed by raw ABS_* axis index.
+    KeyedVector<int32_t, Axis> mAxes;
+
+    void sync(nsecs_t when, bool force);
+
+    bool haveAxis(int32_t axisId);
+    void pruneAxes(bool ignoreExplicitlyMappedAxes);
+    bool filterAxes(bool force);
+
+    static bool hasValueChangedSignificantly(float filter,
+            float newValue, float currentValue, float min, float max);
+    static bool hasMovedNearerToValueWithinFilteredRange(float filter,
+            float newValue, float currentValue, float thresholdValue);
+
+    static bool isCenteredAxis(int32_t axis);
+    static int32_t getCompatAxis(int32_t axis);
+
+    static void addMotionRange(int32_t axisId, const Axis& axis, InputDeviceInfo* info);
+    static void setPointerCoordsAxisValue(PointerCoords* pointerCoords, int32_t axis,
+            float value);
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_READER_H
diff --git a/services/inputflinger/InputWindow.cpp b/services/inputflinger/InputWindow.cpp
new file mode 100644
index 0000000..da59159
--- /dev/null
+++ b/services/inputflinger/InputWindow.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "InputWindow"
+#define LOG_NDEBUG 0
+
+#include "InputWindow.h"
+
+#include <cutils/log.h>
+
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+namespace android {
+
+// --- InputWindowInfo ---
+void InputWindowInfo::addTouchableRegion(const Rect& region) {
+    touchableRegion.orSelf(region);
+}
+
+bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
+    return touchableRegion.contains(x,y);
+}
+
+bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
+    return x >= frameLeft && x <= frameRight
+            && y >= frameTop && y <= frameBottom;
+}
+
+bool InputWindowInfo::isTrustedOverlay() const {
+    return layoutParamsType == TYPE_INPUT_METHOD
+            || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
+            || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
+}
+
+bool InputWindowInfo::supportsSplitTouch() const {
+    return layoutParamsFlags & FLAG_SPLIT_TOUCH;
+}
+
+
+// --- InputWindowHandle ---
+
+InputWindowHandle::InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
+    inputApplicationHandle(inputApplicationHandle), mInfo(NULL) {
+}
+
+InputWindowHandle::~InputWindowHandle() {
+    delete mInfo;
+}
+
+void InputWindowHandle::releaseInfo() {
+    if (mInfo) {
+        delete mInfo;
+        mInfo = NULL;
+    }
+}
+
+} // namespace android
diff --git a/services/inputflinger/InputWindow.h b/services/inputflinger/InputWindow.h
new file mode 100644
index 0000000..9618ffe
--- /dev/null
+++ b/services/inputflinger/InputWindow.h
@@ -0,0 +1,209 @@
+/*
+ * 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 _UI_INPUT_WINDOW_H
+#define _UI_INPUT_WINDOW_H
+
+#include <input/Input.h>
+#include <input/InputTransport.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+#include <utils/String8.h>
+
+#include "InputApplication.h"
+
+namespace android {
+
+
+/*
+ * Describes the properties of a window that can receive input.
+ */
+struct InputWindowInfo {
+    // 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_SLIPPERY = 0x20000000,
+        FLAG_NEEDS_MENU_KEY = 0x40000000,
+    };
+
+    // Private Window flags from WindowManager.LayoutParams
+    enum {
+        PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100,
+    };
+
+    // 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,
+        TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16,
+        TYPE_STATUS_BAR_SUB_PANEL  = FIRST_SYSTEM_WINDOW+17,
+        TYPE_POINTER            = FIRST_SYSTEM_WINDOW+18,
+        TYPE_NAVIGATION_BAR     = FIRST_SYSTEM_WINDOW+19,
+        TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20,
+        TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21,
+        LAST_SYSTEM_WINDOW      = 2999,
+    };
+
+    enum {
+        INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
+        INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002,
+        INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
+    };
+
+    sp<InputChannel> inputChannel;
+    String8 name;
+    int32_t layoutParamsFlags;
+    int32_t layoutParamsPrivateFlags;
+    int32_t layoutParamsType;
+    nsecs_t dispatchingTimeout;
+    int32_t frameLeft;
+    int32_t frameTop;
+    int32_t frameRight;
+    int32_t frameBottom;
+    float scaleFactor;
+    Region touchableRegion;
+    bool visible;
+    bool canReceiveKeys;
+    bool hasFocus;
+    bool hasWallpaper;
+    bool paused;
+    int32_t layer;
+    int32_t ownerPid;
+    int32_t ownerUid;
+    int32_t inputFeatures;
+    int32_t displayId;
+
+    void addTouchableRegion(const Rect& region);
+
+    bool touchableRegionContainsPoint(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;
+
+    bool supportsSplitTouch() const;
+};
+
+
+/*
+ * Handle for a window that can receive input.
+ *
+ * Used by the native input dispatcher to indirectly refer to the window manager objects
+ * that describe a window.
+ */
+class InputWindowHandle : public RefBase {
+public:
+    const sp<InputApplicationHandle> inputApplicationHandle;
+
+    inline const InputWindowInfo* getInfo() const {
+        return mInfo;
+    }
+
+    inline sp<InputChannel> getInputChannel() const {
+        return mInfo ? mInfo->inputChannel : NULL;
+    }
+
+    inline String8 getName() const {
+        return mInfo ? mInfo->name : String8("<invalid>");
+    }
+
+    inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
+        return mInfo ? mInfo->dispatchingTimeout : defaultValue;
+    }
+
+    /**
+     * Requests that the state of this object be updated to reflect
+     * the most current available information about the application.
+     *
+     * This method should only be called from within the input dispatcher's
+     * critical section.
+     *
+     * Returns true on success, or false if the handle is no longer valid.
+     */
+    virtual bool updateInfo() = 0;
+
+    /**
+     * Releases the storage used by the associated information when it is
+     * no longer needed.
+     */
+    void releaseInfo();
+
+protected:
+    InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle);
+    virtual ~InputWindowHandle();
+
+    InputWindowInfo* mInfo;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_WINDOW_H
diff --git a/services/inputflinger/PointerControllerInterface.h b/services/inputflinger/PointerControllerInterface.h
new file mode 100644
index 0000000..e94dd94
--- /dev/null
+++ b/services/inputflinger/PointerControllerInterface.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 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 _INPUTFLINGER_POINTER_CONTROLLER_INTERFACE_H
+#define _INPUTFLINGER_POINTER_CONTROLLER_INTERFACE_H
+
+#include <input/Input.h>
+#include <utils/BitSet.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+/**
+ * Interface for tracking a mouse / touch pad pointer and touch pad spots.
+ *
+ * The spots are sprites on screen that visually represent the positions of
+ * fingers
+ *
+ * The pointer controller is responsible for providing synchronization and for tracking
+ * display orientation changes if needed.
+ */
+class PointerControllerInterface : public virtual RefBase {
+protected:
+    PointerControllerInterface() { }
+    virtual ~PointerControllerInterface() { }
+
+public:
+    /* Gets the bounds of the region that the pointer can traverse.
+     * Returns true if the bounds are available. */
+    virtual bool getBounds(float* outMinX, float* outMinY,
+            float* outMaxX, float* outMaxY) const = 0;
+
+    /* Move the pointer. */
+    virtual void move(float deltaX, float deltaY) = 0;
+
+    /* Sets a mask that indicates which buttons are pressed. */
+    virtual void setButtonState(int32_t buttonState) = 0;
+
+    /* Gets a mask that indicates which buttons are pressed. */
+    virtual int32_t getButtonState() const = 0;
+
+    /* Sets the absolute location of the pointer. */
+    virtual void setPosition(float x, float y) = 0;
+
+    /* Gets the absolute location of the pointer. */
+    virtual void getPosition(float* outX, float* outY) const = 0;
+
+    enum Transition {
+        // Fade/unfade immediately.
+        TRANSITION_IMMEDIATE,
+        // Fade/unfade gradually.
+        TRANSITION_GRADUAL,
+    };
+
+    /* Fades the pointer out now. */
+    virtual void fade(Transition transition) = 0;
+
+    /* Makes the pointer visible if it has faded out.
+     * The pointer never unfades itself automatically.  This method must be called
+     * by the client whenever the pointer is moved or a button is pressed and it
+     * wants to ensure that the pointer becomes visible again. */
+    virtual void unfade(Transition transition) = 0;
+
+    enum Presentation {
+        // Show the mouse pointer.
+        PRESENTATION_POINTER,
+        // Show spots and a spot anchor in place of the mouse pointer.
+        PRESENTATION_SPOT,
+    };
+
+    /* Sets the mode of the pointer controller. */
+    virtual void setPresentation(Presentation presentation) = 0;
+
+    /* Sets the spots for the current gesture.
+     * The spots are not subject to the inactivity timeout like the pointer
+     * itself it since they are expected to remain visible for so long as
+     * the fingers are on the touch pad.
+     *
+     * The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant.
+     * For spotCoords, pressure != 0 indicates that the spot's location is being
+     * pressed (not hovering).
+     */
+    virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+            BitSet32 spotIdBits) = 0;
+
+    /* Removes all spots. */
+    virtual void clearSpots() = 0;
+};
+
+} // namespace android
+
+#endif // _INPUTFLINGER_POINTER_CONTROLLER_INTERFACE_H
diff --git a/services/inputflinger/main.cpp b/services/inputflinger/main.cpp
new file mode 100644
index 0000000..3209a62
--- /dev/null
+++ b/services/inputflinger/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 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/BinderService.h>
+#include "InputFlinger.h"
+
+using namespace android;
+
+int main(int argc, char** argv) {
+    ProcessState::self()->setThreadPoolMaxThreadCount(4);
+    BinderService<InputFlinger>::publishAndJoinThreadPool(true);
+    return 0;
+}
diff --git a/services/inputflinger/tests/Android.mk b/services/inputflinger/tests/Android.mk
new file mode 100644
index 0000000..6dae82f
--- /dev/null
+++ b/services/inputflinger/tests/Android.mk
@@ -0,0 +1,51 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# Build the unit tests.
+test_src_files := \
+    InputReader_test.cpp \
+    InputDispatcher_test.cpp
+
+shared_libraries := \
+    libcutils \
+    liblog \
+    libandroidfw \
+    libutils \
+    libhardware \
+    libhardware_legacy \
+    libui \
+    libskia \
+    libstlport \
+    libinput \
+    libinputflinger \
+    libinputservice
+
+static_libraries := \
+    libgtest \
+    libgtest_main
+
+c_includes := \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport \
+    external/skia/include/core
+
+
+module_tags := eng tests
+
+$(foreach file,$(test_src_files), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+	$(eval LOCAL_CFLAGS += -Wno-unused-parameter) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+    $(eval include $(BUILD_NATIVE_TEST)) \
+)
+
+# Build the manual test programs.
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
new file mode 100644
index 0000000..26b4fab
--- /dev/null
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -0,0 +1,247 @@
+/*
+ * 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 "../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 {
+    InputDispatcherConfiguration mConfig;
+
+protected:
+    virtual ~FakeInputDispatcherPolicy() {
+    }
+
+public:
+    FakeInputDispatcherPolicy() {
+    }
+
+private:
+    virtual void notifyConfigurationChanged(nsecs_t when) {
+    }
+
+    virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) {
+        return 0;
+    }
+
+    virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
+    }
+
+    virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
+        *outConfig = mConfig;
+    }
+
+    virtual bool isKeyRepeatEnabled() {
+        return true;
+    }
+
+    virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
+        return true;
+    }
+
+    virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
+    }
+
+    virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
+    }
+
+    virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
+            const KeyEvent* keyEvent, uint32_t policyFlags) {
+        return 0;
+    }
+
+    virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
+            const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
+        return false;
+    }
+
+    virtual void notifySwitch(nsecs_t when,
+            uint32_t switchValues, uint32_t switchMask, 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, 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, 0))
+            << "Should reject key events with ACTION_MULTIPLE.";
+}
+
+TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
+    MotionEvent event;
+    PointerProperties pointerProperties[MAX_POINTERS + 1];
+    PointerCoords pointerCoords[MAX_POINTERS + 1];
+    for (int i = 0; i <= MAX_POINTERS; i++) {
+        pointerProperties[i].clear();
+        pointerProperties[i].id = i;
+        pointerCoords[i].clear();
+    }
+
+    // Rejects undefined motion actions.
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 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, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 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, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 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, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 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, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 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, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 0, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 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, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
+            << "Should reject motion events with more than MAX_POINTERS pointers.";
+
+    // Rejects motion events with invalid pointer ids.
+    pointerProperties[0].id = -1;
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
+            << "Should reject motion events with pointer ids less than 0.";
+
+    pointerProperties[0].id = MAX_POINTER_ID + 1;
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
+            << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
+
+    // Rejects motion events with duplicate pointer ids.
+    pointerProperties[0].id = 1;
+    pointerProperties[1].id = 1;
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 2, pointerProperties, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
+            << "Should reject motion events with duplicate pointer ids.";
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
new file mode 100644
index 0000000..aaa973d
--- /dev/null
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -0,0 +1,5099 @@
+/*
+ * 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 "../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;
+}
+
+
+// --- FakePointerController ---
+
+class FakePointerController : public PointerControllerInterface {
+    bool mHaveBounds;
+    float mMinX, mMinY, mMaxX, mMaxY;
+    float mX, mY;
+    int32_t mButtonState;
+
+protected:
+    virtual ~FakePointerController() { }
+
+public:
+    FakePointerController() :
+        mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
+        mButtonState(0) {
+    }
+
+    void setBounds(float minX, float minY, float maxX, float maxY) {
+        mHaveBounds = true;
+        mMinX = minX;
+        mMinY = minY;
+        mMaxX = maxX;
+        mMaxY = maxY;
+    }
+
+    virtual void setPosition(float x, float y) {
+        mX = x;
+        mY = y;
+    }
+
+    virtual void setButtonState(int32_t buttonState) {
+        mButtonState = buttonState;
+    }
+
+    virtual int32_t getButtonState() const {
+        return mButtonState;
+    }
+
+    virtual void getPosition(float* outX, float* outY) const {
+        *outX = mX;
+        *outY = mY;
+    }
+
+private:
+    virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
+        *outMinX = mMinX;
+        *outMinY = mMinY;
+        *outMaxX = mMaxX;
+        *outMaxY = mMaxY;
+        return mHaveBounds;
+    }
+
+    virtual void move(float deltaX, float deltaY) {
+        mX += deltaX;
+        if (mX < mMinX) mX = mMinX;
+        if (mX > mMaxX) mX = mMaxX;
+        mY += deltaY;
+        if (mY < mMinY) mY = mMinY;
+        if (mY > mMaxY) mY = mMaxY;
+    }
+
+    virtual void fade(Transition transition) {
+    }
+
+    virtual void unfade(Transition transition) {
+    }
+
+    virtual void setPresentation(Presentation presentation) {
+    }
+
+    virtual void setSpots(const PointerCoords* spotCoords,
+            const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
+    }
+
+    virtual void clearSpots() {
+    }
+};
+
+
+// --- FakeInputReaderPolicy ---
+
+class FakeInputReaderPolicy : public InputReaderPolicyInterface {
+    InputReaderConfiguration mConfig;
+    KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
+    Vector<InputDeviceInfo> mInputDevices;
+
+protected:
+    virtual ~FakeInputReaderPolicy() { }
+
+public:
+    FakeInputReaderPolicy() {
+    }
+
+    void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) {
+        // Set the size of both the internal and external display at the same time.
+        bool isRotated = (orientation == DISPLAY_ORIENTATION_90
+                || orientation == DISPLAY_ORIENTATION_270);
+        DisplayViewport v;
+        v.displayId = displayId;
+        v.orientation = orientation;
+        v.logicalLeft = 0;
+        v.logicalTop = 0;
+        v.logicalRight = isRotated ? height : width;
+        v.logicalBottom = isRotated ? width : height;
+        v.physicalLeft = 0;
+        v.physicalTop = 0;
+        v.physicalRight = isRotated ? height : width;
+        v.physicalBottom = isRotated ? width : height;
+        v.deviceWidth = isRotated ? height : width;
+        v.deviceHeight = isRotated ? width : height;
+        mConfig.setDisplayInfo(false /*external*/, v);
+        mConfig.setDisplayInfo(true /*external*/, v);
+    }
+
+    void addExcludedDeviceName(const String8& deviceName) {
+        mConfig.excludedDeviceNames.push(deviceName);
+    }
+
+    void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) {
+        mPointerControllers.add(deviceId, controller);
+    }
+
+    const InputReaderConfiguration* getReaderConfiguration() const {
+        return &mConfig;
+    }
+
+    const Vector<InputDeviceInfo>& getInputDevices() const {
+        return mInputDevices;
+    }
+
+private:
+    virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
+        *outConfig = mConfig;
+    }
+
+    virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
+        return mPointerControllers.valueFor(deviceId);
+    }
+
+    virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) {
+        mInputDevices = inputDevices;
+    }
+
+    virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier) {
+        return NULL;
+    }
+
+    virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) {
+        return String8::empty();
+    }
+};
+
+
+// --- FakeInputListener ---
+
+class FakeInputListener : public InputListenerInterface {
+private:
+    List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgsQueue;
+    List<NotifyDeviceResetArgs> mNotifyDeviceResetArgsQueue;
+    List<NotifyKeyArgs> mNotifyKeyArgsQueue;
+    List<NotifyMotionArgs> mNotifyMotionArgsQueue;
+    List<NotifySwitchArgs> mNotifySwitchArgsQueue;
+
+protected:
+    virtual ~FakeInputListener() { }
+
+public:
+    FakeInputListener() {
+    }
+
+    void assertNotifyConfigurationChangedWasCalled(
+            NotifyConfigurationChangedArgs* outEventArgs = NULL) {
+        ASSERT_FALSE(mNotifyConfigurationChangedArgsQueue.empty())
+                << "Expected notifyConfigurationChanged() to have been called.";
+        if (outEventArgs) {
+            *outEventArgs = *mNotifyConfigurationChangedArgsQueue.begin();
+        }
+        mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
+    }
+
+    void assertNotifyDeviceResetWasCalled(
+            NotifyDeviceResetArgs* outEventArgs = NULL) {
+        ASSERT_FALSE(mNotifyDeviceResetArgsQueue.empty())
+                << "Expected notifyDeviceReset() to have been called.";
+        if (outEventArgs) {
+            *outEventArgs = *mNotifyDeviceResetArgsQueue.begin();
+        }
+        mNotifyDeviceResetArgsQueue.erase(mNotifyDeviceResetArgsQueue.begin());
+    }
+
+    void assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs = NULL) {
+        ASSERT_FALSE(mNotifyKeyArgsQueue.empty())
+                << "Expected notifyKey() to have been called.";
+        if (outEventArgs) {
+            *outEventArgs = *mNotifyKeyArgsQueue.begin();
+        }
+        mNotifyKeyArgsQueue.erase(mNotifyKeyArgsQueue.begin());
+    }
+
+    void assertNotifyKeyWasNotCalled() {
+        ASSERT_TRUE(mNotifyKeyArgsQueue.empty())
+                << "Expected notifyKey() to not have been called.";
+    }
+
+    void assertNotifyMotionWasCalled(NotifyMotionArgs* outEventArgs = NULL) {
+        ASSERT_FALSE(mNotifyMotionArgsQueue.empty())
+                << "Expected notifyMotion() to have been called.";
+        if (outEventArgs) {
+            *outEventArgs = *mNotifyMotionArgsQueue.begin();
+        }
+        mNotifyMotionArgsQueue.erase(mNotifyMotionArgsQueue.begin());
+    }
+
+    void assertNotifyMotionWasNotCalled() {
+        ASSERT_TRUE(mNotifyMotionArgsQueue.empty())
+                << "Expected notifyMotion() to not have been called.";
+    }
+
+    void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = NULL) {
+        ASSERT_FALSE(mNotifySwitchArgsQueue.empty())
+                << "Expected notifySwitch() to have been called.";
+        if (outEventArgs) {
+            *outEventArgs = *mNotifySwitchArgsQueue.begin();
+        }
+        mNotifySwitchArgsQueue.erase(mNotifySwitchArgsQueue.begin());
+    }
+
+private:
+    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
+        mNotifyConfigurationChangedArgsQueue.push_back(*args);
+    }
+
+    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) {
+        mNotifyDeviceResetArgsQueue.push_back(*args);
+    }
+
+    virtual void notifyKey(const NotifyKeyArgs* args) {
+        mNotifyKeyArgsQueue.push_back(*args);
+    }
+
+    virtual void notifyMotion(const NotifyMotionArgs* args) {
+        mNotifyMotionArgsQueue.push_back(*args);
+    }
+
+    virtual void notifySwitch(const NotifySwitchArgs* args) {
+        mNotifySwitchArgsQueue.push_back(*args);
+    }
+};
+
+
+// --- FakeEventHub ---
+
+class FakeEventHub : public EventHubInterface {
+    struct KeyInfo {
+        int32_t keyCode;
+        uint32_t flags;
+    };
+
+    struct Device {
+        InputDeviceIdentifier identifier;
+        uint32_t classes;
+        PropertyMap configuration;
+        KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
+        KeyedVector<int, bool> relativeAxes;
+        KeyedVector<int32_t, int32_t> keyCodeStates;
+        KeyedVector<int32_t, int32_t> scanCodeStates;
+        KeyedVector<int32_t, int32_t> switchStates;
+        KeyedVector<int32_t, int32_t> absoluteAxisValue;
+        KeyedVector<int32_t, KeyInfo> keysByScanCode;
+        KeyedVector<int32_t, KeyInfo> keysByUsageCode;
+        KeyedVector<int32_t, bool> leds;
+        Vector<VirtualKeyDefinition> virtualKeys;
+
+        Device(uint32_t classes) :
+                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(classes);
+        device->identifier.name = name;
+        mDevices.add(deviceId, device);
+
+        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0);
+    }
+
+    void removeDevice(int32_t deviceId) {
+        delete mDevices.valueFor(deviceId);
+        mDevices.removeItem(deviceId);
+
+        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
+    }
+
+    void finishDeviceScan() {
+        enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
+    }
+
+    void addConfigurationProperty(int32_t deviceId, const String8& key, const String8& value) {
+        Device* device = getDevice(deviceId);
+        device->configuration.addProperty(key, value);
+    }
+
+    void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) {
+        Device* device = getDevice(deviceId);
+        device->configuration.addAll(configuration);
+    }
+
+    void addAbsoluteAxis(int32_t deviceId, int axis,
+            int32_t minValue, int32_t maxValue, int flat, int fuzz, int resolution = 0) {
+        Device* device = getDevice(deviceId);
+
+        RawAbsoluteAxisInfo info;
+        info.valid = true;
+        info.minValue = minValue;
+        info.maxValue = maxValue;
+        info.flat = flat;
+        info.fuzz = fuzz;
+        info.resolution = resolution;
+        device->absoluteAxes.add(axis, info);
+    }
+
+    void addRelativeAxis(int32_t deviceId, int32_t axis) {
+        Device* device = getDevice(deviceId);
+        device->relativeAxes.add(axis, true);
+    }
+
+    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 setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
+        Device* device = getDevice(deviceId);
+        device->absoluteAxisValue.replaceValueFor(axis, value);
+    }
+
+    void addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
+            int32_t keyCode, uint32_t flags) {
+        Device* device = getDevice(deviceId);
+        KeyInfo info;
+        info.keyCode = keyCode;
+        info.flags = flags;
+        if (scanCode) {
+            device->keysByScanCode.add(scanCode, info);
+        }
+        if (usageCode) {
+            device->keysByUsageCode.add(usageCode, info);
+        }
+    }
+
+    void addLed(int32_t deviceId, int32_t led, bool initialState) {
+        Device* device = getDevice(deviceId);
+        device->leds.add(led, initialState);
+    }
+
+    bool getLedState(int32_t deviceId, int32_t led) {
+        Device* device = getDevice(deviceId);
+        return device->leds.valueFor(led);
+    }
+
+    Vector<String8>& getExcludedDevices() {
+        return mExcludedDevices;
+    }
+
+    void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) {
+        Device* device = getDevice(deviceId);
+        device->virtualKeys.push(definition);
+    }
+
+    void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
+            int32_t code, int32_t value) {
+        RawEvent event;
+        event.when = when;
+        event.deviceId = deviceId;
+        event.type = type;
+        event.code = code;
+        event.value = value;
+        mEvents.push_back(event);
+
+        if (type == EV_ABS) {
+            setAbsoluteAxisValue(deviceId, code, value);
+        }
+    }
+
+    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 InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const {
+        Device* device = getDevice(deviceId);
+        return device ? device->identifier : InputDeviceIdentifier();
+    }
+
+    virtual int32_t getDeviceControllerNumber(int32_t deviceId) const {
+        return 0;
+    }
+
+    virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            *outConfiguration = device->configuration;
+        }
+    }
+
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->absoluteAxes.indexOfKey(axis);
+            if (index >= 0) {
+                *outAxisInfo = device->absoluteAxes.valueAt(index);
+                return OK;
+            }
+        }
+        outAxisInfo->clear();
+        return -1;
+    }
+
+    virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            return device->relativeAxes.indexOfKey(axis) >= 0;
+        }
+        return false;
+    }
+
+    virtual bool hasInputProperty(int32_t deviceId, int property) const {
+        return false;
+    }
+
+    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
+            int32_t* outKeycode, uint32_t* outFlags) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            const KeyInfo* key = getKey(device, scanCode, usageCode);
+            if (key) {
+                if (outKeycode) {
+                    *outKeycode = key->keyCode;
+                }
+                if (outFlags) {
+                    *outFlags = key->flags;
+                }
+                return OK;
+            }
+        }
+        return NAME_NOT_FOUND;
+    }
+
+    const KeyInfo* getKey(Device* device, int32_t scanCode, int32_t usageCode) const {
+        if (usageCode) {
+            ssize_t index = device->keysByUsageCode.indexOfKey(usageCode);
+            if (index >= 0) {
+                return &device->keysByUsageCode.valueAt(index);
+            }
+        }
+        if (scanCode) {
+            ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
+            if (index >= 0) {
+                return &device->keysByScanCode.valueAt(index);
+            }
+        }
+        return NULL;
+    }
+
+    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
+            AxisInfo* outAxisInfo) const {
+        return NAME_NOT_FOUND;
+    }
+
+    virtual void setExcludedDevices(const Vector<String8>& devices) {
+        mExcludedDevices = devices;
+    }
+
+    virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
+        if (mEvents.empty()) {
+            return 0;
+        }
+
+        *buffer = *mEvents.begin();
+        mEvents.erase(mEvents.begin());
+        return 1;
+    }
+
+    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 status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+            int32_t* outValue) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
+            if (index >= 0) {
+                *outValue = device->absoluteAxisValue.valueAt(index);
+                return OK;
+            }
+        }
+        *outValue = 0;
+        return -1;
+    }
+
+    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->keysByScanCode.size(); j++) {
+                    if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
+                        outFlags[i] = 1;
+                        result = true;
+                    }
+                }
+                for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
+                    if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
+                        outFlags[i] = 1;
+                        result = true;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
+            return index >= 0;
+        }
+        return false;
+    }
+
+    virtual bool hasLed(int32_t deviceId, int32_t led) const {
+        Device* device = getDevice(deviceId);
+        return device && device->leds.indexOfKey(led) >= 0;
+    }
+
+    virtual void setLedState(int32_t deviceId, int32_t led, bool on) {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->leds.indexOfKey(led);
+            if (index >= 0) {
+                device->leds.replaceValueAt(led, on);
+            } else {
+                ADD_FAILURE()
+                        << "Attempted to set the state of an LED that the EventHub declared "
+                        "was not present.  led=" << led;
+            }
+        }
+    }
+
+    virtual void getVirtualKeyDefinitions(int32_t deviceId,
+            Vector<VirtualKeyDefinition>& outVirtualKeys) const {
+        outVirtualKeys.clear();
+
+        Device* device = getDevice(deviceId);
+        if (device) {
+            outVirtualKeys.appendVector(device->virtualKeys);
+        }
+    }
+
+    virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const {
+        return NULL;
+    }
+
+    virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) {
+        return false;
+    }
+
+    virtual void vibrate(int32_t deviceId, nsecs_t duration) {
+    }
+
+    virtual void cancelVibrate(int32_t deviceId) {
+    }
+
+    virtual bool isExternal(int32_t deviceId) const {
+        return false;
+    }
+
+    virtual void dump(String8& dump) {
+    }
+
+    virtual void monitor() {
+    }
+
+    virtual void requestReopenDevices() {
+    }
+
+    virtual void wake() {
+    }
+};
+
+
+// --- FakeInputReaderContext ---
+
+class FakeInputReaderContext : public InputReaderContext {
+    sp<EventHubInterface> mEventHub;
+    sp<InputReaderPolicyInterface> mPolicy;
+    sp<InputListenerInterface> mListener;
+    int32_t mGlobalMetaState;
+    bool mUpdateGlobalMetaStateWasCalled;
+    int32_t mGeneration;
+
+public:
+    FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputListenerInterface>& listener) :
+            mEventHub(eventHub), mPolicy(policy), mListener(listener),
+            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 InputListenerInterface* getListener() {
+        return mListener.get();
+    }
+
+    virtual void disableVirtualKeysUntil(nsecs_t time) {
+    }
+
+    virtual bool shouldDropVirtualKey(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode) {
+        return false;
+    }
+
+    virtual void fadePointer() {
+    }
+
+    virtual void requestTimeoutAtTime(nsecs_t when) {
+    }
+
+    virtual int32_t bumpGeneration() {
+        return ++mGeneration;
+    }
+};
+
+
+// --- 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(nsecs_t when,
+            const InputReaderConfiguration* config, uint32_t changes) {
+        mConfigureWasCalled = true;
+    }
+
+    virtual void reset(nsecs_t when) {
+        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;
+    }
+
+    virtual void fadePointer() {
+    }
+};
+
+
+// --- InstrumentedInputReader ---
+
+class InstrumentedInputReader : public InputReader {
+    InputDevice* mNextDevice;
+
+public:
+    InstrumentedInputReader(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputListenerInterface>& listener) :
+            InputReader(eventHub, policy, listener),
+            mNextDevice(NULL) {
+    }
+
+    virtual ~InstrumentedInputReader() {
+        if (mNextDevice) {
+            delete mNextDevice;
+        }
+    }
+
+    void setNextDevice(InputDevice* device) {
+        mNextDevice = device;
+    }
+
+    InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const String8& name,
+            uint32_t classes) {
+        InputDeviceIdentifier identifier;
+        identifier.name = name;
+        int32_t generation = deviceId + 1;
+        return new InputDevice(&mContext, deviceId, generation, controllerNumber, identifier,
+                classes);
+    }
+
+protected:
+    virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
+            const InputDeviceIdentifier& identifier, uint32_t classes) {
+        if (mNextDevice) {
+            InputDevice* device = mNextDevice;
+            mNextDevice = NULL;
+            return device;
+        }
+        return InputReader::createDeviceLocked(deviceId, controllerNumber, identifier, classes);
+    }
+
+    friend class InputReaderTest;
+};
+
+
+// --- InputReaderTest ---
+
+class InputReaderTest : public testing::Test {
+protected:
+    sp<FakeInputListener> mFakeListener;
+    sp<FakeInputReaderPolicy> mFakePolicy;
+    sp<FakeEventHub> mFakeEventHub;
+    sp<InstrumentedInputReader> mReader;
+
+    virtual void SetUp() {
+        mFakeEventHub = new FakeEventHub();
+        mFakePolicy = new FakeInputReaderPolicy();
+        mFakeListener = new FakeInputListener();
+
+        mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeListener);
+    }
+
+    virtual void TearDown() {
+        mReader.clear();
+
+        mFakeListener.clear();
+        mFakePolicy.clear();
+        mFakeEventHub.clear();
+    }
+
+    void addDevice(int32_t deviceId, const String8& name, uint32_t classes,
+            const PropertyMap* configuration) {
+        mFakeEventHub->addDevice(deviceId, name, classes);
+
+        if (configuration) {
+            mFakeEventHub->addConfigurationMap(deviceId, configuration);
+        }
+        mFakeEventHub->finishDeviceScan();
+        mReader->loopOnce();
+        mReader->loopOnce();
+        mFakeEventHub->assertQueueIsEmpty();
+    }
+
+    FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber,
+            const String8& name, uint32_t classes, uint32_t sources,
+            const PropertyMap* configuration) {
+        InputDevice* device = mReader->newDevice(deviceId, controllerNumber, name, classes);
+        FakeInputMapper* mapper = new FakeInputMapper(device, sources);
+        device->addMapper(mapper);
+        mReader->setNextDevice(device);
+        addDevice(deviceId, name, classes, configuration);
+        return mapper;
+    }
+};
+
+TEST_F(InputReaderTest, GetInputDevices) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
+            INPUT_DEVICE_CLASS_KEYBOARD, NULL));
+    ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("ignored"),
+            0, NULL)); // no classes so device will be ignored
+
+    Vector<InputDeviceInfo> inputDevices;
+    mReader->getInputDevices(inputDevices);
+
+    ASSERT_EQ(1U, inputDevices.size());
+    ASSERT_EQ(1, inputDevices[0].getId());
+    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
+    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
+    ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
+
+    // Should also have received a notification describing the new input devices.
+    inputDevices = mFakePolicy->getInputDevices();
+    ASSERT_EQ(1U, inputDevices.size());
+    ASSERT_EQ(1, inputDevices[0].getId());
+    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
+    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
+    ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
+}
+
+TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
+    FakeInputMapper* mapper = NULL;
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
+    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, 0, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
+    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, 0, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
+    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, 0, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
+    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, NULL);
+
+    NotifyConfigurationChangedArgs args;
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+}
+
+TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
+    FakeInputMapper* mapper = NULL;
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
+
+    mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1);
+    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.code);
+    ASSERT_EQ(1, event.value);
+}
+
+
+// --- InputDeviceTest ---
+
+class InputDeviceTest : public testing::Test {
+protected:
+    static const char* DEVICE_NAME;
+    static const int32_t DEVICE_ID;
+    static const int32_t DEVICE_GENERATION;
+    static const int32_t DEVICE_CONTROLLER_NUMBER;
+    static const uint32_t DEVICE_CLASSES;
+
+    sp<FakeEventHub> mFakeEventHub;
+    sp<FakeInputReaderPolicy> mFakePolicy;
+    sp<FakeInputListener> mFakeListener;
+    FakeInputReaderContext* mFakeContext;
+
+    InputDevice* mDevice;
+
+    virtual void SetUp() {
+        mFakeEventHub = new FakeEventHub();
+        mFakePolicy = new FakeInputReaderPolicy();
+        mFakeListener = new FakeInputListener();
+        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
+
+        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
+        InputDeviceIdentifier identifier;
+        identifier.name = DEVICE_NAME;
+        mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
+                DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
+    }
+
+    virtual void TearDown() {
+        delete mDevice;
+
+        delete mFakeContext;
+        mFakeListener.clear();
+        mFakePolicy.clear();
+        mFakeEventHub.clear();
+    }
+};
+
+const char* InputDeviceTest::DEVICE_NAME = "device";
+const int32_t InputDeviceTest::DEVICE_ID = 1;
+const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
+const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
+const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD
+        | INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK;
+
+TEST_F(InputDeviceTest, ImmutableProperties) {
+    ASSERT_EQ(DEVICE_ID, mDevice->getId());
+    ASSERT_STREQ(DEVICE_NAME, mDevice->getName());
+    ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses());
+}
+
+TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
+    // Configuration.
+    InputReaderConfiguration config;
+    mDevice->configure(ARBITRARY_TIME, &config, 0);
+
+    // Reset.
+    mDevice->reset(ARBITRARY_TIME);
+
+    NotifyDeviceResetArgs resetArgs;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
+    ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
+
+    // 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.getIdentifier().name.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.";
+}
+
+TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
+    // Configuration.
+    mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8("key"), String8("value"));
+
+    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);
+
+    InputReaderConfiguration config;
+    mDevice->configure(ARBITRARY_TIME, &config, 0);
+
+    String8 propertyValue;
+    ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty(String8("key"), propertyValue))
+            << "Device should have read configuration during configuration phase.";
+    ASSERT_STREQ("value", propertyValue.string());
+
+    ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled());
+    ASSERT_NO_FATAL_FAILURE(mapper2->assertConfigureWasCalled());
+
+    // Reset
+    mDevice->reset(ARBITRARY_TIME);
+    ASSERT_NO_FATAL_FAILURE(mapper1->assertResetWasCalled());
+    ASSERT_NO_FATAL_FAILURE(mapper2->assertResetWasCalled());
+
+    NotifyDeviceResetArgs resetArgs;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
+    ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
+
+    // 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.getIdentifier().name.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, 1);
+
+    ASSERT_NO_FATAL_FAILURE(mapper1->assertProcessWasCalled());
+    ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled());
+}
+
+
+// --- InputMapperTest ---
+
+class InputMapperTest : public testing::Test {
+protected:
+    static const char* DEVICE_NAME;
+    static const int32_t DEVICE_ID;
+    static const int32_t DEVICE_GENERATION;
+    static const int32_t DEVICE_CONTROLLER_NUMBER;
+    static const uint32_t DEVICE_CLASSES;
+
+    sp<FakeEventHub> mFakeEventHub;
+    sp<FakeInputReaderPolicy> mFakePolicy;
+    sp<FakeInputListener> mFakeListener;
+    FakeInputReaderContext* mFakeContext;
+    InputDevice* mDevice;
+
+    virtual void SetUp() {
+        mFakeEventHub = new FakeEventHub();
+        mFakePolicy = new FakeInputReaderPolicy();
+        mFakeListener = new FakeInputListener();
+        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
+        InputDeviceIdentifier identifier;
+        identifier.name = DEVICE_NAME;
+        mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
+                DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
+
+        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
+    }
+
+    virtual void TearDown() {
+        delete mDevice;
+        delete mFakeContext;
+        mFakeListener.clear();
+        mFakePolicy.clear();
+        mFakeEventHub.clear();
+    }
+
+    void addConfigurationProperty(const char* key, const char* value) {
+        mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8(key), String8(value));
+    }
+
+    void addMapperAndConfigure(InputMapper* mapper) {
+        mDevice->addMapper(mapper);
+        mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
+        mDevice->reset(ARBITRARY_TIME);
+    }
+
+    void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
+            int32_t orientation) {
+        mFakePolicy->setDisplayInfo(displayId, width, height, orientation);
+        mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+                InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+    }
+
+    static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type,
+            int32_t code, int32_t value) {
+        RawEvent event;
+        event.when = when;
+        event.deviceId = deviceId;
+        event.type = type;
+        event.code = code;
+        event.value = value;
+        mapper->process(&event);
+    }
+
+    static void assertMotionRange(const InputDeviceInfo& info,
+            int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
+        const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
+        ASSERT_TRUE(range != NULL) << "Axis: " << axis << " Source: " << source;
+        ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
+        ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
+        ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
+        ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
+        ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
+        ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
+    }
+
+    static void assertPointerCoords(const PointerCoords& coords,
+            float x, float y, float pressure, float size,
+            float touchMajor, float touchMinor, float toolMajor, float toolMinor,
+            float orientation, float distance) {
+        ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+        ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+        ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
+        ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
+        ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 1);
+        ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 1);
+        ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1);
+        ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1);
+        ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
+        ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
+    }
+
+    static void assertPosition(const sp<FakePointerController>& controller, float x, float y) {
+        float actualX, actualY;
+        controller->getPosition(&actualX, &actualY);
+        ASSERT_NEAR(x, actualX, 1);
+        ASSERT_NEAR(y, actualY, 1);
+    }
+};
+
+const char* InputMapperTest::DEVICE_NAME = "device";
+const int32_t InputMapperTest::DEVICE_ID = 1;
+const int32_t InputMapperTest::DEVICE_GENERATION = 2;
+const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
+const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests
+
+
+// --- 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, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_HEADPHONE_INSERT, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+
+    NotifySwitchArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySwitchWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+    ASSERT_EQ((1 << SW_LID) | (1 << SW_JACK_PHYSICAL_INSERT), args.switchValues);
+    ASSERT_EQ((1 << SW_LID) | (1 << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
+            args.switchMask);
+    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) {
+    NotifyKeyArgs args;
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper->getSources());
+}
+
+TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
+    const int32_t USAGE_A = 0x070004;
+    const int32_t USAGE_UNKNOWN = 0x07ffff;
+    mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+    mFakeEventHub->addKey(DEVICE_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
+
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    // Key down by scan code.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_HOME, 1);
+    NotifyKeyArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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 by scan code.
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
+            EV_KEY, KEY_HOME, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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);
+
+    // Key down by usage code.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_MSC, MSC_SCAN, USAGE_A);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, 0, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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_A, args.keyCode);
+    ASSERT_EQ(0, 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 by usage code.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_MSC, MSC_SCAN, USAGE_A);
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
+            EV_KEY, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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_A, args.keyCode);
+    ASSERT_EQ(0, 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 down with unknown scan code or usage code.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_UNKNOWN, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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(0, args.keyCode);
+    ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
+    ASSERT_EQ(AMETA_NONE, args.metaState);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
+    ASSERT_EQ(0U, args.policyFlags);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+
+    // Key up with unknown scan code or usage code.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
+            EV_KEY, KEY_UNKNOWN, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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(0, args.keyCode);
+    ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
+    ASSERT_EQ(AMETA_NONE, args.metaState);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
+    ASSERT_EQ(0U, args.policyFlags);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+}
+
+TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
+    mFakeEventHub->addKey(DEVICE_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0);
+
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
+            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, 1);
+    NotifyKeyArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AMETA_NONE, args.metaState);
+    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
+    ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
+}
+
+TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
+    mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
+
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_90);
+    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_WhenOrientationAware_ShouldRotateDPad) {
+    mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
+
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addConfigurationProperty("keyboard.orientationAware", "1");
+    addMapperAndConfigure(mapper);
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_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));
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_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));
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_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));
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_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.
+    NotifyKeyArgs args;
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_270);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
+    ASSERT_EQ(KEY_UP, args.scanCode);
+    ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_180);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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,
+            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,
+            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,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, 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]);
+}
+
+TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
+    mFakeEventHub->addLed(DEVICE_ID, LED_CAPSL, true /*initially on*/);
+    mFakeEventHub->addLed(DEVICE_ID, LED_NUML, false /*initially off*/);
+    mFakeEventHub->addLed(DEVICE_ID, LED_SCROLLL, false /*initially off*/);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
+
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    // Initialization should have turned all of the lights off.
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+
+    // Toggle caps lock on.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_CAPSLOCK, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_CAPSLOCK, 0);
+    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+    ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper->getMetaState());
+
+    // Toggle num lock on.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_NUMLOCK, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_NUMLOCK, 0);
+    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
+    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+    ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper->getMetaState());
+
+    // Toggle caps lock off.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_CAPSLOCK, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_CAPSLOCK, 0);
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
+    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+    ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper->getMetaState());
+
+    // Toggle scroll lock on.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_SCROLLLOCK, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_SCROLLLOCK, 0);
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
+    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
+    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+    ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
+
+    // Toggle num lock off.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_NUMLOCK, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_NUMLOCK, 0);
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
+    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+    ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
+
+    // Toggle scroll lock off.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_SCROLLLOCK, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_SCROLLLOCK, 0);
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
+    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
+    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
+}
+
+
+// --- CursorInputMapperTest ---
+
+class CursorInputMapperTest : public InputMapperTest {
+protected:
+    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
+
+    sp<FakePointerController> mFakePointerController;
+
+    virtual void SetUp() {
+        InputMapperTest::SetUp();
+
+        mFakePointerController = new FakePointerController();
+        mFakePolicy->setPointerController(DEVICE_ID, mFakePointerController);
+    }
+
+    void testMotionRotation(CursorInputMapper* mapper,
+            int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY);
+};
+
+const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
+
+void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper,
+        int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
+    NotifyMotionArgs args;
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, originalX);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, originalY);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0.0f));
+}
+
+TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "pointer");
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
+}
+
+TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources());
+}
+
+TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "pointer");
+    addMapperAndConfigure(mapper);
+
+    InputDeviceInfo info;
+    mapper->populateDeviceInfo(&info);
+
+    // Initially there may not be a valid motion range.
+    ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
+    ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+            AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
+
+    // When the bounds are set, then there should be a valid motion range.
+    mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
+
+    InputDeviceInfo info2;
+    mapper->populateDeviceInfo(&info2);
+
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
+            AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
+            1, 800 - 1, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
+            AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
+            2, 480 - 1, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
+            AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
+            0.0f, 1.0f, 0.0f, 0.0f));
+}
+
+TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addMapperAndConfigure(mapper);
+
+    InputDeviceInfo info;
+    mapper->populateDeviceInfo(&info);
+
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+            AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
+            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+            AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
+            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
+            AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
+            0.0f, 1.0f, 0.0f, 0.0f));
+}
+
+TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    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, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
+    ASSERT_EQ(0, args.edgeFlags);
+    ASSERT_EQ(uint32_t(1), args.pointerCount);
+    ASSERT_EQ(0, args.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
+    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, 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);
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, args.edgeFlags);
+    ASSERT_EQ(uint32_t(1), args.pointerCount);
+    ASSERT_EQ(0, args.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
+    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, 0.0f));
+    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
+    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+}
+
+TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs args;
+
+    // Motion in X but not Y.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0.0f));
+
+    // Motion in Y but not X.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+    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, 0.0f));
+}
+
+TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs args;
+
+    // Button press.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0.0f));
+
+    // Button release.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0.0f));
+}
+
+TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs args;
+
+    // Combined X, Y and Button.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0.0f));
+
+    // Move X, Y a bit while pressed.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 2);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0.0f));
+
+    // Release Button.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 0.0f));
+}
+
+TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addMapperAndConfigure(mapper);
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            DISPLAY_ORIENTATION_90);
+    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(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "navigation");
+    addConfigurationProperty("cursor.orientationAware", "1");
+    addMapperAndConfigure(mapper);
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_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));
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_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));
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_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));
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_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));
+}
+
+TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "pointer");
+    addMapperAndConfigure(mapper);
+
+    mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+    mFakePointerController->setPosition(100, 200);
+    mFakePointerController->setButtonState(0);
+
+    NotifyMotionArgs motionArgs;
+    NotifyKeyArgs keyArgs;
+
+    // press BTN_LEFT, release BTN_LEFT
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+            motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+            mFakePointerController->getButtonState());
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    // press BTN_BACK, release BTN_BACK
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+    // press BTN_SIDE, release BTN_SIDE
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+    // press BTN_FORWARD, release BTN_FORWARD
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+    // press BTN_EXTRA, release BTN_EXTRA
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(0, mFakePointerController->getButtonState());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+}
+
+TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
+    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+    addConfigurationProperty("cursor.mode", "pointer");
+    addMapperAndConfigure(mapper);
+
+    mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+    mFakePointerController->setPosition(100, 200);
+    mFakePointerController->setButtonState(0);
+
+    NotifyMotionArgs args;
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+}
+
+
+// --- 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_DISTANCE_MIN;
+    static const int32_t RAW_DISTANCE_MAX;
+    static const int32_t RAW_TILT_MIN;
+    static const int32_t RAW_TILT_MAX;
+    static const int32_t RAW_ID_MIN;
+    static const int32_t RAW_ID_MAX;
+    static const int32_t RAW_SLOT_MIN;
+    static const int32_t RAW_SLOT_MAX;
+    static const float X_PRECISION;
+    static const float Y_PRECISION;
+
+    static const float GEOMETRIC_SCALE;
+
+    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,
+        DISTANCE = 1 << 7,
+        TILT = 1 << 8,
+        SLOT = 1 << 9,
+        TOOL_TYPE = 1 << 10,
+    };
+
+    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 = 1019;
+const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
+const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
+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_DISTANCE_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
+const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
+const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
+const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
+const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
+const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
+
+const float TouchInputMapperTest::GEOMETRIC_SCALE =
+        avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
+                float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
+
+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) {
+    setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation);
+}
+
+void TouchInputMapperTest::prepareVirtualKeys() {
+    mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[0]);
+    mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[1]);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
+}
+
+int32_t TouchInputMapperTest::toRawX(float displayX) {
+    return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
+}
+
+int32_t TouchInputMapperTest::toRawY(float displayY) {
+    return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / 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 + 1);
+}
+
+float TouchInputMapperTest::toDisplayY(int32_t rawY) {
+    return float(rawY - RAW_Y_MIN) * DISPLAY_HEIGHT / (RAW_Y_MAX - RAW_Y_MIN + 1);
+}
+
+
+// --- SingleTouchInputMapperTest ---
+
+class SingleTouchInputMapperTest : public TouchInputMapperTest {
+protected:
+    void prepareButtons();
+    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 processDistance(SingleTouchInputMapper* mapper, int32_t distance);
+    void processTilt(SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY);
+    void processKey(SingleTouchInputMapper* mapper, int32_t code, int32_t value);
+    void processSync(SingleTouchInputMapper* mapper);
+};
+
+void SingleTouchInputMapperTest::prepareButtons() {
+    mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
+}
+
+void SingleTouchInputMapperTest::prepareAxes(int axes) {
+    if (axes & POSITION) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_X,
+                RAW_X_MIN, RAW_X_MAX, 0, 0);
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_Y,
+                RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+    }
+    if (axes & PRESSURE) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_PRESSURE,
+                RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
+    }
+    if (axes & TOOL) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
+                RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+    }
+    if (axes & DISTANCE) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_DISTANCE,
+                RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+    }
+    if (axes & TILT) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_X,
+                RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_Y,
+                RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
+    }
+}
+
+void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 1);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
+}
+
+void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
+}
+
+void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0);
+}
+
+void SingleTouchInputMapperTest::processPressure(
+        SingleTouchInputMapper* mapper, int32_t pressure) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_PRESSURE, pressure);
+}
+
+void SingleTouchInputMapperTest::processToolMajor(
+        SingleTouchInputMapper* mapper, int32_t toolMajor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
+}
+
+void SingleTouchInputMapperTest::processDistance(
+        SingleTouchInputMapper* mapper, int32_t distance) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_DISTANCE, distance);
+}
+
+void SingleTouchInputMapperTest::processTilt(
+        SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_X, tiltX);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_Y, tiltY);
+}
+
+void SingleTouchInputMapperTest::processKey(
+        SingleTouchInputMapper* mapper, int32_t code, int32_t value) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
+}
+
+void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+}
+
+
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    prepareButtons();
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
+}
+
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndIsACursor_ReturnsTouchPad) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_X);
+    mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_Y);
+    prepareButtons();
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
+}
+
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchPad_ReturnsTouchPad) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    prepareButtons();
+    prepareAxes(POSITION);
+    addConfigurationProperty("touch.deviceType", "touchPad");
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
+}
+
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    prepareButtons();
+    prepareAxes(POSITION);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources());
+}
+
+TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    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(mFakeListener->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(mFakeListener->assertNotifyKeyWasCalled());
+
+    ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
+}
+
+TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    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(mFakeListener->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(mFakeListener->assertNotifyKeyWasCalled());
+
+    ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
+}
+
+TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    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, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    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(mFakeListener->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(mFakeListener->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(mFakeListener->assertNotifyKeyWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    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(mFakeListener->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(mFakeListener->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);
+
+    NotifyMotionArgs motionArgs;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    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(mFakeListener->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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    NotifyMotionArgs motionArgs;
+
+    // Down.
+    int32_t x = 100;
+    int32_t y = 125;
+    processDown(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 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(mFakeListener->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareButtons();
+    prepareAxes(POSITION);
+    addConfigurationProperty("touch.orientationAware", "0");
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs args;
+
+    // Rotation 90.
+    prepareDisplay(DISPLAY_ORIENTATION_90);
+    processDown(mapper, toRawX(50), toRawY(75));
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareButtons();
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs args;
+
+    // Rotation 0.
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    processDown(mapper, toRawX(50), toRawY(75));
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+
+    // Rotation 90.
+    prepareDisplay(DISPLAY_ORIENTATION_90);
+    processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+
+    // Rotation 180.
+    prepareDisplay(DISPLAY_ORIENTATION_180);
+    processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+
+    // Rotation 270.
+    prepareDisplay(DISPLAY_ORIENTATION_270);
+    processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
+    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;
+    int32_t rawDistance = 2;
+    int32_t rawTiltX = 30;
+    int32_t rawTiltY = 110;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
+    float size = float(rawToolMajor) / RAW_TOOL_MAX;
+    float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
+    float distance = float(rawDistance);
+
+    float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
+    float tiltScale = M_PI / 180;
+    float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
+    float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
+    float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
+    float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
+
+    processDown(mapper, rawX, rawY);
+    processPressure(mapper, rawPressure);
+    processToolMajor(mapper, rawToolMajor);
+    processDistance(mapper, rawDistance);
+    processTilt(mapper, rawTiltX, rawTiltY);
+    processSync(mapper);
+
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
+    ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+    NotifyKeyArgs keyArgs;
+
+    processDown(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.buttonState);
+
+    // press BTN_LEFT, release BTN_LEFT
+    processKey(mapper, BTN_LEFT, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+
+    processKey(mapper, BTN_LEFT, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+    processKey(mapper, BTN_RIGHT, 1);
+    processKey(mapper, BTN_MIDDLE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+            motionArgs.buttonState);
+
+    processKey(mapper, BTN_RIGHT, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_MIDDLE, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // press BTN_BACK, release BTN_BACK
+    processKey(mapper, BTN_BACK, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_BACK, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+    // press BTN_SIDE, release BTN_SIDE
+    processKey(mapper, BTN_SIDE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_SIDE, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+    // press BTN_FORWARD, release BTN_FORWARD
+    processKey(mapper, BTN_FORWARD, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_FORWARD, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+    // press BTN_EXTRA, release BTN_EXTRA
+    processKey(mapper, BTN_EXTRA, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_EXTRA, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+    // press BTN_STYLUS, release BTN_STYLUS
+    processKey(mapper, BTN_STYLUS, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
+
+    processKey(mapper, BTN_STYLUS, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // press BTN_STYLUS2, release BTN_STYLUS2
+    processKey(mapper, BTN_STYLUS2, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+
+    processKey(mapper, BTN_STYLUS2, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // release touch
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.buttonState);
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+
+    // default tool type is finger
+    processDown(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // eraser
+    processKey(mapper, BTN_TOOL_RUBBER, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+    // stylus
+    processKey(mapper, BTN_TOOL_RUBBER, 0);
+    processKey(mapper, BTN_TOOL_PEN, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // brush
+    processKey(mapper, BTN_TOOL_PEN, 0);
+    processKey(mapper, BTN_TOOL_BRUSH, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // pencil
+    processKey(mapper, BTN_TOOL_BRUSH, 0);
+    processKey(mapper, BTN_TOOL_PENCIL, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // airbrush
+    processKey(mapper, BTN_TOOL_PENCIL, 0);
+    processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // mouse
+    processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
+    processKey(mapper, BTN_TOOL_MOUSE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+
+    // lens
+    processKey(mapper, BTN_TOOL_MOUSE, 0);
+    processKey(mapper, BTN_TOOL_LENS, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+
+    // double-tap
+    processKey(mapper, BTN_TOOL_LENS, 0);
+    processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // triple-tap
+    processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
+    processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // quad-tap
+    processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
+    processKey(mapper, BTN_TOOL_QUADTAP, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // finger
+    processKey(mapper, BTN_TOOL_QUADTAP, 0);
+    processKey(mapper, BTN_TOOL_FINGER, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // stylus trumps finger
+    processKey(mapper, BTN_TOOL_PEN, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // eraser trumps stylus
+    processKey(mapper, BTN_TOOL_RUBBER, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+    // mouse trumps eraser
+    processKey(mapper, BTN_TOOL_MOUSE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+
+    // back to default tool type
+    processKey(mapper, BTN_TOOL_MOUSE, 0);
+    processKey(mapper, BTN_TOOL_RUBBER, 0);
+    processKey(mapper, BTN_TOOL_PEN, 0);
+    processKey(mapper, BTN_TOOL_FINGER, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION);
+    mFakeEventHub->addKey(DEVICE_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+
+    // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
+    processKey(mapper, BTN_TOOL_FINGER, 1);
+    processMove(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // move a little
+    processMove(mapper, 150, 250);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // down when BTN_TOUCH is pressed, pressure defaults to 1
+    processKey(mapper, BTN_TOUCH, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // up when BTN_TOUCH is released, hover restored
+    processKey(mapper, BTN_TOUCH, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // exit hover when pointer goes away
+    processKey(mapper, BTN_TOOL_FINGER, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareButtons();
+    prepareAxes(POSITION | PRESSURE);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+
+    // initially hovering because pressure is 0
+    processDown(mapper, 100, 200);
+    processPressure(mapper, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // move a little
+    processMove(mapper, 150, 250);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // down when pressure is non-zero
+    processPressure(mapper, RAW_PRESSURE_MAX);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // up when pressure becomes 0, hover restored
+    processPressure(mapper, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // exit hover when pointer goes away
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 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 processDistance(MultiTouchInputMapper* mapper, int32_t distance);
+    void processId(MultiTouchInputMapper* mapper, int32_t id);
+    void processSlot(MultiTouchInputMapper* mapper, int32_t slot);
+    void processToolType(MultiTouchInputMapper* mapper, int32_t toolType);
+    void processKey(MultiTouchInputMapper* mapper, int32_t code, int32_t value);
+    void processMTSync(MultiTouchInputMapper* mapper);
+    void processSync(MultiTouchInputMapper* mapper);
+};
+
+void MultiTouchInputMapperTest::prepareAxes(int axes) {
+    if (axes & POSITION) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_X,
+                RAW_X_MIN, RAW_X_MAX, 0, 0);
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_Y,
+                RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+    }
+    if (axes & TOUCH) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR,
+                RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
+        if (axes & MINOR) {
+            mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
+                    RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
+        }
+    }
+    if (axes & TOOL) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR,
+                RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+        if (axes & MINOR) {
+            mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
+                    RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
+        }
+    }
+    if (axes & ORIENTATION) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_ORIENTATION,
+                RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
+    }
+    if (axes & PRESSURE) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
+                RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
+    }
+    if (axes & DISTANCE) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_DISTANCE,
+                RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+    }
+    if (axes & ID) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
+                RAW_ID_MIN, RAW_ID_MAX, 0, 0);
+    }
+    if (axes & SLOT) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_SLOT,
+                RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
+        mFakeEventHub->setAbsoluteAxisValue(DEVICE_ID, ABS_MT_SLOT, 0);
+    }
+    if (axes & TOOL_TYPE) {
+        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOOL_TYPE,
+                0, MT_TOOL_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, x);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_Y, y);
+}
+
+void MultiTouchInputMapperTest::processTouchMajor(
+        MultiTouchInputMapper* mapper, int32_t touchMajor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
+}
+
+void MultiTouchInputMapperTest::processTouchMinor(
+        MultiTouchInputMapper* mapper, int32_t touchMinor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
+}
+
+void MultiTouchInputMapperTest::processToolMajor(
+        MultiTouchInputMapper* mapper, int32_t toolMajor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
+}
+
+void MultiTouchInputMapperTest::processToolMinor(
+        MultiTouchInputMapper* mapper, int32_t toolMinor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
+}
+
+void MultiTouchInputMapperTest::processOrientation(
+        MultiTouchInputMapper* mapper, int32_t orientation) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_ORIENTATION, orientation);
+}
+
+void MultiTouchInputMapperTest::processPressure(
+        MultiTouchInputMapper* mapper, int32_t pressure) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, pressure);
+}
+
+void MultiTouchInputMapperTest::processDistance(
+        MultiTouchInputMapper* mapper, int32_t distance) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_DISTANCE, distance);
+}
+
+void MultiTouchInputMapperTest::processId(
+        MultiTouchInputMapper* mapper, int32_t id) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, id);
+}
+
+void MultiTouchInputMapperTest::processSlot(
+        MultiTouchInputMapper* mapper, int32_t slot) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_SLOT, slot);
+}
+
+void MultiTouchInputMapperTest::processToolType(
+        MultiTouchInputMapper* mapper, int32_t toolType) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
+}
+
+void MultiTouchInputMapperTest::processKey(
+        MultiTouchInputMapper* mapper, int32_t code, int32_t value) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
+}
+
+void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0);
+}
+
+void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+}
+
+
+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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(mFakeListener->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.buttonState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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(mFakeListener->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | ID);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    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(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 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(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 0));
+
+    // First finger up.
+    x2 += 15; y2 -= 20;
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 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(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 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(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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, 0));
+
+    // Second finger up.
+    x3 += 30; y3 -= 20;
+    processPosition(mapper, x3, y3);
+    processId(mapper, 3);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // Last finger up.
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // Should not have sent any more keys or motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | ID | SLOT);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    NotifyMotionArgs motionArgs;
+
+    // Two fingers down at once.
+    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+    processPosition(mapper, x1, y1);
+    processId(mapper, 1);
+    processSlot(mapper, 1);
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 0));
+
+    // Move.
+    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
+    processSlot(mapper, 0);
+    processPosition(mapper, x1, y1);
+    processSlot(mapper, 1);
+    processPosition(mapper, x2, y2);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 0));
+
+    // First finger up.
+    x2 += 15; y2 -= 20;
+    processSlot(mapper, 0);
+    processId(mapper, -1);
+    processSlot(mapper, 1);
+    processPosition(mapper, x2, y2);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 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, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // Move.
+    x2 += 20; y2 -= 25;
+    processPosition(mapper, x2, y2);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // New finger down.
+    int32_t x3 = 700, y3 = 300;
+    processPosition(mapper, x2, y2);
+    processSlot(mapper, 0);
+    processId(mapper, 3);
+    processPosition(mapper, x3, y3);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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, 0));
+
+    // Second finger up.
+    x3 += 30; y3 -= 20;
+    processSlot(mapper, 1);
+    processId(mapper, -1);
+    processSlot(mapper, 0);
+    processPosition(mapper, x3, y3);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 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, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // Last finger up.
+    processId(mapper, -1);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // Should not have sent any more keys or motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
+    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 rawDistance = 0;
+    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(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
+    float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
+    float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
+    float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
+    float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
+    float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
+    float distance = float(rawDistance);
+
+    processPosition(mapper, rawX, rawY);
+    processTouchMajor(mapper, rawTouchMajor);
+    processTouchMinor(mapper, rawTouchMinor);
+    processToolMajor(mapper, rawToolMajor);
+    processToolMinor(mapper, rawToolMinor);
+    processPressure(mapper, rawPressure);
+    processOrientation(mapper, rawOrientation);
+    processDistance(mapper, rawDistance);
+    processId(mapper, id);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(0, args.pointerProperties[0].id);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
+            orientation, distance));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL | MINOR);
+    addConfigurationProperty("touch.size.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 size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
+    float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
+    float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
+    float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
+    float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
+
+    processPosition(mapper, rawX, rawY);
+    processTouchMajor(mapper, rawTouchMajor);
+    processTouchMinor(mapper, rawTouchMinor);
+    processToolMajor(mapper, rawToolMajor);
+    processToolMinor(mapper, rawToolMinor);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL);
+    addConfigurationProperty("touch.size.calibration", "diameter");
+    addConfigurationProperty("touch.size.scale", "10");
+    addConfigurationProperty("touch.size.bias", "160");
+    addConfigurationProperty("touch.size.isSummed", "1");
+    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 = 5;
+    int32_t rawToolMajor = 8;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float x2 = toDisplayX(rawX2);
+    float y2 = toDisplayY(rawY2);
+    float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
+    float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
+    float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
+
+    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);
+
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->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, 1.0f, size, touch, touch, tool, tool, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
+            x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL);
+    addConfigurationProperty("touch.size.calibration", "area");
+    addConfigurationProperty("touch.size.scale", "43");
+    addConfigurationProperty("touch.size.bias", "3");
+    addMapperAndConfigure(mapper);
+
+    // These calculations are based on the input device calibration documentation.
+    int32_t rawX = 100;
+    int32_t rawY = 200;
+    int32_t rawTouchMajor = 5;
+    int32_t rawToolMajor = 8;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
+    float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
+    float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
+
+    processPosition(mapper, rawX, rawY);
+    processTouchMajor(mapper, rawTouchMajor);
+    processToolMajor(mapper, rawToolMajor);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | PRESSURE);
+    addConfigurationProperty("touch.pressure.calibration", "amplitude");
+    addConfigurationProperty("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 rawPressure = 60;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float pressure = float(rawPressure) * 0.01f;
+
+    processPosition(mapper, rawX, rawY);
+    processPressure(mapper, rawPressure);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | ID | SLOT);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+    NotifyKeyArgs keyArgs;
+
+    processId(mapper, 1);
+    processPosition(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.buttonState);
+
+    // press BTN_LEFT, release BTN_LEFT
+    processKey(mapper, BTN_LEFT, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+
+    processKey(mapper, BTN_LEFT, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+    processKey(mapper, BTN_RIGHT, 1);
+    processKey(mapper, BTN_MIDDLE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+            motionArgs.buttonState);
+
+    processKey(mapper, BTN_RIGHT, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_MIDDLE, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // press BTN_BACK, release BTN_BACK
+    processKey(mapper, BTN_BACK, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_BACK, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+    // press BTN_SIDE, release BTN_SIDE
+    processKey(mapper, BTN_SIDE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_SIDE, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+    // press BTN_FORWARD, release BTN_FORWARD
+    processKey(mapper, BTN_FORWARD, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_FORWARD, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+    // press BTN_EXTRA, release BTN_EXTRA
+    processKey(mapper, BTN_EXTRA, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    processKey(mapper, BTN_EXTRA, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+    // press BTN_STYLUS, release BTN_STYLUS
+    processKey(mapper, BTN_STYLUS, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
+
+    processKey(mapper, BTN_STYLUS, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // press BTN_STYLUS2, release BTN_STYLUS2
+    processKey(mapper, BTN_STYLUS2, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+
+    processKey(mapper, BTN_STYLUS2, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(0, motionArgs.buttonState);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+    // release touch
+    processId(mapper, -1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.buttonState);
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+
+    // default tool type is finger
+    processId(mapper, 1);
+    processPosition(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // eraser
+    processKey(mapper, BTN_TOOL_RUBBER, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+    // stylus
+    processKey(mapper, BTN_TOOL_RUBBER, 0);
+    processKey(mapper, BTN_TOOL_PEN, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // brush
+    processKey(mapper, BTN_TOOL_PEN, 0);
+    processKey(mapper, BTN_TOOL_BRUSH, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // pencil
+    processKey(mapper, BTN_TOOL_BRUSH, 0);
+    processKey(mapper, BTN_TOOL_PENCIL, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // airbrush
+    processKey(mapper, BTN_TOOL_PENCIL, 0);
+    processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // mouse
+    processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
+    processKey(mapper, BTN_TOOL_MOUSE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+
+    // lens
+    processKey(mapper, BTN_TOOL_MOUSE, 0);
+    processKey(mapper, BTN_TOOL_LENS, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+
+    // double-tap
+    processKey(mapper, BTN_TOOL_LENS, 0);
+    processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // triple-tap
+    processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
+    processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // quad-tap
+    processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
+    processKey(mapper, BTN_TOOL_QUADTAP, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // finger
+    processKey(mapper, BTN_TOOL_QUADTAP, 0);
+    processKey(mapper, BTN_TOOL_FINGER, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // stylus trumps finger
+    processKey(mapper, BTN_TOOL_PEN, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // eraser trumps stylus
+    processKey(mapper, BTN_TOOL_RUBBER, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+    // mouse trumps eraser
+    processKey(mapper, BTN_TOOL_MOUSE, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+
+    // MT tool type trumps BTN tool types: MT_TOOL_FINGER
+    processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+    // MT tool type trumps BTN tool types: MT_TOOL_PEN
+    processToolType(mapper, MT_TOOL_PEN);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+    // back to default tool type
+    processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
+    processKey(mapper, BTN_TOOL_MOUSE, 0);
+    processKey(mapper, BTN_TOOL_RUBBER, 0);
+    processKey(mapper, BTN_TOOL_PEN, 0);
+    processKey(mapper, BTN_TOOL_FINGER, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | ID | SLOT);
+    mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+
+    // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
+    processId(mapper, 1);
+    processPosition(mapper, 100, 200);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // move a little
+    processPosition(mapper, 150, 250);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // down when BTN_TOUCH is pressed, pressure defaults to 1
+    processKey(mapper, BTN_TOUCH, 1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // up when BTN_TOUCH is released, hover restored
+    processKey(mapper, BTN_TOUCH, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // exit hover when pointer goes away
+    processId(mapper, -1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION | ID | SLOT | PRESSURE);
+    addMapperAndConfigure(mapper);
+
+    NotifyMotionArgs motionArgs;
+
+    // initially hovering because pressure is 0
+    processId(mapper, 1);
+    processPosition(mapper, 100, 200);
+    processPressure(mapper, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // move a little
+    processPosition(mapper, 150, 250);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // down when pressure becomes non-zero
+    processPressure(mapper, RAW_PRESSURE_MAX);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    // up when pressure becomes 0, hover restored
+    processPressure(mapper, 0);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+    // exit hover when pointer goes away
+    processId(mapper, -1);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+}
+
+
+} // namespace android
diff --git a/services/sensorservice/BatteryService.cpp b/services/sensorservice/BatteryService.cpp
index 38dc749..cb962a6 100644
--- a/services/sensorservice/BatteryService.cpp
+++ b/services/sensorservice/BatteryService.cpp
@@ -34,32 +34,10 @@
     const sp<IServiceManager> sm(defaultServiceManager());
     if (sm != NULL) {
         const String16 name("batterystats");
-        mBatteryStatService = sm->getService(name);
+        mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
     }
 }
 
-status_t BatteryService::noteStartSensor(int uid, int handle) {
-    Parcel data, reply;
-    data.writeInterfaceToken(DESCRIPTOR);
-    data.writeInt32(uid);
-    data.writeInt32(handle);
-    status_t err = mBatteryStatService->transact(
-            TRANSACTION_noteStartSensor, data, &reply, 0);
-    err = reply.readExceptionCode();
-    return err;
-}
-
-status_t BatteryService::noteStopSensor(int uid, int handle) {
-    Parcel data, reply;
-    data.writeInterfaceToken(DESCRIPTOR);
-    data.writeInt32(uid);
-    data.writeInt32(handle);
-    status_t err = mBatteryStatService->transact(
-            TRANSACTION_noteStopSensor, data, &reply, 0);
-    err = reply.readExceptionCode();
-    return err;
-}
-
 bool BatteryService::addSensor(uid_t uid, int handle) {
     Mutex::Autolock _l(mActivationsLock);
     Info key(uid, handle);
@@ -86,7 +64,7 @@
     if (mBatteryStatService != 0) {
         if (addSensor(uid, handle)) {
             int64_t identity = IPCThreadState::self()->clearCallingIdentity();
-            noteStartSensor(uid, handle);
+            mBatteryStatService->noteStartSensor(uid, handle);
             IPCThreadState::self()->restoreCallingIdentity(identity);
         }
     }
@@ -95,7 +73,7 @@
     if (mBatteryStatService != 0) {
         if (removeSensor(uid, handle)) {
             int64_t identity = IPCThreadState::self()->clearCallingIdentity();
-            noteStopSensor(uid, handle);
+            mBatteryStatService->noteStopSensor(uid, handle);
             IPCThreadState::self()->restoreCallingIdentity(identity);
         }
     }
@@ -108,7 +86,7 @@
         for (ssize_t i=0 ; i<mActivations.size() ; i++) {
             const Info& info(mActivations[i]);
             if (info.uid == uid) {
-                noteStopSensor(info.uid, info.handle);
+                mBatteryStatService->noteStopSensor(info.uid, info.handle);
                 mActivations.removeAt(i);
                 i--;
             }
@@ -117,8 +95,6 @@
     }
 }
 
-const String16 BatteryService::DESCRIPTOR("com.android.internal.app.IBatteryStats");
-
 ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
 
 // ---------------------------------------------------------------------------
diff --git a/services/sensorservice/BatteryService.h b/services/sensorservice/BatteryService.h
index 86cc884..08ba857 100644
--- a/services/sensorservice/BatteryService.h
+++ b/services/sensorservice/BatteryService.h
@@ -17,22 +17,18 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <binder/IBatteryStats.h>
 #include <utils/Singleton.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
 
 class BatteryService : public Singleton<BatteryService> {
-    static const int TRANSACTION_noteStartSensor = IBinder::FIRST_CALL_TRANSACTION + 3;
-    static const int TRANSACTION_noteStopSensor = IBinder::FIRST_CALL_TRANSACTION + 4;
-    static const String16 DESCRIPTOR;
 
     friend class Singleton<BatteryService>;
-    sp<IBinder> mBatteryStatService;
+    sp<IBatteryStats> mBatteryStatService;
 
     BatteryService();
-    status_t noteStartSensor(int uid, int handle);
-    status_t noteStopSensor(int uid, int handle);
 
     void enableSensorImpl(uid_t uid, int handle);
     void disableSensorImpl(uid_t uid, int handle);
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 0d0f98d..e5ecf07 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -199,8 +199,8 @@
     mPageFlipCount++;
 }
 
-status_t DisplayDevice::beginFrame() const {
-    return mDisplaySurface->beginFrame();
+status_t DisplayDevice::beginFrame(bool mustRecompose) const {
+    return mDisplaySurface->beginFrame(mustRecompose);
 }
 
 status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 01a9d2e..f750c6c 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -124,7 +124,9 @@
     int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
     const wp<IBinder>&      getDisplayToken() const { return mDisplayToken; }
 
-    status_t beginFrame() const;
+    // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
+    // machine happy without actually queueing a buffer if nothing has changed
+    status_t beginFrame(bool mustRecompose) const;
     status_t prepareFrame(const HWComposer& hwc) const;
 
     void swapBuffers(HWComposer& hwc) const;
diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
index 48bf3f2..1db3eb8 100644
--- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
@@ -33,7 +33,9 @@
     // beginFrame is called at the beginning of the composition loop, before
     // the configuration is known. The DisplaySurface should do anything it
     // needs to do to enable HWComposer to decide how to compose the frame.
-    virtual status_t beginFrame() = 0;
+    // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
+    // machine happy without actually queueing a buffer if nothing has changed.
+    virtual status_t beginFrame(bool mustRecompose) = 0;
 
     // prepareFrame is called after the composition configuration is known but
     // before composition takes place. The DisplaySurface can use the
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 8c634ed..0f34764 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -68,7 +68,7 @@
     mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
 }
 
-status_t FramebufferSurface::beginFrame() {
+status_t FramebufferSurface::beginFrame(bool mustRecompose) {
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 1d67446..ba72ce3 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -39,7 +39,7 @@
 public:
     FramebufferSurface(HWComposer& hwc, int disp, const sp<IGraphicBufferConsumer>& consumer);
 
-    virtual status_t beginFrame();
+    virtual status_t beginFrame(bool mustRecompose);
     virtual status_t prepareFrame(CompositionType compositionType);
     virtual status_t compositionComplete();
     virtual status_t advanceFrame();
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 1b652c3..474f633 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -23,7 +23,6 @@
 #include <sys/types.h>
 #include <math.h>
 
-#include <utils/CallStack.h>
 #include <utils/Errors.h>
 #include <utils/misc.h>
 #include <utils/String8.h>
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index d7fef8c..a1820ab 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -56,7 +56,8 @@
     mOutputUsage(GRALLOC_USAGE_HW_COMPOSER),
     mProducerSlotSource(0),
     mDbgState(DBG_STATE_IDLE),
-    mDbgLastCompositionType(COMPOSITION_UNKNOWN)
+    mDbgLastCompositionType(COMPOSITION_UNKNOWN),
+    mMustRecompose(false)
 {
     mSource[SOURCE_SINK] = sink;
     mSource[SOURCE_SCRATCH] = bq;
@@ -92,10 +93,12 @@
 VirtualDisplaySurface::~VirtualDisplaySurface() {
 }
 
-status_t VirtualDisplaySurface::beginFrame() {
+status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
     if (mDisplayId < 0)
         return NO_ERROR;
 
+    mMustRecompose = mustRecompose;
+
     VDS_LOGW_IF(mDbgState != DBG_STATE_IDLE,
             "Unexpected beginFrame() in %s state", dbgStateStr());
     mDbgState = DBG_STATE_BEGUN;
@@ -228,16 +231,24 @@
         QueueBufferOutput qbo;
         sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
         VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot);
-        status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
-                QueueBufferInput(
-                    systemTime(), false /* isAutoTimestamp */,
-                    Rect(mSinkBufferWidth, mSinkBufferHeight),
-                    NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */,
-                    true /* async*/,
-                    outFence),
-                &qbo);
-        if (result == NO_ERROR) {
-            updateQueueBufferOutput(qbo);
+        if (mMustRecompose) {
+            status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
+                    QueueBufferInput(
+                        systemTime(), false /* isAutoTimestamp */,
+                        Rect(mSinkBufferWidth, mSinkBufferHeight),
+                        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */,
+                        true /* async*/,
+                        outFence),
+                    &qbo);
+            if (result == NO_ERROR) {
+                updateQueueBufferOutput(qbo);
+            }
+        } else {
+            // If the surface hadn't actually been updated, then we only went
+            // through the motions of updating the display to keep our state
+            // machine happy. We cancel the buffer to avoid triggering another
+            // re-composition and causing an infinite loop.
+            mSource[SOURCE_SINK]->cancelBuffer(sslot, outFence);
         }
     }
 
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 1e85ac4..6899904 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -79,7 +79,7 @@
     //
     // DisplaySurface interface
     //
-    virtual status_t beginFrame();
+    virtual status_t beginFrame(bool mustRecompose);
     virtual status_t prepareFrame(CompositionType compositionType);
     virtual status_t compositionComplete();
     virtual status_t advanceFrame();
@@ -222,6 +222,8 @@
 
     const char* dbgStateStr() const;
     static const char* dbgSourceStr(Source s);
+
+    bool mMustRecompose;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 61af51f..fcc9d78 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -64,7 +64,6 @@
         mName("unnamed"),
         mDebug(false),
         mFormat(PIXEL_FORMAT_NONE),
-        mOpaqueLayer(true),
         mTransactionFlags(0),
         mQueuedFrames(0),
         mCurrentTransform(0),
@@ -86,7 +85,9 @@
 
     uint32_t layerFlags = 0;
     if (flags & ISurfaceComposerClient::eHidden)
-        layerFlags = layer_state_t::eLayerHidden;
+        layerFlags |= layer_state_t::eLayerHidden;
+    if (flags & ISurfaceComposerClient::eOpaque)
+        layerFlags |= layer_state_t::eLayerOpaque;
 
     if (flags & ISurfaceComposerClient::eNonPremultiplied)
         mPremultipliedAlpha = false;
@@ -189,7 +190,6 @@
 
     mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
     mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
-    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
     mCurrentOpacity = getOpacityForFormat(format);
 
     mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
@@ -352,7 +352,7 @@
 
     // this gives us only the "orientation" component of the transform
     const State& s(getDrawingState());
-    if (!isOpaque() || s.alpha != 0xFF) {
+    if (!isOpaque(s) || s.alpha != 0xFF) {
         layer.setBlending(mPremultipliedAlpha ?
                 HWC_BLENDING_PREMULT :
                 HWC_BLENDING_COVERAGE);
@@ -596,7 +596,7 @@
     texCoords[3] = vec2(right, 1.0f - top);
 
     RenderEngine& engine(mFlinger->getRenderEngine());
-    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
+    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
     engine.drawMesh(mMesh);
     engine.disableBlending();
 }
@@ -656,7 +656,7 @@
     }
 }
 
-bool Layer::isOpaque() const
+bool Layer::isOpaque(const Layer::State& s) const
 {
     // if we don't have a buffer yet, we're translucent regardless of the
     // layer's opaque flag.
@@ -666,7 +666,7 @@
 
     // if the layer has the opaque flag, then we're always opaque,
     // otherwise we use the current buffer's format.
-    return mOpaqueLayer || mCurrentOpacity;
+    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
 }
 
 bool Layer::isProtected() const
@@ -954,7 +954,8 @@
         }
 
         // Capture the old state of the layer for comparisons later
-        const bool oldOpacity = isOpaque();
+        const State& s(getDrawingState());
+        const bool oldOpacity = isOpaque(s);
         sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
 
         struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
@@ -1122,12 +1123,11 @@
         }
 
         mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
-        if (oldOpacity != isOpaque()) {
+        if (oldOpacity != isOpaque(s)) {
             recomputeVisibleRegions = true;
         }
 
         // FIXME: postedRegion should be dirty & bounds
-        const Layer::State& s(getDrawingState());
         Region dirtyRegion(Rect(s.active.w, s.active.h));
 
         // transform the dirty region to window-manager space
@@ -1188,7 +1188,7 @@
             s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
             s.active.crop.left, s.active.crop.top,
             s.active.crop.right, s.active.crop.bottom,
-            isOpaque(), contentDirty,
+            isOpaque(s), contentDirty,
             s.alpha, s.flags,
             s.transform[0][0], s.transform[0][1],
             s.transform[1][0], s.transform[1][1],
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index ef4a7e9..ea65ded 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -149,8 +149,12 @@
 
     /*
      * isOpaque - true if this surface is opaque
+     *
+     * This takes into account the buffer format (i.e. whether or not the
+     * pixel format includes an alpha channel) and the "opaque" flag set
+     * on the layer.  It does not examine the current plane alpha value.
      */
-    virtual bool isOpaque() const;
+    virtual bool isOpaque(const Layer::State& s) const;
 
     /*
      * isSecure - true if this surface is secure, that is if it prevents
@@ -335,7 +339,6 @@
     String8 mName;
     mutable bool mDebug;
     PixelFormat mFormat;
-    bool mOpaqueLayer;
 
     // these are protected by an external lock
     State mCurrentState;
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 09b0ddc..d130506 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -169,7 +169,8 @@
             fs << "gl_FragColor.rgb = gl_FragColor.rgb/gl_FragColor.a;";
         }
         fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2));";
-        fs << "gl_FragColor     = colorMatrix*gl_FragColor;";
+        fs << "vec4 transformed = colorMatrix * vec4(gl_FragColor.rgb, 1);";
+        fs << "gl_FragColor.rgb = transformed.rgb/transformed.a;";
         fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2));";
         if (!needs.isOpaque() && needs.isPremultiplied()) {
             // and re-premultiply if needed after gamma correction
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c00b034..9f687e2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -152,7 +152,8 @@
         mBootFinished(false),
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
-        mDaltonize(false)
+        mDaltonize(false),
+        mHasColorMatrix(false)
 {
     ALOGI("SurfaceFlinger is starting");
 
@@ -881,7 +882,9 @@
 
 void SurfaceFlinger::setUpHWComposer() {
     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
-        mDisplays[dpy]->beginFrame();
+        bool mustRecompose =
+                !(mDisplays[dpy]->getDirtyRegion(false).isEmpty());
+        mDisplays[dpy]->beginFrame(mustRecompose);
     }
 
     HWComposer& hwc(getHwComposer());
@@ -902,7 +905,7 @@
                         for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
                             const sp<Layer>& layer(currentLayers[i]);
                             layer->setGeometry(hw, *cur);
-                            if (mDebugDisableHWC || mDebugRegion || mDaltonize) {
+                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
                                 cur->setSkip(true);
                             }
                         }
@@ -1379,7 +1382,7 @@
 
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isOpaque();
+            const bool translucent = !layer->isOpaque(s);
             Rect bounds(s.transform.transform(layer->computeBounds()));
             visibleRegion.set(bounds);
             if (!visibleRegion.isEmpty()) {
@@ -1499,6 +1502,15 @@
 void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
         const Region& inDirtyRegion)
 {
+    // We only need to actually compose the display if:
+    // 1) It is being handled by hardware composer, which may need this to
+    //    keep its virtual display state machine in sync, or
+    // 2) There is work to be done (the dirty region isn't empty)
+    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
+    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
+        return;
+    }
+
     Region dirtyRegion(inDirtyRegion);
 
     // compute the invalid region
@@ -1524,11 +1536,15 @@
         }
     }
 
-    if (CC_LIKELY(!mDaltonize)) {
+    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
         doComposeSurfaces(hw, dirtyRegion);
     } else {
         RenderEngine& engine(getRenderEngine());
-        engine.beginGroup(mDaltonizer());
+        mat4 colorMatrix = mColorMatrix;
+        if (mDaltonize) {
+            colorMatrix = colorMatrix * mDaltonizer();
+        }
+        engine.beginGroup(colorMatrix);
         doComposeSurfaces(hw, dirtyRegion);
         engine.endGroup();
     }
@@ -1624,7 +1640,7 @@
                         const Layer::State& state(layer->getDrawingState());
                         if ((cur->getHints() & HWC_HINT_CLEAR_FB)
                                 && i
-                                && layer->isOpaque() && (state.alpha == 0xFF)
+                                && layer->isOpaque(state) && (state.alpha == 0xFF)
                                 && hasGlesComposition) {
                             // never clear the very first layer since we're
                             // guaranteed the FB is already cleared
@@ -1868,7 +1884,9 @@
             if (layer->setTransparentRegionHint(s.transparentRegion))
                 flags |= eTraversalNeeded;
         }
-        if (what & layer_state_t::eVisibilityChanged) {
+        if ((what & layer_state_t::eVisibilityChanged) ||
+                (what & layer_state_t::eOpacityChanged)) {
+            // TODO: should we just use an eFlagsChanged for this?
             if (layer->setFlags(s.flags, s.mask))
                 flags |= eTraversalNeeded;
         }
@@ -2415,7 +2433,8 @@
     colorizer.reset(result);
     result.appendFormat("  h/w composer %s and %s\n",
             hwc.initCheck()==NO_ERROR ? "present" : "not present",
-                    (mDebugDisableHWC || mDebugRegion || mDaltonize) ? "disabled" : "enabled");
+                    (mDebugDisableHWC || mDebugRegion || mDaltonize
+                            || mHasColorMatrix) ? "disabled" : "enabled");
     hwc.dump(result);
 
     /*
@@ -2578,8 +2597,28 @@
                 mDaltonize = n > 0;
                 invalidateHwcGeometry();
                 repaintEverything();
+                return NO_ERROR;
             }
-            return NO_ERROR;
+            case 1015: {
+                // apply a color matrix
+                n = data.readInt32();
+                mHasColorMatrix = n ? 1 : 0;
+                if (n) {
+                    // color matrix is sent as mat3 matrix followed by vec3
+                    // offset, then packed into a mat4 where the last row is
+                    // the offset and extra values are 0
+                    for (size_t i = 0 ; i < 4; i++) {
+                      for (size_t j = 0; j < 4; j++) {
+                          mColorMatrix[i][j] = data.readFloat();
+                      }
+                    }
+                } else {
+                    mColorMatrix = mat4();
+                }
+                invalidateHwcGeometry();
+                repaintEverything();
+                return NO_ERROR;
+            }
         }
     }
     return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 80bb619..9db0ce1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -38,6 +38,7 @@
 #include <binder/IMemory.h>
 
 #include <ui/PixelFormat.h>
+#include <ui/mat4.h>
 
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
@@ -472,6 +473,9 @@
 
     Daltonizer mDaltonizer;
     bool mDaltonize;
+
+    mat4 mColorMatrix;
+    bool mHasColorMatrix;
 };
 
 }; // namespace android
