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/libs/input/Android.mk b/libs/input/Android.mk
new file mode 100644
index 0000000..b3d9e64
--- /dev/null
+++ b/libs/input/Android.mk
@@ -0,0 +1,85 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+# 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
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..15a8774
--- /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
