diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 6d6f77e..b500a6b 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -103,6 +103,9 @@
         { REQ,      "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable" },
         { REQ,      "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable" },
     } },
+    { "mmc",        "eMMC commands",    0, {
+        { REQ,      "/sys/kernel/debug/tracing/events/mmc/enable" },
+    } },
     { "load",       "CPU Load",         0, {
         { REQ,      "/sys/kernel/debug/tracing/events/cpufreq_interactive/enable" },
     } },
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 89bea91..37d4646 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -278,6 +278,17 @@
     run_command("DUMPSYS", 60, "dumpsys", NULL);
 
     printf("========================================================\n");
+    printf("== Checkins\n");
+    printf("========================================================\n");
+
+    run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "--checkin", NULL);
+    run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL);
+    run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL);
+    run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c",
+            "--include-committed", NULL);
+    run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "--c", NULL);
+
+    printf("========================================================\n");
     printf("== Running Application Activities\n");
     printf("========================================================\n");
 
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 8e14a2c..131e03f 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -540,7 +540,6 @@
 }
 
 
-/* a simpler version of dexOptGenerateCacheFileName() */
 int create_cache_path(char path[PKG_PATH_MAX], const char *src)
 {
     char *tmp;
@@ -580,7 +579,7 @@
 }
 
 static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name,
-    const char* dexopt_flags)
+    const char* output_file_name, const char* dexopt_flags)
 {
     static const char* DEX_OPT_BIN = "/system/bin/dexopt";
     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
@@ -590,11 +589,35 @@
     sprintf(zip_num, "%d", zip_fd);
     sprintf(odex_num, "%d", odex_fd);
 
+    ALOGV("Running %s in=%s out=%s\n", DEX_OPT_BIN, input_file_name, output_file_name);
     execl(DEX_OPT_BIN, DEX_OPT_BIN, "--zip", zip_num, odex_num, input_file_name,
         dexopt_flags, (char*) NULL);
     ALOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno));
 }
 
+static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
+    const char* output_file_name, const char* dexopt_flags)
+{
+    static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
+    static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
+    char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
+    char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
+    char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
+    char oat_location_arg[strlen("--oat-name=") + PKG_PATH_MAX];
+
+    sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
+    sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
+    sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
+    sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
+
+    ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
+    execl(DEX2OAT_BIN, DEX2OAT_BIN,
+          zip_fd_arg, zip_location_arg,
+          oat_fd_arg, oat_location_arg,
+          (char*) NULL);
+    ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
+}
+
 static int wait_dexopt(pid_t pid, const char* apk_path)
 {
     int status;
@@ -631,31 +654,33 @@
 {
     struct utimbuf ut;
     struct stat apk_stat, dex_stat;
-    char dex_path[PKG_PATH_MAX];
+    char out_path[PKG_PATH_MAX];
     char dexopt_flags[PROPERTY_VALUE_MAX];
+    char dalvik_vm_lib[PROPERTY_VALUE_MAX];
     char *end;
-    int res, zip_fd=-1, odex_fd=-1;
+    int res, zip_fd=-1, out_fd=-1;
 
-        /* Before anything else: is there a .odex file?  If so, we have
-         * pre-optimized the apk and there is nothing to do here.
-         */
     if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
         return -1;
     }
 
     /* platform-specific flags affecting optimization and verification */
     property_get("dalvik.vm.dexopt-flags", dexopt_flags, "");
+    ALOGV("dalvik.vm.dexopt_flags=%s\n", dexopt_flags);
 
-    strcpy(dex_path, apk_path);
-    end = strrchr(dex_path, '.');
-    if (end != NULL) {
-        strcpy(end, ".odex");
-        if (stat(dex_path, &dex_stat) == 0) {
-            return 0;
-        }
+    /* The command to run depend ones the value of dalvik.vm.lib */
+    property_get("dalvik.vm.lib", dalvik_vm_lib, "libdvm.so");
+    ALOGV("dalvik.vm.lib=%s\n", dalvik_vm_lib);
+
+    /* Before anything else: is there a .odex file?  If so, we have
+     * precompiled the apk and there is nothing to do here.
+     */
+    sprintf(out_path, "%s%s", apk_path, ".odex");
+    if (stat(out_path, &dex_stat) == 0) {
+        return 0;
     }
 
-    if (create_cache_path(dex_path, apk_path)) {
+    if (create_cache_path(out_path, apk_path)) {
         return -1;
     }
 
@@ -664,24 +689,24 @@
 
     zip_fd = open(apk_path, O_RDONLY, 0);
     if (zip_fd < 0) {
-        ALOGE("dexopt cannot open '%s' for input\n", apk_path);
+        ALOGE("installd cannot open '%s' for input during dexopt\n", apk_path);
         return -1;
     }
 
-    unlink(dex_path);
-    odex_fd = open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644);
-    if (odex_fd < 0) {
-        ALOGE("dexopt cannot open '%s' for output\n", dex_path);
+    unlink(out_path);
+    out_fd = open(out_path, O_RDWR | O_CREAT | O_EXCL, 0644);
+    if (out_fd < 0) {
+        ALOGE("installd cannot open '%s' for output during dexopt\n", out_path);
         goto fail;
     }
-    if (fchmod(odex_fd,
+    if (fchmod(out_fd,
                S_IRUSR|S_IWUSR|S_IRGRP |
                (is_public ? S_IROTH : 0)) < 0) {
-        ALOGE("dexopt cannot chmod '%s'\n", dex_path);
+        ALOGE("installd cannot chmod '%s' during dexopt\n", out_path);
         goto fail;
     }
-    if (fchown(odex_fd, AID_SYSTEM, uid) < 0) {
-        ALOGE("dexopt cannot chown '%s'\n", dex_path);
+    if (fchown(out_fd, AID_SYSTEM, uid) < 0) {
+        ALOGE("installd cannot chown '%s' during dexopt\n", out_path);
         goto fail;
     }
 
@@ -692,11 +717,11 @@
     if (pid == 0) {
         /* child -- drop privileges before continuing */
         if (setgid(uid) != 0) {
-            ALOGE("setgid(%d) failed during dexopt\n", uid);
+            ALOGE("setgid(%d) failed in installd during dexopt\n", uid);
             exit(64);
         }
         if (setuid(uid) != 0) {
-            ALOGE("setuid(%d) during dexopt\n", uid);
+            ALOGE("setuid(%d) failed in installd during dexopt\n", uid);
             exit(65);
         }
         // drop capabilities
@@ -709,33 +734,39 @@
             ALOGE("capset failed: %s\n", strerror(errno));
             exit(66);
         }
-        if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) {
-            ALOGE("flock(%s) failed: %s\n", dex_path, strerror(errno));
+        if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) {
+            ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno));
             exit(67);
         }
 
-        run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags);
+        if (strncmp(dalvik_vm_lib, "libdvm", 6) == 0) {
+            run_dexopt(zip_fd, out_fd, apk_path, out_path, dexopt_flags);
+        } else if (strncmp(dalvik_vm_lib, "libart", 6) == 0) {
+            run_dex2oat(zip_fd, out_fd, apk_path, out_path, dexopt_flags);
+        } else {
+            exit(69);   /* Unexpected dalvik.vm.lib value */
+        }
         exit(68);   /* only get here on exec failure */
     } else {
         res = wait_dexopt(pid, apk_path);
         if (res != 0) {
-            ALOGE("dexopt failed on '%s' res = %d\n", dex_path, res);
+            ALOGE("dexopt in='%s' out='%s' res=%d\n", apk_path, out_path, res);
             goto fail;
         }
     }
 
     ut.actime = apk_stat.st_atime;
     ut.modtime = apk_stat.st_mtime;
-    utime(dex_path, &ut);
-    
-    close(odex_fd);
+    utime(out_path, &ut);
+
+    close(out_fd);
     close(zip_fd);
     return 0;
 
 fail:
-    if (odex_fd >= 0) {
-        close(odex_fd);
-        unlink(dex_path);
+    if (out_fd >= 0) {
+        close(out_fd);
+        unlink(out_path);
     }
     if (zip_fd >= 0) {
         close(zip_fd);
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index c918633..87f900a 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -198,7 +198,7 @@
     unsigned short count;
     int ret = -1;
 
-//    ALOGI("execute('%s')\n", cmd);
+    // ALOGI("execute('%s')\n", cmd);
 
         /* default reply is "" */
     reply[0] = 0;
@@ -240,7 +240,7 @@
     if (n > BUFFER_MAX) n = BUFFER_MAX;
     count = n;
 
-//    ALOGI("reply: '%s'\n", cmd);
+    // ALOGI("reply: '%s'\n", cmd);
     if (writex(s, &count, sizeof(count))) return -1;
     if (writex(s, cmd, count)) return -1;
     return 0;
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 3378d97..ad0daee 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -51,6 +51,8 @@
             int64_t             clearCallingIdentity();
             void                restoreCallingIdentity(int64_t token);
             
+            int                 setupPolling(int* fd);
+            status_t            handlePolledCommands();
             void                flushCommands();
 
             void                joinThreadPool(bool isMain = true);
@@ -96,7 +98,9 @@
                                                      uint32_t code,
                                                      const Parcel& data,
                                                      status_t* statusBuffer);
+            status_t            getAndExecuteCommand();
             status_t            executeCommand(int32_t command);
+            void                processPendingDerefs();
             
             void                clearCaller();
             
diff --git a/include/input/Input.h b/include/input/Input.h
new file mode 100644
index 0000000..6d49b18
--- /dev/null
+++ b/include/input/Input.h
@@ -0,0 +1,622 @@
+/*
+ * 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 _LIBINPUT_INPUT_H
+#define _LIBINPUT_INPUT_H
+
+/**
+ * Native input event structures.
+ */
+
+#include <android/input.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+#ifdef HAVE_ANDROID_OS
+class SkMatrix;
+#endif
+
+/*
+ * Additional private constants not defined in ndk/ui/input.h.
+ */
+enum {
+    /* Signifies that the key is being predispatched */
+    AKEY_EVENT_FLAG_PREDISPATCH = 0x20000000,
+
+    /* Private control to determine when an app is tracking a key sequence. */
+    AKEY_EVENT_FLAG_START_TRACKING = 0x40000000,
+
+    /* Key event is inconsistent with previously sent key events. */
+    AKEY_EVENT_FLAG_TAINTED = 0x80000000,
+};
+
+enum {
+    /* Motion event is inconsistent with previously sent motion events. */
+    AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
+};
+
+enum {
+    /* Used when a motion event is not associated with any display.
+     * Typically used for non-pointer events. */
+    ADISPLAY_ID_NONE = -1,
+
+    /* The default display id. */
+    ADISPLAY_ID_DEFAULT = 0,
+};
+
+enum {
+    /*
+     * Indicates that an input device has switches.
+     * This input source flag is hidden from the API because switches are only used by the system
+     * and applications have no way to interact with them.
+     */
+    AINPUT_SOURCE_SWITCH = 0x80000000,
+};
+
+/*
+ * SystemUiVisibility constants from View.
+ */
+enum {
+    ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0,
+    ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001,
+};
+
+/*
+ * Maximum number of pointers supported per motion event.
+ * Smallest number of pointers is 1.
+ * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
+ * will occasionally emit 11.  There is not much harm making this constant bigger.)
+ */
+#define MAX_POINTERS 16
+
+/*
+ * Maximum pointer id value supported in a motion event.
+ * Smallest pointer id is 0.
+ * (This is limited by our use of BitSet32 to track pointer assignments.)
+ */
+#define MAX_POINTER_ID 31
+
+/*
+ * Declare a concrete type for the NDK's input event forward declaration.
+ */
+struct AInputEvent {
+    virtual ~AInputEvent() { }
+};
+
+/*
+ * Declare a concrete type for the NDK's input device forward declaration.
+ */
+struct AInputDevice {
+    virtual ~AInputDevice() { }
+};
+
+
+namespace android {
+
+#ifdef HAVE_ANDROID_OS
+class Parcel;
+#endif
+
+/*
+ * Flags that flow alongside events in the input dispatch system to help with certain
+ * policy decisions such as waking from device sleep.
+ *
+ * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
+ */
+enum {
+    /* These flags originate in RawEvents and are generally set in the key map.
+     * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */
+
+    POLICY_FLAG_WAKE = 0x00000001,
+    POLICY_FLAG_WAKE_DROPPED = 0x00000002,
+    POLICY_FLAG_SHIFT = 0x00000004,
+    POLICY_FLAG_CAPS_LOCK = 0x00000008,
+    POLICY_FLAG_ALT = 0x00000010,
+    POLICY_FLAG_ALT_GR = 0x00000020,
+    POLICY_FLAG_MENU = 0x00000040,
+    POLICY_FLAG_LAUNCHER = 0x00000080,
+    POLICY_FLAG_VIRTUAL = 0x00000100,
+    POLICY_FLAG_FUNCTION = 0x00000200,
+
+    POLICY_FLAG_RAW_MASK = 0x0000ffff,
+
+    /* These flags are set by the input dispatcher. */
+
+    // Indicates that the input event was injected.
+    POLICY_FLAG_INJECTED = 0x01000000,
+
+    // Indicates that the input event is from a trusted source such as a directly attached
+    // input device or an application with system-wide event injection permission.
+    POLICY_FLAG_TRUSTED = 0x02000000,
+
+    // Indicates that the input event has passed through an input filter.
+    POLICY_FLAG_FILTERED = 0x04000000,
+
+    // Disables automatic key repeating behavior.
+    POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000,
+
+    /* These flags are set by the input reader policy as it intercepts each event. */
+
+    // Indicates that the screen was off when the event was received and the event
+    // should wake the device.
+    POLICY_FLAG_WOKE_HERE = 0x10000000,
+
+    // Indicates that the screen was dim when the event was received and the event
+    // should brighten the device.
+    POLICY_FLAG_BRIGHT_HERE = 0x20000000,
+
+    // Indicates that the event should be dispatched to applications.
+    // The input event should still be sent to the InputDispatcher so that it can see all
+    // input events received include those that it will not deliver.
+    POLICY_FLAG_PASS_TO_USER = 0x40000000,
+};
+
+/*
+ * Pointer coordinate data.
+ */
+struct PointerCoords {
+    enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64
+
+    // Bitfield of axes that are present in this structure.
+    uint64_t bits;
+
+    // Values of axes that are stored in this structure packed in order by axis id
+    // for each axis that is present in the structure according to 'bits'.
+    float values[MAX_AXES];
+
+    inline void clear() {
+        bits = 0;
+    }
+
+    float getAxisValue(int32_t axis) const;
+    status_t setAxisValue(int32_t axis, float value);
+
+    void scale(float scale);
+
+    inline float getX() const {
+        return getAxisValue(AMOTION_EVENT_AXIS_X);
+    }
+
+    inline float getY() const {
+        return getAxisValue(AMOTION_EVENT_AXIS_Y);
+    }
+
+#ifdef HAVE_ANDROID_OS
+    status_t readFromParcel(Parcel* parcel);
+    status_t writeToParcel(Parcel* parcel) const;
+#endif
+
+    bool operator==(const PointerCoords& other) const;
+    inline bool operator!=(const PointerCoords& other) const {
+        return !(*this == other);
+    }
+
+    void copyFrom(const PointerCoords& other);
+
+private:
+    void tooManyAxes(int axis);
+};
+
+/*
+ * Pointer property data.
+ */
+struct PointerProperties {
+    // The id of the pointer.
+    int32_t id;
+
+    // The pointer tool type.
+    int32_t toolType;
+
+    inline void clear() {
+        id = -1;
+        toolType = 0;
+    }
+
+    bool operator==(const PointerProperties& other) const;
+    inline bool operator!=(const PointerProperties& other) const {
+        return !(*this == other);
+    }
+
+    void copyFrom(const PointerProperties& other);
+};
+
+/*
+ * Input events.
+ */
+class InputEvent : public AInputEvent {
+public:
+    virtual ~InputEvent() { }
+
+    virtual int32_t getType() const = 0;
+
+    inline int32_t getDeviceId() const { return mDeviceId; }
+
+    inline int32_t getSource() const { return mSource; }
+
+    inline void setSource(int32_t source) { mSource = source; }
+
+protected:
+    void initialize(int32_t deviceId, int32_t source);
+    void initialize(const InputEvent& from);
+
+    int32_t mDeviceId;
+    int32_t mSource;
+};
+
+/*
+ * Key events.
+ */
+class KeyEvent : public InputEvent {
+public:
+    virtual ~KeyEvent() { }
+
+    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getFlags() const { return mFlags; }
+
+    inline void setFlags(int32_t flags) { mFlags = flags; }
+
+    inline int32_t getKeyCode() const { return mKeyCode; }
+
+    inline int32_t getScanCode() const { return mScanCode; }
+
+    inline int32_t getMetaState() const { return mMetaState; }
+
+    inline int32_t getRepeatCount() const { return mRepeatCount; }
+
+    inline nsecs_t getDownTime() const { return mDownTime; }
+
+    inline nsecs_t getEventTime() const { return mEventTime; }
+
+    // Return true if this event may have a default action implementation.
+    static bool hasDefaultAction(int32_t keyCode);
+    bool hasDefaultAction() const;
+
+    // Return true if this event represents a system key.
+    static bool isSystemKey(int32_t keyCode);
+    bool isSystemKey() const;
+    
+    void initialize(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t keyCode,
+            int32_t scanCode,
+            int32_t metaState,
+            int32_t repeatCount,
+            nsecs_t downTime,
+            nsecs_t eventTime);
+    void initialize(const KeyEvent& from);
+
+protected:
+    int32_t mAction;
+    int32_t mFlags;
+    int32_t mKeyCode;
+    int32_t mScanCode;
+    int32_t mMetaState;
+    int32_t mRepeatCount;
+    nsecs_t mDownTime;
+    nsecs_t mEventTime;
+};
+
+/*
+ * Motion events.
+ */
+class MotionEvent : public InputEvent {
+public:
+    virtual ~MotionEvent() { }
+
+    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }
+
+    inline int32_t getActionIndex() const {
+        return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
+                >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+    }
+
+    inline void setAction(int32_t action) { mAction = action; }
+
+    inline int32_t getFlags() const { return mFlags; }
+
+    inline void setFlags(int32_t flags) { mFlags = flags; }
+
+    inline int32_t getEdgeFlags() const { return mEdgeFlags; }
+
+    inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
+
+    inline int32_t getMetaState() const { return mMetaState; }
+
+    inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
+
+    inline int32_t getButtonState() const { return mButtonState; }
+
+    inline float getXOffset() const { return mXOffset; }
+
+    inline float getYOffset() const { return mYOffset; }
+
+    inline float getXPrecision() const { return mXPrecision; }
+
+    inline float getYPrecision() const { return mYPrecision; }
+
+    inline nsecs_t getDownTime() const { return mDownTime; }
+
+    inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }
+
+    inline size_t getPointerCount() const { return mPointerProperties.size(); }
+
+    inline const PointerProperties* getPointerProperties(size_t pointerIndex) const {
+        return &mPointerProperties[pointerIndex];
+    }
+
+    inline int32_t getPointerId(size_t pointerIndex) const {
+        return mPointerProperties[pointerIndex].id;
+    }
+
+    inline int32_t getToolType(size_t pointerIndex) const {
+        return mPointerProperties[pointerIndex].toolType;
+    }
+
+    inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
+
+    const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
+
+    float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
+
+    inline float getRawX(size_t pointerIndex) const {
+        return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
+    }
+
+    inline float getRawY(size_t pointerIndex) const {
+        return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
+    }
+
+    float getAxisValue(int32_t axis, size_t pointerIndex) const;
+
+    inline float getX(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
+    }
+
+    inline float getY(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
+    }
+
+    inline float getPressure(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
+    }
+
+    inline float getSize(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
+    }
+
+    inline float getTouchMajor(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
+    }
+
+    inline float getTouchMinor(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
+    }
+
+    inline float getToolMajor(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
+    }
+
+    inline float getToolMinor(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
+    }
+
+    inline float getOrientation(size_t pointerIndex) const {
+        return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
+    }
+
+    inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
+
+    inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
+        return mSampleEventTimes[historicalIndex];
+    }
+
+    const PointerCoords* getHistoricalRawPointerCoords(
+            size_t pointerIndex, size_t historicalIndex) const;
+
+    float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
+            size_t historicalIndex) const;
+
+    inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalRawAxisValue(
+                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalRawAxisValue(
+                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
+    }
+
+    float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
+
+    inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
+    }
+
+    inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalAxisValue(
+                AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
+    }
+
+    ssize_t findPointerIndex(int32_t pointerId) const;
+
+    void initialize(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t edgeFlags,
+            int32_t metaState,
+            int32_t buttonState,
+            float xOffset,
+            float yOffset,
+            float xPrecision,
+            float yPrecision,
+            nsecs_t downTime,
+            nsecs_t eventTime,
+            size_t pointerCount,
+            const PointerProperties* pointerProperties,
+            const PointerCoords* pointerCoords);
+
+    void copyFrom(const MotionEvent* other, bool keepHistory);
+
+    void addSample(
+            nsecs_t eventTime,
+            const PointerCoords* pointerCoords);
+
+    void offsetLocation(float xOffset, float yOffset);
+
+    void scale(float scaleFactor);
+
+#ifdef HAVE_ANDROID_OS
+    void transform(const SkMatrix* matrix);
+
+    status_t readFromParcel(Parcel* parcel);
+    status_t writeToParcel(Parcel* parcel) const;
+#endif
+
+    static bool isTouchEvent(int32_t source, int32_t action);
+    inline bool isTouchEvent() const {
+        return isTouchEvent(mSource, mAction);
+    }
+
+    // Low-level accessors.
+    inline const PointerProperties* getPointerProperties() const {
+        return mPointerProperties.array();
+    }
+    inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
+    inline const PointerCoords* getSamplePointerCoords() const {
+            return mSamplePointerCoords.array();
+    }
+
+protected:
+    int32_t mAction;
+    int32_t mFlags;
+    int32_t mEdgeFlags;
+    int32_t mMetaState;
+    int32_t mButtonState;
+    float mXOffset;
+    float mYOffset;
+    float mXPrecision;
+    float mYPrecision;
+    nsecs_t mDownTime;
+    Vector<PointerProperties> mPointerProperties;
+    Vector<nsecs_t> mSampleEventTimes;
+    Vector<PointerCoords> mSamplePointerCoords;
+};
+
+/*
+ * Input event factory.
+ */
+class InputEventFactoryInterface {
+protected:
+    virtual ~InputEventFactoryInterface() { }
+
+public:
+    InputEventFactoryInterface() { }
+
+    virtual KeyEvent* createKeyEvent() = 0;
+    virtual MotionEvent* createMotionEvent() = 0;
+};
+
+/*
+ * A simple input event factory implementation that uses a single preallocated instance
+ * of each type of input event that are reused for each request.
+ */
+class PreallocatedInputEventFactory : public InputEventFactoryInterface {
+public:
+    PreallocatedInputEventFactory() { }
+    virtual ~PreallocatedInputEventFactory() { }
+
+    virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
+    virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
+
+private:
+    KeyEvent mKeyEvent;
+    MotionEvent mMotionEvent;
+};
+
+/*
+ * An input event factory implementation that maintains a pool of input events.
+ */
+class PooledInputEventFactory : public InputEventFactoryInterface {
+public:
+    PooledInputEventFactory(size_t maxPoolSize = 20);
+    virtual ~PooledInputEventFactory();
+
+    virtual KeyEvent* createKeyEvent();
+    virtual MotionEvent* createMotionEvent();
+
+    void recycle(InputEvent* event);
+
+private:
+    const size_t mMaxPoolSize;
+
+    Vector<KeyEvent*> mKeyEventPool;
+    Vector<MotionEvent*> mMotionEventPool;
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_INPUT_H
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
new file mode 100644
index 0000000..4672ad4
--- /dev/null
+++ b/include/input/InputDevice.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBINPUT_INPUT_DEVICE_H
+#define _LIBINPUT_INPUT_DEVICE_H
+
+#include <input/Input.h>
+#include <input/KeyCharacterMap.h>
+
+namespace android {
+
+/*
+ * Identifies a device.
+ */
+struct InputDeviceIdentifier {
+    inline InputDeviceIdentifier() :
+            bus(0), vendor(0), product(0), version(0) {
+    }
+
+    // Information provided by the kernel.
+    String8 name;
+    String8 location;
+    String8 uniqueId;
+    uint16_t bus;
+    uint16_t vendor;
+    uint16_t product;
+    uint16_t version;
+
+    // A composite input device descriptor string that uniquely identifies the device
+    // even across reboots or reconnections.  The value of this field is used by
+    // upper layers of the input system to associate settings with individual devices.
+    // It is hashed from whatever kernel provided information is available.
+    // 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;
+};
+
+/*
+ * Describes the characteristics and capabilities of an input device.
+ */
+class InputDeviceInfo {
+public:
+    InputDeviceInfo();
+    InputDeviceInfo(const InputDeviceInfo& other);
+    ~InputDeviceInfo();
+
+    struct MotionRange {
+        int32_t axis;
+        uint32_t source;
+        float min;
+        float max;
+        float flat;
+        float fuzz;
+        float resolution;
+    };
+
+    void initialize(int32_t id, int32_t generation, const InputDeviceIdentifier& identifier,
+            const String8& alias, bool isExternal);
+
+    inline int32_t getId() const { return mId; }
+    inline int32_t getGeneration() const { return mGeneration; }
+    inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
+    inline const String8& getAlias() const { return mAlias; }
+    inline const String8& getDisplayName() const {
+        return mAlias.isEmpty() ? mIdentifier.name : mAlias;
+    }
+    inline bool isExternal() const { return mIsExternal; }
+    inline uint32_t getSources() const { return mSources; }
+
+    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
+
+    void addSource(uint32_t source);
+    void addMotionRange(int32_t axis, uint32_t source,
+            float min, float max, float flat, float fuzz, float resolution);
+    void addMotionRange(const MotionRange& range);
+
+    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
+    inline int32_t getKeyboardType() const { return mKeyboardType; }
+
+    inline void setKeyCharacterMap(const sp<KeyCharacterMap>& value) {
+        mKeyCharacterMap = value;
+    }
+
+    inline sp<KeyCharacterMap> getKeyCharacterMap() const {
+        return mKeyCharacterMap;
+    }
+
+    inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
+    inline bool hasVibrator() const { return mHasVibrator; }
+
+    inline const Vector<MotionRange>& getMotionRanges() const {
+        return mMotionRanges;
+    }
+
+private:
+    int32_t mId;
+    int32_t mGeneration;
+    InputDeviceIdentifier mIdentifier;
+    String8 mAlias;
+    bool mIsExternal;
+    uint32_t mSources;
+    int32_t mKeyboardType;
+    sp<KeyCharacterMap> mKeyCharacterMap;
+    bool mHasVibrator;
+
+    Vector<MotionRange> mMotionRanges;
+};
+
+/* Types of input device configuration files. */
+enum InputDeviceConfigurationFileType {
+    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0,     /* .idc file */
+    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1,        /* .kl file */
+    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */
+};
+
+/*
+ * Gets the path of an input device configuration file, if one is available.
+ * Considers both system provided and user installed configuration files.
+ *
+ * The device identifier is used to construct several default configuration file
+ * names to try based on the device name, vendor, product, and version.
+ *
+ * Returns an empty string if not found.
+ */
+extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
+        const InputDeviceIdentifier& deviceIdentifier,
+        InputDeviceConfigurationFileType type);
+
+/*
+ * Gets the path of an input device configuration file, if one is available.
+ * Considers both system provided and user installed configuration files.
+ *
+ * The name is case-sensitive and is used to construct the filename to resolve.
+ * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.
+ *
+ * Returns an empty string if not found.
+ */
+extern String8 getInputDeviceConfigurationFilePathByName(
+        const String8& name, InputDeviceConfigurationFileType type);
+
+} // namespace android
+
+#endif // _LIBINPUT_INPUT_DEVICE_H
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
new file mode 100644
index 0000000..609b679
--- /dev/null
+++ b/include/input/InputTransport.h
@@ -0,0 +1,443 @@
+/*
+ * 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 _LIBINPUT_INPUT_TRANSPORT_H
+#define _LIBINPUT_INPUT_TRANSPORT_H
+
+/**
+ * Native input transport.
+ *
+ * The InputChannel provides a mechanism for exchanging InputMessage structures across processes.
+ *
+ * The InputPublisher and InputConsumer each handle one end-point of an input channel.
+ * The InputPublisher is used by the input dispatcher to send events to the application.
+ * The InputConsumer is used by the application to receive events from the input dispatcher.
+ */
+
+#include <input/Input.h>
+#include <utils/Errors.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/BitSet.h>
+
+namespace android {
+
+/*
+ * Intermediate representation used to send input events and related signals.
+ */
+struct InputMessage {
+    enum {
+        TYPE_KEY = 1,
+        TYPE_MOTION = 2,
+        TYPE_FINISHED = 3,
+    };
+
+    struct Header {
+        uint32_t type;
+        uint32_t padding; // 8 byte alignment for the body that follows
+    } header;
+
+    union Body {
+        struct Key {
+            uint32_t seq;
+            nsecs_t eventTime;
+            int32_t deviceId;
+            int32_t source;
+            int32_t action;
+            int32_t flags;
+            int32_t keyCode;
+            int32_t scanCode;
+            int32_t metaState;
+            int32_t repeatCount;
+            nsecs_t downTime;
+
+            inline size_t size() const {
+                return sizeof(Key);
+            }
+        } key;
+
+        struct Motion {
+            uint32_t seq;
+            nsecs_t eventTime;
+            int32_t deviceId;
+            int32_t source;
+            int32_t action;
+            int32_t flags;
+            int32_t metaState;
+            int32_t buttonState;
+            int32_t edgeFlags;
+            nsecs_t downTime;
+            float xOffset;
+            float yOffset;
+            float xPrecision;
+            float yPrecision;
+            size_t pointerCount;
+            struct Pointer {
+                PointerProperties properties;
+                PointerCoords coords;
+            } pointers[MAX_POINTERS];
+
+            int32_t getActionId() const {
+                uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
+                        >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+                return pointers[index].properties.id;
+            }
+
+            inline size_t size() const {
+                return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS
+                        + sizeof(Pointer) * pointerCount;
+            }
+        } motion;
+
+        struct Finished {
+            uint32_t seq;
+            bool handled;
+
+            inline size_t size() const {
+                return sizeof(Finished);
+            }
+        } finished;
+    } body;
+
+    bool isValid(size_t actualSize) const;
+    size_t size() const;
+};
+
+/*
+ * An input channel consists of a local unix domain socket used to send and receive
+ * input messages across processes.  Each channel has a descriptive name for debugging purposes.
+ *
+ * Each endpoint has its own InputChannel object that specifies its file descriptor.
+ *
+ * The input channel is closed when all references to it are released.
+ */
+class InputChannel : public RefBase {
+protected:
+    virtual ~InputChannel();
+
+public:
+    InputChannel(const String8& name, int fd);
+
+    /* Creates a pair of input channels.
+     *
+     * Returns OK on success.
+     */
+    static status_t openInputChannelPair(const String8& name,
+            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
+
+    inline String8 getName() const { return mName; }
+    inline int getFd() const { return mFd; }
+
+    /* Sends a message to the other endpoint.
+     *
+     * If the channel is full then the message is guaranteed not to have been sent at all.
+     * Try again after the consumer has sent a finished signal indicating that it has
+     * consumed some of the pending messages from the channel.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if the channel is full.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t sendMessage(const InputMessage* msg);
+
+    /* Receives a message sent by the other endpoint.
+     *
+     * If there is no message present, try again after poll() indicates that the fd
+     * is readable.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no message present.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveMessage(InputMessage* msg);
+
+    /* Returns a new object that has a duplicate of this channel's fd. */
+    sp<InputChannel> dup() const;
+
+private:
+    String8 mName;
+    int mFd;
+};
+
+/*
+ * Publishes input events to an input channel.
+ */
+class InputPublisher {
+public:
+    /* Creates a publisher associated with an input channel. */
+    explicit InputPublisher(const sp<InputChannel>& channel);
+
+    /* Destroys the publisher and releases its input channel. */
+    ~InputPublisher();
+
+    /* Gets the underlying input channel. */
+    inline sp<InputChannel> getChannel() { return mChannel; }
+
+    /* Publishes a key event to the input channel.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if the channel is full.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Returns BAD_VALUE if seq is 0.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t publishKeyEvent(
+            uint32_t seq,
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t keyCode,
+            int32_t scanCode,
+            int32_t metaState,
+            int32_t repeatCount,
+            nsecs_t downTime,
+            nsecs_t eventTime);
+
+    /* Publishes a motion event to the input channel.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if the channel is full.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t publishMotionEvent(
+            uint32_t seq,
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t edgeFlags,
+            int32_t metaState,
+            int32_t buttonState,
+            float xOffset,
+            float yOffset,
+            float xPrecision,
+            float yPrecision,
+            nsecs_t downTime,
+            nsecs_t eventTime,
+            size_t pointerCount,
+            const PointerProperties* pointerProperties,
+            const PointerCoords* pointerCoords);
+
+    /* Receives the finished signal from the consumer in reply to the original dispatch signal.
+     * If a signal was received, returns the message sequence number,
+     * and whether the consumer handled the message.
+     *
+     * The returned sequence number is never 0 unless the operation failed.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no signal present.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);
+
+private:
+    sp<InputChannel> mChannel;
+};
+
+/*
+ * Consumes input events from an input channel.
+ */
+class InputConsumer {
+public:
+    /* Creates a consumer associated with an input channel. */
+    explicit InputConsumer(const sp<InputChannel>& channel);
+
+    /* Destroys the consumer and releases its input channel. */
+    ~InputConsumer();
+
+    /* Gets the underlying input channel. */
+    inline sp<InputChannel> getChannel() { return mChannel; }
+
+    /* Consumes an input event from the input channel and copies its contents into
+     * an InputEvent object created using the specified factory.
+     *
+     * Tries to combine a series of move events into larger batches whenever possible.
+     *
+     * If consumeBatches is false, then defers consuming pending batched events if it
+     * is possible for additional samples to be added to them later.  Call hasPendingBatch()
+     * to determine whether a pending batch is available to be consumed.
+     *
+     * If consumeBatches is true, then events are still batched but they are consumed
+     * immediately as soon as the input channel is exhausted.
+     *
+     * The frameTime parameter specifies the time when the current display frame started
+     * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown.
+     *
+     * The returned sequence number is never 0 unless the operation failed.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no event present.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Returns NO_MEMORY if the event could not be created.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,
+            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
+
+    /* Sends a finished signal to the publisher to inform it that the message
+     * with the specified sequence number has finished being process and whether
+     * the message was handled by the consumer.
+     *
+     * Returns OK on success.
+     * Returns BAD_VALUE if seq is 0.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t sendFinishedSignal(uint32_t seq, bool handled);
+
+    /* Returns true if there is a deferred event waiting.
+     *
+     * Should be called after calling consume() to determine whether the consumer
+     * has a deferred event to be processed.  Deferred events are somewhat special in
+     * that they have already been removed from the input channel.  If the input channel
+     * becomes empty, the client may need to do extra work to ensure that it processes
+     * the deferred event despite the fact that the input channel's file descriptor
+     * is not readable.
+     *
+     * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.
+     * This guarantees that all deferred events will be processed.
+     *
+     * Alternately, the caller can call hasDeferredEvent() to determine whether there is
+     * a deferred event waiting and then ensure that its event loop wakes up at least
+     * one more time to consume the deferred event.
+     */
+    bool hasDeferredEvent() const;
+
+    /* Returns true if there is a pending batch.
+     *
+     * Should be called after calling consume() with consumeBatches == false to determine
+     * whether consume() should be called again later on with consumeBatches == true.
+     */
+    bool hasPendingBatch() const;
+
+private:
+    // True if touch resampling is enabled.
+    const bool mResampleTouch;
+
+    // The input channel.
+    sp<InputChannel> mChannel;
+
+    // The current input message.
+    InputMessage mMsg;
+
+    // True if mMsg contains a valid input message that was deferred from the previous
+    // call to consume and that still needs to be handled.
+    bool mMsgDeferred;
+
+    // Batched motion events per device and source.
+    struct Batch {
+        Vector<InputMessage> samples;
+    };
+    Vector<Batch> mBatches;
+
+    // Touch state per device and source, only for sources of class pointer.
+    struct History {
+        nsecs_t eventTime;
+        BitSet32 idBits;
+        int32_t idToIndex[MAX_POINTER_ID + 1];
+        PointerCoords pointers[MAX_POINTERS];
+
+        void initializeFrom(const InputMessage* msg) {
+            eventTime = msg->body.motion.eventTime;
+            idBits.clear();
+            for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
+                uint32_t id = msg->body.motion.pointers[i].properties.id;
+                idBits.markBit(id);
+                idToIndex[id] = i;
+                pointers[i].copyFrom(msg->body.motion.pointers[i].coords);
+            }
+        }
+
+        const PointerCoords& getPointerById(uint32_t id) const {
+            return pointers[idToIndex[id]];
+        }
+    };
+    struct TouchState {
+        int32_t deviceId;
+        int32_t source;
+        size_t historyCurrent;
+        size_t historySize;
+        History history[2];
+        History lastResample;
+
+        void initialize(int32_t deviceId, int32_t source) {
+            this->deviceId = deviceId;
+            this->source = source;
+            historyCurrent = 0;
+            historySize = 0;
+            lastResample.eventTime = 0;
+            lastResample.idBits.clear();
+        }
+
+        void addHistory(const InputMessage* msg) {
+            historyCurrent ^= 1;
+            if (historySize < 2) {
+                historySize += 1;
+            }
+            history[historyCurrent].initializeFrom(msg);
+        }
+
+        const History* getHistory(size_t index) const {
+            return &history[(historyCurrent + index) & 1];
+        }
+    };
+    Vector<TouchState> mTouchStates;
+
+    // Chain of batched sequence numbers.  When multiple input messages are combined into
+    // a batch, we append a record here that associates the last sequence number in the
+    // batch with the previous one.  When the finished signal is sent, we traverse the
+    // chain to individually finish all input messages that were part of the batch.
+    struct SeqChain {
+        uint32_t seq;   // sequence number of batched input message
+        uint32_t chain; // sequence number of previous batched input message
+    };
+    Vector<SeqChain> mSeqChains;
+
+    status_t consumeBatch(InputEventFactoryInterface* factory,
+            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
+    status_t consumeSamples(InputEventFactoryInterface* factory,
+            Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);
+
+    void updateTouchState(InputMessage* msg);
+    void rewriteMessage(const TouchState& state, InputMessage* msg);
+    void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
+            const InputMessage *next);
+
+    ssize_t findBatch(int32_t deviceId, int32_t source) const;
+    ssize_t findTouchState(int32_t deviceId, int32_t source) const;
+
+    status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);
+
+    static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
+    static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
+    static void addSample(MotionEvent* event, const InputMessage* msg);
+    static bool canAddSample(const Batch& batch, const InputMessage* msg);
+    static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
+    static bool shouldResampleTool(int32_t toolType);
+
+    static bool isTouchResamplingEnabled();
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_INPUT_TRANSPORT_H
diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h
new file mode 100644
index 0000000..e70666a
--- /dev/null
+++ b/include/input/KeyCharacterMap.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBINPUT_KEY_CHARACTER_MAP_H
+#define _LIBINPUT_KEY_CHARACTER_MAP_H
+
+#include <stdint.h>
+
+#if HAVE_ANDROID_OS
+#include <binder/IBinder.h>
+#endif
+
+#include <input/Input.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/Tokenizer.h>
+#include <utils/String8.h>
+#include <utils/Unicode.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+/**
+ * Describes a mapping from Android key codes to characters.
+ * Also specifies other functions of the keyboard such as the keyboard type
+ * and key modifier semantics.
+ *
+ * This object is immutable after it has been loaded.
+ */
+class KeyCharacterMap : public RefBase {
+public:
+    enum KeyboardType {
+        KEYBOARD_TYPE_UNKNOWN = 0,
+        KEYBOARD_TYPE_NUMERIC = 1,
+        KEYBOARD_TYPE_PREDICTIVE = 2,
+        KEYBOARD_TYPE_ALPHA = 3,
+        KEYBOARD_TYPE_FULL = 4,
+        KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
+        KEYBOARD_TYPE_OVERLAY = 6,
+    };
+
+    enum Format {
+        // Base keyboard layout, may contain device-specific options, such as "type" declaration.
+        FORMAT_BASE = 0,
+        // Overlay keyboard layout, more restrictive, may be published by applications,
+        // cannot override device-specific options.
+        FORMAT_OVERLAY = 1,
+        // Either base or overlay layout ok.
+        FORMAT_ANY = 2,
+    };
+
+    // Substitute key code and meta state for fallback action.
+    struct FallbackAction {
+        int32_t keyCode;
+        int32_t metaState;
+    };
+
+    /* Loads a key character map from a file. */
+    static status_t load(const String8& filename, Format format, sp<KeyCharacterMap>* outMap);
+
+    /* Loads a key character map from its string contents. */
+    static status_t loadContents(const String8& filename,
+            const char* contents, Format format, sp<KeyCharacterMap>* outMap);
+
+    /* Combines a base key character map and an overlay. */
+    static sp<KeyCharacterMap> combine(const sp<KeyCharacterMap>& base,
+            const sp<KeyCharacterMap>& overlay);
+
+    /* Returns an empty key character map. */
+    static sp<KeyCharacterMap> empty();
+
+    /* Gets the keyboard type. */
+    int32_t getKeyboardType() const;
+
+    /* Gets the primary character for this key as in the label physically printed on it.
+     * Returns 0 if none (eg. for non-printing keys). */
+    char16_t getDisplayLabel(int32_t keyCode) const;
+
+    /* Gets the Unicode character for the number or symbol generated by the key
+     * when the keyboard is used as a dialing pad.
+     * Returns 0 if no number or symbol is generated.
+     */
+    char16_t getNumber(int32_t keyCode) const;
+
+    /* Gets the Unicode character generated by the key and meta key modifiers.
+     * Returns 0 if no character is generated.
+     */
+    char16_t getCharacter(int32_t keyCode, int32_t metaState) const;
+
+    /* Gets the fallback action to use by default if the application does not
+     * handle the specified key.
+     * Returns true if an action was available, false if none.
+     */
+    bool getFallbackAction(int32_t keyCode, int32_t metaState,
+            FallbackAction* outFallbackAction) const;
+
+    /* Gets the first matching Unicode character that can be generated by the key,
+     * preferring the one with the specified meta key modifiers.
+     * Returns 0 if no matching character is generated.
+     */
+    char16_t getMatch(int32_t keyCode, const char16_t* chars,
+            size_t numChars, int32_t metaState) const;
+
+    /* Gets a sequence of key events that could plausibly generate the specified
+     * character sequence.  Returns false if some of the characters cannot be generated.
+     */
+    bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
+            Vector<KeyEvent>& outEvents) const;
+
+    /* Maps a scan code and usage code to a key code, in case this key map overrides
+     * the mapping in some way. */
+    status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
+
+#if HAVE_ANDROID_OS
+    /* Reads a key map from a parcel. */
+    static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
+
+    /* Writes a key map to a parcel. */
+    void writeToParcel(Parcel* parcel) const;
+#endif
+
+protected:
+    virtual ~KeyCharacterMap();
+
+private:
+    struct Behavior {
+        Behavior();
+        Behavior(const Behavior& other);
+
+        /* The next behavior in the list, or NULL if none. */
+        Behavior* next;
+
+        /* The meta key modifiers for this behavior. */
+        int32_t metaState;
+
+        /* The character to insert. */
+        char16_t character;
+
+        /* The fallback keycode if the key is not handled. */
+        int32_t fallbackKeyCode;
+    };
+
+    struct Key {
+        Key();
+        Key(const Key& other);
+        ~Key();
+
+        /* The single character label printed on the key, or 0 if none. */
+        char16_t label;
+
+        /* The number or symbol character generated by the key, or 0 if none. */
+        char16_t number;
+
+        /* The list of key behaviors sorted from most specific to least specific
+         * meta key binding. */
+        Behavior* firstBehavior;
+    };
+
+    class Parser {
+        enum State {
+            STATE_TOP = 0,
+            STATE_KEY = 1,
+        };
+
+        enum {
+            PROPERTY_LABEL = 1,
+            PROPERTY_NUMBER = 2,
+            PROPERTY_META = 3,
+        };
+
+        struct Property {
+            inline Property(int32_t property = 0, int32_t metaState = 0) :
+                    property(property), metaState(metaState) { }
+
+            int32_t property;
+            int32_t metaState;
+        };
+
+        KeyCharacterMap* mMap;
+        Tokenizer* mTokenizer;
+        Format mFormat;
+        State mState;
+        int32_t mKeyCode;
+
+    public:
+        Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format);
+        ~Parser();
+        status_t parse();
+
+    private:
+        status_t parseType();
+        status_t parseMap();
+        status_t parseMapKey();
+        status_t parseKey();
+        status_t parseKeyProperty();
+        status_t finishKey(Key* key);
+        status_t parseModifier(const String8& token, int32_t* outMetaState);
+        status_t parseCharacterLiteral(char16_t* outCharacter);
+    };
+
+    static sp<KeyCharacterMap> sEmpty;
+
+    KeyedVector<int32_t, Key*> mKeys;
+    int mType;
+
+    KeyedVector<int32_t, int32_t> mKeysByScanCode;
+    KeyedVector<int32_t, int32_t> mKeysByUsageCode;
+
+    KeyCharacterMap();
+    KeyCharacterMap(const KeyCharacterMap& other);
+
+    bool getKey(int32_t keyCode, const Key** outKey) const;
+    bool getKeyBehavior(int32_t keyCode, int32_t metaState,
+            const Key** outKey, const Behavior** outBehavior) const;
+    static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState);
+
+    bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
+
+    static status_t load(Tokenizer* tokenizer, Format format, sp<KeyCharacterMap>* outMap);
+
+    static void addKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
+    static void addMetaKeys(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+            int32_t* currentMetaState);
+    static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+            int32_t keyCode, int32_t keyMetaState,
+            int32_t* currentMetaState);
+    static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+            int32_t leftKeyCode, int32_t leftKeyMetaState,
+            int32_t rightKeyCode, int32_t rightKeyMetaState,
+            int32_t eitherKeyMetaState,
+            int32_t* currentMetaState);
+    static void addLockedMetaKey(Vector<KeyEvent>& outEvents,
+            int32_t deviceId, int32_t metaState, nsecs_t time,
+            int32_t keyCode, int32_t keyMetaState,
+            int32_t* currentMetaState);
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_KEY_CHARACTER_MAP_H
diff --git a/include/input/KeyLayoutMap.h b/include/input/KeyLayoutMap.h
new file mode 100644
index 0000000..eec11cf
--- /dev/null
+++ b/include/input/KeyLayoutMap.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBINPUT_KEY_LAYOUT_MAP_H
+#define _LIBINPUT_KEY_LAYOUT_MAP_H
+
+#include <stdint.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/Tokenizer.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AxisInfo {
+    enum Mode {
+        // Axis value is reported directly.
+        MODE_NORMAL = 0,
+        // Axis value should be inverted before reporting.
+        MODE_INVERT = 1,
+        // Axis value should be split into two axes
+        MODE_SPLIT = 2,
+    };
+
+    // Axis mode.
+    Mode mode;
+
+    // Axis id.
+    // When split, this is the axis used for values smaller than the split position.
+    int32_t axis;
+
+    // When split, this is the axis used for values after higher than the split position.
+    int32_t highAxis;
+
+    // The split value, or 0 if not split.
+    int32_t splitValue;
+
+    // The flat value, or -1 if none.
+    int32_t flatOverride;
+
+    AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
+    }
+};
+
+/**
+ * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
+ *
+ * This object is immutable after it has been loaded.
+ */
+class KeyLayoutMap : public RefBase {
+public:
+    static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap);
+
+    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 mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
+
+protected:
+    virtual ~KeyLayoutMap();
+
+private:
+    struct Key {
+        int32_t keyCode;
+        uint32_t flags;
+    };
+
+    KeyedVector<int32_t, Key> mKeysByScanCode;
+    KeyedVector<int32_t, Key> mKeysByUsageCode;
+    KeyedVector<int32_t, AxisInfo> mAxes;
+
+    KeyLayoutMap();
+
+    const Key* getKey(int32_t scanCode, int32_t usageCode) const;
+
+    class Parser {
+        KeyLayoutMap* mMap;
+        Tokenizer* mTokenizer;
+
+    public:
+        Parser(KeyLayoutMap* map, Tokenizer* tokenizer);
+        ~Parser();
+        status_t parse();
+
+    private:
+        status_t parseKey();
+        status_t parseAxis();
+    };
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_KEY_LAYOUT_MAP_H
diff --git a/include/input/Keyboard.h b/include/input/Keyboard.h
new file mode 100644
index 0000000..846cb0c
--- /dev/null
+++ b/include/input/Keyboard.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBINPUT_KEYBOARD_H
+#define _LIBINPUT_KEYBOARD_H
+
+#include <input/Input.h>
+#include <input/InputDevice.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/PropertyMap.h>
+
+namespace android {
+
+enum {
+    /* Device id of the built in keyboard. */
+    DEVICE_ID_BUILT_IN_KEYBOARD = 0,
+
+    /* Device id of a generic virtual keyboard with a full layout that can be used
+     * to synthesize key events. */
+    DEVICE_ID_VIRTUAL_KEYBOARD = -1,
+};
+
+class KeyLayoutMap;
+class KeyCharacterMap;
+
+/**
+ * Loads the key layout map and key character map for a keyboard device.
+ */
+class KeyMap {
+public:
+    String8 keyLayoutFile;
+    sp<KeyLayoutMap> keyLayoutMap;
+
+    String8 keyCharacterMapFile;
+    sp<KeyCharacterMap> keyCharacterMap;
+
+    KeyMap();
+    ~KeyMap();
+
+    status_t load(const InputDeviceIdentifier& deviceIdenfier,
+            const PropertyMap* deviceConfiguration);
+
+    inline bool haveKeyLayout() const {
+        return !keyLayoutFile.isEmpty();
+    }
+
+    inline bool haveKeyCharacterMap() const {
+        return !keyCharacterMapFile.isEmpty();
+    }
+
+    inline bool isComplete() const {
+        return haveKeyLayout() && haveKeyCharacterMap();
+    }
+
+private:
+    bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
+    status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
+    status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
+            const String8& name);
+    String8 getPath(const InputDeviceIdentifier& deviceIdentifier,
+            const String8& name, InputDeviceConfigurationFileType type);
+};
+
+/**
+ * Returns true if the keyboard is eligible for use as a built-in keyboard.
+ */
+extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
+        const PropertyMap* deviceConfiguration, const KeyMap* keyMap);
+
+/**
+ * Gets a key code by its short form label, eg. "HOME".
+ * Returns 0 if unknown.
+ */
+extern int32_t getKeyCodeByLabel(const char* label);
+
+/**
+ * Gets a key flag by its short form label, eg. "WAKE".
+ * Returns 0 if unknown.
+ */
+extern uint32_t getKeyFlagByLabel(const char* label);
+
+/**
+ * Gets a axis by its short form label, eg. "X".
+ * Returns -1 if unknown.
+ */
+extern int32_t getAxisByLabel(const char* label);
+
+/**
+ * Gets a axis label by its id.
+ * Returns NULL if unknown.
+ */
+extern const char* getAxisLabel(int32_t axisId);
+
+/**
+ * Updates a meta state field when a key is pressed or released.
+ */
+extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
+
+/**
+ * Returns true if a key is a meta key like ALT or CAPS_LOCK.
+ */
+extern bool isMetaKey(int32_t keyCode);
+
+} // namespace android
+
+#endif // _LIBINPUT_KEYBOARD_H
diff --git a/include/input/KeycodeLabels.h b/include/input/KeycodeLabels.h
new file mode 100644
index 0000000..c76ba12
--- /dev/null
+++ b/include/input/KeycodeLabels.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBINPUT_KEYCODE_LABELS_H
+#define _LIBINPUT_KEYCODE_LABELS_H
+
+#include <android/keycodes.h>
+
+struct KeycodeLabel {
+    const char *literal;
+    int value;
+};
+
+static const KeycodeLabel KEYCODES[] = {
+    { "SOFT_LEFT", 1 },
+    { "SOFT_RIGHT", 2 },
+    { "HOME", 3 },
+    { "BACK", 4 },
+    { "CALL", 5 },
+    { "ENDCALL", 6 },
+    { "0", 7 },
+    { "1", 8 },
+    { "2", 9 },
+    { "3", 10 },
+    { "4", 11 },
+    { "5", 12 },
+    { "6", 13 },
+    { "7", 14 },
+    { "8", 15 },
+    { "9", 16 },
+    { "STAR", 17 },
+    { "POUND", 18 },
+    { "DPAD_UP", 19 },
+    { "DPAD_DOWN", 20 },
+    { "DPAD_LEFT", 21 },
+    { "DPAD_RIGHT", 22 },
+    { "DPAD_CENTER", 23 },
+    { "VOLUME_UP", 24 },
+    { "VOLUME_DOWN", 25 },
+    { "POWER", 26 },
+    { "CAMERA", 27 },
+    { "CLEAR", 28 },
+    { "A", 29 },
+    { "B", 30 },
+    { "C", 31 },
+    { "D", 32 },
+    { "E", 33 },
+    { "F", 34 },
+    { "G", 35 },
+    { "H", 36 },
+    { "I", 37 },
+    { "J", 38 },
+    { "K", 39 },
+    { "L", 40 },
+    { "M", 41 },
+    { "N", 42 },
+    { "O", 43 },
+    { "P", 44 },
+    { "Q", 45 },
+    { "R", 46 },
+    { "S", 47 },
+    { "T", 48 },
+    { "U", 49 },
+    { "V", 50 },
+    { "W", 51 },
+    { "X", 52 },
+    { "Y", 53 },
+    { "Z", 54 },
+    { "COMMA", 55 },
+    { "PERIOD", 56 },
+    { "ALT_LEFT", 57 },
+    { "ALT_RIGHT", 58 },
+    { "SHIFT_LEFT", 59 },
+    { "SHIFT_RIGHT", 60 },
+    { "TAB", 61 },
+    { "SPACE", 62 },
+    { "SYM", 63 },
+    { "EXPLORER", 64 },
+    { "ENVELOPE", 65 },
+    { "ENTER", 66 },
+    { "DEL", 67 },
+    { "GRAVE", 68 },
+    { "MINUS", 69 },
+    { "EQUALS", 70 },
+    { "LEFT_BRACKET", 71 },
+    { "RIGHT_BRACKET", 72 },
+    { "BACKSLASH", 73 },
+    { "SEMICOLON", 74 },
+    { "APOSTROPHE", 75 },
+    { "SLASH", 76 },
+    { "AT", 77 },
+    { "NUM", 78 },
+    { "HEADSETHOOK", 79 },
+    { "FOCUS", 80 },
+    { "PLUS", 81 },
+    { "MENU", 82 },
+    { "NOTIFICATION", 83 },
+    { "SEARCH", 84 },
+    { "MEDIA_PLAY_PAUSE", 85 },
+    { "MEDIA_STOP", 86 },
+    { "MEDIA_NEXT", 87 },
+    { "MEDIA_PREVIOUS", 88 },
+    { "MEDIA_REWIND", 89 },
+    { "MEDIA_FAST_FORWARD", 90 },
+    { "MUTE", 91 },
+    { "PAGE_UP", 92 },
+    { "PAGE_DOWN", 93 },
+    { "PICTSYMBOLS", 94 },
+    { "SWITCH_CHARSET", 95 },
+    { "BUTTON_A", 96 },
+    { "BUTTON_B", 97 },
+    { "BUTTON_C", 98 },
+    { "BUTTON_X", 99 },
+    { "BUTTON_Y", 100 },
+    { "BUTTON_Z", 101 },
+    { "BUTTON_L1", 102 },
+    { "BUTTON_R1", 103 },
+    { "BUTTON_L2", 104 },
+    { "BUTTON_R2", 105 },
+    { "BUTTON_THUMBL", 106 },
+    { "BUTTON_THUMBR", 107 },
+    { "BUTTON_START", 108 },
+    { "BUTTON_SELECT", 109 },
+    { "BUTTON_MODE", 110 },
+    { "ESCAPE", 111 },
+    { "FORWARD_DEL", 112 },
+    { "CTRL_LEFT", 113 },
+    { "CTRL_RIGHT", 114 },
+    { "CAPS_LOCK", 115 },
+    { "SCROLL_LOCK", 116 },
+    { "META_LEFT", 117 },
+    { "META_RIGHT", 118 },
+    { "FUNCTION", 119 },
+    { "SYSRQ", 120 },
+    { "BREAK", 121 },
+    { "MOVE_HOME", 122 },
+    { "MOVE_END", 123 },
+    { "INSERT", 124 },
+    { "FORWARD", 125 },
+    { "MEDIA_PLAY", 126 },
+    { "MEDIA_PAUSE", 127 },
+    { "MEDIA_CLOSE", 128 },
+    { "MEDIA_EJECT", 129 },
+    { "MEDIA_RECORD", 130 },
+    { "F1", 131 },
+    { "F2", 132 },
+    { "F3", 133 },
+    { "F4", 134 },
+    { "F5", 135 },
+    { "F6", 136 },
+    { "F7", 137 },
+    { "F8", 138 },
+    { "F9", 139 },
+    { "F10", 140 },
+    { "F11", 141 },
+    { "F12", 142 },
+    { "NUM_LOCK", 143 },
+    { "NUMPAD_0", 144 },
+    { "NUMPAD_1", 145 },
+    { "NUMPAD_2", 146 },
+    { "NUMPAD_3", 147 },
+    { "NUMPAD_4", 148 },
+    { "NUMPAD_5", 149 },
+    { "NUMPAD_6", 150 },
+    { "NUMPAD_7", 151 },
+    { "NUMPAD_8", 152 },
+    { "NUMPAD_9", 153 },
+    { "NUMPAD_DIVIDE", 154 },
+    { "NUMPAD_MULTIPLY", 155 },
+    { "NUMPAD_SUBTRACT", 156 },
+    { "NUMPAD_ADD", 157 },
+    { "NUMPAD_DOT", 158 },
+    { "NUMPAD_COMMA", 159 },
+    { "NUMPAD_ENTER", 160 },
+    { "NUMPAD_EQUALS", 161 },
+    { "NUMPAD_LEFT_PAREN", 162 },
+    { "NUMPAD_RIGHT_PAREN", 163 },
+    { "VOLUME_MUTE", 164 },
+    { "INFO", 165 },
+    { "CHANNEL_UP", 166 },
+    { "CHANNEL_DOWN", 167 },
+    { "ZOOM_IN", 168 },
+    { "ZOOM_OUT", 169 },
+    { "TV", 170 },
+    { "WINDOW", 171 },
+    { "GUIDE", 172 },
+    { "DVR", 173 },
+    { "BOOKMARK", 174 },
+    { "CAPTIONS", 175 },
+    { "SETTINGS", 176 },
+    { "TV_POWER", 177 },
+    { "TV_INPUT", 178 },
+    { "STB_POWER", 179 },
+    { "STB_INPUT", 180 },
+    { "AVR_POWER", 181 },
+    { "AVR_INPUT", 182 },
+    { "PROG_RED", 183 },
+    { "PROG_GREEN", 184 },
+    { "PROG_YELLOW", 185 },
+    { "PROG_BLUE", 186 },
+    { "APP_SWITCH", 187 },
+    { "BUTTON_1", 188 },
+    { "BUTTON_2", 189 },
+    { "BUTTON_3", 190 },
+    { "BUTTON_4", 191 },
+    { "BUTTON_5", 192 },
+    { "BUTTON_6", 193 },
+    { "BUTTON_7", 194 },
+    { "BUTTON_8", 195 },
+    { "BUTTON_9", 196 },
+    { "BUTTON_10", 197 },
+    { "BUTTON_11", 198 },
+    { "BUTTON_12", 199 },
+    { "BUTTON_13", 200 },
+    { "BUTTON_14", 201 },
+    { "BUTTON_15", 202 },
+    { "BUTTON_16", 203 },
+    { "LANGUAGE_SWITCH", 204 },
+    { "MANNER_MODE", 205 },
+    { "3D_MODE", 206 },
+    { "CONTACTS", 207 },
+    { "CALENDAR", 208 },
+    { "MUSIC", 209 },
+    { "CALCULATOR", 210 },
+    { "ZENKAKU_HANKAKU", 211 },
+    { "EISU", 212 },
+    { "MUHENKAN", 213 },
+    { "HENKAN", 214 },
+    { "KATAKANA_HIRAGANA", 215 },
+    { "YEN", 216 },
+    { "RO", 217 },
+    { "KANA", 218 },
+    { "ASSIST", 219 },
+    { "BRIGHTNESS_DOWN", 220 },
+    { "BRIGHTNESS_UP", 221 },
+
+    // NOTE: If you add a new keycode here you must also add it to several other files.
+    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
+
+    { NULL, 0 }
+};
+
+// NOTE: If you edit these flags, also edit policy flags in Input.h.
+static const KeycodeLabel FLAGS[] = {
+    { "WAKE", 0x00000001 },
+    { "WAKE_DROPPED", 0x00000002 },
+    { "SHIFT", 0x00000004 },
+    { "CAPS_LOCK", 0x00000008 },
+    { "ALT", 0x00000010 },
+    { "ALT_GR", 0x00000020 },
+    { "MENU", 0x00000040 },
+    { "LAUNCHER", 0x00000080 },
+    { "VIRTUAL", 0x00000100 },
+    { "FUNCTION", 0x00000200 },
+    { NULL, 0 }
+};
+
+static const KeycodeLabel AXES[] = {
+    { "X", 0 },
+    { "Y", 1 },
+    { "PRESSURE", 2 },
+    { "SIZE", 3 },
+    { "TOUCH_MAJOR", 4 },
+    { "TOUCH_MINOR", 5 },
+    { "TOOL_MAJOR", 6 },
+    { "TOOL_MINOR", 7 },
+    { "ORIENTATION", 8 },
+    { "VSCROLL", 9 },
+    { "HSCROLL", 10 },
+    { "Z", 11 },
+    { "RX", 12 },
+    { "RY", 13 },
+    { "RZ", 14 },
+    { "HAT_X", 15 },
+    { "HAT_Y", 16 },
+    { "LTRIGGER", 17 },
+    { "RTRIGGER", 18 },
+    { "THROTTLE", 19 },
+    { "RUDDER", 20 },
+    { "WHEEL", 21 },
+    { "GAS", 22 },
+    { "BRAKE", 23 },
+    { "DISTANCE", 24 },
+    { "TILT", 25 },
+    { "GENERIC_1", 32 },
+    { "GENERIC_2", 33 },
+    { "GENERIC_3", 34 },
+    { "GENERIC_4", 35 },
+    { "GENERIC_5", 36 },
+    { "GENERIC_6", 37 },
+    { "GENERIC_7", 38 },
+    { "GENERIC_8", 39 },
+    { "GENERIC_9", 40 },
+    { "GENERIC_10", 41 },
+    { "GENERIC_11", 42 },
+    { "GENERIC_12", 43 },
+    { "GENERIC_13", 44 },
+    { "GENERIC_14", 45 },
+    { "GENERIC_15", 46 },
+    { "GENERIC_16", 47 },
+
+    // NOTE: If you add a new axis here you must also add it to several other files.
+    //       Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
+
+    { NULL, -1 }
+};
+
+#endif // _LIBINPUT_KEYCODE_LABELS_H
diff --git a/include/input/VelocityControl.h b/include/input/VelocityControl.h
new file mode 100644
index 0000000..1acc2ae
--- /dev/null
+++ b/include/input/VelocityControl.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBINPUT_VELOCITY_CONTROL_H
+#define _LIBINPUT_VELOCITY_CONTROL_H
+
+#include <input/Input.h>
+#include <input/VelocityTracker.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+/*
+ * Specifies parameters that govern pointer or wheel acceleration.
+ */
+struct VelocityControlParameters {
+    // A scale factor that is multiplied with the raw velocity deltas
+    // prior to applying any other velocity control factors.  The scale
+    // factor should be used to adapt the input device resolution
+    // (eg. counts per inch) to the output device resolution (eg. pixels per inch).
+    //
+    // Must be a positive value.
+    // Default is 1.0 (no scaling).
+    float scale;
+
+    // The scaled speed at which acceleration begins to be applied.
+    // This value establishes the upper bound of a low speed regime for
+    // small precise motions that are performed without any acceleration.
+    //
+    // Must be a non-negative value.
+    // Default is 0.0 (no low threshold).
+    float lowThreshold;
+
+    // The scaled speed at which maximum acceleration is applied.
+    // The difference between highThreshold and lowThreshold controls
+    // the range of speeds over which the acceleration factor is interpolated.
+    // The wider the range, the smoother the acceleration.
+    //
+    // Must be a non-negative value greater than or equal to lowThreshold.
+    // Default is 0.0 (no high threshold).
+    float highThreshold;
+
+    // The acceleration factor.
+    // When the speed is above the low speed threshold, the velocity will scaled
+    // by an interpolated value between 1.0 and this amount.
+    //
+    // Must be a positive greater than or equal to 1.0.
+    // Default is 1.0 (no acceleration).
+    float acceleration;
+
+    VelocityControlParameters() :
+            scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) {
+    }
+
+    VelocityControlParameters(float scale, float lowThreshold,
+            float highThreshold, float acceleration) :
+            scale(scale), lowThreshold(lowThreshold),
+            highThreshold(highThreshold), acceleration(acceleration) {
+    }
+};
+
+/*
+ * Implements mouse pointer and wheel speed control and acceleration.
+ */
+class VelocityControl {
+public:
+    VelocityControl();
+
+    /* Sets the various parameters. */
+    void setParameters(const VelocityControlParameters& parameters);
+
+    /* Resets the current movement counters to zero.
+     * This has the effect of nullifying any acceleration. */
+    void reset();
+
+    /* Translates a raw movement delta into an appropriately
+     * scaled / accelerated delta based on the current velocity. */
+    void move(nsecs_t eventTime, float* deltaX, float* deltaY);
+
+private:
+    // If no movements are received within this amount of time,
+    // we assume the movement has stopped and reset the movement counters.
+    static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms
+
+    VelocityControlParameters mParameters;
+
+    nsecs_t mLastMovementTime;
+    VelocityTracker::Position mRawPosition;
+    VelocityTracker mVelocityTracker;
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_VELOCITY_CONTROL_H
diff --git a/include/input/VelocityTracker.h b/include/input/VelocityTracker.h
new file mode 100644
index 0000000..795f575
--- /dev/null
+++ b/include/input/VelocityTracker.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBINPUT_VELOCITY_TRACKER_H
+#define _LIBINPUT_VELOCITY_TRACKER_H
+
+#include <input/Input.h>
+#include <utils/Timers.h>
+#include <utils/BitSet.h>
+
+namespace android {
+
+class VelocityTrackerStrategy;
+
+/*
+ * Calculates the velocity of pointer movements over time.
+ */
+class VelocityTracker {
+public:
+    struct Position {
+        float x, y;
+    };
+
+    struct Estimator {
+        static const size_t MAX_DEGREE = 4;
+
+        // Estimator time base.
+        nsecs_t time;
+
+        // Polynomial coefficients describing motion in X and Y.
+        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
+
+        // Polynomial degree (number of coefficients), or zero if no information is
+        // available.
+        uint32_t degree;
+
+        // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
+        float confidence;
+
+        inline void clear() {
+            time = 0;
+            degree = 0;
+            confidence = 0;
+            for (size_t i = 0; i <= MAX_DEGREE; i++) {
+                xCoeff[i] = 0;
+                yCoeff[i] = 0;
+            }
+        }
+    };
+
+    // Creates a velocity tracker using the specified strategy.
+    // If strategy is NULL, uses the default strategy for the platform.
+    VelocityTracker(const char* strategy = NULL);
+
+    ~VelocityTracker();
+
+    // Resets the velocity tracker state.
+    void clear();
+
+    // Resets the velocity tracker state for specific pointers.
+    // Call this method when some pointers have changed and may be reusing
+    // an id that was assigned to a different pointer earlier.
+    void clearPointers(BitSet32 idBits);
+
+    // Adds movement information for a set of pointers.
+    // The idBits bitfield specifies the pointer ids of the pointers whose positions
+    // are included in the movement.
+    // The positions array contains position information for each pointer in order by
+    // increasing id.  Its size should be equal to the number of one bits in idBits.
+    void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
+
+    // Adds movement information for all pointers in a MotionEvent, including historical samples.
+    void addMovement(const MotionEvent* event);
+
+    // Gets the velocity of the specified pointer id in position units per second.
+    // Returns false and sets the velocity components to zero if there is
+    // insufficient movement information for the pointer.
+    bool getVelocity(uint32_t id, float* outVx, float* outVy) const;
+
+    // Gets an estimator for the recent movements of the specified pointer id.
+    // Returns false and clears the estimator if there is no information available
+    // about the pointer.
+    bool getEstimator(uint32_t id, Estimator* outEstimator) const;
+
+    // Gets the active pointer id, or -1 if none.
+    inline int32_t getActivePointerId() const { return mActivePointerId; }
+
+    // Gets a bitset containing all pointer ids from the most recent movement.
+    inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
+
+private:
+    static const char* DEFAULT_STRATEGY;
+
+    nsecs_t mLastEventTime;
+    BitSet32 mCurrentPointerIdBits;
+    int32_t mActivePointerId;
+    VelocityTrackerStrategy* mStrategy;
+
+    bool configureStrategy(const char* strategy);
+
+    static VelocityTrackerStrategy* createStrategy(const char* strategy);
+};
+
+
+/*
+ * Implements a particular velocity tracker algorithm.
+ */
+class VelocityTrackerStrategy {
+protected:
+    VelocityTrackerStrategy() { }
+
+public:
+    virtual ~VelocityTrackerStrategy() { }
+
+    virtual void clear() = 0;
+    virtual void clearPointers(BitSet32 idBits) = 0;
+    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
+            const VelocityTracker::Position* positions) = 0;
+    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
+};
+
+
+/*
+ * Velocity tracker algorithm based on least-squares linear regression.
+ */
+class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
+public:
+    enum Weighting {
+        // No weights applied.  All data points are equally reliable.
+        WEIGHTING_NONE,
+
+        // Weight by time delta.  Data points clustered together are weighted less.
+        WEIGHTING_DELTA,
+
+        // Weight such that points within a certain horizon are weighed more than those
+        // outside of that horizon.
+        WEIGHTING_CENTRAL,
+
+        // Weight such that points older than a certain amount are weighed less.
+        WEIGHTING_RECENT,
+    };
+
+    // Degree must be no greater than Estimator::MAX_DEGREE.
+    LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);
+    virtual ~LeastSquaresVelocityTrackerStrategy();
+
+    virtual void clear();
+    virtual void clearPointers(BitSet32 idBits);
+    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
+            const VelocityTracker::Position* positions);
+    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
+
+private:
+    // Sample horizon.
+    // We don't use too much history by default since we want to react to quick
+    // changes in direction.
+    static const nsecs_t HORIZON = 100 * 1000000; // 100 ms
+
+    // Number of samples to keep.
+    static const uint32_t HISTORY_SIZE = 20;
+
+    struct Movement {
+        nsecs_t eventTime;
+        BitSet32 idBits;
+        VelocityTracker::Position positions[MAX_POINTERS];
+
+        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
+            return positions[idBits.getIndexOfBit(id)];
+        }
+    };
+
+    float chooseWeight(uint32_t index) const;
+
+    const uint32_t mDegree;
+    const Weighting mWeighting;
+    uint32_t mIndex;
+    Movement mMovements[HISTORY_SIZE];
+};
+
+
+/*
+ * Velocity tracker algorithm that uses an IIR filter.
+ */
+class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
+public:
+    // Degree must be 1 or 2.
+    IntegratingVelocityTrackerStrategy(uint32_t degree);
+    ~IntegratingVelocityTrackerStrategy();
+
+    virtual void clear();
+    virtual void clearPointers(BitSet32 idBits);
+    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
+            const VelocityTracker::Position* positions);
+    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
+
+private:
+    // Current state estimate for a particular pointer.
+    struct State {
+        nsecs_t updateTime;
+        uint32_t degree;
+
+        float xpos, xvel, xaccel;
+        float ypos, yvel, yaccel;
+    };
+
+    const uint32_t mDegree;
+    BitSet32 mPointerIdBits;
+    State mPointerState[MAX_POINTER_ID + 1];
+
+    void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
+    void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
+    void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
+};
+
+
+/*
+ * Velocity tracker strategy used prior to ICS.
+ */
+class LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {
+public:
+    LegacyVelocityTrackerStrategy();
+    virtual ~LegacyVelocityTrackerStrategy();
+
+    virtual void clear();
+    virtual void clearPointers(BitSet32 idBits);
+    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
+            const VelocityTracker::Position* positions);
+    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
+
+private:
+    // Oldest sample to consider when calculating the velocity.
+    static const nsecs_t HORIZON = 200 * 1000000; // 100 ms
+
+    // Number of samples to keep.
+    static const uint32_t HISTORY_SIZE = 20;
+
+    // The minimum duration between samples when estimating velocity.
+    static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
+
+    struct Movement {
+        nsecs_t eventTime;
+        BitSet32 idBits;
+        VelocityTracker::Position positions[MAX_POINTERS];
+
+        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
+            return positions[idBits.getIndexOfBit(id)];
+        }
+    };
+
+    uint32_t mIndex;
+    Movement mMovements[HISTORY_SIZE];
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_VELOCITY_TRACKER_H
diff --git a/include/input/VirtualKeyMap.h b/include/input/VirtualKeyMap.h
new file mode 100644
index 0000000..e245ead
--- /dev/null
+++ b/include/input/VirtualKeyMap.h
@@ -0,0 +1,81 @@
+/*
+ * 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 _LIBINPUT_VIRTUAL_KEY_MAP_H
+#define _LIBINPUT_VIRTUAL_KEY_MAP_H
+
+#include <stdint.h>
+
+#include <input/Input.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/Tokenizer.h>
+#include <utils/String8.h>
+#include <utils/Unicode.h>
+
+namespace android {
+
+/* Describes a virtual key. */
+struct VirtualKeyDefinition {
+    int32_t scanCode;
+
+    // configured position data, specified in display coords
+    int32_t centerX;
+    int32_t centerY;
+    int32_t width;
+    int32_t height;
+};
+
+
+/**
+ * Describes a collection of virtual keys on a touch screen in terms of
+ * virtual scan codes and hit rectangles.
+ *
+ * This object is immutable after it has been loaded.
+ */
+class VirtualKeyMap {
+public:
+    ~VirtualKeyMap();
+
+    static status_t load(const String8& filename, VirtualKeyMap** outMap);
+
+    inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {
+        return mVirtualKeys;
+    }
+
+private:
+    class Parser {
+        VirtualKeyMap* mMap;
+        Tokenizer* mTokenizer;
+
+    public:
+        Parser(VirtualKeyMap* map, Tokenizer* tokenizer);
+        ~Parser();
+        status_t parse();
+
+    private:
+        bool consumeFieldDelimiterAndSkipWhitespace();
+        bool parseNextIntField(int32_t* outValue);
+    };
+
+    Vector<VirtualKeyDefinition> mVirtualKeys;
+
+    VirtualKeyMap();
+};
+
+} // namespace android
+
+#endif // _LIBINPUT_KEY_CHARACTER_MAP_H
diff --git a/include/media/hardware/HardwareAPI.h b/include/media/hardware/HardwareAPI.h
index cc43bf6..a6a849d 100644
--- a/include/media/hardware/HardwareAPI.h
+++ b/include/media/hardware/HardwareAPI.h
@@ -18,7 +18,8 @@
 
 #define HARDWARE_API_H_
 
-#include <OMXPluginBase.h>
+#include <media/hardware/OMXPluginBase.h>
+#include <media/hardware/MetadataBufferType.h>
 #include <system/window.h>
 #include <utils/RefBase.h>
 
@@ -73,6 +74,13 @@
     OMX_BOOL bStoreMetaData;
 };
 
+// Meta data buffer layout used to transport output frames to the decoder for
+// dynamic buffer handling.
+struct VideoDecoderOutputMetaData {
+  MetadataBufferType eType;
+  buffer_handle_t pHandle;
+};
+
 // A pointer to this struct is passed to OMX_SetParameter when the extension
 // index for the 'OMX.google.android.index.useAndroidNativeBuffer' extension is
 // given.  This call will only be performed if a prior call was made with the
diff --git a/include/media/openmax/OMX_Video.h b/include/media/openmax/OMX_Video.h
index 4f8485d..4441a7a 100644
--- a/include/media/openmax/OMX_Video.h
+++ b/include/media/openmax/OMX_Video.h
@@ -85,7 +85,8 @@
     OMX_VIDEO_CodingRV,         /**< all versions of Real Video */
     OMX_VIDEO_CodingAVC,        /**< H.264/AVC */
     OMX_VIDEO_CodingMJPEG,      /**< Motion JPEG */
-    OMX_VIDEO_CodingVPX,        /**< Google VPX, formerly known as On2 VP8 */
+    OMX_VIDEO_CodingVP8,        /**< Google VP8, formerly known as On2 VP8 */
+    OMX_VIDEO_CodingVP9,        /**< Google VP9 */
     OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
     OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_CodingMax = 0x7FFFFFFF
diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h
index 5e79b47..fa24168 100644
--- a/include/media/openmax/OMX_VideoExt.h
+++ b/include/media/openmax/OMX_VideoExt.h
@@ -58,12 +58,6 @@
     OMX_NALUFORMATSTYPE eNaluFormat;
 } OMX_NALSTREAMFORMATTYPE;
 
-/** Enum for standard video codingtype extensions */
-typedef enum OMX_VIDEO_CODINGEXTTYPE {
-    OMX_VIDEO_ExtCodingUnused = OMX_VIDEO_CodingKhronosExtensions,
-    OMX_VIDEO_CodingVP8,        /**< VP8/WebM */
-} OMX_VIDEO_CODINGEXTTYPE;
-
 /** VP8 profiles */
 typedef enum OMX_VIDEO_VP8PROFILETYPE {
     OMX_VIDEO_VP8ProfileMain = 0x01,
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 28b74ba..5a38b95 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -418,6 +418,60 @@
     talkWithDriver(false);
 }
 
+status_t IPCThreadState::getAndExecuteCommand()
+{
+    status_t result;
+    int32_t cmd;
+
+    result = talkWithDriver();
+    if (result >= NO_ERROR) {
+        size_t IN = mIn.dataAvail();
+        if (IN < sizeof(int32_t)) return result;
+        cmd = mIn.readInt32();
+        IF_LOG_COMMANDS() {
+            alog << "Processing top-level Command: "
+                 << getReturnString(cmd) << endl;
+        }
+
+        result = executeCommand(cmd);
+
+        // After executing the command, ensure that the thread is returned to the
+        // foreground cgroup before rejoining the pool.  The driver takes care of
+        // restoring the priority, but doesn't do anything with cgroups so we
+        // need to take care of that here in userspace.  Note that we do make
+        // sure to go in the foreground after executing a transaction, but
+        // there are other callbacks into user code that could have changed
+        // our group so we want to make absolutely sure it is put back.
+        set_sched_policy(mMyThreadId, SP_FOREGROUND);
+    }
+
+    return result;
+}
+
+// When we've cleared the incoming command queue, process any pending derefs
+void IPCThreadState::processPendingDerefs()
+{
+    if (mIn.dataPosition() >= mIn.dataSize()) {
+        size_t numPending = mPendingWeakDerefs.size();
+        if (numPending > 0) {
+            for (size_t i = 0; i < numPending; i++) {
+                RefBase::weakref_type* refs = mPendingWeakDerefs[i];
+                refs->decWeak(mProcess.get());
+            }
+            mPendingWeakDerefs.clear();
+        }
+
+        numPending = mPendingStrongDerefs.size();
+        if (numPending > 0) {
+            for (size_t i = 0; i < numPending; i++) {
+                BBinder* obj = mPendingStrongDerefs[i];
+                obj->decStrong(mProcess.get());
+            }
+            mPendingStrongDerefs.clear();
+        }
+    }
+}
+
 void IPCThreadState::joinThreadPool(bool isMain)
 {
     LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
@@ -431,57 +485,16 @@
         
     status_t result;
     do {
-        int32_t cmd;
-        
-        // When we've cleared the incoming command queue, process any pending derefs
-        if (mIn.dataPosition() >= mIn.dataSize()) {
-            size_t numPending = mPendingWeakDerefs.size();
-            if (numPending > 0) {
-                for (size_t i = 0; i < numPending; i++) {
-                    RefBase::weakref_type* refs = mPendingWeakDerefs[i];
-                    refs->decWeak(mProcess.get());
-                }
-                mPendingWeakDerefs.clear();
-            }
-
-            numPending = mPendingStrongDerefs.size();
-            if (numPending > 0) {
-                for (size_t i = 0; i < numPending; i++) {
-                    BBinder* obj = mPendingStrongDerefs[i];
-                    obj->decStrong(mProcess.get());
-                }
-                mPendingStrongDerefs.clear();
-            }
-        }
-
+        processPendingDerefs();
         // now get the next command to be processed, waiting if necessary
-        result = talkWithDriver();
-        if (result >= NO_ERROR) {
-            size_t IN = mIn.dataAvail();
-            if (IN < sizeof(int32_t)) continue;
-            cmd = mIn.readInt32();
-            IF_LOG_COMMANDS() {
-                alog << "Processing top-level Command: "
-                    << getReturnString(cmd) << endl;
-            }
+        result = getAndExecuteCommand();
 
-
-            result = executeCommand(cmd);
-        } else if (result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
-            ALOGE("talkWithDriver(fd=%d) returned unexpected error %d, aborting",
+        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
+            ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                   mProcess->mDriverFD, result);
             abort();
         }
         
-        // After executing the command, ensure that the thread is returned to the
-        // foreground cgroup before rejoining the pool.  The driver takes care of
-        // restoring the priority, but doesn't do anything with cgroups so we
-        // need to take care of that here in userspace.  Note that we do make
-        // sure to go in the foreground after executing a transaction, but
-        // there are other callbacks into user code that could have changed
-        // our group so we want to make absolutely sure it is put back.
-        set_sched_policy(mMyThreadId, SP_FOREGROUND);
-
         // Let this thread exit the thread pool if it is no longer
         // needed and it is not the main process thread.
         if(result == TIMED_OUT && !isMain) {
@@ -496,6 +509,30 @@
     talkWithDriver(false);
 }
 
+int IPCThreadState::setupPolling(int* fd)
+{
+    if (mProcess->mDriverFD <= 0) {
+        return -EBADF;
+    }
+
+    mOut.writeInt32(BC_ENTER_LOOPER);
+    *fd = mProcess->mDriverFD;
+    return 0;
+}
+
+status_t IPCThreadState::handlePolledCommands()
+{
+    status_t result;
+
+    do {
+        result = getAndExecuteCommand();
+    } while (mIn.dataPosition() < mIn.dataSize());
+
+    processPendingDerefs();
+    flushCommands();
+    return result;
+}
+
 void IPCThreadState::stopProcess(bool immediate)
 {
     //ALOGI("**** STOPPING PROCESS");
@@ -826,7 +863,7 @@
     IF_LOG_COMMANDS() {
         alog << "Our err: " << (void*)err << ", write consumed: "
             << bwr.write_consumed << " (of " << mOut.dataSize()
-			<< "), read consumed: " << bwr.read_consumed << endl;
+                        << "), read consumed: " << bwr.read_consumed << endl;
     }
 
     if (err >= NO_ERROR) {
@@ -1104,16 +1141,16 @@
 
 void IPCThreadState::threadDestructor(void *st)
 {
-	IPCThreadState* const self = static_cast<IPCThreadState*>(st);
-	if (self) {
-		self->flushCommands();
+        IPCThreadState* const self = static_cast<IPCThreadState*>(st);
+        if (self) {
+                self->flushCommands();
 #if defined(HAVE_ANDROID_OS)
         if (self->mProcess->mDriverFD > 0) {
             ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
         }
 #endif
-		delete self;
-	}
+                delete self;
+        }
 }
 
 
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
new file mode 100644
index 0000000..2a1e762
--- /dev/null
+++ b/libs/input/Android.mk
@@ -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.
+
+ifneq ($(TARGET_BUILD_PDK),true)
+
+LOCAL_PATH:= $(call my-dir)
+
+# libinput is partially built for the host (used by build time keymap validation tool)
+# These files are common to host and target builds.
+
+commonSources := \
+    Input.cpp \
+    InputDevice.cpp \
+    Keyboard.cpp \
+    KeyCharacterMap.cpp \
+    KeyLayoutMap.cpp \
+    VirtualKeyMap.cpp
+
+deviceSources := \
+    $(commonSources) \
+    InputTransport.cpp \
+    VelocityControl.cpp \
+    VelocityTracker.cpp
+
+hostSources := \
+    $(commonSources)
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(hostSources)
+
+LOCAL_MODULE:= libinput
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# For the device
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(deviceSources)
+
+LOCAL_SHARED_LIBRARIES := \
+	liblog \
+	libcutils \
+	libutils \
+	libbinder \
+	libskia \
+	libz
+
+LOCAL_C_INCLUDES := \
+    external/skia/include/core \
+    external/icu4c/common \
+	external/zlib
+
+LOCAL_MODULE:= libinput
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
+
+endif #!PDK
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
new file mode 100644
index 0000000..7a217c3
--- /dev/null
+++ b/libs/input/Input.cpp
@@ -0,0 +1,634 @@
+/*
+ * 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 "Input"
+//#define LOG_NDEBUG 0
+
+#include <math.h>
+#include <limits.h>
+
+#include <input/Input.h>
+
+#ifdef HAVE_ANDROID_OS
+#include <binder/Parcel.h>
+
+#include "SkPoint.h"
+#include "SkMatrix.h"
+#include "SkScalar.h"
+#endif
+
+namespace android {
+
+// --- InputEvent ---
+
+void InputEvent::initialize(int32_t deviceId, int32_t source) {
+    mDeviceId = deviceId;
+    mSource = source;
+}
+
+void InputEvent::initialize(const InputEvent& from) {
+    mDeviceId = from.mDeviceId;
+    mSource = from.mSource;
+}
+
+// --- KeyEvent ---
+
+bool KeyEvent::hasDefaultAction(int32_t keyCode) {
+    switch (keyCode) {
+        case AKEYCODE_HOME:
+        case AKEYCODE_BACK:
+        case AKEYCODE_CALL:
+        case AKEYCODE_ENDCALL:
+        case AKEYCODE_VOLUME_UP:
+        case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_VOLUME_MUTE:
+        case AKEYCODE_POWER:
+        case AKEYCODE_CAMERA:
+        case AKEYCODE_HEADSETHOOK:
+        case AKEYCODE_MENU:
+        case AKEYCODE_NOTIFICATION:
+        case AKEYCODE_FOCUS:
+        case AKEYCODE_SEARCH:
+        case AKEYCODE_MEDIA_PLAY:
+        case AKEYCODE_MEDIA_PAUSE:
+        case AKEYCODE_MEDIA_PLAY_PAUSE:
+        case AKEYCODE_MEDIA_STOP:
+        case AKEYCODE_MEDIA_NEXT:
+        case AKEYCODE_MEDIA_PREVIOUS:
+        case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_RECORD:
+        case AKEYCODE_MEDIA_FAST_FORWARD:
+        case AKEYCODE_MUTE:
+        case AKEYCODE_BRIGHTNESS_DOWN:
+        case AKEYCODE_BRIGHTNESS_UP:
+            return true;
+    }
+    
+    return false;
+}
+
+bool KeyEvent::hasDefaultAction() const {
+    return hasDefaultAction(getKeyCode());
+}
+
+bool KeyEvent::isSystemKey(int32_t keyCode) {
+    switch (keyCode) {
+        case AKEYCODE_MENU:
+        case AKEYCODE_SOFT_RIGHT:
+        case AKEYCODE_HOME:
+        case AKEYCODE_BACK:
+        case AKEYCODE_CALL:
+        case AKEYCODE_ENDCALL:
+        case AKEYCODE_VOLUME_UP:
+        case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_VOLUME_MUTE:
+        case AKEYCODE_MUTE:
+        case AKEYCODE_POWER:
+        case AKEYCODE_HEADSETHOOK:
+        case AKEYCODE_MEDIA_PLAY:
+        case AKEYCODE_MEDIA_PAUSE:
+        case AKEYCODE_MEDIA_PLAY_PAUSE:
+        case AKEYCODE_MEDIA_STOP:
+        case AKEYCODE_MEDIA_NEXT:
+        case AKEYCODE_MEDIA_PREVIOUS:
+        case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_RECORD:
+        case AKEYCODE_MEDIA_FAST_FORWARD:
+        case AKEYCODE_CAMERA:
+        case AKEYCODE_FOCUS:
+        case AKEYCODE_SEARCH:
+        case AKEYCODE_BRIGHTNESS_DOWN:
+        case AKEYCODE_BRIGHTNESS_UP:
+            return true;
+    }
+    
+    return false;
+}
+
+bool KeyEvent::isSystemKey() const {
+    return isSystemKey(getKeyCode());
+}
+
+void KeyEvent::initialize(
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t keyCode,
+        int32_t scanCode,
+        int32_t metaState,
+        int32_t repeatCount,
+        nsecs_t downTime,
+        nsecs_t eventTime) {
+    InputEvent::initialize(deviceId, source);
+    mAction = action;
+    mFlags = flags;
+    mKeyCode = keyCode;
+    mScanCode = scanCode;
+    mMetaState = metaState;
+    mRepeatCount = repeatCount;
+    mDownTime = downTime;
+    mEventTime = eventTime;
+}
+
+void KeyEvent::initialize(const KeyEvent& from) {
+    InputEvent::initialize(from);
+    mAction = from.mAction;
+    mFlags = from.mFlags;
+    mKeyCode = from.mKeyCode;
+    mScanCode = from.mScanCode;
+    mMetaState = from.mMetaState;
+    mRepeatCount = from.mRepeatCount;
+    mDownTime = from.mDownTime;
+    mEventTime = from.mEventTime;
+}
+
+
+// --- PointerCoords ---
+
+float PointerCoords::getAxisValue(int32_t axis) const {
+    if (axis < 0 || axis > 63) {
+        return 0;
+    }
+
+    uint64_t axisBit = 1LL << axis;
+    if (!(bits & axisBit)) {
+        return 0;
+    }
+    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+    return values[index];
+}
+
+status_t PointerCoords::setAxisValue(int32_t axis, float value) {
+    if (axis < 0 || axis > 63) {
+        return NAME_NOT_FOUND;
+    }
+
+    uint64_t axisBit = 1LL << axis;
+    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+    if (!(bits & axisBit)) {
+        if (value == 0) {
+            return OK; // axes with value 0 do not need to be stored
+        }
+        uint32_t count = __builtin_popcountll(bits);
+        if (count >= MAX_AXES) {
+            tooManyAxes(axis);
+            return NO_MEMORY;
+        }
+        bits |= axisBit;
+        for (uint32_t i = count; i > index; i--) {
+            values[i] = values[i - 1];
+        }
+    }
+    values[index] = value;
+    return OK;
+}
+
+static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
+    float value = c.getAxisValue(axis);
+    if (value != 0) {
+        c.setAxisValue(axis, value * scaleFactor);
+    }
+}
+
+void PointerCoords::scale(float scaleFactor) {
+    // No need to scale pressure or size since they are normalized.
+    // No need to scale orientation since it is meaningless to do so.
+    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
+    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
+    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
+    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
+    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
+    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
+}
+
+#ifdef HAVE_ANDROID_OS
+status_t PointerCoords::readFromParcel(Parcel* parcel) {
+    bits = parcel->readInt64();
+
+    uint32_t count = __builtin_popcountll(bits);
+    if (count > MAX_AXES) {
+        return BAD_VALUE;
+    }
+
+    for (uint32_t i = 0; i < count; i++) {
+        values[i] = parcel->readFloat();
+    }
+    return OK;
+}
+
+status_t PointerCoords::writeToParcel(Parcel* parcel) const {
+    parcel->writeInt64(bits);
+
+    uint32_t count = __builtin_popcountll(bits);
+    for (uint32_t i = 0; i < count; i++) {
+        parcel->writeFloat(values[i]);
+    }
+    return OK;
+}
+#endif
+
+void PointerCoords::tooManyAxes(int axis) {
+    ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
+            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
+}
+
+bool PointerCoords::operator==(const PointerCoords& other) const {
+    if (bits != other.bits) {
+        return false;
+    }
+    uint32_t count = __builtin_popcountll(bits);
+    for (uint32_t i = 0; i < count; i++) {
+        if (values[i] != other.values[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void PointerCoords::copyFrom(const PointerCoords& other) {
+    bits = other.bits;
+    uint32_t count = __builtin_popcountll(bits);
+    for (uint32_t i = 0; i < count; i++) {
+        values[i] = other.values[i];
+    }
+}
+
+
+// --- PointerProperties ---
+
+bool PointerProperties::operator==(const PointerProperties& other) const {
+    return id == other.id
+            && toolType == other.toolType;
+}
+
+void PointerProperties::copyFrom(const PointerProperties& other) {
+    id = other.id;
+    toolType = other.toolType;
+}
+
+
+// --- MotionEvent ---
+
+void MotionEvent::initialize(
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t edgeFlags,
+        int32_t metaState,
+        int32_t buttonState,
+        float xOffset,
+        float yOffset,
+        float xPrecision,
+        float yPrecision,
+        nsecs_t downTime,
+        nsecs_t eventTime,
+        size_t pointerCount,
+        const PointerProperties* pointerProperties,
+        const PointerCoords* pointerCoords) {
+    InputEvent::initialize(deviceId, source);
+    mAction = action;
+    mFlags = flags;
+    mEdgeFlags = edgeFlags;
+    mMetaState = metaState;
+    mButtonState = buttonState;
+    mXOffset = xOffset;
+    mYOffset = yOffset;
+    mXPrecision = xPrecision;
+    mYPrecision = yPrecision;
+    mDownTime = downTime;
+    mPointerProperties.clear();
+    mPointerProperties.appendArray(pointerProperties, pointerCount);
+    mSampleEventTimes.clear();
+    mSamplePointerCoords.clear();
+    addSample(eventTime, pointerCoords);
+}
+
+void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
+    InputEvent::initialize(other->mDeviceId, other->mSource);
+    mAction = other->mAction;
+    mFlags = other->mFlags;
+    mEdgeFlags = other->mEdgeFlags;
+    mMetaState = other->mMetaState;
+    mButtonState = other->mButtonState;
+    mXOffset = other->mXOffset;
+    mYOffset = other->mYOffset;
+    mXPrecision = other->mXPrecision;
+    mYPrecision = other->mYPrecision;
+    mDownTime = other->mDownTime;
+    mPointerProperties = other->mPointerProperties;
+
+    if (keepHistory) {
+        mSampleEventTimes = other->mSampleEventTimes;
+        mSamplePointerCoords = other->mSamplePointerCoords;
+    } else {
+        mSampleEventTimes.clear();
+        mSampleEventTimes.push(other->getEventTime());
+        mSamplePointerCoords.clear();
+        size_t pointerCount = other->getPointerCount();
+        size_t historySize = other->getHistorySize();
+        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
+                + (historySize * pointerCount), pointerCount);
+    }
+}
+
+void MotionEvent::addSample(
+        int64_t eventTime,
+        const PointerCoords* pointerCoords) {
+    mSampleEventTimes.push(eventTime);
+    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
+}
+
+const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
+    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+}
+
+float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
+    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
+}
+
+float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
+    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
+    switch (axis) {
+    case AMOTION_EVENT_AXIS_X:
+        return value + mXOffset;
+    case AMOTION_EVENT_AXIS_Y:
+        return value + mYOffset;
+    }
+    return value;
+}
+
+const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
+        size_t pointerIndex, size_t historicalIndex) const {
+    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+}
+
+float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
+        size_t historicalIndex) const {
+    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
+}
+
+float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
+        size_t historicalIndex) const {
+    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
+    switch (axis) {
+    case AMOTION_EVENT_AXIS_X:
+        return value + mXOffset;
+    case AMOTION_EVENT_AXIS_Y:
+        return value + mYOffset;
+    }
+    return value;
+}
+
+ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
+    size_t pointerCount = mPointerProperties.size();
+    for (size_t i = 0; i < pointerCount; i++) {
+        if (mPointerProperties.itemAt(i).id == pointerId) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+void MotionEvent::offsetLocation(float xOffset, float yOffset) {
+    mXOffset += xOffset;
+    mYOffset += yOffset;
+}
+
+void MotionEvent::scale(float scaleFactor) {
+    mXOffset *= scaleFactor;
+    mYOffset *= scaleFactor;
+    mXPrecision *= scaleFactor;
+    mYPrecision *= scaleFactor;
+
+    size_t numSamples = mSamplePointerCoords.size();
+    for (size_t i = 0; i < numSamples; i++) {
+        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
+    }
+}
+
+#ifdef HAVE_ANDROID_OS
+static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
+    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
+    // Coordinate system: down is increasing Y, right is increasing X.
+    SkPoint vector;
+    vector.fX = SkFloatToScalar(sinf(angleRadians));
+    vector.fY = SkFloatToScalar(-cosf(angleRadians));
+    matrix->mapVectors(& vector, 1);
+
+    // Derive the transformed vector's clockwise angle from vertical.
+    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
+    if (result < - M_PI_2) {
+        result += M_PI;
+    } else if (result > M_PI_2) {
+        result -= M_PI;
+    }
+    return result;
+}
+
+void MotionEvent::transform(const SkMatrix* matrix) {
+    float oldXOffset = mXOffset;
+    float oldYOffset = mYOffset;
+
+    // The tricky part of this implementation is to preserve the value of
+    // rawX and rawY.  So we apply the transformation to the first point
+    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
+    SkPoint point;
+    float rawX = getRawX(0);
+    float rawY = getRawY(0);
+    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
+            & point);
+    float newX = SkScalarToFloat(point.fX);
+    float newY = SkScalarToFloat(point.fY);
+    float newXOffset = newX - rawX;
+    float newYOffset = newY - rawY;
+
+    mXOffset = newXOffset;
+    mYOffset = newYOffset;
+
+    // Apply the transformation to all samples.
+    size_t numSamples = mSamplePointerCoords.size();
+    for (size_t i = 0; i < numSamples; i++) {
+        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
+        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
+        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
+        matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
+        c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
+        c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
+
+        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
+        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
+    }
+}
+
+status_t MotionEvent::readFromParcel(Parcel* parcel) {
+    size_t pointerCount = parcel->readInt32();
+    size_t sampleCount = parcel->readInt32();
+    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
+        return BAD_VALUE;
+    }
+
+    mDeviceId = parcel->readInt32();
+    mSource = parcel->readInt32();
+    mAction = parcel->readInt32();
+    mFlags = parcel->readInt32();
+    mEdgeFlags = parcel->readInt32();
+    mMetaState = parcel->readInt32();
+    mButtonState = parcel->readInt32();
+    mXOffset = parcel->readFloat();
+    mYOffset = parcel->readFloat();
+    mXPrecision = parcel->readFloat();
+    mYPrecision = parcel->readFloat();
+    mDownTime = parcel->readInt64();
+
+    mPointerProperties.clear();
+    mPointerProperties.setCapacity(pointerCount);
+    mSampleEventTimes.clear();
+    mSampleEventTimes.setCapacity(sampleCount);
+    mSamplePointerCoords.clear();
+    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        mPointerProperties.push();
+        PointerProperties& properties = mPointerProperties.editTop();
+        properties.id = parcel->readInt32();
+        properties.toolType = parcel->readInt32();
+    }
+
+    while (sampleCount-- > 0) {
+        mSampleEventTimes.push(parcel->readInt64());
+        for (size_t i = 0; i < pointerCount; i++) {
+            mSamplePointerCoords.push();
+            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
+            if (status) {
+                return status;
+            }
+        }
+    }
+    return OK;
+}
+
+status_t MotionEvent::writeToParcel(Parcel* parcel) const {
+    size_t pointerCount = mPointerProperties.size();
+    size_t sampleCount = mSampleEventTimes.size();
+
+    parcel->writeInt32(pointerCount);
+    parcel->writeInt32(sampleCount);
+
+    parcel->writeInt32(mDeviceId);
+    parcel->writeInt32(mSource);
+    parcel->writeInt32(mAction);
+    parcel->writeInt32(mFlags);
+    parcel->writeInt32(mEdgeFlags);
+    parcel->writeInt32(mMetaState);
+    parcel->writeInt32(mButtonState);
+    parcel->writeFloat(mXOffset);
+    parcel->writeFloat(mYOffset);
+    parcel->writeFloat(mXPrecision);
+    parcel->writeFloat(mYPrecision);
+    parcel->writeInt64(mDownTime);
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        const PointerProperties& properties = mPointerProperties.itemAt(i);
+        parcel->writeInt32(properties.id);
+        parcel->writeInt32(properties.toolType);
+    }
+
+    const PointerCoords* pc = mSamplePointerCoords.array();
+    for (size_t h = 0; h < sampleCount; h++) {
+        parcel->writeInt64(mSampleEventTimes.itemAt(h));
+        for (size_t i = 0; i < pointerCount; i++) {
+            status_t status = (pc++)->writeToParcel(parcel);
+            if (status) {
+                return status;
+            }
+        }
+    }
+    return OK;
+}
+#endif
+
+bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
+    if (source & AINPUT_SOURCE_CLASS_POINTER) {
+        // Specifically excludes HOVER_MOVE and SCROLL.
+        switch (action & AMOTION_EVENT_ACTION_MASK) {
+        case AMOTION_EVENT_ACTION_DOWN:
+        case AMOTION_EVENT_ACTION_MOVE:
+        case AMOTION_EVENT_ACTION_UP:
+        case AMOTION_EVENT_ACTION_POINTER_DOWN:
+        case AMOTION_EVENT_ACTION_POINTER_UP:
+        case AMOTION_EVENT_ACTION_CANCEL:
+        case AMOTION_EVENT_ACTION_OUTSIDE:
+            return true;
+        }
+    }
+    return false;
+}
+
+
+// --- PooledInputEventFactory ---
+
+PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
+        mMaxPoolSize(maxPoolSize) {
+}
+
+PooledInputEventFactory::~PooledInputEventFactory() {
+    for (size_t i = 0; i < mKeyEventPool.size(); i++) {
+        delete mKeyEventPool.itemAt(i);
+    }
+    for (size_t i = 0; i < mMotionEventPool.size(); i++) {
+        delete mMotionEventPool.itemAt(i);
+    }
+}
+
+KeyEvent* PooledInputEventFactory::createKeyEvent() {
+    if (!mKeyEventPool.isEmpty()) {
+        KeyEvent* event = mKeyEventPool.top();
+        mKeyEventPool.pop();
+        return event;
+    }
+    return new KeyEvent();
+}
+
+MotionEvent* PooledInputEventFactory::createMotionEvent() {
+    if (!mMotionEventPool.isEmpty()) {
+        MotionEvent* event = mMotionEventPool.top();
+        mMotionEventPool.pop();
+        return event;
+    }
+    return new MotionEvent();
+}
+
+void PooledInputEventFactory::recycle(InputEvent* event) {
+    switch (event->getType()) {
+    case AINPUT_EVENT_TYPE_KEY:
+        if (mKeyEventPool.size() < mMaxPoolSize) {
+            mKeyEventPool.push(static_cast<KeyEvent*>(event));
+            return;
+        }
+        break;
+    case AINPUT_EVENT_TYPE_MOTION:
+        if (mMotionEventPool.size() < mMaxPoolSize) {
+            mMotionEventPool.push(static_cast<MotionEvent*>(event));
+            return;
+        }
+        break;
+    }
+    delete event;
+}
+
+} // namespace android
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
new file mode 100644
index 0000000..77fa49d
--- /dev/null
+++ b/libs/input/InputDevice.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputDevice"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <input/InputDevice.h>
+
+namespace android {
+
+static const char* CONFIGURATION_FILE_DIR[] = {
+        "idc/",
+        "keylayout/",
+        "keychars/",
+};
+
+static const char* CONFIGURATION_FILE_EXTENSION[] = {
+        ".idc",
+        ".kl",
+        ".kcm",
+};
+
+static bool isValidNameChar(char ch) {
+    return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
+}
+
+static void appendInputDeviceConfigurationFileRelativePath(String8& path,
+        const String8& name, InputDeviceConfigurationFileType type) {
+    path.append(CONFIGURATION_FILE_DIR[type]);
+    for (size_t i = 0; i < name.length(); i++) {
+        char ch = name[i];
+        if (!isValidNameChar(ch)) {
+            ch = '_';
+        }
+        path.append(&ch, 1);
+    }
+    path.append(CONFIGURATION_FILE_EXTENSION[type]);
+}
+
+String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
+        const InputDeviceIdentifier& deviceIdentifier,
+        InputDeviceConfigurationFileType type) {
+    if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
+        if (deviceIdentifier.version != 0) {
+            // Try vendor product version.
+            String8 versionPath(getInputDeviceConfigurationFilePathByName(
+                    String8::format("Vendor_%04x_Product_%04x_Version_%04x",
+                            deviceIdentifier.vendor, deviceIdentifier.product,
+                            deviceIdentifier.version),
+                    type));
+            if (!versionPath.isEmpty()) {
+                return versionPath;
+            }
+        }
+
+        // Try vendor product.
+        String8 productPath(getInputDeviceConfigurationFilePathByName(
+                String8::format("Vendor_%04x_Product_%04x",
+                        deviceIdentifier.vendor, deviceIdentifier.product),
+                type));
+        if (!productPath.isEmpty()) {
+            return productPath;
+        }
+    }
+
+    // Try device name.
+    return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
+}
+
+String8 getInputDeviceConfigurationFilePathByName(
+        const String8& name, InputDeviceConfigurationFileType type) {
+    // Search system repository.
+    String8 path;
+    path.setTo(getenv("ANDROID_ROOT"));
+    path.append("/usr/");
+    appendInputDeviceConfigurationFileRelativePath(path, name, type);
+#if DEBUG_PROBE
+    ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
+#endif
+    if (!access(path.string(), R_OK)) {
+#if DEBUG_PROBE
+        ALOGD("Found");
+#endif
+        return path;
+    }
+
+    // Search user repository.
+    // TODO Should only look here if not in safe mode.
+    path.setTo(getenv("ANDROID_DATA"));
+    path.append("/system/devices/");
+    appendInputDeviceConfigurationFileRelativePath(path, name, type);
+#if DEBUG_PROBE
+    ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
+#endif
+    if (!access(path.string(), R_OK)) {
+#if DEBUG_PROBE
+        ALOGD("Found");
+#endif
+        return path;
+    }
+
+    // Not found.
+#if DEBUG_PROBE
+    ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
+            name.string(), type);
+#endif
+    return String8();
+}
+
+
+// --- InputDeviceInfo ---
+
+InputDeviceInfo::InputDeviceInfo() {
+    initialize(-1, -1, InputDeviceIdentifier(), String8(), false);
+}
+
+InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
+        mId(other.mId), mGeneration(other.mGeneration), mIdentifier(other.mIdentifier),
+        mAlias(other.mAlias), mIsExternal(other.mIsExternal), mSources(other.mSources),
+        mKeyboardType(other.mKeyboardType),
+        mKeyCharacterMap(other.mKeyCharacterMap),
+        mHasVibrator(other.mHasVibrator),
+        mMotionRanges(other.mMotionRanges) {
+}
+
+InputDeviceInfo::~InputDeviceInfo() {
+}
+
+void InputDeviceInfo::initialize(int32_t id, int32_t generation,
+        const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal) {
+    mId = id;
+    mGeneration = generation;
+    mIdentifier = identifier;
+    mAlias = alias;
+    mIsExternal = isExternal;
+    mSources = 0;
+    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
+    mHasVibrator = false;
+    mMotionRanges.clear();
+}
+
+const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
+        int32_t axis, uint32_t source) const {
+    size_t numRanges = mMotionRanges.size();
+    for (size_t i = 0; i < numRanges; i++) {
+        const MotionRange& range = mMotionRanges.itemAt(i);
+        if (range.axis == axis && range.source == source) {
+            return &range;
+        }
+    }
+    return NULL;
+}
+
+void InputDeviceInfo::addSource(uint32_t source) {
+    mSources |= source;
+}
+
+void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
+        float flat, float fuzz, float resolution) {
+    MotionRange range = { axis, source, min, max, flat, fuzz, resolution };
+    mMotionRanges.add(range);
+}
+
+void InputDeviceInfo::addMotionRange(const MotionRange& range) {
+    mMotionRanges.add(range);
+}
+
+} // namespace android
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
new file mode 100644
index 0000000..d6507f4
--- /dev/null
+++ b/libs/input/InputTransport.cpp
@@ -0,0 +1,958 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// Provides a shared memory transport for input events.
+//
+#define LOG_TAG "InputTransport"
+
+//#define LOG_NDEBUG 0
+
+// Log debug messages about channel messages (send message, receive message)
+#define DEBUG_CHANNEL_MESSAGES 0
+
+// Log debug messages whenever InputChannel objects are created/destroyed
+#define DEBUG_CHANNEL_LIFECYCLE 0
+
+// Log debug messages about transport actions
+#define DEBUG_TRANSPORT_ACTIONS 0
+
+// Log debug messages about touch event resampling
+#define DEBUG_RESAMPLING 0
+
+
+#include <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <input/InputTransport.h>
+
+
+namespace android {
+
+// Socket buffer size.  The default is typically about 128KB, which is much larger than
+// we really need.  So we make it smaller.  It just needs to be big enough to hold
+// a few dozen large multi-finger motion events in the case where an application gets
+// behind processing touches.
+static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
+
+// Nanoseconds per milliseconds.
+static const nsecs_t NANOS_PER_MS = 1000000;
+
+// Latency added during resampling.  A few milliseconds doesn't hurt much but
+// reduces the impact of mispredicted touch positions.
+static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
+
+// Minimum time difference between consecutive samples before attempting to resample.
+static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
+
+// Maximum time to predict forward from the last known state, to avoid predicting too
+// far into the future.  This time is further bounded by 50% of the last time delta.
+static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
+
+template<typename T>
+inline static T min(const T& a, const T& b) {
+    return a < b ? a : b;
+}
+
+inline static float lerp(float a, float b, float alpha) {
+    return a + alpha * (b - a);
+}
+
+// --- InputMessage ---
+
+bool InputMessage::isValid(size_t actualSize) const {
+    if (size() == actualSize) {
+        switch (header.type) {
+        case TYPE_KEY:
+            return true;
+        case TYPE_MOTION:
+            return body.motion.pointerCount > 0
+                    && body.motion.pointerCount <= MAX_POINTERS;
+        case TYPE_FINISHED:
+            return true;
+        }
+    }
+    return false;
+}
+
+size_t InputMessage::size() const {
+    switch (header.type) {
+    case TYPE_KEY:
+        return sizeof(Header) + body.key.size();
+    case TYPE_MOTION:
+        return sizeof(Header) + body.motion.size();
+    case TYPE_FINISHED:
+        return sizeof(Header) + body.finished.size();
+    }
+    return sizeof(Header);
+}
+
+
+// --- InputChannel ---
+
+InputChannel::InputChannel(const String8& name, int fd) :
+        mName(name), mFd(fd) {
+#if DEBUG_CHANNEL_LIFECYCLE
+    ALOGD("Input channel constructed: name='%s', fd=%d",
+            mName.string(), fd);
+#endif
+
+    int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
+            "non-blocking.  errno=%d", mName.string(), errno);
+}
+
+InputChannel::~InputChannel() {
+#if DEBUG_CHANNEL_LIFECYCLE
+    ALOGD("Input channel destroyed: name='%s', fd=%d",
+            mName.string(), mFd);
+#endif
+
+    ::close(mFd);
+}
+
+status_t InputChannel::openInputChannelPair(const String8& name,
+        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
+    int sockets[2];
+    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
+        status_t result = -errno;
+        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d",
+                name.string(), errno);
+        outServerChannel.clear();
+        outClientChannel.clear();
+        return result;
+    }
+
+    int bufferSize = SOCKET_BUFFER_SIZE;
+    setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
+    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
+    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
+    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
+
+    String8 serverChannelName = name;
+    serverChannelName.append(" (server)");
+    outServerChannel = new InputChannel(serverChannelName, sockets[0]);
+
+    String8 clientChannelName = name;
+    clientChannelName.append(" (client)");
+    outClientChannel = new InputChannel(clientChannelName, sockets[1]);
+    return OK;
+}
+
+status_t InputChannel::sendMessage(const InputMessage* msg) {
+    size_t msgLength = msg->size();
+    ssize_t nWrite;
+    do {
+        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
+    } while (nWrite == -1 && errno == EINTR);
+
+    if (nWrite < 0) {
+        int error = errno;
+#if DEBUG_CHANNEL_MESSAGES
+        ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
+                msg->header.type, error);
+#endif
+        if (error == EAGAIN || error == EWOULDBLOCK) {
+            return WOULD_BLOCK;
+        }
+        if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) {
+            return DEAD_OBJECT;
+        }
+        return -error;
+    }
+
+    if (size_t(nWrite) != msgLength) {
+#if DEBUG_CHANNEL_MESSAGES
+        ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
+                mName.string(), msg->header.type);
+#endif
+        return DEAD_OBJECT;
+    }
+
+#if DEBUG_CHANNEL_MESSAGES
+    ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
+#endif
+    return OK;
+}
+
+status_t InputChannel::receiveMessage(InputMessage* msg) {
+    ssize_t nRead;
+    do {
+        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
+    } while (nRead == -1 && errno == EINTR);
+
+    if (nRead < 0) {
+        int error = errno;
+#if DEBUG_CHANNEL_MESSAGES
+        ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
+#endif
+        if (error == EAGAIN || error == EWOULDBLOCK) {
+            return WOULD_BLOCK;
+        }
+        if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
+            return DEAD_OBJECT;
+        }
+        return -error;
+    }
+
+    if (nRead == 0) { // check for EOF
+#if DEBUG_CHANNEL_MESSAGES
+        ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
+#endif
+        return DEAD_OBJECT;
+    }
+
+    if (!msg->isValid(nRead)) {
+#if DEBUG_CHANNEL_MESSAGES
+        ALOGD("channel '%s' ~ received invalid message", mName.string());
+#endif
+        return BAD_VALUE;
+    }
+
+#if DEBUG_CHANNEL_MESSAGES
+    ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
+#endif
+    return OK;
+}
+
+sp<InputChannel> InputChannel::dup() const {
+    int fd = ::dup(getFd());
+    return fd >= 0 ? new InputChannel(getName(), fd) : NULL;
+}
+
+
+// --- InputPublisher ---
+
+InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
+        mChannel(channel) {
+}
+
+InputPublisher::~InputPublisher() {
+}
+
+status_t InputPublisher::publishKeyEvent(
+        uint32_t seq,
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t keyCode,
+        int32_t scanCode,
+        int32_t metaState,
+        int32_t repeatCount,
+        nsecs_t downTime,
+        nsecs_t eventTime) {
+#if DEBUG_TRANSPORT_ACTIONS
+    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
+            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
+            "downTime=%lld, eventTime=%lld",
+            mChannel->getName().string(), seq,
+            deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
+            downTime, eventTime);
+#endif
+
+    if (!seq) {
+        ALOGE("Attempted to publish a key event with sequence number 0.");
+        return BAD_VALUE;
+    }
+
+    InputMessage msg;
+    msg.header.type = InputMessage::TYPE_KEY;
+    msg.body.key.seq = seq;
+    msg.body.key.deviceId = deviceId;
+    msg.body.key.source = source;
+    msg.body.key.action = action;
+    msg.body.key.flags = flags;
+    msg.body.key.keyCode = keyCode;
+    msg.body.key.scanCode = scanCode;
+    msg.body.key.metaState = metaState;
+    msg.body.key.repeatCount = repeatCount;
+    msg.body.key.downTime = downTime;
+    msg.body.key.eventTime = eventTime;
+    return mChannel->sendMessage(&msg);
+}
+
+status_t InputPublisher::publishMotionEvent(
+        uint32_t seq,
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t edgeFlags,
+        int32_t metaState,
+        int32_t buttonState,
+        float xOffset,
+        float yOffset,
+        float xPrecision,
+        float yPrecision,
+        nsecs_t downTime,
+        nsecs_t eventTime,
+        size_t pointerCount,
+        const PointerProperties* pointerProperties,
+        const PointerCoords* pointerCoords) {
+#if DEBUG_TRANSPORT_ACTIONS
+    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
+            "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
+            "xOffset=%f, yOffset=%f, "
+            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
+            "pointerCount=%d",
+            mChannel->getName().string(), seq,
+            deviceId, source, action, flags, edgeFlags, metaState, buttonState,
+            xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
+#endif
+
+    if (!seq) {
+        ALOGE("Attempted to publish a motion event with sequence number 0.");
+        return BAD_VALUE;
+    }
+
+    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
+        ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
+                mChannel->getName().string(), pointerCount);
+        return BAD_VALUE;
+    }
+
+    InputMessage msg;
+    msg.header.type = InputMessage::TYPE_MOTION;
+    msg.body.motion.seq = seq;
+    msg.body.motion.deviceId = deviceId;
+    msg.body.motion.source = source;
+    msg.body.motion.action = action;
+    msg.body.motion.flags = flags;
+    msg.body.motion.edgeFlags = edgeFlags;
+    msg.body.motion.metaState = metaState;
+    msg.body.motion.buttonState = buttonState;
+    msg.body.motion.xOffset = xOffset;
+    msg.body.motion.yOffset = yOffset;
+    msg.body.motion.xPrecision = xPrecision;
+    msg.body.motion.yPrecision = yPrecision;
+    msg.body.motion.downTime = downTime;
+    msg.body.motion.eventTime = eventTime;
+    msg.body.motion.pointerCount = pointerCount;
+    for (size_t i = 0; i < pointerCount; i++) {
+        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
+        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
+    }
+    return mChannel->sendMessage(&msg);
+}
+
+status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
+#if DEBUG_TRANSPORT_ACTIONS
+    ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
+            mChannel->getName().string());
+#endif
+
+    InputMessage msg;
+    status_t result = mChannel->receiveMessage(&msg);
+    if (result) {
+        *outSeq = 0;
+        *outHandled = false;
+        return result;
+    }
+    if (msg.header.type != InputMessage::TYPE_FINISHED) {
+        ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
+                mChannel->getName().string(), msg.header.type);
+        return UNKNOWN_ERROR;
+    }
+    *outSeq = msg.body.finished.seq;
+    *outHandled = msg.body.finished.handled;
+    return OK;
+}
+
+// --- InputConsumer ---
+
+InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
+        mResampleTouch(isTouchResamplingEnabled()),
+        mChannel(channel), mMsgDeferred(false) {
+}
+
+InputConsumer::~InputConsumer() {
+}
+
+bool InputConsumer::isTouchResamplingEnabled() {
+    char value[PROPERTY_VALUE_MAX];
+    int length = property_get("debug.inputconsumer.resample", value, NULL);
+    if (length > 0) {
+        if (!strcmp("0", value)) {
+            return false;
+        }
+        if (strcmp("1", value)) {
+            ALOGD("Unrecognized property value for 'debug.inputconsumer.resample'.  "
+                    "Use '1' or '0'.");
+        }
+    }
+    return true;
+}
+
+status_t InputConsumer::consume(InputEventFactoryInterface* factory,
+        bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
+#if DEBUG_TRANSPORT_ACTIONS
+    ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld",
+            mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime);
+#endif
+
+    *outSeq = 0;
+    *outEvent = NULL;
+
+    // Fetch the next input message.
+    // Loop until an event can be returned or no additional events are received.
+    while (!*outEvent) {
+        if (mMsgDeferred) {
+            // mMsg contains a valid input message from the previous call to consume
+            // that has not yet been processed.
+            mMsgDeferred = false;
+        } else {
+            // Receive a fresh message.
+            status_t result = mChannel->receiveMessage(&mMsg);
+            if (result) {
+                // Consume the next batched event unless batches are being held for later.
+                if (consumeBatches || result != WOULD_BLOCK) {
+                    result = consumeBatch(factory, frameTime, outSeq, outEvent);
+                    if (*outEvent) {
+#if DEBUG_TRANSPORT_ACTIONS
+                        ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
+                                mChannel->getName().string(), *outSeq);
+#endif
+                        break;
+                    }
+                }
+                return result;
+            }
+        }
+
+        switch (mMsg.header.type) {
+        case InputMessage::TYPE_KEY: {
+            KeyEvent* keyEvent = factory->createKeyEvent();
+            if (!keyEvent) return NO_MEMORY;
+
+            initializeKeyEvent(keyEvent, &mMsg);
+            *outSeq = mMsg.body.key.seq;
+            *outEvent = keyEvent;
+#if DEBUG_TRANSPORT_ACTIONS
+            ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
+                    mChannel->getName().string(), *outSeq);
+#endif
+            break;
+        }
+
+        case AINPUT_EVENT_TYPE_MOTION: {
+            ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
+            if (batchIndex >= 0) {
+                Batch& batch = mBatches.editItemAt(batchIndex);
+                if (canAddSample(batch, &mMsg)) {
+                    batch.samples.push(mMsg);
+#if DEBUG_TRANSPORT_ACTIONS
+                    ALOGD("channel '%s' consumer ~ appended to batch event",
+                            mChannel->getName().string());
+#endif
+                    break;
+                } else {
+                    // We cannot append to the batch in progress, so we need to consume
+                    // the previous batch right now and defer the new message until later.
+                    mMsgDeferred = true;
+                    status_t result = consumeSamples(factory,
+                            batch, batch.samples.size(), outSeq, outEvent);
+                    mBatches.removeAt(batchIndex);
+                    if (result) {
+                        return result;
+                    }
+#if DEBUG_TRANSPORT_ACTIONS
+                    ALOGD("channel '%s' consumer ~ consumed batch event and "
+                            "deferred current event, seq=%u",
+                            mChannel->getName().string(), *outSeq);
+#endif
+                    break;
+                }
+            }
+
+            // Start a new batch if needed.
+            if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
+                    || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+                mBatches.push();
+                Batch& batch = mBatches.editTop();
+                batch.samples.push(mMsg);
+#if DEBUG_TRANSPORT_ACTIONS
+                ALOGD("channel '%s' consumer ~ started batch event",
+                        mChannel->getName().string());
+#endif
+                break;
+            }
+
+            MotionEvent* motionEvent = factory->createMotionEvent();
+            if (! motionEvent) return NO_MEMORY;
+
+            updateTouchState(&mMsg);
+            initializeMotionEvent(motionEvent, &mMsg);
+            *outSeq = mMsg.body.motion.seq;
+            *outEvent = motionEvent;
+#if DEBUG_TRANSPORT_ACTIONS
+            ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
+                    mChannel->getName().string(), *outSeq);
+#endif
+            break;
+        }
+
+        default:
+            ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
+                    mChannel->getName().string(), mMsg.header.type);
+            return UNKNOWN_ERROR;
+        }
+    }
+    return OK;
+}
+
+status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
+        nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
+    status_t result;
+    for (size_t i = mBatches.size(); i-- > 0; ) {
+        Batch& batch = mBatches.editItemAt(i);
+        if (frameTime < 0) {
+            result = consumeSamples(factory, batch, batch.samples.size(),
+                    outSeq, outEvent);
+            mBatches.removeAt(i);
+            return result;
+        }
+
+        nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY;
+        ssize_t split = findSampleNoLaterThan(batch, sampleTime);
+        if (split < 0) {
+            continue;
+        }
+
+        result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
+        const InputMessage* next;
+        if (batch.samples.isEmpty()) {
+            mBatches.removeAt(i);
+            next = NULL;
+        } else {
+            next = &batch.samples.itemAt(0);
+        }
+        if (!result) {
+            resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
+        }
+        return result;
+    }
+
+    return WOULD_BLOCK;
+}
+
+status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
+        Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
+    MotionEvent* motionEvent = factory->createMotionEvent();
+    if (! motionEvent) return NO_MEMORY;
+
+    uint32_t chain = 0;
+    for (size_t i = 0; i < count; i++) {
+        InputMessage& msg = batch.samples.editItemAt(i);
+        updateTouchState(&msg);
+        if (i) {
+            SeqChain seqChain;
+            seqChain.seq = msg.body.motion.seq;
+            seqChain.chain = chain;
+            mSeqChains.push(seqChain);
+            addSample(motionEvent, &msg);
+        } else {
+            initializeMotionEvent(motionEvent, &msg);
+        }
+        chain = msg.body.motion.seq;
+    }
+    batch.samples.removeItemsAt(0, count);
+
+    *outSeq = chain;
+    *outEvent = motionEvent;
+    return OK;
+}
+
+void InputConsumer::updateTouchState(InputMessage* msg) {
+    if (!mResampleTouch ||
+            !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
+        return;
+    }
+
+    int32_t deviceId = msg->body.motion.deviceId;
+    int32_t source = msg->body.motion.source;
+    nsecs_t eventTime = msg->body.motion.eventTime;
+
+    // Update the touch state history to incorporate the new input message.
+    // If the message is in the past relative to the most recently produced resampled
+    // touch, then use the resampled time and coordinates instead.
+    switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) {
+    case AMOTION_EVENT_ACTION_DOWN: {
+        ssize_t index = findTouchState(deviceId, source);
+        if (index < 0) {
+            mTouchStates.push();
+            index = mTouchStates.size() - 1;
+        }
+        TouchState& touchState = mTouchStates.editItemAt(index);
+        touchState.initialize(deviceId, source);
+        touchState.addHistory(msg);
+        break;
+    }
+
+    case AMOTION_EVENT_ACTION_MOVE: {
+        ssize_t index = findTouchState(deviceId, source);
+        if (index >= 0) {
+            TouchState& touchState = mTouchStates.editItemAt(index);
+            touchState.addHistory(msg);
+            if (eventTime < touchState.lastResample.eventTime) {
+                rewriteMessage(touchState, msg);
+            } else {
+                touchState.lastResample.idBits.clear();
+            }
+        }
+        break;
+    }
+
+    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
+        ssize_t index = findTouchState(deviceId, source);
+        if (index >= 0) {
+            TouchState& touchState = mTouchStates.editItemAt(index);
+            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
+            rewriteMessage(touchState, msg);
+        }
+        break;
+    }
+
+    case AMOTION_EVENT_ACTION_POINTER_UP: {
+        ssize_t index = findTouchState(deviceId, source);
+        if (index >= 0) {
+            TouchState& touchState = mTouchStates.editItemAt(index);
+            rewriteMessage(touchState, msg);
+            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
+        }
+        break;
+    }
+
+    case AMOTION_EVENT_ACTION_SCROLL: {
+        ssize_t index = findTouchState(deviceId, source);
+        if (index >= 0) {
+            const TouchState& touchState = mTouchStates.itemAt(index);
+            rewriteMessage(touchState, msg);
+        }
+        break;
+    }
+
+    case AMOTION_EVENT_ACTION_UP:
+    case AMOTION_EVENT_ACTION_CANCEL: {
+        ssize_t index = findTouchState(deviceId, source);
+        if (index >= 0) {
+            const TouchState& touchState = mTouchStates.itemAt(index);
+            rewriteMessage(touchState, msg);
+            mTouchStates.removeAt(index);
+        }
+        break;
+    }
+    }
+}
+
+void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
+    for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
+        uint32_t id = msg->body.motion.pointers[i].properties.id;
+        if (state.lastResample.idBits.hasBit(id)) {
+            PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
+            const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
+#if DEBUG_RESAMPLING
+            ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
+                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
+                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y),
+                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
+                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
+#endif
+            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
+            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
+        }
+    }
+}
+
+void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
+    const InputMessage* next) {
+    if (!mResampleTouch
+            || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER)
+            || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
+        return;
+    }
+
+    ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
+    if (index < 0) {
+#if DEBUG_RESAMPLING
+        ALOGD("Not resampled, no touch state for device.");
+#endif
+        return;
+    }
+
+    TouchState& touchState = mTouchStates.editItemAt(index);
+    if (touchState.historySize < 1) {
+#if DEBUG_RESAMPLING
+        ALOGD("Not resampled, no history for device.");
+#endif
+        return;
+    }
+
+    // Ensure that the current sample has all of the pointers that need to be reported.
+    const History* current = touchState.getHistory(0);
+    size_t pointerCount = event->getPointerCount();
+    for (size_t i = 0; i < pointerCount; i++) {
+        uint32_t id = event->getPointerId(i);
+        if (!current->idBits.hasBit(id)) {
+#if DEBUG_RESAMPLING
+            ALOGD("Not resampled, missing id %d", id);
+#endif
+            return;
+        }
+    }
+
+    // Find the data to use for resampling.
+    const History* other;
+    History future;
+    float alpha;
+    if (next) {
+        // Interpolate between current sample and future sample.
+        // So current->eventTime <= sampleTime <= future.eventTime.
+        future.initializeFrom(next);
+        other = &future;
+        nsecs_t delta = future.eventTime - current->eventTime;
+        if (delta < RESAMPLE_MIN_DELTA) {
+#if DEBUG_RESAMPLING
+            ALOGD("Not resampled, delta time is %lld ns.", delta);
+#endif
+            return;
+        }
+        alpha = float(sampleTime - current->eventTime) / delta;
+    } else if (touchState.historySize >= 2) {
+        // Extrapolate future sample using current sample and past sample.
+        // So other->eventTime <= current->eventTime <= sampleTime.
+        other = touchState.getHistory(1);
+        nsecs_t delta = current->eventTime - other->eventTime;
+        if (delta < RESAMPLE_MIN_DELTA) {
+#if DEBUG_RESAMPLING
+            ALOGD("Not resampled, delta time is %lld ns.", delta);
+#endif
+            return;
+        }
+        nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
+        if (sampleTime > maxPredict) {
+#if DEBUG_RESAMPLING
+            ALOGD("Sample time is too far in the future, adjusting prediction "
+                    "from %lld to %lld ns.",
+                    sampleTime - current->eventTime, maxPredict - current->eventTime);
+#endif
+            sampleTime = maxPredict;
+        }
+        alpha = float(current->eventTime - sampleTime) / delta;
+    } else {
+#if DEBUG_RESAMPLING
+        ALOGD("Not resampled, insufficient data.");
+#endif
+        return;
+    }
+
+    // Resample touch coordinates.
+    touchState.lastResample.eventTime = sampleTime;
+    touchState.lastResample.idBits.clear();
+    for (size_t i = 0; i < pointerCount; i++) {
+        uint32_t id = event->getPointerId(i);
+        touchState.lastResample.idToIndex[id] = i;
+        touchState.lastResample.idBits.markBit(id);
+        PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
+        const PointerCoords& currentCoords = current->getPointerById(id);
+        if (other->idBits.hasBit(id)
+                && shouldResampleTool(event->getToolType(i))) {
+            const PointerCoords& otherCoords = other->getPointerById(id);
+            resampledCoords.copyFrom(currentCoords);
+            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
+                    lerp(currentCoords.getX(), otherCoords.getX(), alpha));
+            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
+                    lerp(currentCoords.getY(), otherCoords.getY(), alpha));
+#if DEBUG_RESAMPLING
+            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
+                    "other (%0.3f, %0.3f), alpha %0.3f",
+                    id, resampledCoords.getX(), resampledCoords.getY(),
+                    currentCoords.getX(), currentCoords.getY(),
+                    otherCoords.getX(), otherCoords.getY(),
+                    alpha);
+#endif
+        } else {
+            resampledCoords.copyFrom(currentCoords);
+#if DEBUG_RESAMPLING
+            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
+                    id, resampledCoords.getX(), resampledCoords.getY(),
+                    currentCoords.getX(), currentCoords.getY());
+#endif
+        }
+    }
+
+    event->addSample(sampleTime, touchState.lastResample.pointers);
+}
+
+bool InputConsumer::shouldResampleTool(int32_t toolType) {
+    return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
+            || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+}
+
+status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
+#if DEBUG_TRANSPORT_ACTIONS
+    ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
+            mChannel->getName().string(), seq, handled ? "true" : "false");
+#endif
+
+    if (!seq) {
+        ALOGE("Attempted to send a finished signal with sequence number 0.");
+        return BAD_VALUE;
+    }
+
+    // Send finished signals for the batch sequence chain first.
+    size_t seqChainCount = mSeqChains.size();
+    if (seqChainCount) {
+        uint32_t currentSeq = seq;
+        uint32_t chainSeqs[seqChainCount];
+        size_t chainIndex = 0;
+        for (size_t i = seqChainCount; i-- > 0; ) {
+             const SeqChain& seqChain = mSeqChains.itemAt(i);
+             if (seqChain.seq == currentSeq) {
+                 currentSeq = seqChain.chain;
+                 chainSeqs[chainIndex++] = currentSeq;
+                 mSeqChains.removeAt(i);
+             }
+        }
+        status_t status = OK;
+        while (!status && chainIndex-- > 0) {
+            status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
+        }
+        if (status) {
+            // An error occurred so at least one signal was not sent, reconstruct the chain.
+            do {
+                SeqChain seqChain;
+                seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
+                seqChain.chain = chainSeqs[chainIndex];
+                mSeqChains.push(seqChain);
+            } while (chainIndex-- > 0);
+            return status;
+        }
+    }
+
+    // Send finished signal for the last message in the batch.
+    return sendUnchainedFinishedSignal(seq, handled);
+}
+
+status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
+    InputMessage msg;
+    msg.header.type = InputMessage::TYPE_FINISHED;
+    msg.body.finished.seq = seq;
+    msg.body.finished.handled = handled;
+    return mChannel->sendMessage(&msg);
+}
+
+bool InputConsumer::hasDeferredEvent() const {
+    return mMsgDeferred;
+}
+
+bool InputConsumer::hasPendingBatch() const {
+    return !mBatches.isEmpty();
+}
+
+ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
+    for (size_t i = 0; i < mBatches.size(); i++) {
+        const Batch& batch = mBatches.itemAt(i);
+        const InputMessage& head = batch.samples.itemAt(0);
+        if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
+    for (size_t i = 0; i < mTouchStates.size(); i++) {
+        const TouchState& touchState = mTouchStates.itemAt(i);
+        if (touchState.deviceId == deviceId && touchState.source == source) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
+    event->initialize(
+            msg->body.key.deviceId,
+            msg->body.key.source,
+            msg->body.key.action,
+            msg->body.key.flags,
+            msg->body.key.keyCode,
+            msg->body.key.scanCode,
+            msg->body.key.metaState,
+            msg->body.key.repeatCount,
+            msg->body.key.downTime,
+            msg->body.key.eventTime);
+}
+
+void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
+    size_t pointerCount = msg->body.motion.pointerCount;
+    PointerProperties pointerProperties[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+    for (size_t i = 0; i < pointerCount; i++) {
+        pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
+        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
+    }
+
+    event->initialize(
+            msg->body.motion.deviceId,
+            msg->body.motion.source,
+            msg->body.motion.action,
+            msg->body.motion.flags,
+            msg->body.motion.edgeFlags,
+            msg->body.motion.metaState,
+            msg->body.motion.buttonState,
+            msg->body.motion.xOffset,
+            msg->body.motion.yOffset,
+            msg->body.motion.xPrecision,
+            msg->body.motion.yPrecision,
+            msg->body.motion.downTime,
+            msg->body.motion.eventTime,
+            pointerCount,
+            pointerProperties,
+            pointerCoords);
+}
+
+void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
+    size_t pointerCount = msg->body.motion.pointerCount;
+    PointerCoords pointerCoords[pointerCount];
+    for (size_t i = 0; i < pointerCount; i++) {
+        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
+    }
+
+    event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
+    event->addSample(msg->body.motion.eventTime, pointerCoords);
+}
+
+bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
+    const InputMessage& head = batch.samples.itemAt(0);
+    size_t pointerCount = msg->body.motion.pointerCount;
+    if (head.body.motion.pointerCount != pointerCount
+            || head.body.motion.action != msg->body.motion.action) {
+        return false;
+    }
+    for (size_t i = 0; i < pointerCount; i++) {
+        if (head.body.motion.pointers[i].properties
+                != msg->body.motion.pointers[i].properties) {
+            return false;
+        }
+    }
+    return true;
+}
+
+ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
+    size_t numSamples = batch.samples.size();
+    size_t index = 0;
+    while (index < numSamples
+            && batch.samples.itemAt(index).body.motion.eventTime <= time) {
+        index += 1;
+    }
+    return ssize_t(index) - 1;
+}
+
+} // namespace android
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
new file mode 100644
index 0000000..15a877447
--- /dev/null
+++ b/libs/input/KeyCharacterMap.cpp
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "KeyCharacterMap"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_ANDROID_OS
+#include <binder/Parcel.h>
+#endif
+
+#include <android/keycodes.h>
+#include <input/Keyboard.h>
+#include <input/KeyCharacterMap.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/Tokenizer.h>
+#include <utils/Timers.h>
+
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+// Enables debug output for mapping.
+#define DEBUG_MAPPING 0
+
+
+namespace android {
+
+static const char* WHITESPACE = " \t\r";
+static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:";
+
+struct Modifier {
+    const char* label;
+    int32_t metaState;
+};
+static const Modifier modifiers[] = {
+        { "shift", AMETA_SHIFT_ON },
+        { "lshift", AMETA_SHIFT_LEFT_ON },
+        { "rshift", AMETA_SHIFT_RIGHT_ON },
+        { "alt", AMETA_ALT_ON },
+        { "lalt", AMETA_ALT_LEFT_ON },
+        { "ralt", AMETA_ALT_RIGHT_ON },
+        { "ctrl", AMETA_CTRL_ON },
+        { "lctrl", AMETA_CTRL_LEFT_ON },
+        { "rctrl", AMETA_CTRL_RIGHT_ON },
+        { "meta", AMETA_META_ON },
+        { "lmeta", AMETA_META_LEFT_ON },
+        { "rmeta", AMETA_META_RIGHT_ON },
+        { "sym", AMETA_SYM_ON },
+        { "fn", AMETA_FUNCTION_ON },
+        { "capslock", AMETA_CAPS_LOCK_ON },
+        { "numlock", AMETA_NUM_LOCK_ON },
+        { "scrolllock", AMETA_SCROLL_LOCK_ON },
+};
+
+#if DEBUG_MAPPING
+static String8 toString(const char16_t* chars, size_t numChars) {
+    String8 result;
+    for (size_t i = 0; i < numChars; i++) {
+        result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]);
+    }
+    return result;
+}
+#endif
+
+
+// --- KeyCharacterMap ---
+
+sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap();
+
+KeyCharacterMap::KeyCharacterMap() :
+    mType(KEYBOARD_TYPE_UNKNOWN) {
+}
+
+KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) :
+    RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode),
+    mKeysByUsageCode(other.mKeysByUsageCode) {
+    for (size_t i = 0; i < other.mKeys.size(); i++) {
+        mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i)));
+    }
+}
+
+KeyCharacterMap::~KeyCharacterMap() {
+    for (size_t i = 0; i < mKeys.size(); i++) {
+        Key* key = mKeys.editValueAt(i);
+        delete key;
+    }
+}
+
+status_t KeyCharacterMap::load(const String8& filename,
+        Format format, sp<KeyCharacterMap>* outMap) {
+    outMap->clear();
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::open(filename, &tokenizer);
+    if (status) {
+        ALOGE("Error %d opening key character map file %s.", status, filename.string());
+    } else {
+        status = load(tokenizer, format, outMap);
+        delete tokenizer;
+    }
+    return status;
+}
+
+status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents,
+        Format format, sp<KeyCharacterMap>* outMap) {
+    outMap->clear();
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::fromContents(filename, contents, &tokenizer);
+    if (status) {
+        ALOGE("Error %d opening key character map.", status);
+    } else {
+        status = load(tokenizer, format, outMap);
+        delete tokenizer;
+    }
+    return status;
+}
+
+status_t KeyCharacterMap::load(Tokenizer* tokenizer,
+        Format format, sp<KeyCharacterMap>* outMap) {
+    status_t status = OK;
+    sp<KeyCharacterMap> map = new KeyCharacterMap();
+    if (!map.get()) {
+        ALOGE("Error allocating key character map.");
+        status = NO_MEMORY;
+    } else {
+#if DEBUG_PARSER_PERFORMANCE
+        nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+        Parser parser(map.get(), tokenizer, format);
+        status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+        nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+        ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
+                tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                elapsedTime / 1000000.0);
+#endif
+        if (!status) {
+            *outMap = map;
+        }
+    }
+    return status;
+}
+
+sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base,
+        const sp<KeyCharacterMap>& overlay) {
+    if (overlay == NULL) {
+        return base;
+    }
+    if (base == NULL) {
+        return overlay;
+    }
+
+    sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get());
+    for (size_t i = 0; i < overlay->mKeys.size(); i++) {
+        int32_t keyCode = overlay->mKeys.keyAt(i);
+        Key* key = overlay->mKeys.valueAt(i);
+        ssize_t oldIndex = map->mKeys.indexOfKey(keyCode);
+        if (oldIndex >= 0) {
+            delete map->mKeys.valueAt(oldIndex);
+            map->mKeys.editValueAt(oldIndex) = new Key(*key);
+        } else {
+            map->mKeys.add(keyCode, new Key(*key));
+        }
+    }
+
+    for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) {
+        map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i),
+                overlay->mKeysByScanCode.valueAt(i));
+    }
+
+    for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) {
+        map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i),
+                overlay->mKeysByUsageCode.valueAt(i));
+    }
+    return map;
+}
+
+sp<KeyCharacterMap> KeyCharacterMap::empty() {
+    return sEmpty;
+}
+
+int32_t KeyCharacterMap::getKeyboardType() const {
+    return mType;
+}
+
+char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
+    char16_t result = 0;
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        result = key->label;
+    }
+#if DEBUG_MAPPING
+    ALOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result);
+#endif
+    return result;
+}
+
+char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
+    char16_t result = 0;
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        result = key->number;
+    }
+#if DEBUG_MAPPING
+    ALOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result);
+#endif
+    return result;
+}
+
+char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
+    char16_t result = 0;
+    const Key* key;
+    const Behavior* behavior;
+    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+        result = behavior->character;
+    }
+#if DEBUG_MAPPING
+    ALOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
+#endif
+    return result;
+}
+
+bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
+        FallbackAction* outFallbackAction) const {
+    outFallbackAction->keyCode = 0;
+    outFallbackAction->metaState = 0;
+
+    bool result = false;
+    const Key* key;
+    const Behavior* behavior;
+    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+        if (behavior->fallbackKeyCode) {
+            outFallbackAction->keyCode = behavior->fallbackKeyCode;
+            outFallbackAction->metaState = metaState & ~behavior->metaState;
+            result = true;
+        }
+    }
+#if DEBUG_MAPPING
+    ALOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
+            "fallback keyCode=%d, fallback metaState=0x%08x.",
+            keyCode, metaState, result ? "true" : "false",
+            outFallbackAction->keyCode, outFallbackAction->metaState);
+#endif
+    return result;
+}
+
+char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
+        int32_t metaState) const {
+    char16_t result = 0;
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        // Try to find the most general behavior that maps to this character.
+        // For example, the base key behavior will usually be last in the list.
+        // However, if we find a perfect meta state match for one behavior then use that one.
+        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
+            if (behavior->character) {
+                for (size_t i = 0; i < numChars; i++) {
+                    if (behavior->character == chars[i]) {
+                        result = behavior->character;
+                        if ((behavior->metaState & metaState) == behavior->metaState) {
+                            goto ExactMatch;
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    ExactMatch: ;
+    }
+#if DEBUG_MAPPING
+    ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
+            keyCode, toString(chars, numChars).string(), metaState, result);
+#endif
+    return result;
+}
+
+bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
+        Vector<KeyEvent>& outEvents) const {
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+
+    for (size_t i = 0; i < numChars; i++) {
+        int32_t keyCode, metaState;
+        char16_t ch = chars[i];
+        if (!findKey(ch, &keyCode, &metaState)) {
+#if DEBUG_MAPPING
+            ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
+                    deviceId, toString(chars, numChars).string(), ch);
+#endif
+            return false;
+        }
+
+        int32_t currentMetaState = 0;
+        addMetaKeys(outEvents, deviceId, metaState, true, now, &currentMetaState);
+        addKey(outEvents, deviceId, keyCode, currentMetaState, true, now);
+        addKey(outEvents, deviceId, keyCode, currentMetaState, false, now);
+        addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
+    }
+#if DEBUG_MAPPING
+    ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
+            deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
+    for (size_t i = 0; i < outEvents.size(); i++) {
+        ALOGD("  Key: keyCode=%d, metaState=0x%08x, %s.",
+                outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
+                outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up");
+    }
+#endif
+    return true;
+}
+
+status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const {
+    if (usageCode) {
+        ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
+        if (index >= 0) {
+#if DEBUG_MAPPING
+    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
+            scanCode, usageCode, *outKeyCode);
+#endif
+            *outKeyCode = mKeysByUsageCode.valueAt(index);
+            return OK;
+        }
+    }
+    if (scanCode) {
+        ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
+        if (index >= 0) {
+#if DEBUG_MAPPING
+    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
+            scanCode, usageCode, *outKeyCode);
+#endif
+            *outKeyCode = mKeysByScanCode.valueAt(index);
+            return OK;
+        }
+    }
+
+#if DEBUG_MAPPING
+        ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
+#endif
+    *outKeyCode = AKEYCODE_UNKNOWN;
+    return NAME_NOT_FOUND;
+}
+
+bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
+    ssize_t index = mKeys.indexOfKey(keyCode);
+    if (index >= 0) {
+        *outKey = mKeys.valueAt(index);
+        return true;
+    }
+    return false;
+}
+
+bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
+        const Key** outKey, const Behavior** outBehavior) const {
+    const Key* key;
+    if (getKey(keyCode, &key)) {
+        const Behavior* behavior = key->firstBehavior;
+        while (behavior) {
+            if (matchesMetaState(metaState, behavior->metaState)) {
+                *outKey = key;
+                *outBehavior = behavior;
+                return true;
+            }
+            behavior = behavior->next;
+        }
+    }
+    return false;
+}
+
+bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) {
+    // Behavior must have at least the set of meta states specified.
+    // And if the key event has CTRL, ALT or META then the behavior must exactly
+    // match those, taking into account that a behavior can specify that it handles
+    // one, both or either of a left/right modifier pair.
+    if ((eventMetaState & behaviorMetaState) == behaviorMetaState) {
+        const int32_t EXACT_META_STATES =
+                AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON
+                | AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON
+                | AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON;
+        int32_t unmatchedMetaState = eventMetaState & ~behaviorMetaState & EXACT_META_STATES;
+        if (behaviorMetaState & AMETA_CTRL_ON) {
+            unmatchedMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
+        } else if (behaviorMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
+            unmatchedMetaState &= ~AMETA_CTRL_ON;
+        }
+        if (behaviorMetaState & AMETA_ALT_ON) {
+            unmatchedMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
+        } else if (behaviorMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
+            unmatchedMetaState &= ~AMETA_ALT_ON;
+        }
+        if (behaviorMetaState & AMETA_META_ON) {
+            unmatchedMetaState &= ~(AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
+        } else if (behaviorMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
+            unmatchedMetaState &= ~AMETA_META_ON;
+        }
+        return !unmatchedMetaState;
+    }
+    return false;
+}
+
+bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
+    if (!ch) {
+        return false;
+    }
+
+    for (size_t i = 0; i < mKeys.size(); i++) {
+        const Key* key = mKeys.valueAt(i);
+
+        // Try to find the most general behavior that maps to this character.
+        // For example, the base key behavior will usually be last in the list.
+        const Behavior* found = NULL;
+        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
+            if (behavior->character == ch) {
+                found = behavior;
+            }
+        }
+        if (found) {
+            *outKeyCode = mKeys.keyAt(i);
+            *outMetaState = found->metaState;
+            return true;
+        }
+    }
+    return false;
+}
+
+void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
+    outEvents.push();
+    KeyEvent& event = outEvents.editTop();
+    event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD,
+            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
+            0, keyCode, 0, metaState, 0, time, time);
+}
+
+void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+        int32_t* currentMetaState) {
+    // Add and remove meta keys symmetrically.
+    if (down) {
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
+
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
+                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
+                AMETA_SHIFT_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
+                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
+                AMETA_ALT_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
+                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
+                AMETA_CTRL_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
+                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
+                AMETA_META_ON, currentMetaState);
+
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
+                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
+    } else {
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
+
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
+                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
+                AMETA_META_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
+                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
+                AMETA_CTRL_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
+                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
+                AMETA_ALT_ON, currentMetaState);
+        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
+                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
+                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
+                AMETA_SHIFT_ON, currentMetaState);
+
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
+        addLockedMetaKey(outEvents, deviceId, metaState, time,
+                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
+    }
+}
+
+bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+        int32_t keyCode, int32_t keyMetaState,
+        int32_t* currentMetaState) {
+    if ((metaState & keyMetaState) == keyMetaState) {
+        *currentMetaState = updateMetaState(keyCode, down, *currentMetaState);
+        addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time);
+        return true;
+    }
+    return false;
+}
+
+void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
+        int32_t leftKeyCode, int32_t leftKeyMetaState,
+        int32_t rightKeyCode, int32_t rightKeyMetaState,
+        int32_t eitherKeyMetaState,
+        int32_t* currentMetaState) {
+    bool specific = false;
+    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
+            leftKeyCode, leftKeyMetaState, currentMetaState);
+    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
+            rightKeyCode, rightKeyMetaState, currentMetaState);
+
+    if (!specific) {
+        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
+                leftKeyCode, eitherKeyMetaState, currentMetaState);
+    }
+}
+
+void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents,
+        int32_t deviceId, int32_t metaState, nsecs_t time,
+        int32_t keyCode, int32_t keyMetaState,
+        int32_t* currentMetaState) {
+    if ((metaState & keyMetaState) == keyMetaState) {
+        *currentMetaState = updateMetaState(keyCode, true, *currentMetaState);
+        addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time);
+        *currentMetaState = updateMetaState(keyCode, false, *currentMetaState);
+        addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time);
+    }
+}
+
+#if HAVE_ANDROID_OS
+sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) {
+    sp<KeyCharacterMap> map = new KeyCharacterMap();
+    map->mType = parcel->readInt32();
+    size_t numKeys = parcel->readInt32();
+    if (parcel->errorCheck()) {
+        return NULL;
+    }
+
+    for (size_t i = 0; i < numKeys; i++) {
+        int32_t keyCode = parcel->readInt32();
+        char16_t label = parcel->readInt32();
+        char16_t number = parcel->readInt32();
+        if (parcel->errorCheck()) {
+            return NULL;
+        }
+
+        Key* key = new Key();
+        key->label = label;
+        key->number = number;
+        map->mKeys.add(keyCode, key);
+
+        Behavior* lastBehavior = NULL;
+        while (parcel->readInt32()) {
+            int32_t metaState = parcel->readInt32();
+            char16_t character = parcel->readInt32();
+            int32_t fallbackKeyCode = parcel->readInt32();
+            if (parcel->errorCheck()) {
+                return NULL;
+            }
+
+            Behavior* behavior = new Behavior();
+            behavior->metaState = metaState;
+            behavior->character = character;
+            behavior->fallbackKeyCode = fallbackKeyCode;
+            if (lastBehavior) {
+                lastBehavior->next = behavior;
+            } else {
+                key->firstBehavior = behavior;
+            }
+            lastBehavior = behavior;
+        }
+
+        if (parcel->errorCheck()) {
+            return NULL;
+        }
+    }
+    return map;
+}
+
+void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
+    parcel->writeInt32(mType);
+
+    size_t numKeys = mKeys.size();
+    parcel->writeInt32(numKeys);
+    for (size_t i = 0; i < numKeys; i++) {
+        int32_t keyCode = mKeys.keyAt(i);
+        const Key* key = mKeys.valueAt(i);
+        parcel->writeInt32(keyCode);
+        parcel->writeInt32(key->label);
+        parcel->writeInt32(key->number);
+        for (const Behavior* behavior = key->firstBehavior; behavior != NULL;
+                behavior = behavior->next) {
+            parcel->writeInt32(1);
+            parcel->writeInt32(behavior->metaState);
+            parcel->writeInt32(behavior->character);
+            parcel->writeInt32(behavior->fallbackKeyCode);
+        }
+        parcel->writeInt32(0);
+    }
+}
+#endif
+
+
+// --- KeyCharacterMap::Key ---
+
+KeyCharacterMap::Key::Key() :
+        label(0), number(0), firstBehavior(NULL) {
+}
+
+KeyCharacterMap::Key::Key(const Key& other) :
+        label(other.label), number(other.number),
+        firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL) {
+}
+
+KeyCharacterMap::Key::~Key() {
+    Behavior* behavior = firstBehavior;
+    while (behavior) {
+        Behavior* next = behavior->next;
+        delete behavior;
+        behavior = next;
+    }
+}
+
+
+// --- KeyCharacterMap::Behavior ---
+
+KeyCharacterMap::Behavior::Behavior() :
+        next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
+}
+
+KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
+        next(other.next ? new Behavior(*other.next) : NULL),
+        metaState(other.metaState), character(other.character),
+        fallbackKeyCode(other.fallbackKeyCode) {
+}
+
+
+// --- KeyCharacterMap::Parser ---
+
+KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) :
+        mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) {
+}
+
+KeyCharacterMap::Parser::~Parser() {
+}
+
+status_t KeyCharacterMap::Parser::parse() {
+    while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+                mTokenizer->peekRemainderOfLine().string());
+#endif
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+
+        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+            switch (mState) {
+            case STATE_TOP: {
+                String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+                if (keywordToken == "type") {
+                    mTokenizer->skipDelimiters(WHITESPACE);
+                    status_t status = parseType();
+                    if (status) return status;
+                } else if (keywordToken == "map") {
+                    mTokenizer->skipDelimiters(WHITESPACE);
+                    status_t status = parseMap();
+                    if (status) return status;
+                } else if (keywordToken == "key") {
+                    mTokenizer->skipDelimiters(WHITESPACE);
+                    status_t status = parseKey();
+                    if (status) return status;
+                } else {
+                    ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
+                            keywordToken.string());
+                    return BAD_VALUE;
+                }
+                break;
+            }
+
+            case STATE_KEY: {
+                status_t status = parseKeyProperty();
+                if (status) return status;
+                break;
+            }
+            }
+
+            mTokenizer->skipDelimiters(WHITESPACE);
+            if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+                ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
+                        mTokenizer->getLocation().string(),
+                        mTokenizer->peekRemainderOfLine().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->nextLine();
+    }
+
+    if (mState != STATE_TOP) {
+        ALOGE("%s: Unterminated key description at end of file.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
+        ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    if (mFormat == FORMAT_BASE) {
+        if (mMap->mType == KEYBOARD_TYPE_OVERLAY) {
+            ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.",
+                    mTokenizer->getLocation().string());
+            return BAD_VALUE;
+        }
+    } else if (mFormat == FORMAT_OVERLAY) {
+        if (mMap->mType != KEYBOARD_TYPE_OVERLAY) {
+            ALOGE("%s: Overlay keyboard layout missing required keyboard "
+                    "'type OVERLAY' declaration.",
+                    mTokenizer->getLocation().string());
+            return BAD_VALUE;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseType() {
+    if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) {
+        ALOGE("%s: Duplicate keyboard 'type' declaration.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    KeyboardType type;
+    String8 typeToken = mTokenizer->nextToken(WHITESPACE);
+    if (typeToken == "NUMERIC") {
+        type = KEYBOARD_TYPE_NUMERIC;
+    } else if (typeToken == "PREDICTIVE") {
+        type = KEYBOARD_TYPE_PREDICTIVE;
+    } else if (typeToken == "ALPHA") {
+        type = KEYBOARD_TYPE_ALPHA;
+    } else if (typeToken == "FULL") {
+        type = KEYBOARD_TYPE_FULL;
+    } else if (typeToken == "SPECIAL_FUNCTION") {
+        type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
+    } else if (typeToken == "OVERLAY") {
+        type = KEYBOARD_TYPE_OVERLAY;
+    } else {
+        ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
+                typeToken.string());
+        return BAD_VALUE;
+    }
+
+#if DEBUG_PARSER
+    ALOGD("Parsed type: type=%d.", type);
+#endif
+    mMap->mType = type;
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseMap() {
+    String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+    if (keywordToken == "key") {
+        mTokenizer->skipDelimiters(WHITESPACE);
+        return parseMapKey();
+    }
+    ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
+            keywordToken.string());
+    return BAD_VALUE;
+}
+
+status_t KeyCharacterMap::Parser::parseMapKey() {
+    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 key %s number, got '%s'.", mTokenizer->getLocation().string(),
+                mapUsage ? "usage" : "scan code", codeToken.string());
+        return BAD_VALUE;
+    }
+    KeyedVector<int32_t, int32_t>& 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());
+        return BAD_VALUE;
+    }
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
+    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
+    if (!keyCode) {
+        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
+                keyCodeToken.string());
+        return BAD_VALUE;
+    }
+
+#if DEBUG_PARSER
+    ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
+            mapUsage ? "usage" : "scan code", code, keyCode);
+#endif
+    map.add(code, keyCode);
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseKey() {
+    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
+    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
+    if (!keyCode) {
+        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
+                keyCodeToken.string());
+        return BAD_VALUE;
+    }
+    if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
+        ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
+                keyCodeToken.string());
+        return BAD_VALUE;
+    }
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
+    if (openBraceToken != "{") {
+        ALOGE("%s: Expected '{' after key code label, got '%s'.",
+                mTokenizer->getLocation().string(), openBraceToken.string());
+        return BAD_VALUE;
+    }
+
+#if DEBUG_PARSER
+    ALOGD("Parsed beginning of key: keyCode=%d.", keyCode);
+#endif
+    mKeyCode = keyCode;
+    mMap->mKeys.add(keyCode, new Key());
+    mState = STATE_KEY;
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseKeyProperty() {
+    Key* key = mMap->mKeys.valueFor(mKeyCode);
+    String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
+    if (token == "}") {
+        mState = STATE_TOP;
+        return finishKey(key);
+    }
+
+    Vector<Property> properties;
+
+    // Parse all comma-delimited property names up to the first colon.
+    for (;;) {
+        if (token == "label") {
+            properties.add(Property(PROPERTY_LABEL));
+        } else if (token == "number") {
+            properties.add(Property(PROPERTY_NUMBER));
+        } else {
+            int32_t metaState;
+            status_t status = parseModifier(token, &metaState);
+            if (status) {
+                ALOGE("%s: Expected a property name or modifier, got '%s'.",
+                        mTokenizer->getLocation().string(), token.string());
+                return status;
+            }
+            properties.add(Property(PROPERTY_META, metaState));
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        if (!mTokenizer->isEol()) {
+            char ch = mTokenizer->nextChar();
+            if (ch == ':') {
+                break;
+            } else if (ch == ',') {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
+                continue;
+            }
+        }
+
+        ALOGE("%s: Expected ',' or ':' after property name.",
+                mTokenizer->getLocation().string());
+        return BAD_VALUE;
+    }
+
+    // Parse behavior after the colon.
+    mTokenizer->skipDelimiters(WHITESPACE);
+
+    Behavior behavior;
+    bool haveCharacter = false;
+    bool haveFallback = false;
+
+    do {
+        char ch = mTokenizer->peekChar();
+        if (ch == '\'') {
+            char16_t character;
+            status_t status = parseCharacterLiteral(&character);
+            if (status || !character) {
+                ALOGE("%s: Invalid character literal for key.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            if (haveCharacter) {
+                ALOGE("%s: Cannot combine multiple character literals or 'none'.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            behavior.character = character;
+            haveCharacter = true;
+        } else {
+            token = mTokenizer->nextToken(WHITESPACE);
+            if (token == "none") {
+                if (haveCharacter) {
+                    ALOGE("%s: Cannot combine multiple character literals or 'none'.",
+                            mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+                haveCharacter = true;
+            } else if (token == "fallback") {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                token = mTokenizer->nextToken(WHITESPACE);
+                int32_t keyCode = getKeyCodeByLabel(token.string());
+                if (!keyCode) {
+                    ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
+                            mTokenizer->getLocation().string(),
+                            token.string());
+                    return BAD_VALUE;
+                }
+                if (haveFallback) {
+                    ALOGE("%s: Cannot combine multiple fallback key codes.",
+                            mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+                behavior.fallbackKeyCode = keyCode;
+                haveFallback = true;
+            } else {
+                ALOGE("%s: Expected a key behavior after ':'.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+    } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#');
+
+    // Add the behavior.
+    for (size_t i = 0; i < properties.size(); i++) {
+        const Property& property = properties.itemAt(i);
+        switch (property.property) {
+        case PROPERTY_LABEL:
+            if (key->label) {
+                ALOGE("%s: Duplicate label for key.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            key->label = behavior.character;
+#if DEBUG_PARSER
+            ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label);
+#endif
+            break;
+        case PROPERTY_NUMBER:
+            if (key->number) {
+                ALOGE("%s: Duplicate number for key.",
+                        mTokenizer->getLocation().string());
+                return BAD_VALUE;
+            }
+            key->number = behavior.character;
+#if DEBUG_PARSER
+            ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number);
+#endif
+            break;
+        case PROPERTY_META: {
+            for (Behavior* b = key->firstBehavior; b; b = b->next) {
+                if (b->metaState == property.metaState) {
+                    ALOGE("%s: Duplicate key behavior for modifier.",
+                            mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+            }
+            Behavior* newBehavior = new Behavior(behavior);
+            newBehavior->metaState = property.metaState;
+            newBehavior->next = key->firstBehavior;
+            key->firstBehavior = newBehavior;
+#if DEBUG_PARSER
+            ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode,
+                    newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode);
+#endif
+            break;
+        }
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::finishKey(Key* key) {
+    // Fill in default number property.
+    if (!key->number) {
+        char16_t digit = 0;
+        char16_t symbol = 0;
+        for (Behavior* b = key->firstBehavior; b; b = b->next) {
+            char16_t ch = b->character;
+            if (ch) {
+                if (ch >= '0' && ch <= '9') {
+                    digit = ch;
+                } else if (ch == '(' || ch == ')' || ch == '#' || ch == '*'
+                        || ch == '-' || ch == '+' || ch == ',' || ch == '.'
+                        || ch == '\'' || ch == ':' || ch == ';' || ch == '/') {
+                    symbol = ch;
+                }
+            }
+        }
+        key->number = digit ? digit : symbol;
+    }
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
+    if (token == "base") {
+        *outMetaState = 0;
+        return NO_ERROR;
+    }
+
+    int32_t combinedMeta = 0;
+
+    const char* str = token.string();
+    const char* start = str;
+    for (const char* cur = str; ; cur++) {
+        char ch = *cur;
+        if (ch == '+' || ch == '\0') {
+            size_t len = cur - start;
+            int32_t metaState = 0;
+            for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) {
+                if (strlen(modifiers[i].label) == len
+                        && strncmp(modifiers[i].label, start, len) == 0) {
+                    metaState = modifiers[i].metaState;
+                    break;
+                }
+            }
+            if (!metaState) {
+                return BAD_VALUE;
+            }
+            if (combinedMeta & metaState) {
+                ALOGE("%s: Duplicate modifier combination '%s'.",
+                        mTokenizer->getLocation().string(), token.string());
+                return BAD_VALUE;
+            }
+
+            combinedMeta |= metaState;
+            start = cur + 1;
+
+            if (ch == '\0') {
+                break;
+            }
+        }
+    }
+    *outMetaState = combinedMeta;
+    return NO_ERROR;
+}
+
+status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) {
+    char ch = mTokenizer->nextChar();
+    if (ch != '\'') {
+        goto Error;
+    }
+
+    ch = mTokenizer->nextChar();
+    if (ch == '\\') {
+        // Escape sequence.
+        ch = mTokenizer->nextChar();
+        if (ch == 'n') {
+            *outCharacter = '\n';
+        } else if (ch == 't') {
+            *outCharacter = '\t';
+        } else if (ch == '\\') {
+            *outCharacter = '\\';
+        } else if (ch == '\'') {
+            *outCharacter = '\'';
+        } else if (ch == '"') {
+            *outCharacter = '"';
+        } else if (ch == 'u') {
+            *outCharacter = 0;
+            for (int i = 0; i < 4; i++) {
+                ch = mTokenizer->nextChar();
+                int digit;
+                if (ch >= '0' && ch <= '9') {
+                    digit = ch - '0';
+                } else if (ch >= 'A' && ch <= 'F') {
+                    digit = ch - 'A' + 10;
+                } else if (ch >= 'a' && ch <= 'f') {
+                    digit = ch - 'a' + 10;
+                } else {
+                    goto Error;
+                }
+                *outCharacter = (*outCharacter << 4) | digit;
+            }
+        } else {
+            goto Error;
+        }
+    } else if (ch >= 32 && ch <= 126 && ch != '\'') {
+        // ASCII literal character.
+        *outCharacter = ch;
+    } else {
+        goto Error;
+    }
+
+    ch = mTokenizer->nextChar();
+    if (ch != '\'') {
+        goto Error;
+    }
+
+    // Ensure that we consumed the entire token.
+    if (mTokenizer->nextToken(WHITESPACE).isEmpty()) {
+        return NO_ERROR;
+    }
+
+Error:
+    ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
+    return BAD_VALUE;
+}
+
+} // namespace android
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
new file mode 100644
index 0000000..2f5494b
--- /dev/null
+++ b/libs/input/KeyLayoutMap.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "KeyLayoutMap"
+
+#include <stdlib.h>
+
+#include <android/keycodes.h>
+#include <input/Keyboard.h>
+#include <input/KeyLayoutMap.h>
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/Tokenizer.h>
+#include <utils/Timers.h>
+
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+// Enables debug output for mapping.
+#define DEBUG_MAPPING 0
+
+
+namespace android {
+
+static const char* WHITESPACE = " \t\r";
+
+// --- KeyLayoutMap ---
+
+KeyLayoutMap::KeyLayoutMap() {
+}
+
+KeyLayoutMap::~KeyLayoutMap() {
+}
+
+status_t KeyLayoutMap::load(const String8& filename, sp<KeyLayoutMap>* outMap) {
+    outMap->clear();
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::open(filename, &tokenizer);
+    if (status) {
+        ALOGE("Error %d opening key layout map file %s.", status, filename.string());
+    } else {
+        sp<KeyLayoutMap> map = new KeyLayoutMap();
+        if (!map.get()) {
+            ALOGE("Error allocating key layout map.");
+            status = NO_MEMORY;
+        } else {
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+            Parser parser(map.get(), tokenizer);
+            status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+            ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
+                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                    elapsedTime / 1000000.0);
+#endif
+            if (!status) {
+                *outMap = map;
+            }
+        }
+        delete tokenizer;
+    }
+    return status;
+}
+
+status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t usageCode,
+        int32_t* outKeyCode, uint32_t* outFlags) const {
+    const Key* key = getKey(scanCode, usageCode);
+    if (!key) {
+#if DEBUG_MAPPING
+        ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
+#endif
+        *outKeyCode = AKEYCODE_UNKNOWN;
+        *outFlags = 0;
+        return NAME_NOT_FOUND;
+    }
+
+    *outKeyCode = key->keyCode;
+    *outFlags = key->flags;
+
+#if DEBUG_MAPPING
+    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d, outFlags=0x%08x.",
+            scanCode, usageCode, *outKeyCode, *outFlags);
+#endif
+    return NO_ERROR;
+}
+
+const KeyLayoutMap::Key* KeyLayoutMap::getKey(int32_t scanCode, int32_t usageCode) const {
+    if (usageCode) {
+        ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
+        if (index >= 0) {
+            return &mKeysByUsageCode.valueAt(index);
+        }
+    }
+    if (scanCode) {
+        ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
+        if (index >= 0) {
+            return &mKeysByScanCode.valueAt(index);
+        }
+    }
+    return NULL;
+}
+
+status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
+    const size_t N = mKeysByScanCode.size();
+    for (size_t i=0; i<N; i++) {
+        if (mKeysByScanCode.valueAt(i).keyCode == keyCode) {
+            outScanCodes->add(mKeysByScanCode.keyAt(i));
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
+    ssize_t index = mAxes.indexOfKey(scanCode);
+    if (index < 0) {
+#if DEBUG_MAPPING
+        ALOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
+#endif
+        return NAME_NOT_FOUND;
+    }
+
+    *outAxisInfo = mAxes.valueAt(index);
+
+#if DEBUG_MAPPING
+    ALOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
+            "splitValue=%d, flatOverride=%d.",
+            scanCode,
+            outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
+            outAxisInfo->splitValue, outAxisInfo->flatOverride);
+#endif
+    return NO_ERROR;
+}
+
+
+// --- KeyLayoutMap::Parser ---
+
+KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
+        mMap(map), mTokenizer(tokenizer) {
+}
+
+KeyLayoutMap::Parser::~Parser() {
+}
+
+status_t KeyLayoutMap::Parser::parse() {
+    while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+                mTokenizer->peekRemainderOfLine().string());
+#endif
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+
+        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+            String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+            if (keywordToken == "key") {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                status_t status = parseKey();
+                if (status) return status;
+            } else if (keywordToken == "axis") {
+                mTokenizer->skipDelimiters(WHITESPACE);
+                status_t status = parseAxis();
+                if (status) return status;
+            } else {
+                ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
+                        keywordToken.string());
+                return BAD_VALUE;
+            }
+
+            mTokenizer->skipDelimiters(WHITESPACE);
+            if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+                ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
+                        mTokenizer->getLocation().string(),
+                        mTokenizer->peekRemainderOfLine().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->nextLine();
+    }
+    return NO_ERROR;
+}
+
+status_t KeyLayoutMap::Parser::parseKey() {
+    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 key %s number, got '%s'.", mTokenizer->getLocation().string(),
+                mapUsage ? "usage" : "scan code", codeToken.string());
+        return BAD_VALUE;
+    }
+    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());
+        return BAD_VALUE;
+    }
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
+    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
+    if (!keyCode) {
+        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
+                keyCodeToken.string());
+        return BAD_VALUE;
+    }
+
+    uint32_t flags = 0;
+    for (;;) {
+        mTokenizer->skipDelimiters(WHITESPACE);
+        if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
+
+        String8 flagToken = mTokenizer->nextToken(WHITESPACE);
+        uint32_t flag = getKeyFlagByLabel(flagToken.string());
+        if (!flag) {
+            ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
+                    flagToken.string());
+            return BAD_VALUE;
+        }
+        if (flags & flag) {
+            ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
+                    flagToken.string());
+            return BAD_VALUE;
+        }
+        flags |= flag;
+    }
+
+#if DEBUG_PARSER
+    ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
+            mapUsage ? "usage" : "scan code", code, keyCode, flags);
+#endif
+    Key key;
+    key.keyCode = keyCode;
+    key.flags = flags;
+    map.add(code, key);
+    return NO_ERROR;
+}
+
+status_t KeyLayoutMap::Parser::parseAxis() {
+    String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
+    char* end;
+    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
+    if (*end) {
+        ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
+                scanCodeToken.string());
+        return BAD_VALUE;
+    }
+    if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
+        ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
+                scanCodeToken.string());
+        return BAD_VALUE;
+    }
+
+    AxisInfo axisInfo;
+
+    mTokenizer->skipDelimiters(WHITESPACE);
+    String8 token = mTokenizer->nextToken(WHITESPACE);
+    if (token == "invert") {
+        axisInfo.mode = AxisInfo::MODE_INVERT;
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 axisToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.axis = getAxisByLabel(axisToken.string());
+        if (axisInfo.axis < 0) {
+            ALOGE("%s: Expected inverted axis label, got '%s'.",
+                    mTokenizer->getLocation().string(), axisToken.string());
+            return BAD_VALUE;
+        }
+    } else if (token == "split") {
+        axisInfo.mode = AxisInfo::MODE_SPLIT;
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 splitToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
+        if (*end) {
+            ALOGE("%s: Expected split value, got '%s'.",
+                    mTokenizer->getLocation().string(), splitToken.string());
+            return BAD_VALUE;
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.axis = getAxisByLabel(lowAxisToken.string());
+        if (axisInfo.axis < 0) {
+            ALOGE("%s: Expected low axis label, got '%s'.",
+                    mTokenizer->getLocation().string(), lowAxisToken.string());
+            return BAD_VALUE;
+        }
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+        String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
+        axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
+        if (axisInfo.highAxis < 0) {
+            ALOGE("%s: Expected high axis label, got '%s'.",
+                    mTokenizer->getLocation().string(), highAxisToken.string());
+            return BAD_VALUE;
+        }
+    } else {
+        axisInfo.axis = getAxisByLabel(token.string());
+        if (axisInfo.axis < 0) {
+            ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
+                    mTokenizer->getLocation().string(), token.string());
+            return BAD_VALUE;
+        }
+    }
+
+    for (;;) {
+        mTokenizer->skipDelimiters(WHITESPACE);
+        if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') {
+            break;
+        }
+        String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
+        if (keywordToken == "flat") {
+            mTokenizer->skipDelimiters(WHITESPACE);
+            String8 flatToken = mTokenizer->nextToken(WHITESPACE);
+            axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
+            if (*end) {
+                ALOGE("%s: Expected flat value, got '%s'.",
+                        mTokenizer->getLocation().string(), flatToken.string());
+                return BAD_VALUE;
+            }
+        } else {
+            ALOGE("%s: Expected keyword 'flat', got '%s'.",
+                    mTokenizer->getLocation().string(), keywordToken.string());
+            return BAD_VALUE;
+        }
+    }
+
+#if DEBUG_PARSER
+    ALOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
+            "splitValue=%d, flatOverride=%d.",
+            scanCode,
+            axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
+            axisInfo.splitValue, axisInfo.flatOverride);
+#endif
+    mMap->mAxes.add(scanCode, axisInfo);
+    return NO_ERROR;
+}
+
+};
diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp
new file mode 100644
index 0000000..b6551ee
--- /dev/null
+++ b/libs/input/Keyboard.cpp
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Keyboard"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <input/Keyboard.h>
+#include <input/KeycodeLabels.h>
+#include <input/KeyLayoutMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/InputDevice.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+namespace android {
+
+// --- KeyMap ---
+
+KeyMap::KeyMap() {
+}
+
+KeyMap::~KeyMap() {
+}
+
+status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
+        const PropertyMap* deviceConfiguration) {
+    // Use the configured key layout if available.
+    if (deviceConfiguration) {
+        String8 keyLayoutName;
+        if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
+                keyLayoutName)) {
+            status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName);
+            if (status == NAME_NOT_FOUND) {
+                ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
+                        "it was not found.",
+                        deviceIdenfifier.name.string(), keyLayoutName.string());
+            }
+        }
+
+        String8 keyCharacterMapName;
+        if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
+                keyCharacterMapName)) {
+            status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName);
+            if (status == NAME_NOT_FOUND) {
+                ALOGE("Configuration for keyboard device '%s' requested keyboard character "
+                        "map '%s' but it was not found.",
+                        deviceIdenfifier.name.string(), keyLayoutName.string());
+            }
+        }
+
+        if (isComplete()) {
+            return OK;
+        }
+    }
+
+    // Try searching by device identifier.
+    if (probeKeyMap(deviceIdenfifier, String8::empty())) {
+        return OK;
+    }
+
+    // Fall back on the Generic key map.
+    // TODO Apply some additional heuristics here to figure out what kind of
+    //      generic key map to use (US English, etc.) for typical external keyboards.
+    if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
+        return OK;
+    }
+
+    // Try the Virtual key map as a last resort.
+    if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
+        return OK;
+    }
+
+    // Give up!
+    ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
+            deviceIdenfifier.name.string());
+    return NAME_NOT_FOUND;
+}
+
+bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& keyMapName) {
+    if (!haveKeyLayout()) {
+        loadKeyLayout(deviceIdentifier, keyMapName);
+    }
+    if (!haveKeyCharacterMap()) {
+        loadKeyCharacterMap(deviceIdentifier, keyMapName);
+    }
+    return isComplete();
+}
+
+status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& name) {
+    String8 path(getPath(deviceIdentifier, name,
+            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
+    if (path.isEmpty()) {
+        return NAME_NOT_FOUND;
+    }
+
+    status_t status = KeyLayoutMap::load(path, &keyLayoutMap);
+    if (status) {
+        return status;
+    }
+
+    keyLayoutFile.setTo(path);
+    return OK;
+}
+
+status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& name) {
+    String8 path(getPath(deviceIdentifier, name,
+            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
+    if (path.isEmpty()) {
+        return NAME_NOT_FOUND;
+    }
+
+    status_t status = KeyCharacterMap::load(path,
+            KeyCharacterMap::FORMAT_BASE, &keyCharacterMap);
+    if (status) {
+        return status;
+    }
+
+    keyCharacterMapFile.setTo(path);
+    return OK;
+}
+
+String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
+        const String8& name, InputDeviceConfigurationFileType type) {
+    return name.isEmpty()
+            ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
+            : getInputDeviceConfigurationFilePathByName(name, type);
+}
+
+
+// --- Global functions ---
+
+bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
+        const PropertyMap* deviceConfiguration, const KeyMap* keyMap) {
+    if (!keyMap->haveKeyCharacterMap()
+            || keyMap->keyCharacterMap->getKeyboardType()
+                    == KeyCharacterMap::KEYBOARD_TYPE_SPECIAL_FUNCTION) {
+        return false;
+    }
+
+    if (deviceConfiguration) {
+        bool builtIn = false;
+        if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn)
+                && builtIn) {
+            return true;
+        }
+    }
+
+    return strstr(deviceIdentifier.name.string(), "-keypad");
+}
+
+static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
+    while (list->literal) {
+        if (strcmp(literal, list->literal) == 0) {
+            return list->value;
+        }
+        list++;
+    }
+    return list->value;
+}
+
+static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
+    while (list->literal) {
+        if (list->value == value) {
+            return list->literal;
+        }
+        list++;
+    }
+    return NULL;
+}
+
+int32_t getKeyCodeByLabel(const char* label) {
+    return int32_t(lookupValueByLabel(label, KEYCODES));
+}
+
+uint32_t getKeyFlagByLabel(const char* label) {
+    return uint32_t(lookupValueByLabel(label, FLAGS));
+}
+
+int32_t getAxisByLabel(const char* label) {
+    return int32_t(lookupValueByLabel(label, AXES));
+}
+
+const char* getAxisLabel(int32_t axisId) {
+    return lookupLabelByValue(axisId, AXES);
+}
+
+static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
+    int32_t newMetaState;
+    if (down) {
+        newMetaState = oldMetaState | mask;
+    } else {
+        newMetaState = oldMetaState &
+                ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
+    }
+
+    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
+        newMetaState |= AMETA_ALT_ON;
+    }
+
+    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
+        newMetaState |= AMETA_SHIFT_ON;
+    }
+
+    if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
+        newMetaState |= AMETA_CTRL_ON;
+    }
+
+    if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
+        newMetaState |= AMETA_META_ON;
+    }
+    return newMetaState;
+}
+
+static int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) {
+    if (down) {
+        return oldMetaState;
+    } else {
+        return oldMetaState ^ mask;
+    }
+}
+
+int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
+    int32_t mask;
+    switch (keyCode) {
+    case AKEYCODE_ALT_LEFT:
+        return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_ALT_RIGHT:
+        return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_SHIFT_LEFT:
+        return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_SHIFT_RIGHT:
+        return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_SYM:
+        return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState);
+    case AKEYCODE_FUNCTION:
+        return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState);
+    case AKEYCODE_CTRL_LEFT:
+        return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_CTRL_RIGHT:
+        return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_META_LEFT:
+        return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState);
+    case AKEYCODE_META_RIGHT:
+        return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState);
+    case AKEYCODE_CAPS_LOCK:
+        return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState);
+    case AKEYCODE_NUM_LOCK:
+        return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState);
+    case AKEYCODE_SCROLL_LOCK:
+        return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState);
+    default:
+        return oldMetaState;
+    }
+}
+
+bool isMetaKey(int32_t keyCode) {
+    switch (keyCode) {
+    case AKEYCODE_ALT_LEFT:
+    case AKEYCODE_ALT_RIGHT:
+    case AKEYCODE_SHIFT_LEFT:
+    case AKEYCODE_SHIFT_RIGHT:
+    case AKEYCODE_SYM:
+    case AKEYCODE_FUNCTION:
+    case AKEYCODE_CTRL_LEFT:
+    case AKEYCODE_CTRL_RIGHT:
+    case AKEYCODE_META_LEFT:
+    case AKEYCODE_META_RIGHT:
+    case AKEYCODE_CAPS_LOCK:
+    case AKEYCODE_NUM_LOCK:
+    case AKEYCODE_SCROLL_LOCK:
+        return true;
+    default:
+        return false;
+    }
+}
+
+
+} // namespace android
diff --git a/libs/input/VelocityControl.cpp b/libs/input/VelocityControl.cpp
new file mode 100644
index 0000000..bcf55b0
--- /dev/null
+++ b/libs/input/VelocityControl.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VelocityControl"
+//#define LOG_NDEBUG 0
+
+// Log debug messages about acceleration.
+#define DEBUG_ACCELERATION 0
+
+#include <math.h>
+#include <limits.h>
+
+#include <input/VelocityControl.h>
+#include <utils/BitSet.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+// --- VelocityControl ---
+
+const nsecs_t VelocityControl::STOP_TIME;
+
+VelocityControl::VelocityControl() {
+    reset();
+}
+
+void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
+    mParameters = parameters;
+    reset();
+}
+
+void VelocityControl::reset() {
+    mLastMovementTime = LLONG_MIN;
+    mRawPosition.x = 0;
+    mRawPosition.y = 0;
+    mVelocityTracker.clear();
+}
+
+void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
+    if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
+        if (eventTime >= mLastMovementTime + STOP_TIME) {
+#if DEBUG_ACCELERATION
+            ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
+                    (eventTime - mLastMovementTime) * 0.000001f);
+#endif
+            reset();
+        }
+
+        mLastMovementTime = eventTime;
+        if (deltaX) {
+            mRawPosition.x += *deltaX;
+        }
+        if (deltaY) {
+            mRawPosition.y += *deltaY;
+        }
+        mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition);
+
+        float vx, vy;
+        float scale = mParameters.scale;
+        if (mVelocityTracker.getVelocity(0, &vx, &vy)) {
+            float speed = hypotf(vx, vy) * scale;
+            if (speed >= mParameters.highThreshold) {
+                // Apply full acceleration above the high speed threshold.
+                scale *= mParameters.acceleration;
+            } else if (speed > mParameters.lowThreshold) {
+                // Linearly interpolate the acceleration to apply between the low and high
+                // speed thresholds.
+                scale *= 1 + (speed - mParameters.lowThreshold)
+                        / (mParameters.highThreshold - mParameters.lowThreshold)
+                        * (mParameters.acceleration - 1);
+            }
+
+#if DEBUG_ACCELERATION
+            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
+                    "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
+                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
+                    mParameters.acceleration,
+                    vx, vy, speed, scale / mParameters.scale);
+#endif
+        } else {
+#if DEBUG_ACCELERATION
+            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
+                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
+                    mParameters.acceleration);
+#endif
+        }
+
+        if (deltaX) {
+            *deltaX *= scale;
+        }
+        if (deltaY) {
+            *deltaY *= scale;
+        }
+    }
+}
+
+} // namespace android
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
new file mode 100644
index 0000000..6c70c3c
--- /dev/null
+++ b/libs/input/VelocityTracker.cpp
@@ -0,0 +1,927 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VelocityTracker"
+//#define LOG_NDEBUG 0
+
+// Log debug messages about velocity tracking.
+#define DEBUG_VELOCITY 0
+
+// Log debug messages about the progress of the algorithm itself.
+#define DEBUG_STRATEGY 0
+
+#include <math.h>
+#include <limits.h>
+
+#include <cutils/properties.h>
+#include <input/VelocityTracker.h>
+#include <utils/BitSet.h>
+#include <utils/String8.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+// Nanoseconds per milliseconds.
+static const nsecs_t NANOS_PER_MS = 1000000;
+
+// Threshold for determining that a pointer has stopped moving.
+// Some input devices do not send ACTION_MOVE events in the case where a pointer has
+// stopped.  We need to detect this case so that we can accurately predict the
+// velocity after the pointer starts moving again.
+static const nsecs_t ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS;
+
+
+static float vectorDot(const float* a, const float* b, uint32_t m) {
+    float r = 0;
+    while (m--) {
+        r += *(a++) * *(b++);
+    }
+    return r;
+}
+
+static float vectorNorm(const float* a, uint32_t m) {
+    float r = 0;
+    while (m--) {
+        float t = *(a++);
+        r += t * t;
+    }
+    return sqrtf(r);
+}
+
+#if DEBUG_STRATEGY || DEBUG_VELOCITY
+static String8 vectorToString(const float* a, uint32_t m) {
+    String8 str;
+    str.append("[");
+    while (m--) {
+        str.appendFormat(" %f", *(a++));
+        if (m) {
+            str.append(",");
+        }
+    }
+    str.append(" ]");
+    return str;
+}
+
+static String8 matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMajor) {
+    String8 str;
+    str.append("[");
+    for (size_t i = 0; i < m; i++) {
+        if (i) {
+            str.append(",");
+        }
+        str.append(" [");
+        for (size_t j = 0; j < n; j++) {
+            if (j) {
+                str.append(",");
+            }
+            str.appendFormat(" %f", a[rowMajor ? i * n + j : j * m + i]);
+        }
+        str.append(" ]");
+    }
+    str.append(" ]");
+    return str;
+}
+#endif
+
+
+// --- VelocityTracker ---
+
+// The default velocity tracker strategy.
+// Although other strategies are available for testing and comparison purposes,
+// this is the strategy that applications will actually use.  Be very careful
+// when adjusting the default strategy because it can dramatically affect
+// (often in a bad way) the user experience.
+const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
+
+VelocityTracker::VelocityTracker(const char* strategy) :
+        mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
+    char value[PROPERTY_VALUE_MAX];
+
+    // Allow the default strategy to be overridden using a system property for debugging.
+    if (!strategy) {
+        int length = property_get("debug.velocitytracker.strategy", value, NULL);
+        if (length > 0) {
+            strategy = value;
+        } else {
+            strategy = DEFAULT_STRATEGY;
+        }
+    }
+
+    // Configure the strategy.
+    if (!configureStrategy(strategy)) {
+        ALOGD("Unrecognized velocity tracker strategy name '%s'.", strategy);
+        if (!configureStrategy(DEFAULT_STRATEGY)) {
+            LOG_ALWAYS_FATAL("Could not create the default velocity tracker strategy '%s'!",
+                    strategy);
+        }
+    }
+}
+
+VelocityTracker::~VelocityTracker() {
+    delete mStrategy;
+}
+
+bool VelocityTracker::configureStrategy(const char* strategy) {
+    mStrategy = createStrategy(strategy);
+    return mStrategy != NULL;
+}
+
+VelocityTrackerStrategy* VelocityTracker::createStrategy(const char* strategy) {
+    if (!strcmp("lsq1", strategy)) {
+        // 1st order least squares.  Quality: POOR.
+        // Frequently underfits the touch data especially when the finger accelerates
+        // or changes direction.  Often underestimates velocity.  The direction
+        // is overly influenced by historical touch points.
+        return new LeastSquaresVelocityTrackerStrategy(1);
+    }
+    if (!strcmp("lsq2", strategy)) {
+        // 2nd order least squares.  Quality: VERY GOOD.
+        // Pretty much ideal, but can be confused by certain kinds of touch data,
+        // particularly if the panel has a tendency to generate delayed,
+        // duplicate or jittery touch coordinates when the finger is released.
+        return new LeastSquaresVelocityTrackerStrategy(2);
+    }
+    if (!strcmp("lsq3", strategy)) {
+        // 3rd order least squares.  Quality: UNUSABLE.
+        // Frequently overfits the touch data yielding wildly divergent estimates
+        // of the velocity when the finger is released.
+        return new LeastSquaresVelocityTrackerStrategy(3);
+    }
+    if (!strcmp("wlsq2-delta", strategy)) {
+        // 2nd order weighted least squares, delta weighting.  Quality: EXPERIMENTAL
+        return new LeastSquaresVelocityTrackerStrategy(2,
+                LeastSquaresVelocityTrackerStrategy::WEIGHTING_DELTA);
+    }
+    if (!strcmp("wlsq2-central", strategy)) {
+        // 2nd order weighted least squares, central weighting.  Quality: EXPERIMENTAL
+        return new LeastSquaresVelocityTrackerStrategy(2,
+                LeastSquaresVelocityTrackerStrategy::WEIGHTING_CENTRAL);
+    }
+    if (!strcmp("wlsq2-recent", strategy)) {
+        // 2nd order weighted least squares, recent weighting.  Quality: EXPERIMENTAL
+        return new LeastSquaresVelocityTrackerStrategy(2,
+                LeastSquaresVelocityTrackerStrategy::WEIGHTING_RECENT);
+    }
+    if (!strcmp("int1", strategy)) {
+        // 1st order integrating filter.  Quality: GOOD.
+        // Not as good as 'lsq2' because it cannot estimate acceleration but it is
+        // more tolerant of errors.  Like 'lsq1', this strategy tends to underestimate
+        // the velocity of a fling but this strategy tends to respond to changes in
+        // direction more quickly and accurately.
+        return new IntegratingVelocityTrackerStrategy(1);
+    }
+    if (!strcmp("int2", strategy)) {
+        // 2nd order integrating filter.  Quality: EXPERIMENTAL.
+        // For comparison purposes only.  Unlike 'int1' this strategy can compensate
+        // for acceleration but it typically overestimates the effect.
+        return new IntegratingVelocityTrackerStrategy(2);
+    }
+    if (!strcmp("legacy", strategy)) {
+        // Legacy velocity tracker algorithm.  Quality: POOR.
+        // For comparison purposes only.  This algorithm is strongly influenced by
+        // old data points, consistently underestimates velocity and takes a very long
+        // time to adjust to changes in direction.
+        return new LegacyVelocityTrackerStrategy();
+    }
+    return NULL;
+}
+
+void VelocityTracker::clear() {
+    mCurrentPointerIdBits.clear();
+    mActivePointerId = -1;
+
+    mStrategy->clear();
+}
+
+void VelocityTracker::clearPointers(BitSet32 idBits) {
+    BitSet32 remainingIdBits(mCurrentPointerIdBits.value & ~idBits.value);
+    mCurrentPointerIdBits = remainingIdBits;
+
+    if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
+        mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
+    }
+
+    mStrategy->clearPointers(idBits);
+}
+
+void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
+    while (idBits.count() > MAX_POINTERS) {
+        idBits.clearLastMarkedBit();
+    }
+
+    if ((mCurrentPointerIdBits.value & idBits.value)
+            && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
+#if DEBUG_VELOCITY
+        ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
+                (eventTime - mLastEventTime) * 0.000001f);
+#endif
+        // We have not received any movements for too long.  Assume that all pointers
+        // have stopped.
+        mStrategy->clear();
+    }
+    mLastEventTime = eventTime;
+
+    mCurrentPointerIdBits = idBits;
+    if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
+        mActivePointerId = idBits.isEmpty() ? -1 : idBits.firstMarkedBit();
+    }
+
+    mStrategy->addMovement(eventTime, idBits, positions);
+
+#if DEBUG_VELOCITY
+    ALOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
+            eventTime, idBits.value, mActivePointerId);
+    for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
+        uint32_t id = iterBits.firstMarkedBit();
+        uint32_t index = idBits.getIndexOfBit(id);
+        iterBits.clearBit(id);
+        Estimator estimator;
+        getEstimator(id, &estimator);
+        ALOGD("  %d: position (%0.3f, %0.3f), "
+                "estimator (degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f)",
+                id, positions[index].x, positions[index].y,
+                int(estimator.degree),
+                vectorToString(estimator.xCoeff, estimator.degree + 1).string(),
+                vectorToString(estimator.yCoeff, estimator.degree + 1).string(),
+                estimator.confidence);
+    }
+#endif
+}
+
+void VelocityTracker::addMovement(const MotionEvent* event) {
+    int32_t actionMasked = event->getActionMasked();
+
+    switch (actionMasked) {
+    case AMOTION_EVENT_ACTION_DOWN:
+    case AMOTION_EVENT_ACTION_HOVER_ENTER:
+        // Clear all pointers on down before adding the new movement.
+        clear();
+        break;
+    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
+        // Start a new movement trace for a pointer that just went down.
+        // We do this on down instead of on up because the client may want to query the
+        // final velocity for a pointer that just went up.
+        BitSet32 downIdBits;
+        downIdBits.markBit(event->getPointerId(event->getActionIndex()));
+        clearPointers(downIdBits);
+        break;
+    }
+    case AMOTION_EVENT_ACTION_MOVE:
+    case AMOTION_EVENT_ACTION_HOVER_MOVE:
+        break;
+    default:
+        // Ignore all other actions because they do not convey any new information about
+        // pointer movement.  We also want to preserve the last known velocity of the pointers.
+        // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position
+        // of the pointers that went up.  ACTION_POINTER_UP does include the new position of
+        // pointers that remained down but we will also receive an ACTION_MOVE with this
+        // information if any of them actually moved.  Since we don't know how many pointers
+        // will be going up at once it makes sense to just wait for the following ACTION_MOVE
+        // before adding the movement.
+        return;
+    }
+
+    size_t pointerCount = event->getPointerCount();
+    if (pointerCount > MAX_POINTERS) {
+        pointerCount = MAX_POINTERS;
+    }
+
+    BitSet32 idBits;
+    for (size_t i = 0; i < pointerCount; i++) {
+        idBits.markBit(event->getPointerId(i));
+    }
+
+    uint32_t pointerIndex[MAX_POINTERS];
+    for (size_t i = 0; i < pointerCount; i++) {
+        pointerIndex[i] = idBits.getIndexOfBit(event->getPointerId(i));
+    }
+
+    nsecs_t eventTime;
+    Position positions[pointerCount];
+
+    size_t historySize = event->getHistorySize();
+    for (size_t h = 0; h < historySize; h++) {
+        eventTime = event->getHistoricalEventTime(h);
+        for (size_t i = 0; i < pointerCount; i++) {
+            uint32_t index = pointerIndex[i];
+            positions[index].x = event->getHistoricalX(i, h);
+            positions[index].y = event->getHistoricalY(i, h);
+        }
+        addMovement(eventTime, idBits, positions);
+    }
+
+    eventTime = event->getEventTime();
+    for (size_t i = 0; i < pointerCount; i++) {
+        uint32_t index = pointerIndex[i];
+        positions[index].x = event->getX(i);
+        positions[index].y = event->getY(i);
+    }
+    addMovement(eventTime, idBits, positions);
+}
+
+bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
+    Estimator estimator;
+    if (getEstimator(id, &estimator) && estimator.degree >= 1) {
+        *outVx = estimator.xCoeff[1];
+        *outVy = estimator.yCoeff[1];
+        return true;
+    }
+    *outVx = 0;
+    *outVy = 0;
+    return false;
+}
+
+bool VelocityTracker::getEstimator(uint32_t id, Estimator* outEstimator) const {
+    return mStrategy->getEstimator(id, outEstimator);
+}
+
+
+// --- LeastSquaresVelocityTrackerStrategy ---
+
+const nsecs_t LeastSquaresVelocityTrackerStrategy::HORIZON;
+const uint32_t LeastSquaresVelocityTrackerStrategy::HISTORY_SIZE;
+
+LeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy(
+        uint32_t degree, Weighting weighting) :
+        mDegree(degree), mWeighting(weighting) {
+    clear();
+}
+
+LeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {
+}
+
+void LeastSquaresVelocityTrackerStrategy::clear() {
+    mIndex = 0;
+    mMovements[0].idBits.clear();
+}
+
+void LeastSquaresVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
+    BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
+    mMovements[mIndex].idBits = remainingIdBits;
+}
+
+void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
+        const VelocityTracker::Position* positions) {
+    if (++mIndex == HISTORY_SIZE) {
+        mIndex = 0;
+    }
+
+    Movement& movement = mMovements[mIndex];
+    movement.eventTime = eventTime;
+    movement.idBits = idBits;
+    uint32_t count = idBits.count();
+    for (uint32_t i = 0; i < count; i++) {
+        movement.positions[i] = positions[i];
+    }
+}
+
+/**
+ * Solves a linear least squares problem to obtain a N degree polynomial that fits
+ * the specified input data as nearly as possible.
+ *
+ * Returns true if a solution is found, false otherwise.
+ *
+ * The input consists of two vectors of data points X and Y with indices 0..m-1
+ * along with a weight vector W of the same size.
+ *
+ * The output is a vector B with indices 0..n that describes a polynomial
+ * that fits the data, such the sum of W[i] * W[i] * abs(Y[i] - (B[0] + B[1] X[i]
+ * + B[2] X[i]^2 ... B[n] X[i]^n)) for all i between 0 and m-1 is minimized.
+ *
+ * Accordingly, the weight vector W should be initialized by the caller with the
+ * reciprocal square root of the variance of the error in each input data point.
+ * In other words, an ideal choice for W would be W[i] = 1 / var(Y[i]) = 1 / stddev(Y[i]).
+ * The weights express the relative importance of each data point.  If the weights are
+ * all 1, then the data points are considered to be of equal importance when fitting
+ * the polynomial.  It is a good idea to choose weights that diminish the importance
+ * of data points that may have higher than usual error margins.
+ *
+ * Errors among data points are assumed to be independent.  W is represented here
+ * as a vector although in the literature it is typically taken to be a diagonal matrix.
+ *
+ * That is to say, the function that generated the input data can be approximated
+ * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.
+ *
+ * The coefficient of determination (R^2) is also returned to describe the goodness
+ * of fit of the model for the given data.  It is a value between 0 and 1, where 1
+ * indicates perfect correspondence.
+ *
+ * This function first expands the X vector to a m by n matrix A such that
+ * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n, then
+ * multiplies it by w[i]./
+ *
+ * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q
+ * and an m by n upper triangular matrix R.  Because R is upper triangular (lower
+ * part is all zeroes), we can simplify the decomposition into an m by n matrix
+ * Q1 and a n by n matrix R1 such that A = Q1 R1.
+ *
+ * Finally we solve the system of linear equations given by R1 B = (Qtranspose W Y)
+ * to find B.
+ *
+ * For efficiency, we lay out A and Q column-wise in memory because we frequently
+ * operate on the column vectors.  Conversely, we lay out R row-wise.
+ *
+ * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
+ * http://en.wikipedia.org/wiki/Gram-Schmidt
+ */
+static bool solveLeastSquares(const float* x, const float* y,
+        const float* w, uint32_t m, uint32_t n, float* outB, float* outDet) {
+#if DEBUG_STRATEGY
+    ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
+            vectorToString(x, m).string(), vectorToString(y, m).string(),
+            vectorToString(w, m).string());
+#endif
+
+    // Expand the X vector to a matrix A, pre-multiplied by the weights.
+    float a[n][m]; // column-major order
+    for (uint32_t h = 0; h < m; h++) {
+        a[0][h] = w[h];
+        for (uint32_t i = 1; i < n; i++) {
+            a[i][h] = a[i - 1][h] * x[h];
+        }
+    }
+#if DEBUG_STRATEGY
+    ALOGD("  - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).string());
+#endif
+
+    // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
+    float q[n][m]; // orthonormal basis, column-major order
+    float r[n][n]; // upper triangular matrix, row-major order
+    for (uint32_t j = 0; j < n; j++) {
+        for (uint32_t h = 0; h < m; h++) {
+            q[j][h] = a[j][h];
+        }
+        for (uint32_t i = 0; i < j; i++) {
+            float dot = vectorDot(&q[j][0], &q[i][0], m);
+            for (uint32_t h = 0; h < m; h++) {
+                q[j][h] -= dot * q[i][h];
+            }
+        }
+
+        float norm = vectorNorm(&q[j][0], m);
+        if (norm < 0.000001f) {
+            // vectors are linearly dependent or zero so no solution
+#if DEBUG_STRATEGY
+            ALOGD("  - no solution, norm=%f", norm);
+#endif
+            return false;
+        }
+
+        float invNorm = 1.0f / norm;
+        for (uint32_t h = 0; h < m; h++) {
+            q[j][h] *= invNorm;
+        }
+        for (uint32_t i = 0; i < n; i++) {
+            r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);
+        }
+    }
+#if DEBUG_STRATEGY
+    ALOGD("  - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).string());
+    ALOGD("  - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).string());
+
+    // calculate QR, if we factored A correctly then QR should equal A
+    float qr[n][m];
+    for (uint32_t h = 0; h < m; h++) {
+        for (uint32_t i = 0; i < n; i++) {
+            qr[i][h] = 0;
+            for (uint32_t j = 0; j < n; j++) {
+                qr[i][h] += q[j][h] * r[j][i];
+            }
+        }
+    }
+    ALOGD("  - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).string());
+#endif
+
+    // Solve R B = Qt W Y to find B.  This is easy because R is upper triangular.
+    // We just work from bottom-right to top-left calculating B's coefficients.
+    float wy[m];
+    for (uint32_t h = 0; h < m; h++) {
+        wy[h] = y[h] * w[h];
+    }
+    for (uint32_t i = n; i-- != 0; ) {
+        outB[i] = vectorDot(&q[i][0], wy, m);
+        for (uint32_t j = n - 1; j > i; j--) {
+            outB[i] -= r[i][j] * outB[j];
+        }
+        outB[i] /= r[i][i];
+    }
+#if DEBUG_STRATEGY
+    ALOGD("  - b=%s", vectorToString(outB, n).string());
+#endif
+
+    // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
+    // SSerr is the residual sum of squares (variance of the error),
+    // and SStot is the total sum of squares (variance of the data) where each
+    // has been weighted.
+    float ymean = 0;
+    for (uint32_t h = 0; h < m; h++) {
+        ymean += y[h];
+    }
+    ymean /= m;
+
+    float sserr = 0;
+    float sstot = 0;
+    for (uint32_t h = 0; h < m; h++) {
+        float err = y[h] - outB[0];
+        float term = 1;
+        for (uint32_t i = 1; i < n; i++) {
+            term *= x[h];
+            err -= term * outB[i];
+        }
+        sserr += w[h] * w[h] * err * err;
+        float var = y[h] - ymean;
+        sstot += w[h] * w[h] * var * var;
+    }
+    *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
+#if DEBUG_STRATEGY
+    ALOGD("  - sserr=%f", sserr);
+    ALOGD("  - sstot=%f", sstot);
+    ALOGD("  - det=%f", *outDet);
+#endif
+    return true;
+}
+
+bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
+        VelocityTracker::Estimator* outEstimator) const {
+    outEstimator->clear();
+
+    // Iterate over movement samples in reverse time order and collect samples.
+    float x[HISTORY_SIZE];
+    float y[HISTORY_SIZE];
+    float w[HISTORY_SIZE];
+    float time[HISTORY_SIZE];
+    uint32_t m = 0;
+    uint32_t index = mIndex;
+    const Movement& newestMovement = mMovements[mIndex];
+    do {
+        const Movement& movement = mMovements[index];
+        if (!movement.idBits.hasBit(id)) {
+            break;
+        }
+
+        nsecs_t age = newestMovement.eventTime - movement.eventTime;
+        if (age > HORIZON) {
+            break;
+        }
+
+        const VelocityTracker::Position& position = movement.getPosition(id);
+        x[m] = position.x;
+        y[m] = position.y;
+        w[m] = chooseWeight(index);
+        time[m] = -age * 0.000000001f;
+        index = (index == 0 ? HISTORY_SIZE : index) - 1;
+    } while (++m < HISTORY_SIZE);
+
+    if (m == 0) {
+        return false; // no data
+    }
+
+    // Calculate a least squares polynomial fit.
+    uint32_t degree = mDegree;
+    if (degree > m - 1) {
+        degree = m - 1;
+    }
+    if (degree >= 1) {
+        float xdet, ydet;
+        uint32_t n = degree + 1;
+        if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)
+                && solveLeastSquares(time, y, w, m, n, outEstimator->yCoeff, &ydet)) {
+            outEstimator->time = newestMovement.eventTime;
+            outEstimator->degree = degree;
+            outEstimator->confidence = xdet * ydet;
+#if DEBUG_STRATEGY
+            ALOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
+                    int(outEstimator->degree),
+                    vectorToString(outEstimator->xCoeff, n).string(),
+                    vectorToString(outEstimator->yCoeff, n).string(),
+                    outEstimator->confidence);
+#endif
+            return true;
+        }
+    }
+
+    // No velocity data available for this pointer, but we do have its current position.
+    outEstimator->xCoeff[0] = x[0];
+    outEstimator->yCoeff[0] = y[0];
+    outEstimator->time = newestMovement.eventTime;
+    outEstimator->degree = 0;
+    outEstimator->confidence = 1;
+    return true;
+}
+
+float LeastSquaresVelocityTrackerStrategy::chooseWeight(uint32_t index) const {
+    switch (mWeighting) {
+    case WEIGHTING_DELTA: {
+        // Weight points based on how much time elapsed between them and the next
+        // point so that points that "cover" a shorter time span are weighed less.
+        //   delta  0ms: 0.5
+        //   delta 10ms: 1.0
+        if (index == mIndex) {
+            return 1.0f;
+        }
+        uint32_t nextIndex = (index + 1) % HISTORY_SIZE;
+        float deltaMillis = (mMovements[nextIndex].eventTime- mMovements[index].eventTime)
+                * 0.000001f;
+        if (deltaMillis < 0) {
+            return 0.5f;
+        }
+        if (deltaMillis < 10) {
+            return 0.5f + deltaMillis * 0.05;
+        }
+        return 1.0f;
+    }
+
+    case WEIGHTING_CENTRAL: {
+        // Weight points based on their age, weighing very recent and very old points less.
+        //   age  0ms: 0.5
+        //   age 10ms: 1.0
+        //   age 50ms: 1.0
+        //   age 60ms: 0.5
+        float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
+                * 0.000001f;
+        if (ageMillis < 0) {
+            return 0.5f;
+        }
+        if (ageMillis < 10) {
+            return 0.5f + ageMillis * 0.05;
+        }
+        if (ageMillis < 50) {
+            return 1.0f;
+        }
+        if (ageMillis < 60) {
+            return 0.5f + (60 - ageMillis) * 0.05;
+        }
+        return 0.5f;
+    }
+
+    case WEIGHTING_RECENT: {
+        // Weight points based on their age, weighing older points less.
+        //   age   0ms: 1.0
+        //   age  50ms: 1.0
+        //   age 100ms: 0.5
+        float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
+                * 0.000001f;
+        if (ageMillis < 50) {
+            return 1.0f;
+        }
+        if (ageMillis < 100) {
+            return 0.5f + (100 - ageMillis) * 0.01f;
+        }
+        return 0.5f;
+    }
+
+    case WEIGHTING_NONE:
+    default:
+        return 1.0f;
+    }
+}
+
+
+// --- IntegratingVelocityTrackerStrategy ---
+
+IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy(uint32_t degree) :
+        mDegree(degree) {
+}
+
+IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {
+}
+
+void IntegratingVelocityTrackerStrategy::clear() {
+    mPointerIdBits.clear();
+}
+
+void IntegratingVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
+    mPointerIdBits.value &= ~idBits.value;
+}
+
+void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
+        const VelocityTracker::Position* positions) {
+    uint32_t index = 0;
+    for (BitSet32 iterIdBits(idBits); !iterIdBits.isEmpty();) {
+        uint32_t id = iterIdBits.clearFirstMarkedBit();
+        State& state = mPointerState[id];
+        const VelocityTracker::Position& position = positions[index++];
+        if (mPointerIdBits.hasBit(id)) {
+            updateState(state, eventTime, position.x, position.y);
+        } else {
+            initState(state, eventTime, position.x, position.y);
+        }
+    }
+
+    mPointerIdBits = idBits;
+}
+
+bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
+        VelocityTracker::Estimator* outEstimator) const {
+    outEstimator->clear();
+
+    if (mPointerIdBits.hasBit(id)) {
+        const State& state = mPointerState[id];
+        populateEstimator(state, outEstimator);
+        return true;
+    }
+
+    return false;
+}
+
+void IntegratingVelocityTrackerStrategy::initState(State& state,
+        nsecs_t eventTime, float xpos, float ypos) const {
+    state.updateTime = eventTime;
+    state.degree = 0;
+
+    state.xpos = xpos;
+    state.xvel = 0;
+    state.xaccel = 0;
+    state.ypos = ypos;
+    state.yvel = 0;
+    state.yaccel = 0;
+}
+
+void IntegratingVelocityTrackerStrategy::updateState(State& state,
+        nsecs_t eventTime, float xpos, float ypos) const {
+    const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
+    const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds
+
+    if (eventTime <= state.updateTime + MIN_TIME_DELTA) {
+        return;
+    }
+
+    float dt = (eventTime - state.updateTime) * 0.000000001f;
+    state.updateTime = eventTime;
+
+    float xvel = (xpos - state.xpos) / dt;
+    float yvel = (ypos - state.ypos) / dt;
+    if (state.degree == 0) {
+        state.xvel = xvel;
+        state.yvel = yvel;
+        state.degree = 1;
+    } else {
+        float alpha = dt / (FILTER_TIME_CONSTANT + dt);
+        if (mDegree == 1) {
+            state.xvel += (xvel - state.xvel) * alpha;
+            state.yvel += (yvel - state.yvel) * alpha;
+        } else {
+            float xaccel = (xvel - state.xvel) / dt;
+            float yaccel = (yvel - state.yvel) / dt;
+            if (state.degree == 1) {
+                state.xaccel = xaccel;
+                state.yaccel = yaccel;
+                state.degree = 2;
+            } else {
+                state.xaccel += (xaccel - state.xaccel) * alpha;
+                state.yaccel += (yaccel - state.yaccel) * alpha;
+            }
+            state.xvel += (state.xaccel * dt) * alpha;
+            state.yvel += (state.yaccel * dt) * alpha;
+        }
+    }
+    state.xpos = xpos;
+    state.ypos = ypos;
+}
+
+void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
+        VelocityTracker::Estimator* outEstimator) const {
+    outEstimator->time = state.updateTime;
+    outEstimator->confidence = 1.0f;
+    outEstimator->degree = state.degree;
+    outEstimator->xCoeff[0] = state.xpos;
+    outEstimator->xCoeff[1] = state.xvel;
+    outEstimator->xCoeff[2] = state.xaccel / 2;
+    outEstimator->yCoeff[0] = state.ypos;
+    outEstimator->yCoeff[1] = state.yvel;
+    outEstimator->yCoeff[2] = state.yaccel / 2;
+}
+
+
+// --- LegacyVelocityTrackerStrategy ---
+
+const nsecs_t LegacyVelocityTrackerStrategy::HORIZON;
+const uint32_t LegacyVelocityTrackerStrategy::HISTORY_SIZE;
+const nsecs_t LegacyVelocityTrackerStrategy::MIN_DURATION;
+
+LegacyVelocityTrackerStrategy::LegacyVelocityTrackerStrategy() {
+    clear();
+}
+
+LegacyVelocityTrackerStrategy::~LegacyVelocityTrackerStrategy() {
+}
+
+void LegacyVelocityTrackerStrategy::clear() {
+    mIndex = 0;
+    mMovements[0].idBits.clear();
+}
+
+void LegacyVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
+    BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
+    mMovements[mIndex].idBits = remainingIdBits;
+}
+
+void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
+        const VelocityTracker::Position* positions) {
+    if (++mIndex == HISTORY_SIZE) {
+        mIndex = 0;
+    }
+
+    Movement& movement = mMovements[mIndex];
+    movement.eventTime = eventTime;
+    movement.idBits = idBits;
+    uint32_t count = idBits.count();
+    for (uint32_t i = 0; i < count; i++) {
+        movement.positions[i] = positions[i];
+    }
+}
+
+bool LegacyVelocityTrackerStrategy::getEstimator(uint32_t id,
+        VelocityTracker::Estimator* outEstimator) const {
+    outEstimator->clear();
+
+    const Movement& newestMovement = mMovements[mIndex];
+    if (!newestMovement.idBits.hasBit(id)) {
+        return false; // no data
+    }
+
+    // Find the oldest sample that contains the pointer and that is not older than HORIZON.
+    nsecs_t minTime = newestMovement.eventTime - HORIZON;
+    uint32_t oldestIndex = mIndex;
+    uint32_t numTouches = 1;
+    do {
+        uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1;
+        const Movement& nextOldestMovement = mMovements[nextOldestIndex];
+        if (!nextOldestMovement.idBits.hasBit(id)
+                || nextOldestMovement.eventTime < minTime) {
+            break;
+        }
+        oldestIndex = nextOldestIndex;
+    } while (++numTouches < HISTORY_SIZE);
+
+    // Calculate an exponentially weighted moving average of the velocity estimate
+    // at different points in time measured relative to the oldest sample.
+    // This is essentially an IIR filter.  Newer samples are weighted more heavily
+    // than older samples.  Samples at equal time points are weighted more or less
+    // equally.
+    //
+    // One tricky problem is that the sample data may be poorly conditioned.
+    // Sometimes samples arrive very close together in time which can cause us to
+    // overestimate the velocity at that time point.  Most samples might be measured
+    // 16ms apart but some consecutive samples could be only 0.5sm apart because
+    // the hardware or driver reports them irregularly or in bursts.
+    float accumVx = 0;
+    float accumVy = 0;
+    uint32_t index = oldestIndex;
+    uint32_t samplesUsed = 0;
+    const Movement& oldestMovement = mMovements[oldestIndex];
+    const VelocityTracker::Position& oldestPosition = oldestMovement.getPosition(id);
+    nsecs_t lastDuration = 0;
+
+    while (numTouches-- > 1) {
+        if (++index == HISTORY_SIZE) {
+            index = 0;
+        }
+        const Movement& movement = mMovements[index];
+        nsecs_t duration = movement.eventTime - oldestMovement.eventTime;
+
+        // If the duration between samples is small, we may significantly overestimate
+        // the velocity.  Consequently, we impose a minimum duration constraint on the
+        // samples that we include in the calculation.
+        if (duration >= MIN_DURATION) {
+            const VelocityTracker::Position& position = movement.getPosition(id);
+            float scale = 1000000000.0f / duration; // one over time delta in seconds
+            float vx = (position.x - oldestPosition.x) * scale;
+            float vy = (position.y - oldestPosition.y) * scale;
+            accumVx = (accumVx * lastDuration + vx * duration) / (duration + lastDuration);
+            accumVy = (accumVy * lastDuration + vy * duration) / (duration + lastDuration);
+            lastDuration = duration;
+            samplesUsed += 1;
+        }
+    }
+
+    // Report velocity.
+    const VelocityTracker::Position& newestPosition = newestMovement.getPosition(id);
+    outEstimator->time = newestMovement.eventTime;
+    outEstimator->confidence = 1;
+    outEstimator->xCoeff[0] = newestPosition.x;
+    outEstimator->yCoeff[0] = newestPosition.y;
+    if (samplesUsed) {
+        outEstimator->xCoeff[1] = accumVx;
+        outEstimator->yCoeff[1] = accumVy;
+        outEstimator->degree = 1;
+    } else {
+        outEstimator->degree = 0;
+    }
+    return true;
+}
+
+} // namespace android
diff --git a/libs/input/VirtualKeyMap.cpp b/libs/input/VirtualKeyMap.cpp
new file mode 100644
index 0000000..28ea717
--- /dev/null
+++ b/libs/input/VirtualKeyMap.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VirtualKeyMap"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <input/VirtualKeyMap.h>
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/Tokenizer.h>
+#include <utils/Timers.h>
+
+// Enables debug output for the parser.
+#define DEBUG_PARSER 0
+
+// Enables debug output for parser performance.
+#define DEBUG_PARSER_PERFORMANCE 0
+
+
+namespace android {
+
+static const char* WHITESPACE = " \t\r";
+static const char* WHITESPACE_OR_FIELD_DELIMITER = " \t\r:";
+
+
+// --- VirtualKeyMap ---
+
+VirtualKeyMap::VirtualKeyMap() {
+}
+
+VirtualKeyMap::~VirtualKeyMap() {
+}
+
+status_t VirtualKeyMap::load(const String8& filename, VirtualKeyMap** outMap) {
+    *outMap = NULL;
+
+    Tokenizer* tokenizer;
+    status_t status = Tokenizer::open(filename, &tokenizer);
+    if (status) {
+        ALOGE("Error %d opening virtual key map file %s.", status, filename.string());
+    } else {
+        VirtualKeyMap* map = new VirtualKeyMap();
+        if (!map) {
+            ALOGE("Error allocating virtual key map.");
+            status = NO_MEMORY;
+        } else {
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+            Parser parser(map, tokenizer);
+            status = parser.parse();
+#if DEBUG_PARSER_PERFORMANCE
+            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
+            ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
+                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
+                    elapsedTime / 1000000.0);
+#endif
+            if (status) {
+                delete map;
+            } else {
+                *outMap = map;
+            }
+        }
+        delete tokenizer;
+    }
+    return status;
+}
+
+
+// --- VirtualKeyMap::Parser ---
+
+VirtualKeyMap::Parser::Parser(VirtualKeyMap* map, Tokenizer* tokenizer) :
+        mMap(map), mTokenizer(tokenizer) {
+}
+
+VirtualKeyMap::Parser::~Parser() {
+}
+
+status_t VirtualKeyMap::Parser::parse() {
+    while (!mTokenizer->isEof()) {
+#if DEBUG_PARSER
+        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
+                mTokenizer->peekRemainderOfLine().string());
+#endif
+
+        mTokenizer->skipDelimiters(WHITESPACE);
+
+        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
+            // Multiple keys can appear on one line or they can be broken up across multiple lines.
+            do {
+                String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
+                if (token != "0x01") {
+                    ALOGE("%s: Unknown virtual key type, expected 0x01.",
+                          mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+
+                VirtualKeyDefinition defn;
+                bool success = parseNextIntField(&defn.scanCode)
+                        && parseNextIntField(&defn.centerX)
+                        && parseNextIntField(&defn.centerY)
+                        && parseNextIntField(&defn.width)
+                        && parseNextIntField(&defn.height);
+                if (!success) {
+                    ALOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
+                          mTokenizer->getLocation().string());
+                    return BAD_VALUE;
+                }
+
+#if DEBUG_PARSER
+                ALOGD("Parsed virtual key: scanCode=%d, centerX=%d, centerY=%d, "
+                        "width=%d, height=%d",
+                        defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height);
+#endif
+                mMap->mVirtualKeys.push(defn);
+            } while (consumeFieldDelimiterAndSkipWhitespace());
+
+            if (!mTokenizer->isEol()) {
+                ALOGE("%s: Expected end of line, got '%s'.",
+                        mTokenizer->getLocation().string(),
+                        mTokenizer->peekRemainderOfLine().string());
+                return BAD_VALUE;
+            }
+        }
+
+        mTokenizer->nextLine();
+    }
+
+    return NO_ERROR;
+}
+
+bool VirtualKeyMap::Parser::consumeFieldDelimiterAndSkipWhitespace() {
+    mTokenizer->skipDelimiters(WHITESPACE);
+    if (mTokenizer->peekChar() == ':') {
+        mTokenizer->nextChar();
+        mTokenizer->skipDelimiters(WHITESPACE);
+        return true;
+    }
+    return false;
+}
+
+bool VirtualKeyMap::Parser::parseNextIntField(int32_t* outValue) {
+    if (!consumeFieldDelimiterAndSkipWhitespace()) {
+        return false;
+    }
+
+    String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
+    char* end;
+    *outValue = strtol(token.string(), &end, 0);
+    if (token.isEmpty() || *end != '\0') {
+        ALOGE("Expected an integer, got '%s'.", token.string());
+        return false;
+    }
+    return true;
+}
+
+} // namespace android
diff --git a/libs/input/tests/Android.mk b/libs/input/tests/Android.mk
new file mode 100644
index 0000000..4292741
--- /dev/null
+++ b/libs/input/tests/Android.mk
@@ -0,0 +1,34 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# Build the unit tests.
+test_src_files := \
+    InputChannel_test.cpp \
+    InputEvent_test.cpp \
+    InputPublisherAndConsumer_test.cpp
+
+shared_libraries := \
+    libinput \
+    libcutils \
+    libutils \
+    libbinder \
+    libui \
+    libstlport \
+    libskia
+
+static_libraries := \
+    libgtest \
+    libgtest_main
+
+$(foreach file,$(test_src_files), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval include $(BUILD_NATIVE_TEST)) \
+)
+
+# Build the manual test programs.
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp
new file mode 100644
index 0000000..e71ebe2
--- /dev/null
+++ b/libs/input/tests/InputChannel_test.cpp
@@ -0,0 +1,159 @@
+/*
+ * 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 "TestHelpers.h"
+
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+
+#include <gtest/gtest.h>
+#include <input/InputTransport.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class InputChannelTest : public testing::Test {
+protected:
+    virtual void SetUp() { }
+    virtual void TearDown() { }
+};
+
+
+TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
+    // Our purpose here is to verify that the input channel destructor closes the
+    // file descriptor provided to it.  One easy way is to provide it with one end
+    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
+    Pipe pipe;
+
+    sp<InputChannel> inputChannel = new InputChannel(String8("channel name"), pipe.sendFd);
+
+    EXPECT_STREQ("channel name", inputChannel->getName().string())
+            << "channel should have provided name";
+    EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
+            << "channel should have provided fd";
+
+    inputChannel.clear(); // destroys input channel
+
+    EXPECT_EQ(-EPIPE, pipe.readSignal())
+            << "channel should have closed fd when destroyed";
+
+    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
+    pipe.sendFd = -1;
+}
+
+TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    // Name
+    EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
+            << "server channel should have suffixed name";
+    EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
+            << "client channel should have suffixed name";
+
+    // Server->Client communication
+    InputMessage serverMsg;
+    memset(&serverMsg, 0, sizeof(InputMessage));
+    serverMsg.header.type = InputMessage::TYPE_KEY;
+    serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
+    EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
+            << "server channel should be able to send message to client channel";
+
+    InputMessage clientMsg;
+    EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
+            << "client channel should be able to receive message from server channel";
+    EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
+            << "client channel should receive the correct message from server channel";
+    EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
+            << "client channel should receive the correct message from server channel";
+
+    // Client->Server communication
+    InputMessage clientReply;
+    memset(&clientReply, 0, sizeof(InputMessage));
+    clientReply.header.type = InputMessage::TYPE_FINISHED;
+    clientReply.body.finished.seq = 0x11223344;
+    clientReply.body.finished.handled = true;
+    EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
+            << "client channel should be able to send message to server channel";
+
+    InputMessage serverReply;
+    EXPECT_EQ(OK, serverChannel->receiveMessage(&serverReply))
+            << "server channel should be able to receive message from client channel";
+    EXPECT_EQ(clientReply.header.type, serverReply.header.type)
+            << "server channel should receive the correct message from client channel";
+    EXPECT_EQ(clientReply.body.finished.seq, serverReply.body.finished.seq)
+            << "server channel should receive the correct message from client channel";
+    EXPECT_EQ(clientReply.body.finished.handled, serverReply.body.finished.handled)
+            << "server channel should receive the correct message from client channel";
+}
+
+TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    InputMessage msg;
+    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveMessage(&msg))
+            << "receiveMessage should have returned WOULD_BLOCK";
+}
+
+TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    serverChannel.clear(); // close server channel
+
+    InputMessage msg;
+    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveMessage(&msg))
+            << "receiveMessage should have returned DEAD_OBJECT";
+}
+
+TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    serverChannel.clear(); // close server channel
+
+    InputMessage msg;
+    msg.header.type = InputMessage::TYPE_KEY;
+    EXPECT_EQ(DEAD_OBJECT, clientChannel->sendMessage(&msg))
+            << "sendMessage should have returned DEAD_OBJECT";
+}
+
+
+} // namespace android
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
new file mode 100644
index 0000000..ab1feb3
--- /dev/null
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -0,0 +1,581 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <math.h>
+
+#include <binder/Parcel.h>
+#include <core/SkMatrix.h>
+#include <gtest/gtest.h>
+#include <input/Input.h>
+
+namespace android {
+
+class BaseTest : public testing::Test {
+protected:
+    virtual void SetUp() { }
+    virtual void TearDown() { }
+};
+
+// --- PointerCoordsTest ---
+
+class PointerCoordsTest : public BaseTest {
+};
+
+TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
+    PointerCoords coords;
+    coords.clear();
+
+    ASSERT_EQ(0ULL, coords.bits);
+}
+
+TEST_F(PointerCoordsTest, AxisValues) {
+    float* valuePtr;
+    PointerCoords coords;
+    coords.clear();
+
+    // Check invariants when no axes are present.
+    ASSERT_EQ(0, coords.getAxisValue(0))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(0, coords.getAxisValue(1))
+            << "getAxisValue should return zero because axis is not present";
+
+    // Set first axis.
+    ASSERT_EQ(OK, coords.setAxisValue(1, 5));
+    ASSERT_EQ(0x00000002ULL, coords.bits);
+    ASSERT_EQ(5, coords.values[0]);
+
+    ASSERT_EQ(0, coords.getAxisValue(0))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(5, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+
+    // Set an axis with a higher id than all others.  (appending value at the end)
+    ASSERT_EQ(OK, coords.setAxisValue(3, 2));
+    ASSERT_EQ(0x0000000aULL, coords.bits);
+    ASSERT_EQ(5, coords.values[0]);
+    ASSERT_EQ(2, coords.values[1]);
+
+    ASSERT_EQ(0, coords.getAxisValue(0))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(5, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(0, coords.getAxisValue(2))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Set an axis with an id lower than all others.  (prepending value at beginning)
+    ASSERT_EQ(OK, coords.setAxisValue(0, 4));
+    ASSERT_EQ(0x0000000bULL, coords.bits);
+    ASSERT_EQ(4, coords.values[0]);
+    ASSERT_EQ(5, coords.values[1]);
+    ASSERT_EQ(2, coords.values[2]);
+
+    ASSERT_EQ(4, coords.getAxisValue(0))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(5, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(0, coords.getAxisValue(2))
+            << "getAxisValue should return zero because axis is not present";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Set an axis with an id between the others.  (inserting value in the middle)
+    ASSERT_EQ(OK, coords.setAxisValue(2, 1));
+    ASSERT_EQ(0x0000000fULL, coords.bits);
+    ASSERT_EQ(4, coords.values[0]);
+    ASSERT_EQ(5, coords.values[1]);
+    ASSERT_EQ(1, coords.values[2]);
+    ASSERT_EQ(2, coords.values[3]);
+
+    ASSERT_EQ(4, coords.getAxisValue(0))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(5, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(1, coords.getAxisValue(2))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Set an existing axis value in place.
+    ASSERT_EQ(OK, coords.setAxisValue(1, 6));
+    ASSERT_EQ(0x0000000fULL, coords.bits);
+    ASSERT_EQ(4, coords.values[0]);
+    ASSERT_EQ(6, coords.values[1]);
+    ASSERT_EQ(1, coords.values[2]);
+    ASSERT_EQ(2, coords.values[3]);
+
+    ASSERT_EQ(4, coords.getAxisValue(0))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(6, coords.getAxisValue(1))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(1, coords.getAxisValue(2))
+            << "getAxisValue should return value of axis";
+    ASSERT_EQ(2, coords.getAxisValue(3))
+            << "getAxisValue should return value of axis";
+
+    // Set maximum number of axes.
+    for (size_t axis = 4; axis < PointerCoords::MAX_AXES; axis++) {
+        ASSERT_EQ(OK, coords.setAxisValue(axis, axis));
+    }
+    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+
+    // Try to set one more axis beyond maximum number.
+    // Ensure bits are unchanged.
+    ASSERT_EQ(NO_MEMORY, coords.setAxisValue(PointerCoords::MAX_AXES, 100));
+    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+}
+
+TEST_F(PointerCoordsTest, Parcel) {
+    Parcel parcel;
+
+    PointerCoords inCoords;
+    inCoords.clear();
+    PointerCoords outCoords;
+
+    // Round trip with empty coords.
+    inCoords.writeToParcel(&parcel);
+    parcel.setDataPosition(0);
+    outCoords.readFromParcel(&parcel);
+
+    ASSERT_EQ(0ULL, outCoords.bits);
+
+    // Round trip with some values.
+    parcel.freeData();
+    inCoords.setAxisValue(2, 5);
+    inCoords.setAxisValue(5, 8);
+
+    inCoords.writeToParcel(&parcel);
+    parcel.setDataPosition(0);
+    outCoords.readFromParcel(&parcel);
+
+    ASSERT_EQ(outCoords.bits, inCoords.bits);
+    ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
+    ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
+}
+
+
+// --- KeyEventTest ---
+
+class KeyEventTest : public BaseTest {
+};
+
+TEST_F(KeyEventTest, Properties) {
+    KeyEvent event;
+
+    // Initialize and get properties.
+    const nsecs_t ARBITRARY_DOWN_TIME = 1;
+    const nsecs_t ARBITRARY_EVENT_TIME = 2;
+    event.initialize(2, AINPUT_SOURCE_GAMEPAD, AKEY_EVENT_ACTION_DOWN,
+            AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
+            AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
+
+    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
+    ASSERT_EQ(2, event.getDeviceId());
+    ASSERT_EQ(AINPUT_SOURCE_GAMEPAD, event.getSource());
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
+    ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
+    ASSERT_EQ(121, event.getScanCode());
+    ASSERT_EQ(AMETA_ALT_ON, event.getMetaState());
+    ASSERT_EQ(1, event.getRepeatCount());
+    ASSERT_EQ(ARBITRARY_DOWN_TIME, event.getDownTime());
+    ASSERT_EQ(ARBITRARY_EVENT_TIME, event.getEventTime());
+
+    // Set source.
+    event.setSource(AINPUT_SOURCE_JOYSTICK);
+    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+}
+
+
+// --- MotionEventTest ---
+
+class MotionEventTest : public BaseTest {
+protected:
+    static const nsecs_t ARBITRARY_DOWN_TIME;
+    static const nsecs_t ARBITRARY_EVENT_TIME;
+    static const float X_OFFSET;
+    static const float Y_OFFSET;
+
+    void initializeEventWithHistory(MotionEvent* event);
+    void assertEqualsEventWithHistory(const MotionEvent* event);
+};
+
+const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
+const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
+const float MotionEventTest::X_OFFSET = 1.0f;
+const float MotionEventTest::Y_OFFSET = 1.1f;
+
+void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
+    PointerProperties pointerProperties[2];
+    pointerProperties[0].clear();
+    pointerProperties[0].id = 1;
+    pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+    pointerProperties[1].clear();
+    pointerProperties[1].id = 2;
+    pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+
+    PointerCoords pointerCoords[2];
+    pointerCoords[0].clear();
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 11);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 12);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 13);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 14);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 15);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
+    pointerCoords[1].clear();
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 23);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 24);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 25);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
+    event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
+            AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
+            AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
+            X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
+            ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
+            2, pointerProperties, pointerCoords);
+
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 113);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 114);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 115);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 123);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 124);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 125);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
+    event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
+
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 213);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 214);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 215);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
+    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 223);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 224);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 225);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 226);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 227);
+    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 228);
+    event->addSample(ARBITRARY_EVENT_TIME + 2, pointerCoords);
+}
+
+void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
+    // Check properties.
+    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
+    ASSERT_EQ(2, event->getDeviceId());
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, event->getSource());
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
+    ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
+    ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
+    ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
+    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
+    ASSERT_EQ(X_OFFSET, event->getXOffset());
+    ASSERT_EQ(Y_OFFSET, event->getYOffset());
+    ASSERT_EQ(2.0f, event->getXPrecision());
+    ASSERT_EQ(2.1f, event->getYPrecision());
+    ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
+
+    ASSERT_EQ(2U, event->getPointerCount());
+    ASSERT_EQ(1, event->getPointerId(0));
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, event->getToolType(0));
+    ASSERT_EQ(2, event->getPointerId(1));
+    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, event->getToolType(1));
+
+    ASSERT_EQ(2U, event->getHistorySize());
+
+    // Check data.
+    ASSERT_EQ(ARBITRARY_EVENT_TIME, event->getHistoricalEventTime(0));
+    ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
+    ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
+
+    ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(211, event->getRawPointerCoords(0)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(221, event->getRawPointerCoords(1)->
+            getAxisValue(AMOTION_EVENT_AXIS_Y));
+
+    ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
+    ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
+    ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
+    ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
+    ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
+    ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
+
+    ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
+    ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
+    ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
+    ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
+    ASSERT_EQ(210, event->getRawX(0));
+    ASSERT_EQ(220, event->getRawX(1));
+
+    ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
+    ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
+    ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
+    ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
+    ASSERT_EQ(211, event->getRawY(0));
+    ASSERT_EQ(221, event->getRawY(1));
+
+    ASSERT_EQ(X_OFFSET + 10, event->getHistoricalX(0, 0));
+    ASSERT_EQ(X_OFFSET + 20, event->getHistoricalX(1, 0));
+    ASSERT_EQ(X_OFFSET + 110, event->getHistoricalX(0, 1));
+    ASSERT_EQ(X_OFFSET + 120, event->getHistoricalX(1, 1));
+    ASSERT_EQ(X_OFFSET + 210, event->getX(0));
+    ASSERT_EQ(X_OFFSET + 220, event->getX(1));
+
+    ASSERT_EQ(Y_OFFSET + 11, event->getHistoricalY(0, 0));
+    ASSERT_EQ(Y_OFFSET + 21, event->getHistoricalY(1, 0));
+    ASSERT_EQ(Y_OFFSET + 111, event->getHistoricalY(0, 1));
+    ASSERT_EQ(Y_OFFSET + 121, event->getHistoricalY(1, 1));
+    ASSERT_EQ(Y_OFFSET + 211, event->getY(0));
+    ASSERT_EQ(Y_OFFSET + 221, event->getY(1));
+
+    ASSERT_EQ(12, event->getHistoricalPressure(0, 0));
+    ASSERT_EQ(22, event->getHistoricalPressure(1, 0));
+    ASSERT_EQ(112, event->getHistoricalPressure(0, 1));
+    ASSERT_EQ(122, event->getHistoricalPressure(1, 1));
+    ASSERT_EQ(212, event->getPressure(0));
+    ASSERT_EQ(222, event->getPressure(1));
+
+    ASSERT_EQ(13, event->getHistoricalSize(0, 0));
+    ASSERT_EQ(23, event->getHistoricalSize(1, 0));
+    ASSERT_EQ(113, event->getHistoricalSize(0, 1));
+    ASSERT_EQ(123, event->getHistoricalSize(1, 1));
+    ASSERT_EQ(213, event->getSize(0));
+    ASSERT_EQ(223, event->getSize(1));
+
+    ASSERT_EQ(14, event->getHistoricalTouchMajor(0, 0));
+    ASSERT_EQ(24, event->getHistoricalTouchMajor(1, 0));
+    ASSERT_EQ(114, event->getHistoricalTouchMajor(0, 1));
+    ASSERT_EQ(124, event->getHistoricalTouchMajor(1, 1));
+    ASSERT_EQ(214, event->getTouchMajor(0));
+    ASSERT_EQ(224, event->getTouchMajor(1));
+
+    ASSERT_EQ(15, event->getHistoricalTouchMinor(0, 0));
+    ASSERT_EQ(25, event->getHistoricalTouchMinor(1, 0));
+    ASSERT_EQ(115, event->getHistoricalTouchMinor(0, 1));
+    ASSERT_EQ(125, event->getHistoricalTouchMinor(1, 1));
+    ASSERT_EQ(215, event->getTouchMinor(0));
+    ASSERT_EQ(225, event->getTouchMinor(1));
+
+    ASSERT_EQ(16, event->getHistoricalToolMajor(0, 0));
+    ASSERT_EQ(26, event->getHistoricalToolMajor(1, 0));
+    ASSERT_EQ(116, event->getHistoricalToolMajor(0, 1));
+    ASSERT_EQ(126, event->getHistoricalToolMajor(1, 1));
+    ASSERT_EQ(216, event->getToolMajor(0));
+    ASSERT_EQ(226, event->getToolMajor(1));
+
+    ASSERT_EQ(17, event->getHistoricalToolMinor(0, 0));
+    ASSERT_EQ(27, event->getHistoricalToolMinor(1, 0));
+    ASSERT_EQ(117, event->getHistoricalToolMinor(0, 1));
+    ASSERT_EQ(127, event->getHistoricalToolMinor(1, 1));
+    ASSERT_EQ(217, event->getToolMinor(0));
+    ASSERT_EQ(227, event->getToolMinor(1));
+
+    ASSERT_EQ(18, event->getHistoricalOrientation(0, 0));
+    ASSERT_EQ(28, event->getHistoricalOrientation(1, 0));
+    ASSERT_EQ(118, event->getHistoricalOrientation(0, 1));
+    ASSERT_EQ(128, event->getHistoricalOrientation(1, 1));
+    ASSERT_EQ(218, event->getOrientation(0));
+    ASSERT_EQ(228, event->getOrientation(1));
+}
+
+TEST_F(MotionEventTest, Properties) {
+    MotionEvent event;
+
+    // Initialize, add samples and check properties.
+    initializeEventWithHistory(&event);
+    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+
+    // Set source.
+    event.setSource(AINPUT_SOURCE_JOYSTICK);
+    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+
+    // Set action.
+    event.setAction(AMOTION_EVENT_ACTION_CANCEL);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
+
+    // Set meta state.
+    event.setMetaState(AMETA_CTRL_ON);
+    ASSERT_EQ(AMETA_CTRL_ON, event.getMetaState());
+}
+
+TEST_F(MotionEventTest, CopyFrom_KeepHistory) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    MotionEvent copy;
+    copy.copyFrom(&event, true /*keepHistory*/);
+
+    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+}
+
+TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    MotionEvent copy;
+    copy.copyFrom(&event, false /*keepHistory*/);
+
+    ASSERT_EQ(event.getPointerCount(), copy.getPointerCount());
+    ASSERT_EQ(0U, copy.getHistorySize());
+
+    ASSERT_EQ(event.getPointerId(0), copy.getPointerId(0));
+    ASSERT_EQ(event.getPointerId(1), copy.getPointerId(1));
+
+    ASSERT_EQ(event.getEventTime(), copy.getEventTime());
+
+    ASSERT_EQ(event.getX(0), copy.getX(0));
+}
+
+TEST_F(MotionEventTest, OffsetLocation) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    event.offsetLocation(5.0f, -2.0f);
+
+    ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
+    ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
+}
+
+TEST_F(MotionEventTest, Scale) {
+    MotionEvent event;
+    initializeEventWithHistory(&event);
+
+    event.scale(2.0f);
+
+    ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
+    ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
+
+    ASSERT_EQ(210 * 2, event.getRawX(0));
+    ASSERT_EQ(211 * 2, event.getRawY(0));
+    ASSERT_EQ((X_OFFSET + 210) * 2, event.getX(0));
+    ASSERT_EQ((Y_OFFSET + 211) * 2, event.getY(0));
+    ASSERT_EQ(212, event.getPressure(0));
+    ASSERT_EQ(213, event.getSize(0));
+    ASSERT_EQ(214 * 2, event.getTouchMajor(0));
+    ASSERT_EQ(215 * 2, event.getTouchMinor(0));
+    ASSERT_EQ(216 * 2, event.getToolMajor(0));
+    ASSERT_EQ(217 * 2, event.getToolMinor(0));
+    ASSERT_EQ(218, event.getOrientation(0));
+}
+
+TEST_F(MotionEventTest, Parcel) {
+    Parcel parcel;
+
+    MotionEvent inEvent;
+    initializeEventWithHistory(&inEvent);
+    MotionEvent outEvent;
+
+    // Round trip.
+    inEvent.writeToParcel(&parcel);
+    parcel.setDataPosition(0);
+    outEvent.readFromParcel(&parcel);
+
+    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
+}
+
+TEST_F(MotionEventTest, Transform) {
+    // Generate some points on a circle.
+    // Each point 'i' is a point on a circle of radius ROTATION centered at (3,2) at an angle
+    // of ARC * i degrees clockwise relative to the Y axis.
+    // The geometrical representation is irrelevant to the test, it's just easy to generate
+    // and check rotation.  We set the orientation to the same angle.
+    // Coordinate system: down is increasing Y, right is increasing X.
+    const float PI_180 = float(M_PI / 180);
+    const float RADIUS = 10;
+    const float ARC = 36;
+    const float ROTATION = ARC * 2;
+
+    const size_t pointerCount = 11;
+    PointerProperties pointerProperties[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+    for (size_t i = 0; i < pointerCount; i++) {
+        float angle = float(i * ARC * PI_180);
+        pointerProperties[i].clear();
+        pointerProperties[i].id = i;
+        pointerCoords[i].clear();
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
+    }
+    MotionEvent event;
+    event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
+    float originalRawX = 0 + 3;
+    float originalRawY = -RADIUS + 2;
+
+    // Check original raw X and Y assumption.
+    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+    // Now translate the motion event so the circle's origin is at (0,0).
+    event.offsetLocation(-3, -2);
+
+    // Offsetting the location should preserve the raw X and Y of the first point.
+    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+    // Apply a rotation about the origin by ROTATION degrees clockwise.
+    SkMatrix matrix;
+    matrix.setRotate(ROTATION);
+    event.transform(&matrix);
+
+    // Check the points.
+    for (size_t i = 0; i < pointerCount; i++) {
+        float angle = float((i * ARC + ROTATION) * PI_180);
+        ASSERT_NEAR(sinf(angle) * RADIUS, event.getX(i), 0.001);
+        ASSERT_NEAR(-cosf(angle) * RADIUS, event.getY(i), 0.001);
+        ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
+    }
+
+    // Applying the transformation should preserve the raw X and Y of the first point.
+    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+}
+
+} // namespace android
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
new file mode 100644
index 0000000..de192f1
--- /dev/null
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -0,0 +1,288 @@
+/*
+ * 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 "TestHelpers.h"
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <time.h>
+
+#include <cutils/ashmem.h>
+#include <gtest/gtest.h>
+#include <input/InputTransport.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+
+namespace android {
+
+class InputPublisherAndConsumerTest : public testing::Test {
+protected:
+    sp<InputChannel> serverChannel, clientChannel;
+    InputPublisher* mPublisher;
+    InputConsumer* mConsumer;
+    PreallocatedInputEventFactory mEventFactory;
+
+    virtual void SetUp() {
+        status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+                serverChannel, clientChannel);
+
+        mPublisher = new InputPublisher(serverChannel);
+        mConsumer = new InputConsumer(clientChannel);
+    }
+
+    virtual void TearDown() {
+        if (mPublisher) {
+            delete mPublisher;
+            mPublisher = NULL;
+        }
+
+        if (mConsumer) {
+            delete mConsumer;
+            mConsumer = NULL;
+        }
+
+        serverChannel.clear();
+        clientChannel.clear();
+    }
+
+    void PublishAndConsumeKeyEvent();
+    void PublishAndConsumeMotionEvent();
+};
+
+TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
+    EXPECT_EQ(serverChannel.get(), mPublisher->getChannel().get());
+    EXPECT_EQ(clientChannel.get(), mConsumer->getChannel().get());
+}
+
+void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() {
+    status_t status;
+
+    const uint32_t seq = 15;
+    const int32_t deviceId = 1;
+    const int32_t source = AINPUT_SOURCE_KEYBOARD;
+    const int32_t action = AKEY_EVENT_ACTION_DOWN;
+    const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
+    const int32_t keyCode = AKEYCODE_ENTER;
+    const int32_t scanCode = 13;
+    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+    const int32_t repeatCount = 1;
+    const nsecs_t downTime = 3;
+    const nsecs_t eventTime = 4;
+
+    status = mPublisher->publishKeyEvent(seq, deviceId, source, action, flags,
+            keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
+    ASSERT_EQ(OK, status)
+            << "publisher publishKeyEvent should return OK";
+
+    uint32_t consumeSeq;
+    InputEvent* event;
+    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
+    ASSERT_EQ(OK, status)
+            << "consumer consume should return OK";
+
+    ASSERT_TRUE(event != NULL)
+            << "consumer should have returned non-NULL event";
+    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType())
+            << "consumer should have returned a key event";
+
+    KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
+    EXPECT_EQ(seq, consumeSeq);
+    EXPECT_EQ(deviceId, keyEvent->getDeviceId());
+    EXPECT_EQ(source, keyEvent->getSource());
+    EXPECT_EQ(action, keyEvent->getAction());
+    EXPECT_EQ(flags, keyEvent->getFlags());
+    EXPECT_EQ(keyCode, keyEvent->getKeyCode());
+    EXPECT_EQ(scanCode, keyEvent->getScanCode());
+    EXPECT_EQ(metaState, keyEvent->getMetaState());
+    EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
+    EXPECT_EQ(downTime, keyEvent->getDownTime());
+    EXPECT_EQ(eventTime, keyEvent->getEventTime());
+
+    status = mConsumer->sendFinishedSignal(seq, true);
+    ASSERT_EQ(OK, status)
+            << "consumer sendFinishedSignal should return OK";
+
+    uint32_t finishedSeq = 0;
+    bool handled = false;
+    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
+    ASSERT_EQ(OK, status)
+            << "publisher receiveFinishedSignal should return OK";
+    ASSERT_EQ(seq, finishedSeq)
+            << "publisher receiveFinishedSignal should have returned the original sequence number";
+    ASSERT_TRUE(handled)
+            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
+}
+
+void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() {
+    status_t status;
+
+    const uint32_t seq = 15;
+    const int32_t deviceId = 1;
+    const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
+    const int32_t action = AMOTION_EVENT_ACTION_MOVE;
+    const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+    const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
+    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+    const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
+    const float xOffset = -10;
+    const float yOffset = -20;
+    const float xPrecision = 0.25;
+    const float yPrecision = 0.5;
+    const nsecs_t downTime = 3;
+    const size_t pointerCount = 3;
+    const nsecs_t eventTime = 4;
+    PointerProperties pointerProperties[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+    for (size_t i = 0; i < pointerCount; i++) {
+        pointerProperties[i].clear();
+        pointerProperties[i].id = (i + 2) % pointerCount;
+        pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+
+        pointerCoords[i].clear();
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i);
+        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
+    }
+
+    status = mPublisher->publishMotionEvent(seq, deviceId, source, action, flags, edgeFlags,
+            metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision,
+            downTime, eventTime, pointerCount,
+            pointerProperties, pointerCoords);
+    ASSERT_EQ(OK, status)
+            << "publisher publishMotionEvent should return OK";
+
+    uint32_t consumeSeq;
+    InputEvent* event;
+    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
+    ASSERT_EQ(OK, status)
+            << "consumer consume should return OK";
+
+    ASSERT_TRUE(event != NULL)
+            << "consumer should have returned non-NULL event";
+    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
+            << "consumer should have returned a motion event";
+
+    MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
+    EXPECT_EQ(seq, consumeSeq);
+    EXPECT_EQ(deviceId, motionEvent->getDeviceId());
+    EXPECT_EQ(source, motionEvent->getSource());
+    EXPECT_EQ(action, motionEvent->getAction());
+    EXPECT_EQ(flags, motionEvent->getFlags());
+    EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
+    EXPECT_EQ(metaState, motionEvent->getMetaState());
+    EXPECT_EQ(buttonState, motionEvent->getButtonState());
+    EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
+    EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
+    EXPECT_EQ(downTime, motionEvent->getDownTime());
+    EXPECT_EQ(eventTime, motionEvent->getEventTime());
+    EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
+    EXPECT_EQ(0U, motionEvent->getHistorySize());
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        SCOPED_TRACE(i);
+        EXPECT_EQ(pointerProperties[i].id, motionEvent->getPointerId(i));
+        EXPECT_EQ(pointerProperties[i].toolType, motionEvent->getToolType(i));
+
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+                motionEvent->getRawX(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+                motionEvent->getRawY(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
+                motionEvent->getX(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
+                motionEvent->getY(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+                motionEvent->getPressure(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+                motionEvent->getSize(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+                motionEvent->getTouchMajor(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+                motionEvent->getTouchMinor(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+                motionEvent->getToolMajor(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+                motionEvent->getToolMinor(i));
+        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
+                motionEvent->getOrientation(i));
+    }
+
+    status = mConsumer->sendFinishedSignal(seq, false);
+    ASSERT_EQ(OK, status)
+            << "consumer sendFinishedSignal should return OK";
+
+    uint32_t finishedSeq = 0;
+    bool handled = true;
+    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
+    ASSERT_EQ(OK, status)
+            << "publisher receiveFinishedSignal should return OK";
+    ASSERT_EQ(seq, finishedSeq)
+            << "publisher receiveFinishedSignal should have returned the original sequence number";
+    ASSERT_FALSE(handled)
+            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
+    status_t status;
+    const size_t pointerCount = 0;
+    PointerProperties pointerProperties[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerProperties, pointerCoords);
+    ASSERT_EQ(BAD_VALUE, status)
+            << "publisher publishMotionEvent should return BAD_VALUE";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
+    status_t status;
+    const size_t pointerCount = MAX_POINTERS + 1;
+    PointerProperties pointerProperties[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+    for (size_t i = 0; i < pointerCount; i++) {
+        pointerProperties[i].clear();
+        pointerCoords[i].clear();
+    }
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerProperties, pointerCoords);
+    ASSERT_EQ(BAD_VALUE, status)
+            << "publisher publishMotionEvent should return BAD_VALUE";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+}
+
+} // namespace android
diff --git a/libs/input/tests/TestHelpers.h b/libs/input/tests/TestHelpers.h
new file mode 100644
index 0000000..fe87bb9
--- /dev/null
+++ b/libs/input/tests/TestHelpers.h
@@ -0,0 +1,81 @@
+/*
+ * 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 TESTHELPERS_H
+#define TESTHELPERS_H
+
+#include <unistd.h>
+
+#include <utils/threads.h>
+
+namespace android {
+
+class Pipe {
+public:
+    int sendFd;
+    int receiveFd;
+
+    Pipe() {
+        int fds[2];
+        ::pipe(fds);
+
+        receiveFd = fds[0];
+        sendFd = fds[1];
+    }
+
+    ~Pipe() {
+        if (sendFd != -1) {
+            ::close(sendFd);
+        }
+
+        if (receiveFd != -1) {
+            ::close(receiveFd);
+        }
+    }
+
+    status_t writeSignal() {
+        ssize_t nWritten = ::write(sendFd, "*", 1);
+        return nWritten == 1 ? 0 : -errno;
+    }
+
+    status_t readSignal() {
+        char buf[1];
+        ssize_t nRead = ::read(receiveFd, buf, 1);
+        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
+    }
+};
+
+class DelayedTask : public Thread {
+    int mDelayMillis;
+
+public:
+    DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
+
+protected:
+    virtual ~DelayedTask() { }
+
+    virtual void doTask() = 0;
+
+    virtual bool threadLoop() {
+        usleep(mDelayMillis * 1000);
+        doTask();
+        return false;
+    }
+};
+
+} // namespace android
+
+#endif // TESTHELPERS_H
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 6ac8724..86637dc 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -230,9 +230,6 @@
 
 static void early_egl_init(void)
 {
-#if !USE_FAST_TLS_KEY
-    pthread_key_create(&gGLWrapperKey, NULL);
-#endif
 #if EGL_TRACE
     pthread_key_create(&gGLTraceKey, NULL);
     initEglTraceLevel();
@@ -341,42 +338,11 @@
 
 // ----------------------------------------------------------------------------
 
-#if USE_FAST_TLS_KEY
-
-// We have a dedicated TLS slot in bionic
-static inline gl_hooks_t const * volatile * get_tls_hooks() {
-    volatile void *tls_base = __get_tls();
-    gl_hooks_t const * volatile * tls_hooks =
-            reinterpret_cast<gl_hooks_t const * volatile *>(tls_base);
-    return tls_hooks;
-}
-
 void setGlThreadSpecific(gl_hooks_t const *value) {
     gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
     tls_hooks[TLS_SLOT_OPENGL_API] = value;
 }
 
-gl_hooks_t const* getGlThreadSpecific() {
-    gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
-    gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API];
-    if (hooks) return hooks;
-    return &gHooksNoContext;
-}
-
-#else
-
-void setGlThreadSpecific(gl_hooks_t const *value) {
-    pthread_setspecific(gGLWrapperKey, value);
-}
-
-gl_hooks_t const* getGlThreadSpecific() {
-    gl_hooks_t const* hooks =  static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey));
-    if (hooks) return hooks;
-    return &gHooksNoContext;
-}
-
-#endif
-
 // ----------------------------------------------------------------------------
 // GL / EGL hooks
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 334e164..0358fcc 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -516,8 +516,11 @@
 
     egl_connection_t* cnx = NULL;
     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
-    if (dpy) {
+    if (dp) {
         if (share_list != EGL_NO_CONTEXT) {
+            if (!ContextRef(dp.get(), share_list).get()) {
+                return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+            }
             egl_context_t* const c = get_context(share_list);
             share_list = c->context;
         }
@@ -601,7 +604,7 @@
     // validate the context (if not EGL_NO_CONTEXT)
     if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
         // EGL_NO_CONTEXT is valid
-        return EGL_FALSE;
+        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
     }
 
     // these are the underlying implementation's object
@@ -622,12 +625,12 @@
         impl_ctx = c->context;
     } else {
         // no context given, use the implementation of the current context
+        if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
+            // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
+            return setError(EGL_BAD_MATCH, EGL_FALSE);
+        }
         if (cur_c == NULL) {
             // no current context
-            if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
-                // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
-                return setError(EGL_BAD_MATCH, EGL_FALSE);
-            }
             // not an error, there is just no current context.
             return EGL_TRUE;
         }
@@ -635,12 +638,14 @@
 
     // retrieve the underlying implementation's draw EGLSurface
     if (draw != EGL_NO_SURFACE) {
+        if (!_d.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
         d = get_surface(draw);
         impl_draw = d->surface;
     }
 
     // retrieve the underlying implementation's read EGLSurface
     if (read != EGL_NO_SURFACE) {
+        if (!_r.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
         r = get_surface(read);
         impl_read = r->surface;
     }
@@ -844,9 +849,7 @@
             }
 
             if (found) {
-#if USE_FAST_TLS_KEY
                 addr = gExtensionForwarders[slot];
-#endif
                 sGLExtentionMap.add(name, addr);
                 sGLExtentionSlot++;
             }
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
index c160aa0..add2a79 100644
--- a/opengl/libs/EGL/getProcAddress.cpp
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -34,9 +34,7 @@
 #undef GL_EXTENSION_LIST
 #undef GET_TLS
 
-#if USE_FAST_TLS_KEY
-
-    #if defined(__arm__)
+#if defined(__arm__)
 
     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
 
@@ -58,7 +56,7 @@
             :                                                   \
             );
 
-    #elif defined(__mips__)
+#elif defined(__mips__)
 
         #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -88,27 +86,21 @@
                                           ext.extensions[_api]))    \
                 :                                                   \
             );
+#endif
 
-    #else
-        #error Unsupported architecture
-    #endif
-
+#if defined(CALL_GL_EXTENSION_API)
     #define GL_EXTENSION_NAME(_n)   __glExtFwd##_n
 
     #define GL_EXTENSION(_n)                         \
         void API_ENTRY(GL_EXTENSION_NAME(_n))() {    \
             CALL_GL_EXTENSION_API(_n);               \
         }
-
-
 #else
+        #define GL_EXTENSION_NAME(_n) NULL
 
-    #define GL_EXTENSION_NAME(_n) NULL
+        #define GL_EXTENSION(_n)
 
-    #define GL_EXTENSION(_n)
-
-    #warning "eglGetProcAddress() partially supported"
-
+        #warning "eglGetProcAddress() partially supported"
 #endif
 
 
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index fad2176..3134e56 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -40,13 +40,11 @@
 #undef CALL_GL_API
 #undef CALL_GL_API_RETURN
 
-#if USE_FAST_TLS_KEY
-
-  #if defined(__arm__)
+#if defined(__arm__) && !USE_SLOW_BINDING
 
     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
 
-    #define API_ENTRY(_api) __attribute__((naked)) _api
+    #define API_ENTRY(_api) __attribute__((noinline)) _api
 
     #define CALL_GL_API(_api, ...)                              \
          asm volatile(                                          \
@@ -54,15 +52,13 @@
             "ldr   r12, [r12, %[tls]] \n"                       \
             "cmp   r12, #0            \n"                       \
             "ldrne pc,  [r12, %[api]] \n"                       \
-            "mov   r0, #0             \n"                       \
-            "bx    lr                 \n"                       \
             :                                                   \
             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
             :                                                   \
             );
 
-  #elif defined(__mips__)
+#elif defined(__mips__) && !USE_SLOW_BINDING
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -94,30 +90,21 @@
             :                                                    \
             );
 
-  #else
-
-    #error Unsupported architecture
-
-  #endif
-
-    #define CALL_GL_API_RETURN(_api, ...) \
-        CALL_GL_API(_api, __VA_ARGS__) \
-        return 0; // placate gcc's warnings. never reached.
-
 #else
 
     #define API_ENTRY(_api) _api
 
     #define CALL_GL_API(_api, ...)                                       \
         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
-        _c->_api(__VA_ARGS__);
-
-    #define CALL_GL_API_RETURN(_api, ...)                                \
-        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
-        return _c->_api(__VA_ARGS__)
+        if (_c) return _c->_api(__VA_ARGS__);
 
 #endif
 
+#define CALL_GL_API_RETURN(_api, ...) \
+    CALL_GL_API(_api, __VA_ARGS__) \
+    return 0;
+
+
 
 extern "C" {
 #include "gl3_api.in"
@@ -139,7 +126,8 @@
 {
     const GLubyte * ret = egl_get_string_for_current_context(name);
     if (ret == NULL) {
-        ret = __glGetString(name);
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
+        ret = _c->glGetString(name);
     }
     return ret;
 }
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index a5bbdc6..18ef6f9 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -31,9 +31,6 @@
 
 using namespace android;
 
-// set this to 1 for crude GL debugging
-#define CHECK_FOR_GL_ERRORS     0
-
 // ----------------------------------------------------------------------------
 // extensions for the framework
 // ----------------------------------------------------------------------------
@@ -95,13 +92,11 @@
 #undef CALL_GL_API
 #undef CALL_GL_API_RETURN
 
-#if USE_FAST_TLS_KEY && !CHECK_FOR_GL_ERRORS
-
-  #if defined(__arm__)
+#if defined(__arm__) && !USE_SLOW_BINDING
 
     #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n"
 
-    #define API_ENTRY(_api) __attribute__((naked)) _api
+    #define API_ENTRY(_api) __attribute__((noinline)) _api
 
     #define CALL_GL_API(_api, ...)                              \
          asm volatile(                                          \
@@ -109,15 +104,13 @@
             "ldr   r12, [r12, %[tls]] \n"                       \
             "cmp   r12, #0            \n"                       \
             "ldrne pc,  [r12, %[api]] \n"                       \
-            "mov   r0, #0             \n"                       \
-            "bx    lr                 \n"                       \
             :                                                   \
             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
               [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
             :                                                   \
             );
 
-  #elif defined(__mips__)
+#elif defined(__mips__) && !USE_SLOW_BINDING
 
     #define API_ENTRY(_api) __attribute__((noinline)) _api
 
@@ -149,43 +142,20 @@
             :                                                    \
             );
 
-  #else
-    #error Unsupported architecture
-  #endif
-
-    #define CALL_GL_API_RETURN(_api, ...) \
-        CALL_GL_API(_api, __VA_ARGS__) \
-        return 0; // placate gcc's warnings. never reached.
-
 #else
 
-    #if CHECK_FOR_GL_ERRORS
-    
-        #define CHECK_GL_ERRORS(_api) \
-            do { GLint err = glGetError(); \
-                ALOGE_IF(err != GL_NO_ERROR, "%s failed (0x%04X)", #_api, err); \
-            } while(false);
-
-    #else
-
-        #define CHECK_GL_ERRORS(_api) do { } while(false);
-
-    #endif
-
-
     #define API_ENTRY(_api) _api
 
-    #define CALL_GL_API(_api, ...)                                      \
-        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-        _c->_api(__VA_ARGS__);                                          \
-        CHECK_GL_ERRORS(_api)
-
-    #define CALL_GL_API_RETURN(_api, ...)                               \
-        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-        return _c->_api(__VA_ARGS__)
+    #define CALL_GL_API(_api, ...)                                       \
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;  \
+        if (_c) return _c->_api(__VA_ARGS__);
 
 #endif
 
+#define CALL_GL_API_RETURN(_api, ...) \
+    CALL_GL_API(_api, __VA_ARGS__) \
+    return 0;
+
 
 extern "C" {
 #include "gl_api.in"
@@ -202,11 +172,11 @@
 
 extern "C" const GLubyte * __glGetString(GLenum name);
 
-const GLubyte * glGetString(GLenum name)
-{
+const GLubyte * glGetString(GLenum name) {
     const GLubyte * ret = egl_get_string_for_current_context(name);
     if (ret == NULL) {
-        ret = __glGetString(name);
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
+        ret = _c->glGetString(name);
     }
     return ret;
 }
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index b2a684c..4b43198 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -32,13 +32,11 @@
 #include <GLES3/gl3.h>
 #include <GLES3/gl3ext.h>
 
-#if !defined(__arm__) && !defined(__mips__)
-#define USE_SLOW_BINDING            1
-#else
-#define USE_SLOW_BINDING            0
-#endif
+// set to 1 for debugging
+#define USE_SLOW_BINDING    0
+
 #undef NELEM
-#define NELEM(x)                    (sizeof(x)/sizeof(*(x)))
+#define NELEM(x)            (sizeof(x)/sizeof(*(x)))
 
 // maximum number of GL extensions that can be used simultaneously in
 // a given process. this limitation exists because we need to have
@@ -47,15 +45,7 @@
 #define MAX_NUMBER_OF_GL_EXTENSIONS 256
 
 
-#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__
-#define USE_FAST_TLS_KEY            1
-#else
-#define USE_FAST_TLS_KEY            0
-#endif
-
-#if USE_FAST_TLS_KEY
-#   include <bionic_tls.h>  /* special private C library header */
-#endif
+#include <bionic_tls.h>  /* special private C library header */
 
 // ----------------------------------------------------------------------------
 namespace android {
@@ -84,7 +74,20 @@
 #undef EGL_ENTRY
 
 EGLAPI void setGlThreadSpecific(gl_hooks_t const *value);
-EGLAPI gl_hooks_t const* getGlThreadSpecific();
+
+// We have a dedicated TLS slot in bionic
+inline gl_hooks_t const * volatile * get_tls_hooks() {
+    volatile void *tls_base = __get_tls();
+    gl_hooks_t const * volatile * tls_hooks =
+            reinterpret_cast<gl_hooks_t const * volatile *>(tls_base);
+    return tls_hooks;
+}
+
+inline EGLAPI gl_hooks_t const* getGlThreadSpecific() {
+    gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
+    gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API];
+    return hooks;
+}
 
 // ----------------------------------------------------------------------------
 }; // namespace android
diff --git a/opengl/specs/EGL_ANDROID_presentation_time.txt b/opengl/specs/EGL_ANDROID_presentation_time.txt
index 09b3938..e1dab34 100644
--- a/opengl/specs/EGL_ANDROID_presentation_time.txt
+++ b/opengl/specs/EGL_ANDROID_presentation_time.txt
@@ -10,6 +10,7 @@
 
     Jamie Gennis
     Andy McFadden
+    Jesse Hall
 
 Contact
 
@@ -21,7 +22,7 @@
 
 Version
 
-    Version 2, April 1, 2013
+    Version 3, June 26, 2013
 
 Number
 
@@ -92,7 +93,9 @@
 
     If the surface presentation time is successfully set, EGL_TRUE is
     returned.  Otherwise EGL_FALSE is returned and an appropriate error is
-    set.
+    set.  If <dpy> is not the name of a valid, initialized EGLDisplay, an
+    EGL_BAD_DISPLAY error is generated.  If <surface> is not a valid EGLSurface
+    then an EGL_BAD_SURFACE error is generated.
 
 Issues
 
@@ -110,9 +113,21 @@
     System.nanoTime() method, or from the native clock_gettime function by
     passing CLOCK_MONOTONIC as the clock identifier.
 
+    3. Should the presentation time be state which is used by eglSwapBuffers,
+    or should it be a new parameter to an extended variant of eglSwapBuffers?
+
+    RESOLVED: The presentation time should be new state which is used by
+    the existing eglSwapBuffers call. Adding new state composes better with
+    other (hypothetical) extensions that also modify the behavior of
+    eglSwapBuffers.
+
 Revision History
 
-#1 (Jamie Gennis, April 1, 2013)
+#3 (Jesse Hall, June 26, 2013)
+    - Enumerated errors generated by eglPresentationTimeANDROID.
+    - Added Issue #3 with resolution.
+
+#2 (Jamie Gennis, April 1, 2013)
     - Clarified how uses that either do or do not need an absolute time should
       be handled.
     - Specified the eglPresentationTimeANDROID return value.
diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen
index d236c1e..7146a29 100755
--- a/opengl/tools/glgen/gen
+++ b/opengl/tools/glgen/gen
@@ -32,10 +32,6 @@
 echo "package android.util; public class Log {public static void w(String a, String b) {} public static void e(String a, String b) {}}" > out/android/util/Log.java
 
 echo "package android.opengl; public abstract class EGLObjectHandle { public int getHandle() { return 0; } }" > out/android/opengl/EGLObjectHandle.java
-echo "package android.opengl; public class EGLSurface extends EGLObjectHandle {  }" > out/android/opengl/EGLSurface.java
-echo "package android.opengl; public class EGLContext extends EGLObjectHandle {  }" > out/android/opengl/EGLContext.java
-echo "package android.opengl; public class EGLDisplay extends EGLObjectHandle {  }" > out/android/opengl/EGLDisplay.java
-echo "package android.opengl; public class EGLConfig extends EGLObjectHandle {  }" > out/android/opengl/EGLConfig.java
 
 
 echo "package android.graphics;" > out/android/graphics/SurfaceTexture.java
@@ -47,6 +43,7 @@
 echo "package android.view;" > out/android/view/SurfaceHolder.java
 echo "public interface SurfaceHolder { Surface getSurface(); }" >> out/android/view/SurfaceHolder.java
 
+cp static/egl/*.java out/android/opengl/
 
 GLFILE=out/javax/microedition/khronos/opengles/GL.java
 cp stubs/jsr239/GLHeader.java-if $GLFILE
@@ -141,8 +138,8 @@
             echo
             SAID_PLEASE=1
         fi
-        echo "    " cp $2/$3 $1
-        echo "    " git add $1/$3
+        echo "    cp $2/$3 $1"
+        echo "    (cd $1; git add $3)"
         KEEP_GENERATED=1
     fi
 }
@@ -161,6 +158,11 @@
     compareGenerated ../../../../base/core/jni generated/C android_opengl_${x}.cpp
 done
 
+for x in EGLConfig EGLContext EGLDisplay EGLObjectHandle EGLSurface
+do
+    compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java
+done
+
 if [ $KEEP_GENERATED == "0" ] ; then
     rm -rf generated
 fi
diff --git a/opengl/tools/glgen/static/egl/EGLConfig.java b/opengl/tools/glgen/static/egl/EGLConfig.java
index d457c9f..a7a6bbb 100644
--- a/opengl/tools/glgen/static/egl/EGLConfig.java
+++ b/opengl/tools/glgen/static/egl/EGLConfig.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLConfig)) return false;
 
         EGLConfig that = (EGLConfig) o;
         return getHandle() == that.getHandle();
diff --git a/opengl/tools/glgen/static/egl/EGLContext.java b/opengl/tools/glgen/static/egl/EGLContext.java
index 41b8ef1..c93bd6e 100644
--- a/opengl/tools/glgen/static/egl/EGLContext.java
+++ b/opengl/tools/glgen/static/egl/EGLContext.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLContext)) return false;
 
         EGLContext that = (EGLContext) o;
         return getHandle() == that.getHandle();
diff --git a/opengl/tools/glgen/static/egl/EGLDisplay.java b/opengl/tools/glgen/static/egl/EGLDisplay.java
index 17d1a64..5b8043a 100644
--- a/opengl/tools/glgen/static/egl/EGLDisplay.java
+++ b/opengl/tools/glgen/static/egl/EGLDisplay.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLDisplay)) return false;
 
         EGLDisplay that = (EGLDisplay) o;
         return getHandle() == that.getHandle();
diff --git a/opengl/tools/glgen/static/egl/EGLSurface.java b/opengl/tools/glgen/static/egl/EGLSurface.java
index 65bec4f..c379dc9 100644
--- a/opengl/tools/glgen/static/egl/EGLSurface.java
+++ b/opengl/tools/glgen/static/egl/EGLSurface.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLSurface)) return false;
 
         EGLSurface that = (EGLSurface) o;
         return getHandle() == that.getHandle();
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 6912dc0..7ac5c60 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -69,7 +69,7 @@
     // reject buffers which have the wrong size
     int buf = item.mBuf;
     if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {
-        releaseBufferLocked(buf, item.mGraphicBuffer, EGL_NO_SYNC_KHR);
+        releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
         return NO_ERROR;
     }
 
