diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 3b18c77..d322a34 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -18,6 +18,7 @@
 #ifndef _RUNTIME_EVENT_HUB_H
 #define _RUNTIME_EVENT_HUB_H
 
+#include <android/input.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Log.h>
@@ -27,6 +28,31 @@
 
 #include <linux/input.h>
 
+/* These constants are not defined in linux/input.h but they are part of the multitouch
+ * input protocol. */
+
+#define ABS_MT_TOUCH_MAJOR 0x30  /* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR 0x31  /* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR 0x32  /* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR 0x33  /* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION 0x34  /* Ellipse orientation */
+#define ABS_MT_POSITION_X 0x35   /* Center X ellipse position */
+#define ABS_MT_POSITION_Y 0x36   /* Center Y ellipse position */
+#define ABS_MT_TOOL_TYPE 0x37    /* Type of touching device (finger, pen, ...) */
+#define ABS_MT_BLOB_ID 0x38      /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID 0x39  /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE 0x3a     /* Pressure on contact area */
+
+#define MT_TOOL_FINGER 0 /* Identifies a finger */
+#define MT_TOOL_PEN 1    /* Identifies a pen */
+
+#define SYN_MT_REPORT 2
+
+/* Convenience constants. */
+
+#define BTN_FIRST 0x100  // first button scancode
+#define BTN_LAST 0x15f   // last button scancode
+
 struct pollfd;
 
 namespace android {
@@ -34,62 +60,101 @@
 class KeyLayoutMap;
 
 /*
- * Grand Central Station for events.  With a single call to waitEvent()
- * you can wait for:
- *  - input events from the keypad of a real device
- *  - input events and meta-events (e.g. "quit") from the simulator
- *  - synthetic events from the runtime (e.g. "URL fetch completed")
- *  - real or forged "vsync" events
+ * Grand Central Station for events.
  *
- * Do not instantiate this class.  Instead, call startUp().
+ * The event hub aggregates input events received across all known input
+ * devices on the system, including devices that may be emulated by the simulator
+ * environment.  In addition, the event hub generates fake input events to indicate
+ * when devices are added or removed.
+ *
+ * The event hub provies a stream of input events (via the getEvent function).
+ * It also supports querying the current actual state of input devices such as identifying
+ * which keys are currently down.  Finally, the event hub keeps track of the capabilities of
+ * individual input devices, such as their class and the set of key codes that they support.
  */
-class EventHub : public RefBase
-{
+class EventHubInterface : public virtual RefBase {
+protected:
+    EventHubInterface() { }
+    virtual ~EventHubInterface() { }
+
 public:
-    EventHub();
-    
-    status_t errorCheck() const;
-    
-    // bit fields for classes of devices.
-    enum {
-        CLASS_KEYBOARD      = 0x00000001,
-        CLASS_ALPHAKEY      = 0x00000002,
-        CLASS_TOUCHSCREEN   = 0x00000004,
-        CLASS_TRACKBALL     = 0x00000008,
-        CLASS_TOUCHSCREEN_MT= 0x00000010,
-        CLASS_DPAD          = 0x00000020
-    };
-    uint32_t getDeviceClasses(int32_t deviceId) const;
-    
-    String8 getDeviceName(int32_t deviceId) const;
-    
-    int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
-            int* outMaxValue, int* outFlat, int* outFuzz) const;
-        
-    int getSwitchState(int sw) const;
-    int getSwitchState(int32_t deviceId, int sw) const;
-    
-    int getScancodeState(int key) const;
-    int getScancodeState(int32_t deviceId, int key) const;
-    
-    int getKeycodeState(int key) const;
-    int getKeycodeState(int32_t deviceId, int key) const;
-    
-    status_t scancodeToKeycode(int32_t deviceId, int scancode,
-            int32_t* outKeycode, uint32_t* outFlags) const;
-
-    // exclude a particular device from opening
-    // this can be used to ignore input devices for sensors
-    void addExcludedDevice(const char* deviceName);
-
-    // special type codes when devices are added/removed.
+    // Synthetic raw event type codes produced when devices are added or removed.
     enum {
         DEVICE_ADDED = 0x10000000,
         DEVICE_REMOVED = 0x20000000
     };
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
+
+    virtual String8 getDeviceName(int32_t deviceId) const = 0;
+
+    virtual int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
+            int* outMaxValue, int* outFlat, int* outFuzz) const = 0;
+
+    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const = 0;
+
+    // exclude a particular device from opening
+    // this can be used to ignore input devices for sensors
+    virtual void addExcludedDevice(const char* deviceName) = 0;
+
+    /*
+     * Wait for the next event to become available and return it.
+     * After returning, the EventHub holds onto a wake lock until the next call to getEvent.
+     * This ensures that the device will not go to sleep while the event is being processed.
+     * If the device needs to remain awake longer than that, then the caller is responsible
+     * for taking care of it (say, by poking the power manager user activity timer).
+     */
+    virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
+            int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
+            int32_t* outValue, nsecs_t* outWhen) = 0;
+
+    /*
+     * Query current input state.
+     *   deviceId may be -1 to search for the device automatically, filtered by class.
+     *   deviceClasses may be -1 to ignore device class while searching.
+     */
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t scanCode) const = 0;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t keyCode) const = 0;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
+            int32_t sw) const = 0;
+
+    /*
+     * Examine key input devices for specific framework keycode support
+     */
+    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes,
+            uint8_t* outFlags) const = 0;
+};
+
+class EventHub : public EventHubInterface
+{
+public:
+    EventHub();
+
+    status_t errorCheck() const;
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const;
     
-    // examine key input devices for specific framework keycode support
-    bool hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags);
+    virtual String8 getDeviceName(int32_t deviceId) const;
+    
+    virtual int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
+            int* outMaxValue, int* outFlat, int* outFuzz) const;
+        
+    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const;
+
+    virtual void addExcludedDevice(const char* deviceName);
+
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t scanCode) const;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t keyCode) const;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
+            int32_t sw) const;
+
+    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
 
     virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
             int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
@@ -126,6 +191,10 @@
     device_t* getDevice(int32_t deviceId) const;
     bool hasKeycode(device_t* device, int keycode) const;
     
+    int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const;
+    int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const;
+    int32_t getSwitchStateLocked(device_t* device, int32_t sw) const;
+
     // Protect all internal state.
     mutable Mutex   mLock;
     
@@ -151,7 +220,7 @@
 
     // device ids that report particular switches.
 #ifdef EV_SW
-    int32_t         mSwitches[SW_MAX+1];
+    int32_t         mSwitches[SW_MAX + 1];
 #endif
 };
 
diff --git a/include/ui/Input.h b/include/ui/Input.h
new file mode 100644
index 0000000..6a5c8a8
--- /dev/null
+++ b/include/ui/Input.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_H
+#define _UI_INPUT_H
+
+/**
+ * Native input event structures.
+ */
+
+#include <android/input.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+
+/*
+ * Additional private constants not defined in ndk/ui/input.h.
+ */
+enum {
+    /*
+     * Private control to determine when an app is tracking a key sequence.
+     */
+    KEY_EVENT_FLAG_START_TRACKING = 0x40000000
+};
+
+/*
+ * Maximum number of pointers supported per motion event.
+ */
+#define MAX_POINTERS 10
+
+namespace android {
+
+/*
+ * A raw event as retrieved from the EventHub.
+ */
+struct RawEvent {
+    nsecs_t when;
+    int32_t deviceId;
+    int32_t type;
+    int32_t scanCode;
+    int32_t keyCode;
+    int32_t value;
+    uint32_t flags;
+};
+
+/*
+ * Flags that flow alongside events in the input dispatch system to help with certain
+ * policy decisions such as waking from device sleep.
+ *
+ * TODO This enumeration should probably be split up or relabeled for clarity.
+ */
+enum {
+    /* These flags originate in RawEvents and are generally set in the key map. */
+
+    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,
+
+    /* These flags are set by the input dispatch 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,
+};
+
+/*
+ * Pointer coordinate data.
+ */
+struct PointerCoords {
+    float x;
+    float y;
+    float pressure;
+    float size;
+};
+
+/*
+ * Input events.
+ */
+struct input_event_t { };
+
+class InputEvent : public input_event_t {
+public:
+    virtual ~InputEvent() { }
+
+    virtual int32_t getType() const = 0;
+
+    inline int32_t getDeviceId() const { return mDeviceId; }
+
+    inline int32_t getNature() const { return mNature; }
+
+protected:
+    void initialize(int32_t deviceId, int32_t nature);
+
+private:
+    int32_t mDeviceId;
+    int32_t mNature;
+};
+
+class KeyEvent : public InputEvent {
+public:
+    virtual ~KeyEvent() { }
+
+    virtual int32_t getType() const { return INPUT_EVENT_TYPE_KEY; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getFlags() const { return mFlags; }
+
+    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; }
+
+    void initialize(
+            int32_t deviceId,
+            int32_t nature,
+            int32_t action,
+            int32_t flags,
+            int32_t keyCode,
+            int32_t scanCode,
+            int32_t metaState,
+            int32_t repeatCount,
+            nsecs_t downTime,
+            nsecs_t eventTime);
+
+private:
+    int32_t mAction;
+    int32_t mFlags;
+    int32_t mKeyCode;
+    int32_t mScanCode;
+    int32_t mMetaState;
+    int32_t mRepeatCount;
+    nsecs_t mDownTime;
+    nsecs_t mEventTime;
+};
+
+class MotionEvent : public InputEvent {
+public:
+    virtual ~MotionEvent() { }
+
+    virtual int32_t getType() const { return INPUT_EVENT_TYPE_MOTION; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getEdgeFlags() const { return mEdgeFlags; }
+
+    inline int32_t getMetaState() const { return mMetaState; }
+
+    inline float getXPrecision() const { return mXPrecision; }
+
+    inline float getYPrecision() const { return mYPrecision; }
+
+    inline nsecs_t getDownTime() const { return mDownTime; }
+
+    inline size_t getPointerCount() const { return mPointerIds.size(); }
+
+    inline int32_t getPointerId(size_t pointerIndex) const { return mPointerIds[pointerIndex]; }
+
+    inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
+
+    inline float getRawX() const { return mRawX; }
+
+    inline float getRawY() const { return mRawY; }
+
+    inline float getX(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).x;
+    }
+
+    inline float getY(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).y;
+    }
+
+    inline float getPressure(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).pressure;
+    }
+
+    inline float getSize(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).size;
+    }
+
+    inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
+
+    inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
+        return mSampleEventTimes[historicalIndex];
+    }
+
+    inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).x;
+    }
+
+    inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).y;
+    }
+
+    inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).pressure;
+    }
+
+    inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).size;
+    }
+
+    void initialize(
+            int32_t deviceId,
+            int32_t nature,
+            int32_t action,
+            int32_t edgeFlags,
+            int32_t metaState,
+            float rawX,
+            float rawY,
+            float xPrecision,
+            float yPrecision,
+            nsecs_t downTime,
+            nsecs_t eventTime,
+            size_t pointerCount,
+            const int32_t* pointerIds,
+            const PointerCoords* pointerCoords);
+
+    void addSample(
+            nsecs_t eventTime,
+            const PointerCoords* pointerCoords);
+
+    void offsetLocation(float xOffset, float yOffset);
+
+private:
+    int32_t mAction;
+    int32_t mEdgeFlags;
+    int32_t mMetaState;
+    float mRawX;
+    float mRawY;
+    float mXPrecision;
+    float mYPrecision;
+    nsecs_t mDownTime;
+    Vector<int32_t> mPointerIds;
+    Vector<nsecs_t> mSampleEventTimes;
+    Vector<PointerCoords> mSamplePointerCoords;
+
+    inline const PointerCoords& getCurrentPointerCoords(size_t pointerIndex) const {
+        return mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+    }
+
+    inline const PointerCoords& getHistoricalPointerCoords(
+            size_t pointerIndex, size_t historicalIndex) const {
+        return mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+    }
+};
+
+/*
+ * 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;
+};
+
+
+} // namespace android
+
+#endif // _UI_INPUT_H
diff --git a/include/ui/InputDispatchPolicy.h b/include/ui/InputDispatchPolicy.h
new file mode 100644
index 0000000..3546813
--- /dev/null
+++ b/include/ui/InputDispatchPolicy.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_DISPATCH_POLICY_H
+#define _UI_INPUT_DISPATCH_POLICY_H
+
+/**
+ * Native input dispatch policy.
+ */
+
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class InputChannel;
+
+/*
+ * An input target specifies how an input event is to be dispatched to a particular window
+ * including the window's input channel, control flags, a timeout, and an X / Y offset to
+ * be added to input event coordinates to compensate for the absolute position of the
+ * window area.
+ */
+struct InputTarget {
+    enum {
+        /* This flag indicates that subsequent event delivery should be held until the
+         * current event is delivered to this target or a timeout occurs. */
+        FLAG_SYNC = 0x01,
+
+        /* This flag indicates that a MotionEvent with ACTION_DOWN falls outside of the area of
+         * this target and so should instead be delivered as an ACTION_OUTSIDE to this target. */
+        FLAG_OUTSIDE = 0x02,
+
+        /* This flag indicates that a KeyEvent or MotionEvent is being canceled.
+         * In the case of a key event, it should be delivered with KeyEvent.FLAG_CANCELED set.
+         * In the case of a motion event, it should be delivered as MotionEvent.ACTION_CANCEL. */
+        FLAG_CANCEL = 0x04
+    };
+
+    // The input channel to be targeted.
+    sp<InputChannel> inputChannel;
+
+    // Flags for the input target.
+    int32_t flags;
+
+    // The timeout for event delivery to this target in nanoseconds.  Or -1 if none.
+    nsecs_t timeout;
+
+    // The x and y offset to add to a MotionEvent as it is delivered.
+    // (ignored for KeyEvents)
+    float xOffset, yOffset;
+};
+
+/*
+ * Input dispatch policy interface.
+ *
+ * The input dispatch policy is used by the input dispatcher to interact with the
+ * Window Manager and other system components.  This separation of concerns keeps
+ * the input dispatcher relatively free of special case logic such as is required
+ * to determine the target of iput events, when to wake the device, how to interact
+ * with key guard, and when to transition to the home screen.
+ *
+ * The actual implementation is partially supported by callbacks into the DVM
+ * via JNI.  This class is also mocked in the input dispatcher unit tests since
+ * it is an ideal test seam.
+ */
+class InputDispatchPolicyInterface : public virtual RefBase {
+protected:
+    InputDispatchPolicyInterface() { }
+    virtual ~InputDispatchPolicyInterface() { }
+
+public:
+    enum {
+        ROTATION_0 = 0,
+        ROTATION_90 = 1,
+        ROTATION_180 = 2,
+        ROTATION_270 = 3
+    };
+
+    enum {
+        // The input dispatcher should do nothing and discard the input unless other
+        // flags are set.
+        ACTION_NONE = 0,
+
+        // The input dispatcher should dispatch the input to the application.
+        ACTION_DISPATCH = 0x00000001,
+
+        // The input dispatcher should perform special filtering in preparation for
+        // a pending app switch.
+        ACTION_APP_SWITCH_COMING = 0x00000002,
+
+        // The input dispatcher should add POLICY_FLAG_WOKE_HERE to the policy flags it
+        // passes through the dispatch pipeline.
+        ACTION_WOKE_HERE = 0x00000004,
+
+        // The input dispatcher should add POLICY_FLAG_BRIGHT_HERE to the policy flags it
+        // passes through the dispatch pipeline.
+        ACTION_BRIGHT_HERE = 0x00000008
+    };
+
+    enum {
+        TOUCHSCREEN_UNDEFINED = 0,
+        TOUCHSCREEN_NOTOUCH = 1,
+        TOUCHSCREEN_STYLUS = 2,
+        TOUCHSCREEN_FINGER = 3
+    };
+
+    enum {
+        KEYBOARD_UNDEFINED = 0,
+        KEYBOARD_NOKEYS = 1,
+        KEYBOARD_QWERTY = 2,
+        KEYBOARD_12KEY = 3
+    };
+
+    enum {
+        NAVIGATION_UNDEFINED = 0,
+        NAVIGATION_NONAV = 1,
+        NAVIGATION_DPAD = 2,
+        NAVIGATION_TRACKBALL = 3,
+        NAVIGATION_WHEEL = 4
+    };
+
+    struct VirtualKeyDefinition {
+        int32_t scanCode;
+
+        // configured position data, specified in display coords
+        int32_t centerX;
+        int32_t centerY;
+        int32_t width;
+        int32_t height;
+    };
+
+    /* Gets information about the display with the specified id.
+     * Returns true if the display info is available, false otherwise.
+     */
+    virtual bool getDisplayInfo(int32_t displayId,
+            int32_t* width, int32_t* height, int32_t* orientation) = 0;
+
+    virtual void notifyConfigurationChanged(nsecs_t when,
+            int32_t touchScreenConfig, int32_t keyboardConfig, int32_t navigationConfig) = 0;
+
+    virtual void notifyLidSwitchChanged(nsecs_t when, bool lidOpen) = 0;
+
+    virtual void virtualKeyFeedback(nsecs_t when, int32_t deviceId,
+            int32_t action, int32_t flags, int32_t keyCode,
+            int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
+
+    virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
+            bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) = 0;
+
+    virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown,
+            bool rolled) = 0;
+
+    virtual int32_t interceptTouch(nsecs_t when) = 0;
+
+    virtual bool allowKeyRepeat() = 0;
+    virtual nsecs_t getKeyRepeatTimeout() = 0;
+
+    virtual void getKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
+            Vector<InputTarget>& outTargets) = 0;
+    virtual void getMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
+            Vector<InputTarget>& outTargets) = 0;
+
+    /* Determine whether to turn on some hacks we have to improve the touch interaction with a
+     * certain device whose screen currently is not all that good.
+     */
+    virtual bool filterTouchEvents() = 0;
+
+    /* Determine whether to turn on some hacks to improve touch interaction with another device
+     * where touch coordinate data can get corrupted.
+     */
+    virtual bool filterJumpyTouchEvents() = 0;
+
+    virtual void getVirtualKeyDefinitions(const String8& deviceName,
+            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
+    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_DISPATCH_POLICY_H
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
new file mode 100644
index 0000000..bde07f2
--- /dev/null
+++ b/include/ui/InputDispatcher.h
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_DISPATCHER_H
+#define _UI_INPUT_DISPATCHER_H
+
+#include <ui/Input.h>
+#include <ui/InputDispatchPolicy.h>
+#include <ui/InputTransport.h>
+#include <utils/KeyedVector.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/PollLoop.h>
+#include <utils/Pool.h>
+
+#include <stddef.h>
+#include <unistd.h>
+
+
+namespace android {
+
+/* Notifies the system about input events generated by the input reader.
+ * The dispatcher is expected to be mostly asynchronous. */
+class InputDispatcherInterface : public virtual RefBase {
+protected:
+    InputDispatcherInterface() { }
+    virtual ~InputDispatcherInterface() { }
+
+public:
+    /* Runs a single iteration of the dispatch loop.
+     * Nominally processes one queued event, a timeout, or a response from an input consumer.
+     *
+     * This method should only be called on the input dispatcher thread.
+     */
+    virtual void dispatchOnce() = 0;
+
+    /* Notifies the dispatcher about new events.
+     * The dispatcher will process most of these events asynchronously although some
+     * policy processing may occur synchronously.
+     *
+     * These methods should only be called on the input reader thread.
+     */
+    virtual void notifyConfigurationChanged(nsecs_t eventTime,
+            int32_t touchScreenConfig, int32_t keyboardConfig, int32_t navigationConfig) = 0;
+    virtual void notifyLidSwitchChanged(nsecs_t eventTime, bool lidOpen) = 0;
+    virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
+    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
+            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
+            int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
+    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
+            uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
+            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+            float xPrecision, float yPrecision, nsecs_t downTime) = 0;
+
+    /* Registers or unregister input channels that may be used as targets for input events.
+     *
+     * These methods may be called on any thread (usually by the input manager).
+     */
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
+};
+
+/* Dispatches events. */
+class InputDispatcher : public InputDispatcherInterface {
+protected:
+    virtual ~InputDispatcher();
+
+public:
+    explicit InputDispatcher(const sp<InputDispatchPolicyInterface>& policy);
+
+    virtual void dispatchOnce();
+
+    virtual void notifyConfigurationChanged(nsecs_t eventTime,
+            int32_t touchScreenConfig, int32_t keyboardConfig, int32_t navigationConfig);
+    virtual void notifyLidSwitchChanged(nsecs_t eventTime, bool lidOpen);
+    virtual void notifyAppSwitchComing(nsecs_t eventTime);
+    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
+            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
+            int32_t scanCode, int32_t metaState, nsecs_t downTime);
+    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
+            uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
+            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+            float xPrecision, float yPrecision, nsecs_t downTime);
+
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+private:
+    template <typename T>
+    struct Link {
+        T* next;
+        T* prev;
+    };
+
+    struct EventEntry : Link<EventEntry> {
+        enum {
+            TYPE_SENTINEL,
+            TYPE_CONFIGURATION_CHANGED,
+            TYPE_KEY,
+            TYPE_MOTION
+        };
+
+        int32_t refCount;
+        int32_t type;
+        nsecs_t eventTime;
+    };
+
+    struct ConfigurationChangedEntry : EventEntry {
+        int32_t touchScreenConfig;
+        int32_t keyboardConfig;
+        int32_t navigationConfig;
+    };
+
+    struct KeyEntry : EventEntry {
+        int32_t deviceId;
+        int32_t nature;
+        uint32_t policyFlags;
+        int32_t action;
+        int32_t flags;
+        int32_t keyCode;
+        int32_t scanCode;
+        int32_t metaState;
+        int32_t repeatCount;
+        nsecs_t downTime;
+    };
+
+    struct MotionSample {
+        MotionSample* next;
+
+        nsecs_t eventTime;
+        PointerCoords pointerCoords[MAX_POINTERS];
+    };
+
+    struct MotionEntry : EventEntry {
+        int32_t deviceId;
+        int32_t nature;
+        uint32_t policyFlags;
+        int32_t action;
+        int32_t metaState;
+        int32_t edgeFlags;
+        float xPrecision;
+        float yPrecision;
+        nsecs_t downTime;
+        uint32_t pointerCount;
+        int32_t pointerIds[MAX_POINTERS];
+
+        // Linked list of motion samples associated with this motion event.
+        MotionSample firstSample;
+        MotionSample* lastSample;
+    };
+
+    struct DispatchEntry : Link<DispatchEntry> {
+        EventEntry* eventEntry; // the event to dispatch
+        int32_t targetFlags;
+        float xOffset;
+        float yOffset;
+        nsecs_t timeout;
+
+        // True if dispatch has started.
+        bool inProgress;
+
+        // For motion events:
+        //   Pointer to the first motion sample to dispatch in this cycle.
+        //   Usually NULL to indicate that the list of motion samples begins at
+        //   MotionEntry::firstSample.  Otherwise, some samples were dispatched in a previous
+        //   cycle and this pointer indicates the location of the first remainining sample
+        //   to dispatch during the current cycle.
+        MotionSample* headMotionSample;
+        //   Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
+        //   unable to send all motion samples during this cycle.  On the next cycle,
+        //   headMotionSample will be initialized to tailMotionSample and tailMotionSample
+        //   will be set to NULL.
+        MotionSample* tailMotionSample;
+    };
+
+    template <typename T>
+    struct Queue {
+        T head;
+        T tail;
+
+        inline Queue() {
+            head.prev = NULL;
+            head.next = & tail;
+            tail.prev = & head;
+            tail.next = NULL;
+        }
+
+        inline bool isEmpty() {
+            return head.next == & tail;
+        }
+
+        inline void enqueueAtTail(T* entry) {
+            T* last = tail.prev;
+            last->next = entry;
+            entry->prev = last;
+            entry->next = & tail;
+            tail.prev = entry;
+        }
+
+        inline void enqueueAtHead(T* entry) {
+            T* first = head.next;
+            head.next = entry;
+            entry->prev = & head;
+            entry->next = first;
+            first->prev = entry;
+        }
+
+        inline void dequeue(T* entry) {
+            entry->prev->next = entry->next;
+            entry->next->prev = entry->prev;
+        }
+
+        inline T* dequeueAtHead() {
+            T* first = head.next;
+            dequeue(first);
+            return first;
+        }
+    };
+
+    /* Allocates queue entries and performs reference counting as needed. */
+    class Allocator {
+    public:
+        Allocator();
+
+        ConfigurationChangedEntry* obtainConfigurationChangedEntry();
+        KeyEntry* obtainKeyEntry();
+        MotionEntry* obtainMotionEntry();
+        DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
+
+        void releaseEventEntry(EventEntry* entry);
+        void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
+        void releaseKeyEntry(KeyEntry* entry);
+        void releaseMotionEntry(MotionEntry* entry);
+        void releaseDispatchEntry(DispatchEntry* entry);
+
+        void appendMotionSample(MotionEntry* motionEntry,
+                nsecs_t eventTime, int32_t pointerCount, const PointerCoords* pointerCoords);
+        void freeMotionSample(MotionSample* sample);
+        void freeMotionSampleList(MotionSample* head);
+
+    private:
+        Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
+        Pool<KeyEntry> mKeyEntryPool;
+        Pool<MotionEntry> mMotionEntryPool;
+        Pool<MotionSample> mMotionSamplePool;
+        Pool<DispatchEntry> mDispatchEntryPool;
+    };
+
+    /* Manages the dispatch state associated with a single input channel. */
+    class Connection : public RefBase {
+    protected:
+        virtual ~Connection();
+
+    public:
+        enum Status {
+            // Everything is peachy.
+            STATUS_NORMAL,
+            // An unrecoverable communication error has occurred.
+            STATUS_BROKEN,
+            // The client is not responding.
+            STATUS_NOT_RESPONDING,
+            // The input channel has been unregistered.
+            STATUS_ZOMBIE
+        };
+
+        Status status;
+        sp<InputChannel> inputChannel;
+        InputPublisher inputPublisher;
+        Queue<DispatchEntry> outboundQueue;
+        nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
+
+        nsecs_t lastEventTime; // the time when the event was originally captured
+        nsecs_t lastDispatchTime; // the time when the last event was dispatched
+        nsecs_t lastANRTime; // the time when the last ANR was recorded
+
+        explicit Connection(const sp<InputChannel>& inputChannel);
+
+        inline const char* getInputChannelName() { return inputChannel->getName().string(); }
+
+        // Finds a DispatchEntry in the outbound queue associated with the specified event.
+        // Returns NULL if not found.
+        DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
+
+        // Determine whether this connection has a pending synchronous dispatch target.
+        // Since there can only ever be at most one such target at a time, if there is one,
+        // it must be at the tail because nothing else can be enqueued after it.
+        inline bool hasPendingSyncTarget() {
+            return ! outboundQueue.isEmpty()
+                    && (outboundQueue.tail.prev->targetFlags & InputTarget::FLAG_SYNC);
+        }
+
+        // Gets the time since the current event was originally obtained from the input driver.
+        inline double getEventLatencyMillis(nsecs_t currentTime) {
+            return (currentTime - lastEventTime) / 1000000.0;
+        }
+
+        // Gets the time since the current event entered the outbound dispatch queue.
+        inline double getDispatchLatencyMillis(nsecs_t currentTime) {
+            return (currentTime - lastDispatchTime) / 1000000.0;
+        }
+
+        // Gets the time since the current event ANR was declared, if applicable.
+        inline double getANRLatencyMillis(nsecs_t currentTime) {
+            return (currentTime - lastANRTime) / 1000000.0;
+        }
+
+        status_t initialize();
+    };
+
+    sp<InputDispatchPolicyInterface> mPolicy;
+
+    Mutex mLock;
+
+    Queue<EventEntry> mInboundQueue;
+    Allocator mAllocator;
+
+    sp<PollLoop> mPollLoop;
+
+    // All registered connections mapped by receive pipe file descriptor.
+    KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
+
+    // Active connections are connections that have a non-empty outbound queue.
+    Vector<Connection*> mActiveConnections;
+
+    // Pool of key and motion event objects used only to ask the input dispatch policy
+    // for the targets of an event that is to be dispatched.
+    KeyEvent mReusableKeyEvent;
+    MotionEvent mReusableMotionEvent;
+
+    // The input targets that were most recently identified for dispatch.
+    // If there is a synchronous event dispatch in progress, the current input targets will
+    // remain unchanged until the dispatch has completed or been aborted.
+    Vector<InputTarget> mCurrentInputTargets;
+
+    // Key repeat tracking.
+    // XXX Move this up to the input reader instead.
+    struct KeyRepeatState {
+        KeyEntry* lastKeyEntry; // or null if no repeat
+        nsecs_t nextRepeatTime;
+    } mKeyRepeatState;
+
+    void resetKeyRepeatLocked();
+
+    // Process events that have just been dequeued from the head of the input queue.
+    void processConfigurationChangedLocked(nsecs_t currentTime, ConfigurationChangedEntry* entry);
+    void processKeyLocked(nsecs_t currentTime, KeyEntry* entry);
+    void processKeyRepeatLocked(nsecs_t currentTime);
+    void processMotionLocked(nsecs_t currentTime, MotionEntry* entry);
+
+    // Identify input targets for an event and dispatch to them.
+    void identifyInputTargetsAndDispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry);
+    void identifyInputTargetsAndDispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry);
+    void dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime, EventEntry* entry,
+            bool resumeWithAppendedMotionSample);
+
+    // Manage the dispatch cycle for a single connection.
+    void prepareDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
+            EventEntry* eventEntry, const InputTarget* inputTarget,
+            bool resumeWithAppendedMotionSample);
+    void startDispatchCycleLocked(nsecs_t currentTime, Connection* connection);
+    void finishDispatchCycleLocked(nsecs_t currentTime, Connection* connection);
+    bool timeoutDispatchCycleLocked(nsecs_t currentTime, Connection* connection);
+    bool abortDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
+            bool broken);
+    static bool handleReceiveCallback(int receiveFd, int events, void* data);
+
+    // Add or remove a connection to the mActiveConnections vector.
+    void activateConnectionLocked(Connection* connection);
+    void deactivateConnectionLocked(Connection* connection);
+
+    // Interesting events that we might like to log or tell the framework about.
+    void onDispatchCycleStartedLocked(nsecs_t currentTime, Connection* connection);
+    void onDispatchCycleFinishedLocked(nsecs_t currentTime, Connection* connection,
+            bool recoveredFromANR);
+    void onDispatchCycleANRLocked(nsecs_t currentTime, Connection* connection);
+    void onDispatchCycleBrokenLocked(nsecs_t currentTime, Connection* connection);
+};
+
+/* Enqueues and dispatches input events, endlessly. */
+class InputDispatcherThread : public Thread {
+public:
+    explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
+    ~InputDispatcherThread();
+
+private:
+    virtual bool threadLoop();
+
+    sp<InputDispatcherInterface> mDispatcher;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_DISPATCHER_PRIV_H
diff --git a/include/ui/InputManager.h b/include/ui/InputManager.h
new file mode 100644
index 0000000..eb27513
--- /dev/null
+++ b/include/ui/InputManager.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_MANAGER_H
+#define _UI_INPUT_MANAGER_H
+
+/**
+ * Native input manager.
+ */
+
+#include <ui/EventHub.h>
+#include <ui/Input.h>
+#include <ui/InputDispatchPolicy.h>
+#include <utils/Errors.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class InputReader;
+class InputDispatcher;
+class InputReaderThread;
+class InputDispatcherThread;
+
+/*
+ * The input manager is the core of the system event processing.
+ *
+ * The input manager uses two threads.
+ *
+ * 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
+ *    applies policy, and posts messages to a queue managed by the DispatcherThread.
+ * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
+ *    queue and asynchronously dispatches them to applications.
+ *
+ * By design, the InputReaderThread class and InputDispatcherThread class do not share any
+ * internal state.  Moreover, all communication is done one way from the InputReaderThread
+ * into the InputDispatcherThread and never the reverse.  Both classes may interact with the
+ * InputDispatchPolicy, however.
+ *
+ * The InputManager class never makes any calls into Java itself.  Instead, the
+ * InputDispatchPolicy is responsible for performing all external interactions with the
+ * system, including calling DVM services.
+ */
+class InputManagerInterface : public virtual RefBase {
+protected:
+    InputManagerInterface() { }
+    virtual ~InputManagerInterface() { }
+
+public:
+    /* Starts the input manager threads. */
+    virtual status_t start() = 0;
+
+    /* Stops the input manager threads and waits for them to exit. */
+    virtual status_t stop() = 0;
+
+    /* Registers an input channel prior to using it as the target of an event. */
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
+
+    /* Unregisters an input channel. */
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
+
+    /*
+     * Query current input state.
+     *   deviceId may be -1 to search for the device automatically, filtered by class.
+     *   deviceClasses may be -1 to ignore device class while searching.
+     */
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t scanCode) const = 0;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t keyCode) const = 0;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
+            int32_t sw) const = 0;
+
+    /* Determine whether physical keys exist for the given framework-domain key codes. */
+    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const = 0;
+};
+
+class InputManager : public InputManagerInterface {
+protected:
+    virtual ~InputManager();
+
+public:
+    /*
+     * Creates an input manager that reads events from the given
+     * event hub and applies the given input dispatch policy.
+     */
+    InputManager(const sp<EventHubInterface>& eventHub,
+            const sp<InputDispatchPolicyInterface>& policy);
+
+    virtual status_t start();
+    virtual status_t stop();
+
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t scanCode) const;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
+            int32_t keyCode) const;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
+            int32_t sw) const;
+    virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
+
+private:
+    sp<EventHubInterface> mEventHub;
+    sp<InputDispatchPolicyInterface> mPolicy;
+
+    sp<InputDispatcher> mDispatcher;
+    sp<InputDispatcherThread> mDispatcherThread;
+
+    sp<InputReader> mReader;
+    sp<InputReaderThread> mReaderThread;
+
+    void configureExcludedDevices();
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_MANAGER_H
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
new file mode 100644
index 0000000..7e7a64c
--- /dev/null
+++ b/include/ui/InputReader.h
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_READER_H
+#define _UI_INPUT_READER_H
+
+#include <ui/EventHub.h>
+#include <ui/Input.h>
+#include <ui/InputDispatchPolicy.h>
+#include <ui/InputDispatcher.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/BitSet.h>
+
+#include <stddef.h>
+#include <unistd.h>
+
+/* Maximum pointer id value supported.
+ * (This is limited by our use of BitSet32 to track pointer assignments.) */
+#define MAX_POINTER_ID 32
+
+/** Amount that trackball needs to move in order to generate a key event. */
+#define TRACKBALL_MOVEMENT_THRESHOLD 6
+
+/* Slop distance for jumpy pointer detection.
+ * The vertical range of the screen divided by this is our epsilon value. */
+#define JUMPY_EPSILON_DIVISOR 212
+
+/* Number of jumpy points to drop for touchscreens that need it. */
+#define JUMPY_TRANSITION_DROPS 3
+#define JUMPY_DROP_LIMIT 3
+
+/* Maximum squared distance for averaging.
+ * If moving farther than this, turn of averaging to avoid lag in response. */
+#define AVERAGING_DISTANCE_LIMIT (75 * 75)
+
+/* Maximum number of historical samples to average. */
+#define AVERAGING_HISTORY_SIZE 5
+
+
+namespace android {
+
+extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
+extern int32_t rotateKeyCode(int32_t keyCode, int32_t orientation);
+
+/*
+ * An input device structure tracks the state of a single input device.
+ *
+ * This structure is only used by ReaderThread and is not intended to be shared with
+ * DispatcherThread (because that would require locking).  This works out fine because
+ * DispatcherThread is only interested in cooked event data anyways and does not need
+ * any of the low-level data from InputDevice.
+ */
+struct InputDevice {
+    struct AbsoluteAxisInfo {
+        int32_t minValue;  // minimum value
+        int32_t maxValue;  // maximum value
+        int32_t range;     // range of values, equal to maxValue - minValue
+        int32_t flat;      // center flat position, eg. flat == 8 means center is between -8 and 8
+        int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
+    };
+
+    struct VirtualKey {
+        int32_t keyCode;
+        int32_t scanCode;
+        uint32_t flags;
+
+        // computed hit box, specified in touch screen coords based on known display size
+        int32_t hitLeft;
+        int32_t hitTop;
+        int32_t hitRight;
+        int32_t hitBottom;
+
+        inline bool isHit(int32_t x, int32_t y) const {
+            return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
+        }
+    };
+
+    struct KeyboardState {
+        struct Current {
+            int32_t metaState;
+            nsecs_t downTime; // time of most recent key down
+        } current;
+
+        void reset();
+    };
+
+    struct TrackballState {
+        struct Accumulator {
+            enum {
+                FIELD_BTN_MOUSE = 1,
+                FIELD_REL_X = 2,
+                FIELD_REL_Y = 4
+            };
+
+            uint32_t fields;
+
+            bool btnMouse;
+            int32_t relX;
+            int32_t relY;
+
+            inline void clear() {
+                fields = 0;
+            }
+
+            inline bool isDirty() {
+                return fields != 0;
+            }
+        } accumulator;
+
+        struct Current {
+            bool down;
+            nsecs_t downTime;
+        } current;
+
+        struct Precalculated {
+            float xScale;
+            float yScale;
+            float xPrecision;
+            float yPrecision;
+        } precalculated;
+
+        void reset();
+    };
+
+    struct SingleTouchScreenState {
+        struct Accumulator {
+            enum {
+                FIELD_BTN_TOUCH = 1,
+                FIELD_ABS_X = 2,
+                FIELD_ABS_Y = 4,
+                FIELD_ABS_PRESSURE = 8,
+                FIELD_ABS_TOOL_WIDTH = 16
+            };
+
+            uint32_t fields;
+
+            bool btnTouch;
+            int32_t absX;
+            int32_t absY;
+            int32_t absPressure;
+            int32_t absToolWidth;
+
+            inline void clear() {
+                fields = 0;
+            }
+
+            inline bool isDirty() {
+                return fields != 0;
+            }
+        } accumulator;
+
+        struct Current {
+            bool down;
+            int32_t x;
+            int32_t y;
+            int32_t pressure;
+            int32_t size;
+        } current;
+
+        void reset();
+    };
+
+    struct MultiTouchScreenState {
+        struct Accumulator {
+            enum {
+                FIELD_ABS_MT_POSITION_X = 1,
+                FIELD_ABS_MT_POSITION_Y = 2,
+                FIELD_ABS_MT_TOUCH_MAJOR = 4,
+                FIELD_ABS_MT_WIDTH_MAJOR = 8,
+                FIELD_ABS_MT_TRACKING_ID = 16
+            };
+
+            uint32_t pointerCount;
+            struct Pointer {
+                uint32_t fields;
+
+                int32_t absMTPositionX;
+                int32_t absMTPositionY;
+                int32_t absMTTouchMajor;
+                int32_t absMTWidthMajor;
+                int32_t absMTTrackingId;
+
+                inline void clear() {
+                    fields = 0;
+                }
+            } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
+
+            inline void clear() {
+                pointerCount = 0;
+                pointers[0].clear();
+            }
+
+            inline bool isDirty() {
+                return pointerCount != 0;
+            }
+        } accumulator;
+
+        void reset();
+    };
+
+    struct PointerData {
+        uint32_t id;
+        int32_t x;
+        int32_t y;
+        int32_t pressure;
+        int32_t size;
+    };
+
+    struct TouchData {
+        uint32_t pointerCount;
+        PointerData pointers[MAX_POINTERS];
+        BitSet32 idBits;
+        uint32_t idToIndex[MAX_POINTER_ID];
+
+        void copyFrom(const TouchData& other);
+
+        inline void clear() {
+            pointerCount = 0;
+            idBits.clear();
+        }
+    };
+
+    // common state used for both single-touch and multi-touch screens after the initial
+    // touch decoding has been performed
+    struct TouchScreenState {
+        Vector<VirtualKey> virtualKeys;
+
+        struct Parameters {
+            bool useBadTouchFilter;
+            bool useJumpyTouchFilter;
+            bool useAveragingTouchFilter;
+
+            AbsoluteAxisInfo xAxis;
+            AbsoluteAxisInfo yAxis;
+            AbsoluteAxisInfo pressureAxis;
+            AbsoluteAxisInfo sizeAxis;
+        } parameters;
+
+        // The touch data of the current sample being processed.
+        TouchData currentTouch;
+
+        // The touch data of the previous sample that was processed.  This is updated
+        // incrementally while the current sample is being processed.
+        TouchData lastTouch;
+
+        // The time the primary pointer last went down.
+        nsecs_t downTime;
+
+        struct CurrentVirtualKeyState {
+            bool down;
+            nsecs_t downTime;
+            int32_t keyCode;
+            int32_t scanCode;
+        } currentVirtualKey;
+
+        struct AveragingTouchFilterState {
+            // Individual history tracks are stored by pointer id
+            uint32_t historyStart[MAX_POINTERS];
+            uint32_t historyEnd[MAX_POINTERS];
+            struct {
+                struct {
+                    int32_t x;
+                    int32_t y;
+                    int32_t pressure;
+                } pointers[MAX_POINTERS];
+            } historyData[AVERAGING_HISTORY_SIZE];
+        } averagingTouchFilter;
+
+        struct JumpTouchFilterState {
+            int32_t jumpyPointsDropped;
+        } jumpyTouchFilter;
+
+        struct Precalculated {
+            float xScale;
+            float yScale;
+            float pressureScale;
+            float sizeScale;
+        } precalculated;
+
+        void reset();
+
+        bool applyBadTouchFilter();
+        bool applyJumpyTouchFilter();
+        void applyAveragingTouchFilter();
+        void calculatePointerIds();
+
+        bool isPointInsideDisplay(int32_t x, int32_t y) const;
+    };
+
+    InputDevice(int32_t id, uint32_t classes, String8 name);
+
+    int32_t id;
+    uint32_t classes;
+    String8 name;
+    bool ignored;
+
+    KeyboardState keyboard;
+    TrackballState trackball;
+    TouchScreenState touchScreen;
+    union {
+        SingleTouchScreenState singleTouchScreen;
+        MultiTouchScreenState multiTouchScreen;
+    };
+
+    void reset();
+
+    inline bool isKeyboard() const { return classes & INPUT_DEVICE_CLASS_KEYBOARD; }
+    inline bool isAlphaKey() const { return classes & INPUT_DEVICE_CLASS_ALPHAKEY; }
+    inline bool isTrackball() const { return classes & INPUT_DEVICE_CLASS_TRACKBALL; }
+    inline bool isDPad() const { return classes & INPUT_DEVICE_CLASS_DPAD; }
+    inline bool isSingleTouchScreen() const { return (classes
+            & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT))
+            == INPUT_DEVICE_CLASS_TOUCHSCREEN; }
+    inline bool isMultiTouchScreen() const { return classes
+            & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT; }
+    inline bool isTouchScreen() const { return classes
+            & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT); }
+};
+
+
+/* Processes raw input events and sends cooked event data to an input dispatcher
+ * in accordance with the input dispatch policy. */
+class InputReaderInterface : public virtual RefBase {
+protected:
+    InputReaderInterface() { }
+    virtual ~InputReaderInterface() { }
+
+public:
+    /* Runs a single iteration of the processing loop.
+     * Nominally reads and processes one incoming message from the EventHub.
+     *
+     * This method should be called on the input reader thread.
+     */
+    virtual void loopOnce() = 0;
+
+    /* Gets the current virtual key.  Returns false if not down.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual bool getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const = 0;
+};
+
+/* The input reader reads raw event data from the event hub and processes it into input events
+ * that it sends to the input dispatcher.  Some functions of the input reader are controlled
+ * by the input dispatch policy, such as early event filtering in low power states.
+ */
+class InputReader : public InputReaderInterface {
+public:
+    InputReader(const sp<EventHubInterface>& eventHub,
+            const sp<InputDispatchPolicyInterface>& policy,
+            const sp<InputDispatcherInterface>& dispatcher);
+    virtual ~InputReader();
+
+    virtual void loopOnce();
+
+    virtual bool getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const;
+
+private:
+    // Lock that must be acquired while manipulating state that may be concurrently accessed
+    // from other threads by input state query methods.  It should be held for as short a
+    // time as possible.
+    //
+    // Exported state:
+    //   - global virtual key code and scan code
+    //   - device list and immutable properties of devices such as id, name, and class
+    //     (but not other internal device state)
+    mutable Mutex mExportedStateLock;
+
+    // current virtual key information
+    int32_t mGlobalVirtualKeyCode;
+    int32_t mGlobalVirtualScanCode;
+
+    // combined key meta state
+    int32_t mGlobalMetaState;
+
+    sp<EventHubInterface> mEventHub;
+    sp<InputDispatchPolicyInterface> mPolicy;
+    sp<InputDispatcherInterface> mDispatcher;
+
+    KeyedVector<int32_t, InputDevice*> mDevices;
+
+    // display properties needed to translate touch screen coordinates into display coordinates
+    int32_t mDisplayOrientation;
+    int32_t mDisplayWidth;
+    int32_t mDisplayHeight;
+
+    // low-level input event decoding
+    void process(const RawEvent* rawEvent);
+    void handleDeviceAdded(const RawEvent* rawEvent);
+    void handleDeviceRemoved(const RawEvent* rawEvent);
+    void handleSync(const RawEvent* rawEvent);
+    void handleKey(const RawEvent* rawEvent);
+    void handleRelativeMotion(const RawEvent* rawEvent);
+    void handleAbsoluteMotion(const RawEvent* rawEvent);
+    void handleSwitch(const RawEvent* rawEvent);
+
+    // input policy processing and dispatch
+    void onKey(nsecs_t when, InputDevice* device, bool down,
+            int32_t keyCode, int32_t scanCode, uint32_t policyFlags);
+    void onSwitch(nsecs_t when, InputDevice* device, bool down, int32_t code);
+    void onSingleTouchScreenStateChanged(nsecs_t when, InputDevice* device);
+    void onMultiTouchScreenStateChanged(nsecs_t when, InputDevice* device);
+    void onTouchScreenChanged(nsecs_t when, InputDevice* device, bool havePointerIds);
+    void onTrackballStateChanged(nsecs_t when, InputDevice* device);
+    void onConfigurationChanged(nsecs_t when);
+
+    bool applyStandardInputDispatchPolicyActions(nsecs_t when,
+            int32_t policyActions, uint32_t* policyFlags);
+
+    bool consumeVirtualKeyTouches(nsecs_t when, InputDevice* device, uint32_t policyFlags);
+    void dispatchVirtualKey(nsecs_t when, InputDevice* device, uint32_t policyFlags,
+            int32_t keyEventAction, int32_t keyEventFlags);
+    void dispatchTouches(nsecs_t when, InputDevice* device, uint32_t policyFlags);
+    void dispatchTouch(nsecs_t when, InputDevice* device, uint32_t policyFlags,
+            InputDevice::TouchData* touch, BitSet32 idBits, int32_t motionEventAction);
+
+    // display
+    void resetDisplayProperties();
+    bool refreshDisplayProperties();
+
+    // device management
+    InputDevice* getDevice(int32_t deviceId);
+    InputDevice* getNonIgnoredDevice(int32_t deviceId);
+    void addDevice(nsecs_t when, int32_t deviceId);
+    void removeDevice(nsecs_t when, InputDevice* device);
+    void configureDevice(InputDevice* device);
+    void configureDeviceForCurrentDisplaySize(InputDevice* device);
+    void configureVirtualKeys(InputDevice* device);
+    void configureAbsoluteAxisInfo(InputDevice* device, int axis, const char* name,
+            InputDevice::AbsoluteAxisInfo* out);
+
+    // global meta state management for all devices
+    void resetGlobalMetaState();
+    int32_t globalMetaState();
+
+    // virtual key management
+    void updateGlobalVirtualKeyState();
+};
+
+
+/* Reads raw events from the event hub and processes them, endlessly. */
+class InputReaderThread : public Thread {
+public:
+    InputReaderThread(const sp<InputReaderInterface>& reader);
+    virtual ~InputReaderThread();
+
+private:
+    sp<InputReaderInterface> mReader;
+
+    virtual bool threadLoop();
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_READER_H
diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h
new file mode 100644
index 0000000..9537523
--- /dev/null
+++ b/include/ui/InputTransport.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_TRANSPORT_H
+#define _UI_INPUT_TRANSPORT_H
+
+/**
+ * Native input transport.
+ *
+ * Uses anonymous shared memory as a whiteboard for sending input events from an
+ * InputPublisher to an InputConsumer and ensuring appropriate synchronization.
+ * One interesting feature is that published events can be updated in place as long as they
+ * have not yet been consumed.
+ *
+ * The InputPublisher and InputConsumer only take care of transferring event data
+ * over an InputChannel and sending synchronization signals.  The InputDispatcher and InputQueue
+ * build on these abstractions to add multiplexing and queueing.
+ */
+
+#include <semaphore.h>
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/*
+ * An input channel consists of a shared memory buffer and a pair of pipes
+ * used to send input messages from an InputPublisher to an InputConsumer
+ * across processes.  Each channel has a descriptive name for debugging purposes.
+ *
+ * Each endpoint has its own InputChannel object that specifies its own file descriptors.
+ *
+ * The input channel is closed when all references to it are released.
+ */
+class InputChannel : public RefBase {
+protected:
+    virtual ~InputChannel();
+
+public:
+    InputChannel(const String8& name, int32_t ashmemFd, int32_t receivePipeFd,
+            int32_t sendPipeFd);
+
+    /* Creates a pair of input channels and their underlying shared memory buffers
+     * and pipes.
+     *
+     * Returns OK on success.
+     */
+    static status_t openInputChannelPair(const String8& name,
+            InputChannel** outServerChannel, InputChannel** outClientChannel);
+
+    inline String8 getName() const { return mName; }
+    inline int32_t getAshmemFd() const { return mAshmemFd; }
+    inline int32_t getReceivePipeFd() const { return mReceivePipeFd; }
+    inline int32_t getSendPipeFd() const { return mSendPipeFd; }
+
+    /* Sends a signal to the other endpoint.
+     *
+     * Returns OK on success.
+     * Errors probably indicate that the channel is broken.
+     */
+    status_t sendSignal(char signal);
+
+    /* Receives a signal send by the other endpoint.
+     * (Should only call this after poll() indicates that the receivePipeFd has available input.)
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no signal present.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveSignal(char* outSignal);
+
+private:
+    String8 mName;
+    int32_t mAshmemFd;
+    int32_t mReceivePipeFd;
+    int32_t mSendPipeFd;
+};
+
+/*
+ * Private intermediate representation of input events as messages written into an
+ * ashmem buffer.
+ */
+struct InputMessage {
+    /* Semaphore count is set to 1 when the message is published.
+     * It becomes 0 transiently while the publisher updates the message.
+     * It becomes 0 permanently when the consumer consumes the message.
+     */
+    sem_t semaphore;
+
+    /* Initialized to false by the publisher.
+     * Set to true by the consumer when it consumes the message.
+     */
+    bool consumed;
+
+    int32_t type;
+
+    struct SampleData {
+        nsecs_t eventTime;
+        PointerCoords coords[0]; // variable length
+    };
+
+    int32_t deviceId;
+    int32_t nature;
+
+    union {
+        struct {
+            int32_t action;
+            int32_t flags;
+            int32_t keyCode;
+            int32_t scanCode;
+            int32_t metaState;
+            int32_t repeatCount;
+            nsecs_t downTime;
+            nsecs_t eventTime;
+        } key;
+
+        struct {
+            int32_t action;
+            int32_t metaState;
+            int32_t edgeFlags;
+            nsecs_t downTime;
+            float xOffset;
+            float yOffset;
+            float xPrecision;
+            float yPrecision;
+            size_t pointerCount;
+            int32_t pointerIds[MAX_POINTERS];
+            size_t sampleCount;
+            SampleData sampleData[0]; // variable length
+        } motion;
+    };
+
+    /* Gets the number of bytes to add to step to the next SampleData object in a motion
+     * event message for a given number of pointers.
+     */
+    static inline size_t sampleDataStride(size_t pointerCount) {
+        return sizeof(InputMessage::SampleData) + pointerCount * sizeof(PointerCoords);
+    }
+
+    /* Adds the SampleData stride to the given pointer. */
+    static inline SampleData* sampleDataPtrIncrement(SampleData* ptr, size_t stride) {
+        return reinterpret_cast<InputMessage::SampleData*>(reinterpret_cast<char*>(ptr) + stride);
+    }
+};
+
+/*
+ * Publishes input events to an anonymous shared memory buffer.
+ * Uses atomic operations to coordinate shared access with a single concurrent consumer.
+ */
+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; }
+
+    /* Prepares the publisher for use.  Must be called before it is used.
+     * Returns OK on success.
+     *
+     * This method implicitly calls reset(). */
+    status_t initialize();
+
+    /* Resets the publisher to its initial state and unpins its ashmem buffer.
+     * Returns OK on success.
+     *
+     * Should be called after an event has been consumed to release resources used by the
+     * publisher until the next event is ready to be published.
+     */
+    status_t reset();
+
+    /* Publishes a key event to the ashmem buffer.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if the publisher has not been reset.
+     */
+    status_t publishKeyEvent(
+            int32_t deviceId,
+            int32_t nature,
+            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 ashmem buffer.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if the publisher has not been reset.
+     * Returns BAD_VALUE if pointerCount is less than 1 or greater than MAX_POINTERS.
+     */
+    status_t publishMotionEvent(
+            int32_t deviceId,
+            int32_t nature,
+            int32_t action,
+            int32_t edgeFlags,
+            int32_t metaState,
+            float xOffset,
+            float yOffset,
+            float xPrecision,
+            float yPrecision,
+            nsecs_t downTime,
+            nsecs_t eventTime,
+            size_t pointerCount,
+            const int32_t* pointerIds,
+            const PointerCoords* pointerCoords);
+
+    /* Appends a motion sample to a motion event unless already consumed.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if the current event is not a MOTION_EVENT_ACTION_MOVE event.
+     * Returns FAILED_TRANSACTION if the current event has already been consumed.
+     * Returns NO_MEMORY if the buffer is full and no additional samples can be added.
+     */
+    status_t appendMotionSample(
+            nsecs_t eventTime,
+            const PointerCoords* pointerCoords);
+
+    /* Sends a dispatch signal to the consumer to inform it that a new message is available.
+     *
+     * Returns OK on success.
+     * Errors probably indicate that the channel is broken.
+     */
+    status_t sendDispatchSignal();
+
+    /* Receives the finished signal from the consumer in reply to the original dispatch signal.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no signal present.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveFinishedSignal();
+
+private:
+    sp<InputChannel> mChannel;
+
+    size_t mAshmemSize;
+    InputMessage* mSharedMessage;
+    bool mPinned;
+    bool mSemaphoreInitialized;
+    bool mWasDispatched;
+
+    size_t mMotionEventPointerCount;
+    InputMessage::SampleData* mMotionEventSampleDataTail;
+    size_t mMotionEventSampleDataStride;
+
+    status_t publishInputEvent(
+            int32_t type,
+            int32_t deviceId,
+            int32_t nature);
+};
+
+/*
+ * Consumes input events from an anonymous shared memory buffer.
+ * Uses atomic operations to coordinate shared access with a single concurrent publisher.
+ */
+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; }
+
+    /* Prepares the consumer for use.  Must be called before it is used. */
+    status_t initialize();
+
+    /* Consumes the input event in the buffer and copies its contents into
+     * an InputEvent object created using the specified factory.
+     * This operation will block if the publisher is updating the event.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if there is no currently published event.
+     * Returns NO_MEMORY if the event could not be created.
+     */
+    status_t consume(InputEventFactoryInterface* factory, InputEvent** event);
+
+    /* Sends a finished signal to the publisher to inform it that the current message is
+     * finished processing.
+     *
+     * Returns OK on success.
+     * Errors probably indicate that the channel is broken.
+     */
+    status_t sendFinishedSignal();
+
+    /* Receives the dispatched signal from the publisher.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no signal present.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveDispatchSignal();
+
+private:
+    sp<InputChannel> mChannel;
+
+    size_t mAshmemSize;
+    InputMessage* mSharedMessage;
+
+    void populateKeyEvent(KeyEvent* keyEvent) const;
+    void populateMotionEvent(MotionEvent* motionEvent) const;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_TRANSPORT_H
diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h
new file mode 100644
index 0000000..19c8bf0
--- /dev/null
+++ b/include/utils/BitSet.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTILS_BITSET_H
+#define UTILS_BITSET_H
+
+#include <stdint.h>
+
+/*
+ * Contains some bit manipulation helpers.
+ */
+
+namespace android {
+
+// A simple set of 32 bits that can be individually marked or cleared.
+struct BitSet32 {
+    uint32_t value;
+
+    inline BitSet32() : value(0) { }
+    explicit inline BitSet32(uint32_t value) : value(value) { }
+
+    // Gets the value associated with a particular bit index.
+    static inline uint32_t valueForBit(uint32_t n) { return 0x80000000 >> n; }
+
+    // Clears the bit set.
+    inline void clear() { value = 0; }
+
+    // Returns true if the bit set does not contain any marked bits.
+    inline bool isEmpty() const { return ! value; }
+
+    // Returns true if the specified bit is marked.
+    inline bool hasBit(uint32_t n) const { return value & valueForBit(n); }
+
+    // Marks the specified bit.
+    inline void markBit(uint32_t n) { value |= valueForBit(n); }
+
+    // Clears the specified bit.
+    inline void clearBit(uint32_t n) { value &= ~ valueForBit(n); }
+
+    // Finds the first marked bit in the set.
+    // Result is undefined if all bits are unmarked.
+    inline uint32_t firstMarkedBit() const { return __builtin_clz(value); }
+
+    // Finds the first unmarked bit in the set.
+    // Result is undefined if all bits are marked.
+    inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); }
+
+    inline bool operator== (const BitSet32& other) const { return value == other.value; }
+    inline bool operator!= (const BitSet32& other) const { return value != other.value; }
+};
+
+} // namespace android
+
+#endif // UTILS_BITSET_H
diff --git a/include/utils/Buffer.h b/include/utils/Buffer.h
deleted file mode 100644
index 8e22b0f..0000000
--- a/include/utils/Buffer.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __UTILS_BUFFER_H__
-#define __UTILS_BUFFER_H__ 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-namespace android {
-
-class Buffer
-{
-private:
-    char *buf;
-    int bufsiz;
-    int used;
-    void ensureCapacity(int len);
-
-    void
-    makeRoomFor(int len)
-    {
-        if (len + used >= bufsiz) {
-            bufsiz = (len + used) * 3/2 + 2;
-            char *blah = new char[bufsiz];
-
-            memcpy(blah, buf, used);
-            delete[] buf;
-            buf = blah;
-        }
-    }
-    
-public:
-    Buffer()
-    {
-        bufsiz = 16;
-        buf = new char[bufsiz];
-        clear();
-    }
-
-    ~Buffer()
-    {
-       delete[] buf;
-    }
-
-    void
-    clear()
-    {
-        buf[0] = '\0';
-        used = 0;
-    }
-
-    int
-    length()
-    {
-        return used;
-    }
-
-    void
-    append(const char c)
-    {
-        makeRoomFor(1);
-        buf[used] = c;
-        used++;
-        buf[used] = '\0';
-    }
-
-    void
-    append(const char *s, int len)
-    {
-        makeRoomFor(len);
-
-        memcpy(buf + used, s, len);
-        used += len;
-        buf[used] = '\0';
-    }
-
-    void
-    append(const char *s)
-    {
-        append(s, strlen(s));
-    }
-
-    char *
-    getBytes()
-    {
-        return buf;
-    }
-};
-
-}; // namespace android
-
-#endif
diff --git a/include/utils/PollLoop.h b/include/utils/PollLoop.h
new file mode 100644
index 0000000..c9d951f
--- /dev/null
+++ b/include/utils/PollLoop.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTILS_POLL_LOOP_H
+#define UTILS_POLL_LOOP_H
+
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+#include <sys/poll.h>
+
+namespace android {
+
+/**
+ * A basic file descriptor polling loop based on poll() with callbacks.
+ */
+class PollLoop : public RefBase {
+protected:
+    virtual ~PollLoop();
+
+public:
+    PollLoop();
+
+    /**
+     * A callback that it to be invoked when an event occurs on a file descriptor.
+     * Specifies the events that were triggered and the user data provided when the
+     * callback was set.
+     *
+     * Returns true if the callback should be kept, false if it should be removed automatically
+     * after the callback returns.
+     */
+    typedef bool (*Callback)(int fd, int events, void* data);
+
+    /**
+     * Performs a single call to poll() with optional timeout in milliseconds.
+     * Invokes callbacks for all file descriptors on which an event occurred.
+     *
+     * If the timeout is zero, returns immediately without blocking.
+     * If the timeout is negative, waits indefinitely until awoken.
+     *
+     * Returns true if a callback was invoked or if the loop was awoken by wake().
+     * Returns false if a timeout or error occurred.
+     *
+     * This method must only be called on the main thread.
+     * This method blocks until either a file descriptor is signalled, a timeout occurs,
+     * or wake() is called.
+     * This method does not return until it has finished invoking the appropriate callbacks
+     * for all file descriptors that were signalled.
+     */
+    bool pollOnce(int timeoutMillis);
+
+    /**
+     * Wakes the loop asynchronously.
+     *
+     * This method can be called on any thread.
+     * This method returns immediately.
+     */
+    void wake();
+
+    /**
+     * Sets the callback for a file descriptor, replacing the existing one, if any.
+     * It is an error to call this method with events == 0 or callback == NULL.
+     *
+     * Note that a callback can be invoked with the POLLERR, POLLHUP or POLLNVAL events
+     * even if it is not explicitly requested when registered.
+     *
+     * This method can be called on any thread.
+     * This method may block briefly if it needs to wake the poll loop.
+     */
+    void setCallback(int fd, int events, Callback callback, void* data = NULL);
+
+    /**
+     * Removes the callback for a file descriptor, if one exists.
+     *
+     * When this method returns, it is safe to close the file descriptor since the poll loop
+     * will no longer have a reference to it.  However, it is possible for the callback to
+     * already be running or for it to run one last time if the file descriptor was already
+     * signalled.  Calling code is responsible for ensuring that this case is safely handled.
+     * For example, if the callback takes care of removing itself during its own execution either
+     * by returning false or calling this method, then it can be guaranteed to not be invoked
+     * again at any later time unless registered anew.
+     *
+     * This method can be called on any thread.
+     * This method may block briefly if it needs to wake the poll loop.
+     *
+     * Returns true if a callback was actually removed, false if none was registered.
+     */
+    bool removeCallback(int fd);
+
+private:
+    struct RequestedCallback {
+        Callback callback;
+        void* data;
+    };
+
+    struct PendingCallback {
+        int fd;
+        int events;
+        Callback callback;
+        void* data;
+    };
+
+    Mutex mLock;
+    Condition mAwake;
+    bool mPolling;
+
+    int mWakeReadPipeFd;
+    int mWakeWritePipeFd;
+
+    Vector<struct pollfd> mRequestedFds;
+    Vector<RequestedCallback> mRequestedCallbacks;
+
+    Vector<PendingCallback> mPendingCallbacks; // used privately by pollOnce
+
+    void openWakePipe();
+    void closeWakePipe();
+
+    ssize_t getRequestIndexLocked(int fd);
+    void wakeAndLock();
+};
+
+} // namespace android
+
+#endif // UTILS_POLL_LOOP_H
diff --git a/include/utils/Pool.h b/include/utils/Pool.h
new file mode 100644
index 0000000..2ee768e
--- /dev/null
+++ b/include/utils/Pool.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTILS_POOL_H
+#define UTILS_POOL_H
+
+#include <utils/TypeHelpers.h>
+
+namespace android {
+
+class PoolImpl {
+public:
+    PoolImpl(size_t objSize);
+    ~PoolImpl();
+
+    void* allocImpl();
+    void freeImpl(void* obj);
+
+private:
+    size_t mObjSize;
+};
+
+/*
+ * A homogeneous typed memory pool for fixed size objects.
+ * Not intended to be thread-safe.
+ */
+template<typename T>
+class Pool : private PoolImpl {
+public:
+    /* Creates an initially empty pool. */
+    Pool() : PoolImpl(sizeof(T)) { }
+
+    /* Destroys the pool.
+     * Assumes that the pool is empty. */
+    ~Pool() { }
+
+    /* Allocates an object from the pool, growing the pool if needed. */
+    inline T* alloc() {
+        void* mem = allocImpl();
+        if (! traits<T>::has_trivial_ctor) {
+            return new (mem) T();
+        } else {
+            return static_cast<T*>(mem);
+        }
+    }
+
+    /* Frees an object from the pool. */
+    inline void free(T* obj) {
+        if (! traits<T>::has_trivial_dtor) {
+            obj->~T();
+        }
+        freeImpl(obj);
+    }
+};
+
+} // namespace android
+
+#endif // UTILS_POOL_H
diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h
index cc0bebc..693dd3c 100644
--- a/include/utils/StopWatch.h
+++ b/include/utils/StopWatch.h
@@ -37,6 +37,8 @@
         const char* name() const;
         nsecs_t     lap();
         nsecs_t     elapsedTime() const;
+
+        void        reset();
         
 private:
     const char*     mName;
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index ad59fd6..d40ae16 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -114,6 +114,12 @@
             ssize_t         appendVector(const Vector<TYPE>& vector);
 
 
+    //! insert an array at a given index
+            ssize_t         insertArrayAt(const TYPE* array, size_t index, size_t numItems);
+
+    //! append an array at the end of this vector
+            ssize_t         appendArray(const TYPE* array, size_t numItems);
+
             /*! 
              * add/insert/replace items
              */
@@ -259,6 +265,16 @@
 }
 
 template<class TYPE> inline
+ssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t numItems) {
+    return VectorImpl::insertAt(array, index, numItems);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t numItems) {
+    return VectorImpl::add(array, numItems);
+}
+
+template<class TYPE> inline
 ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
     return VectorImpl::insertAt(&item, index, numItems);
 }
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
index 49b03f1..46a7bc2 100644
--- a/include/utils/VectorImpl.h
+++ b/include/utils/VectorImpl.h
@@ -76,7 +76,7 @@
             void            push();
             void            push(const void* item);
             ssize_t         add();
-            ssize_t         add(const void* item);
+            ssize_t         add(const void* item, size_t numItems = 1);
             ssize_t         replaceAt(size_t index);
             ssize_t         replaceAt(const void* item, size_t index);
 
@@ -184,6 +184,8 @@
             void            push(const void* item);
             ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
             ssize_t         appendVector(const VectorImpl& vector);
+            ssize_t         insertArrayAt(const void* array, size_t index, size_t numItems);
+            ssize_t         appendArray(const void* array, size_t numItems);
             ssize_t         insertAt(size_t where, size_t numItems = 1);
             ssize_t         insertAt(const void* item, size_t where, size_t numItems = 1);
             ssize_t         replaceAt(size_t index);
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index f7acd97..24cdc78 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -11,6 +11,11 @@
 	GraphicBufferMapper.cpp \
 	KeyLayoutMap.cpp \
 	KeyCharacterMap.cpp \
+	Input.cpp \
+	InputDispatcher.cpp \
+	InputManager.cpp \
+	InputReader.cpp \
+	InputTransport.cpp \
 	IOverlay.cpp \
 	Overlay.cpp \
 	PixelFormat.cpp \
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index d45eaf0..27895f2 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -155,77 +155,70 @@
     return 0;
 }
 
-int EventHub::getSwitchState(int sw) const
-{
-#ifdef EV_SW
-    if (sw >= 0 && sw <= SW_MAX) {
-        int32_t devid = mSwitches[sw];
-        if (devid != 0) {
-            return getSwitchState(devid, sw);
+int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t deviceClasses,
+        int32_t scanCode) const {
+    if (scanCode >= 0 && scanCode <= KEY_MAX) {
+        AutoMutex _l(mLock);
+
+        if (deviceId == -1) {
+            for (int i = 0; i < mNumDevicesById; i++) {
+                device_t* device = mDevicesById[i].device;
+                if (device != NULL && (device->classes & deviceClasses) != 0) {
+                    int32_t result = getScanCodeStateLocked(device, scanCode);
+                    if (result >= KEY_STATE_DOWN) {
+                        return result;
+                    }
+                }
+            }
+            return KEY_STATE_UP;
+        } else {
+            device_t* device = getDevice(deviceId);
+            if (device != NULL) {
+                return getScanCodeStateLocked(device, scanCode);
+            }
         }
     }
-#endif
-    return -1;
+    return KEY_STATE_UNKNOWN;
 }
 
-int EventHub::getSwitchState(int32_t deviceId, int sw) const
-{
-#ifdef EV_SW
-    AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
-    if (device == NULL) return -1;
-    
-    if (sw >= 0 && sw <= SW_MAX) {
-        uint8_t sw_bitmask[(SW_MAX+7)/8];
-        memset(sw_bitmask, 0, sizeof(sw_bitmask));
-        if (ioctl(mFDs[id_to_index(device->id)].fd,
-                   EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
-            return test_bit(sw, sw_bitmask) ? 1 : 0;
+int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) const {
+    uint8_t key_bitmask[(KEY_MAX + 7) / 8];
+    memset(key_bitmask, 0, sizeof(key_bitmask));
+    if (ioctl(mFDs[id_to_index(device->id)].fd,
+               EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
+        return test_bit(scanCode, key_bitmask) ? KEY_STATE_DOWN : KEY_STATE_UP;
+    }
+    return KEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
+        int32_t keyCode) const {
+
+    if (deviceId == -1) {
+        for (int i = 0; i < mNumDevicesById; i++) {
+            device_t* device = mDevicesById[i].device;
+            if (device != NULL && (device->classes & deviceClasses) != 0) {
+                int32_t result = getKeyCodeStateLocked(device, keyCode);
+                if (result >= KEY_STATE_DOWN) {
+                    return result;
+                }
+            }
+        }
+        return KEY_STATE_UP;
+    } else {
+        device_t* device = getDevice(deviceId);
+        if (device != NULL) {
+            return getKeyCodeStateLocked(device, keyCode);
         }
     }
-#endif
-    
-    return -1;
+    return KEY_STATE_UNKNOWN;
 }
 
-int EventHub::getScancodeState(int code) const
-{
-    return getScancodeState(mFirstKeyboardId, code);
-}
-
-int EventHub::getScancodeState(int32_t deviceId, int code) const
-{
-    AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
-    if (device == NULL) return -1;
-    
-    if (code >= 0 && code <= KEY_MAX) {
-        uint8_t key_bitmask[(KEY_MAX+7)/8];
-        memset(key_bitmask, 0, sizeof(key_bitmask));
-        if (ioctl(mFDs[id_to_index(device->id)].fd,
-                   EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
-            return test_bit(code, key_bitmask) ? 1 : 0;
-        }
-    }
-    
-    return -1;
-}
-
-int EventHub::getKeycodeState(int code) const
-{
-    return getKeycodeState(mFirstKeyboardId, code);
-}
-
-int EventHub::getKeycodeState(int32_t deviceId, int code) const
-{
-    AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
-    if (device == NULL || device->layoutMap == NULL) return -1;
-    
+int32_t EventHub::getKeyCodeStateLocked(device_t* device, int32_t keyCode) const {
     Vector<int32_t> scanCodes;
-    device->layoutMap->findScancodes(code, &scanCodes);
-    
-    uint8_t key_bitmask[(KEY_MAX+7)/8];
+    device->layoutMap->findScancodes(keyCode, &scanCodes);
+
+    uint8_t key_bitmask[(KEY_MAX + 7) / 8];
     memset(key_bitmask, 0, sizeof(key_bitmask));
     if (ioctl(mFDs[id_to_index(device->id)].fd,
                EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
@@ -239,12 +232,45 @@
             int32_t sc = scanCodes.itemAt(i);
             //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask));
             if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) {
-                return 1;
+                return KEY_STATE_DOWN;
             }
         }
+        return KEY_STATE_UP;
     }
-    
-    return 0;
+    return KEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getSwitchState(int32_t deviceId, int32_t deviceClasses, int32_t sw) const {
+#ifdef EV_SW
+    if (sw >= 0 && sw <= SW_MAX) {
+        AutoMutex _l(mLock);
+
+        if (deviceId == -1) {
+            deviceId = mSwitches[sw];
+            if (deviceId == 0) {
+                return KEY_STATE_UNKNOWN;
+            }
+        }
+
+        device_t* device = getDevice(deviceId);
+        if (device == NULL) {
+            return KEY_STATE_UNKNOWN;
+        }
+
+        return getSwitchStateLocked(device, sw);
+    }
+#endif
+    return KEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const {
+    uint8_t sw_bitmask[(SW_MAX + 7) / 8];
+    memset(sw_bitmask, 0, sizeof(sw_bitmask));
+    if (ioctl(mFDs[id_to_index(device->id)].fd,
+               EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
+        return test_bit(sw, sw_bitmask) ? KEY_STATE_DOWN : KEY_STATE_UP;
+    }
+    return KEY_STATE_UNKNOWN;
 }
 
 status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
@@ -309,9 +335,6 @@
 
     status_t err;
 
-    fd_set readfds;
-    int maxFd = -1;
-    int cc;
     int i;
     int res;
     int pollres;
@@ -457,7 +480,7 @@
  * Inspect the known devices to determine whether physical keys exist for the given
  * framework-domain key codes.
  */
-bool EventHub::hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags) {
+bool EventHub::hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const {
     for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
         outFlags[codeIndex] = 0;
 
@@ -465,7 +488,8 @@
         Vector<int32_t> scanCodes;
         for (int n = 0; (n < mFDCount) && (outFlags[codeIndex] == 0); n++) {
             if (mDevices[n]) {
-                status_t err = mDevices[n]->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
+                status_t err = mDevices[n]->layoutMap->findScancodes(
+                        keyCodes[codeIndex], &scanCodes);
                 if (!err) {
                     // check the possible scan codes identified by the layout map against the
                     // map of codes actually emitted by the driver
@@ -618,11 +642,11 @@
         //}
         for (int i=0; i<((BTN_MISC+7)/8); i++) {
             if (key_bitmask[i] != 0) {
-                device->classes |= CLASS_KEYBOARD;
+                device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
                 break;
             }
         }
-        if ((device->classes & CLASS_KEYBOARD) != 0) {
+        if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
             device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
             if (device->keyBitmask != NULL) {
                 memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
@@ -642,7 +666,7 @@
         if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
         {
             if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
-                device->classes |= CLASS_TRACKBALL;
+                device->classes |= INPUT_DEVICE_CLASS_TRACKBALL;
             }
         }
     }
@@ -656,12 +680,12 @@
     if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
             && test_bit(ABS_MT_POSITION_X, abs_bitmask)
             && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
-        device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;
+        device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
         
     // Is this an old style single-touch driver?
     } else if (test_bit(BTN_TOUCH, key_bitmask)
             && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
-        device->classes |= CLASS_TOUCHSCREEN;
+        device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN;
     }
 
 #ifdef EV_SW
@@ -680,7 +704,7 @@
     }
 #endif
 
-    if ((device->classes&CLASS_KEYBOARD) != 0) {
+    if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
         char tmpfn[sizeof(name)];
         char keylayoutFilename[300];
 
@@ -723,7 +747,7 @@
 
         // 'Q' key support = cheap test of whether this is an alpha-capable kbd
         if (hasKeycode(device, kKeyCodeQ)) {
-            device->classes |= CLASS_ALPHAKEY;
+            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
         }
         
         // See if this has a DPAD.
@@ -732,7 +756,7 @@
                 hasKeycode(device, kKeyCodeDpadLeft) &&
                 hasKeycode(device, kKeyCodeDpadRight) &&
                 hasKeycode(device, kKeyCodeDpadCenter)) {
-            device->classes |= CLASS_DPAD;
+            device->classes |= INPUT_DEVICE_CLASS_DPAD;
         }
         
         LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
new file mode 100644
index 0000000..d367708
--- /dev/null
+++ b/libs/ui/Input.cpp
@@ -0,0 +1,238 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// Provides a pipe-based transport for native events in the NDK.
+//
+#define LOG_TAG "Input"
+
+//#define LOG_NDEBUG 0
+
+#include <ui/Input.h>
+
+namespace android {
+
+// class InputEvent
+
+void InputEvent::initialize(int32_t deviceId, int32_t nature) {
+    mDeviceId = deviceId;
+    mNature = nature;
+}
+
+// class KeyEvent
+
+void KeyEvent::initialize(
+        int32_t deviceId,
+        int32_t nature,
+        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, nature);
+    mAction = action;
+    mFlags = flags;
+    mKeyCode = keyCode;
+    mScanCode = scanCode;
+    mMetaState = metaState;
+    mRepeatCount = repeatCount;
+    mDownTime = downTime;
+    mEventTime = eventTime;
+}
+
+// class MotionEvent
+
+void MotionEvent::initialize(
+        int32_t deviceId,
+        int32_t nature,
+        int32_t action,
+        int32_t edgeFlags,
+        int32_t metaState,
+        float rawX,
+        float rawY,
+        float xPrecision,
+        float yPrecision,
+        nsecs_t downTime,
+        nsecs_t eventTime,
+        size_t pointerCount,
+        const int32_t* pointerIds,
+        const PointerCoords* pointerCoords) {
+    InputEvent::initialize(deviceId, nature);
+    mAction = action;
+    mEdgeFlags = edgeFlags;
+    mMetaState = metaState;
+    mRawX = rawX;
+    mRawY = rawY;
+    mXPrecision = xPrecision;
+    mYPrecision = yPrecision;
+    mDownTime = downTime;
+    mPointerIds.clear();
+    mPointerIds.appendArray(pointerIds, pointerCount);
+    mSampleEventTimes.clear();
+    mSamplePointerCoords.clear();
+    addSample(eventTime, pointerCoords);
+}
+
+void MotionEvent::addSample(
+        int64_t eventTime,
+        const PointerCoords* pointerCoords) {
+    mSampleEventTimes.push(eventTime);
+    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
+}
+
+void MotionEvent::offsetLocation(float xOffset, float yOffset) {
+    if (xOffset != 0 || yOffset != 0) {
+        for (size_t i = 0; i < mSamplePointerCoords.size(); i++) {
+            PointerCoords& pointerCoords = mSamplePointerCoords.editItemAt(i);
+            pointerCoords.x += xOffset;
+            pointerCoords.y += yOffset;
+        }
+    }
+}
+
+} // namespace android
+
+// NDK APIs
+
+using android::InputEvent;
+using android::KeyEvent;
+using android::MotionEvent;
+
+int32_t input_event_get_type(const input_event_t* event) {
+    return reinterpret_cast<const InputEvent*>(event)->getType();
+}
+
+int32_t input_event_get_device_id(const input_event_t* event) {
+    return reinterpret_cast<const InputEvent*>(event)->getDeviceId();
+}
+
+int32_t input_event_get_nature(const input_event_t* event) {
+    return reinterpret_cast<const InputEvent*>(event)->getNature();
+}
+
+int32_t key_event_get_action(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getAction();
+}
+
+int32_t key_event_get_flags(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getFlags();
+}
+
+int32_t key_event_get_key_code(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getKeyCode();
+}
+
+int32_t key_event_get_scan_code(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getScanCode();
+}
+
+int32_t key_event_get_meta_state(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getMetaState();
+}
+int32_t key_event_get_repeat_count(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getRepeatCount();
+}
+
+int64_t key_event_get_down_time(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getDownTime();
+}
+
+int64_t key_event_get_event_time(const input_event_t* key_event) {
+    return reinterpret_cast<const KeyEvent*>(key_event)->getEventTime();
+}
+
+int32_t motion_event_get_action(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getAction();
+}
+
+int32_t motion_event_get_meta_state(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getMetaState();
+}
+
+int32_t motion_event_get_edge_flags(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getEdgeFlags();
+}
+
+int64_t motion_event_get_down_time(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getDownTime();
+}
+
+int64_t motion_event_get_event_time(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getEventTime();
+}
+
+float motion_event_get_x_precision(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getXPrecision();
+}
+
+float motion_event_get_y_precision(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getYPrecision();
+}
+
+size_t motion_event_get_pointer_count(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getPointerCount();
+}
+
+int32_t motion_event_get_pointer_id(const input_event_t* motion_event, size_t pointer_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getPointerId(pointer_index);
+}
+
+float motion_event_get_raw_x(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getRawX();
+}
+
+float motion_event_get_raw_y(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getRawY();
+}
+
+float motion_event_get_x(const input_event_t* motion_event, size_t pointer_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getX(pointer_index);
+}
+
+float motion_event_get_y(const input_event_t* motion_event, size_t pointer_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getY(pointer_index);
+}
+
+float motion_event_get_pressure(const input_event_t* motion_event, size_t pointer_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getPressure(pointer_index);
+}
+
+float motion_event_get_size(const input_event_t* motion_event, size_t pointer_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getSize(pointer_index);
+}
+
+size_t motion_event_get_history_size(const input_event_t* motion_event) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getHistorySize();
+}
+
+int64_t motion_event_get_historical_event_time(input_event_t* motion_event,
+        size_t history_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalEventTime(
+            history_index);
+}
+
+float motion_event_get_historical_x(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalX(
+            pointer_index, history_index);
+}
+
+float motion_event_get_historical_y(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalY(
+            pointer_index, history_index);
+}
+
+float motion_event_get_historical_pressure(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalPressure(
+            pointer_index, history_index);
+}
+
+float motion_event_get_historical_size(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index) {
+    return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalSize(
+            pointer_index, history_index);
+}
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
new file mode 100644
index 0000000..0ccde0d
--- /dev/null
+++ b/libs/ui/InputDispatcher.cpp
@@ -0,0 +1,1313 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// The input dispatcher.
+//
+#define LOG_TAG "InputDispatcher"
+
+//#define LOG_NDEBUG 0
+
+// Log detailed debug messages about each inbound event notification to the dispatcher.
+#define DEBUG_INBOUND_EVENT_DETAILS 1
+
+// Log detailed debug messages about each outbound event processed by the dispatcher.
+#define DEBUG_OUTBOUND_EVENT_DETAILS 1
+
+// Log debug messages about batching.
+#define DEBUG_BATCHING 1
+
+// Log debug messages about the dispatch cycle.
+#define DEBUG_DISPATCH_CYCLE 1
+
+// Log debug messages about performance statistics.
+#define DEBUG_PERFORMANCE_STATISTICS 1
+
+#include <cutils/log.h>
+#include <ui/InputDispatcher.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+namespace android {
+
+// TODO, this needs to be somewhere else, perhaps in the policy
+static inline bool isMovementKey(int32_t keyCode) {
+    return keyCode == KEYCODE_DPAD_UP
+            || keyCode == KEYCODE_DPAD_DOWN
+            || keyCode == KEYCODE_DPAD_LEFT
+            || keyCode == KEYCODE_DPAD_RIGHT;
+}
+
+// --- InputDispatcher ---
+
+InputDispatcher::InputDispatcher(const sp<InputDispatchPolicyInterface>& policy) :
+    mPolicy(policy) {
+    mPollLoop = new PollLoop();
+
+    mInboundQueue.head.refCount = -1;
+    mInboundQueue.head.type = EventEntry::TYPE_SENTINEL;
+    mInboundQueue.head.eventTime = LONG_LONG_MIN;
+
+    mInboundQueue.tail.refCount = -1;
+    mInboundQueue.tail.type = EventEntry::TYPE_SENTINEL;
+    mInboundQueue.tail.eventTime = LONG_LONG_MAX;
+
+    mKeyRepeatState.lastKeyEntry = NULL;
+}
+
+InputDispatcher::~InputDispatcher() {
+    resetKeyRepeatLocked();
+
+    while (mConnectionsByReceiveFd.size() != 0) {
+        unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
+    }
+
+    for (EventEntry* entry = mInboundQueue.head.next; entry != & mInboundQueue.tail; ) {
+        EventEntry* next = entry->next;
+        mAllocator.releaseEventEntry(next);
+        entry = next;
+    }
+}
+
+void InputDispatcher::dispatchOnce() {
+    bool allowKeyRepeat = mPolicy->allowKeyRepeat();
+
+    nsecs_t currentTime;
+    nsecs_t nextWakeupTime = LONG_LONG_MAX;
+    { // acquire lock
+        AutoMutex _l(mLock);
+        currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
+        // Reset the key repeat timer whenever we disallow key events, even if the next event
+        // is not a key.  This is to ensure that we abort a key repeat if the device is just coming
+        // out of sleep.
+        // XXX we should handle resetting input state coming out of sleep more generally elsewhere
+        if (! allowKeyRepeat) {
+            resetKeyRepeatLocked();
+        }
+
+        // Process timeouts for all connections and determine if there are any synchronous
+        // event dispatches pending.
+        bool hasPendingSyncTarget = false;
+        for (size_t i = 0; i < mActiveConnections.size(); ) {
+            Connection* connection = mActiveConnections.itemAt(i);
+
+            nsecs_t connectionTimeoutTime  = connection->nextTimeoutTime;
+            if (connectionTimeoutTime <= currentTime) {
+                bool deactivated = timeoutDispatchCycleLocked(currentTime, connection);
+                if (deactivated) {
+                    // Don't increment i because the connection has been removed
+                    // from mActiveConnections (hence, deactivated).
+                    continue;
+                }
+            }
+
+            if (connectionTimeoutTime < nextWakeupTime) {
+                nextWakeupTime = connectionTimeoutTime;
+            }
+
+            if (connection->hasPendingSyncTarget()) {
+                hasPendingSyncTarget = true;
+            }
+
+            i += 1;
+        }
+
+        // If we don't have a pending sync target, then we can begin delivering a new event.
+        // (Otherwise we wait for dispatch to complete for that target.)
+        if (! hasPendingSyncTarget) {
+            if (mInboundQueue.isEmpty()) {
+                if (mKeyRepeatState.lastKeyEntry) {
+                    if (currentTime >= mKeyRepeatState.nextRepeatTime) {
+                        processKeyRepeatLocked(currentTime);
+                        return; // dispatched once
+                    } else {
+                        if (mKeyRepeatState.nextRepeatTime < nextWakeupTime) {
+                            nextWakeupTime = mKeyRepeatState.nextRepeatTime;
+                        }
+                    }
+                }
+            } else {
+                // Inbound queue has at least one entry.  Dequeue it and begin dispatching.
+                // Note that we do not hold the lock for this process because dispatching may
+                // involve making many callbacks.
+                EventEntry* entry = mInboundQueue.dequeueAtHead();
+
+                switch (entry->type) {
+                case EventEntry::TYPE_CONFIGURATION_CHANGED: {
+                    ConfigurationChangedEntry* typedEntry =
+                            static_cast<ConfigurationChangedEntry*>(entry);
+                    processConfigurationChangedLocked(currentTime, typedEntry);
+                    mAllocator.releaseConfigurationChangedEntry(typedEntry);
+                    break;
+                }
+
+                case EventEntry::TYPE_KEY: {
+                    KeyEntry* typedEntry = static_cast<KeyEntry*>(entry);
+                    processKeyLocked(currentTime, typedEntry);
+                    mAllocator.releaseKeyEntry(typedEntry);
+                    break;
+                }
+
+                case EventEntry::TYPE_MOTION: {
+                    MotionEntry* typedEntry = static_cast<MotionEntry*>(entry);
+                    processMotionLocked(currentTime, typedEntry);
+                    mAllocator.releaseMotionEntry(typedEntry);
+                    break;
+                }
+
+                default:
+                    assert(false);
+                    break;
+                }
+                return; // dispatched once
+            }
+        }
+    } // release lock
+
+    // Wait for callback or timeout or wake.
+    nsecs_t timeout = nanoseconds_to_milliseconds(nextWakeupTime - currentTime);
+    int32_t timeoutMillis = timeout > INT_MAX ? -1 : timeout > 0 ? int32_t(timeout) : 0;
+    mPollLoop->pollOnce(timeoutMillis);
+}
+
+void InputDispatcher::processConfigurationChangedLocked(nsecs_t currentTime,
+        ConfigurationChangedEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processConfigurationChanged - eventTime=%lld, touchScreenConfig=%d, "
+            "keyboardConfig=%d, navigationConfig=%d", entry->eventTime,
+            entry->touchScreenConfig, entry->keyboardConfig, entry->navigationConfig);
+#endif
+
+    mPolicy->notifyConfigurationChanged(entry->eventTime, entry->touchScreenConfig,
+            entry->keyboardConfig, entry->navigationConfig);
+}
+
+void InputDispatcher::processKeyLocked(nsecs_t currentTime, KeyEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processKey - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, "
+            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
+            entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags, entry->action,
+            entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
+            entry->downTime);
+#endif
+
+    // TODO: Poke user activity.
+
+    if (entry->action == KEY_EVENT_ACTION_DOWN) {
+        if (mKeyRepeatState.lastKeyEntry
+                && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
+            // We have seen two identical key downs in a row which indicates that the device
+            // driver is automatically generating key repeats itself.  We take note of the
+            // repeat here, but we disable our own next key repeat timer since it is clear that
+            // we will not need to synthesize key repeats ourselves.
+            entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
+            resetKeyRepeatLocked();
+            mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
+        } else {
+            // Not a repeat.  Save key down state in case we do see a repeat later.
+            resetKeyRepeatLocked();
+            mKeyRepeatState.nextRepeatTime = entry->eventTime + mPolicy->getKeyRepeatTimeout();
+        }
+        mKeyRepeatState.lastKeyEntry = entry;
+        entry->refCount += 1;
+    } else {
+        resetKeyRepeatLocked();
+    }
+
+    identifyInputTargetsAndDispatchKeyLocked(currentTime, entry);
+}
+
+void InputDispatcher::processKeyRepeatLocked(nsecs_t currentTime) {
+    // TODO Old WindowManagerServer code sniffs the input queue for following key up
+    //      events and drops the repeat if one is found.  We should do something similar.
+    //      One good place to do it is in notifyKey as soon as the key up enters the
+    //      inbound event queue.
+
+    // Synthesize a key repeat after the repeat timeout expired.
+    // We reuse the previous key entry if otherwise unreferenced.
+    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
+    if (entry->refCount == 1) {
+        entry->repeatCount += 1;
+    } else {
+        KeyEntry* newEntry = mAllocator.obtainKeyEntry();
+        newEntry->deviceId = entry->deviceId;
+        newEntry->nature = entry->nature;
+        newEntry->policyFlags = entry->policyFlags;
+        newEntry->action = entry->action;
+        newEntry->flags = entry->flags;
+        newEntry->keyCode = entry->keyCode;
+        newEntry->scanCode = entry->scanCode;
+        newEntry->metaState = entry->metaState;
+        newEntry->repeatCount = entry->repeatCount + 1;
+
+        mKeyRepeatState.lastKeyEntry = newEntry;
+        mAllocator.releaseKeyEntry(entry);
+
+        entry = newEntry;
+    }
+    entry->eventTime = currentTime;
+    entry->downTime = currentTime;
+    entry->policyFlags = 0;
+
+    mKeyRepeatState.nextRepeatTime = currentTime + mPolicy->getKeyRepeatTimeout();
+
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processKeyRepeat - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, "
+            "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
+            "repeatCount=%d, downTime=%lld",
+            entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags,
+            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
+            entry->repeatCount, entry->downTime);
+#endif
+
+    identifyInputTargetsAndDispatchKeyLocked(currentTime, entry);
+}
+
+void InputDispatcher::processMotionLocked(nsecs_t currentTime, MotionEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processMotion - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, "
+            "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
+            entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags, entry->action,
+            entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
+            entry->downTime);
+
+    // Print the most recent sample that we have available, this may change due to batching.
+    size_t sampleCount = 1;
+    MotionSample* sample = & entry->firstSample;
+    for (; sample->next != NULL; sample = sample->next) {
+        sampleCount += 1;
+    }
+    for (uint32_t i = 0; i < entry->pointerCount; i++) {
+        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
+                i, entry->pointerIds[i],
+                sample->pointerCoords[i].x,
+                sample->pointerCoords[i].y,
+                sample->pointerCoords[i].pressure,
+                sample->pointerCoords[i].size);
+    }
+
+    // Keep in mind that due to batching, it is possible for the number of samples actually
+    // dispatched to change before the application finally consumed them.
+    if (entry->action == MOTION_EVENT_ACTION_MOVE) {
+        LOGD("  ... Total movement samples currently batched %d ...", sampleCount);
+    }
+#endif
+
+    identifyInputTargetsAndDispatchMotionLocked(currentTime, entry);
+}
+
+void InputDispatcher::identifyInputTargetsAndDispatchKeyLocked(
+        nsecs_t currentTime, KeyEntry* entry) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("identifyInputTargetsAndDispatchKey");
+#endif
+
+    mReusableKeyEvent.initialize(entry->deviceId, entry->nature, entry->action, entry->flags,
+            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
+            entry->downTime, entry->eventTime);
+
+    mCurrentInputTargets.clear();
+    mPolicy->getKeyEventTargets(& mReusableKeyEvent, entry->policyFlags,
+            mCurrentInputTargets);
+
+    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+}
+
+void InputDispatcher::identifyInputTargetsAndDispatchMotionLocked(
+        nsecs_t currentTime, MotionEntry* entry) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("identifyInputTargetsAndDispatchMotion");
+#endif
+
+    mReusableMotionEvent.initialize(entry->deviceId, entry->nature, entry->action,
+            entry->edgeFlags, entry->metaState,
+            entry->firstSample.pointerCoords[0].x, entry->firstSample.pointerCoords[0].y,
+            entry->xPrecision, entry->yPrecision,
+            entry->downTime, entry->eventTime, entry->pointerCount, entry->pointerIds,
+            entry->firstSample.pointerCoords);
+
+    mCurrentInputTargets.clear();
+    mPolicy->getMotionEventTargets(& mReusableMotionEvent, entry->policyFlags,
+            mCurrentInputTargets);
+
+    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+}
+
+void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
+        EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("dispatchEventToCurrentInputTargets, "
+            "resumeWithAppendedMotionSample=%s",
+            resumeWithAppendedMotionSample ? "true" : "false");
+#endif
+
+    for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
+        const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
+
+        ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(
+                inputTarget.inputChannel->getReceivePipeFd());
+        if (connectionIndex >= 0) {
+            sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+            prepareDispatchCycleLocked(currentTime, connection.get(), eventEntry, & inputTarget,
+                    resumeWithAppendedMotionSample);
+        } else {
+            LOGW("Framework requested delivery of an input event to channel '%s' but it "
+                    "is not registered with the input dispatcher.",
+                    inputTarget.inputChannel->getName().string());
+        }
+    }
+}
+
+void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
+        EventEntry* eventEntry, const InputTarget* inputTarget,
+        bool resumeWithAppendedMotionSample) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ prepareDispatchCycle, flags=%d, timeout=%lldns, "
+            "xOffset=%f, yOffset=%f, resumeWithAppendedMotionSample=%s",
+            connection->getInputChannelName(), inputTarget->flags, inputTarget->timeout,
+            inputTarget->xOffset, inputTarget->yOffset,
+            resumeWithAppendedMotionSample ? "true" : "false");
+#endif
+
+    // Skip this event if the connection status is not normal.
+    // We don't want to queue outbound events at all if the connection is broken or
+    // not responding.
+    if (connection->status != Connection::STATUS_NORMAL) {
+        LOGV("channel '%s' ~ Dropping event because the channel status is %s",
+                connection->status == Connection::STATUS_BROKEN ? "BROKEN" : "NOT RESPONDING");
+        return;
+    }
+
+    // Resume the dispatch cycle with a freshly appended motion sample.
+    // First we check that the last dispatch entry in the outbound queue is for the same
+    // motion event to which we appended the motion sample.  If we find such a dispatch
+    // entry, and if it is currently in progress then we try to stream the new sample.
+    bool wasEmpty = connection->outboundQueue.isEmpty();
+
+    if (! wasEmpty && resumeWithAppendedMotionSample) {
+        DispatchEntry* motionEventDispatchEntry =
+                connection->findQueuedDispatchEntryForEvent(eventEntry);
+        if (motionEventDispatchEntry) {
+            // If the dispatch entry is not in progress, then we must be busy dispatching an
+            // earlier event.  Not a problem, the motion event is on the outbound queue and will
+            // be dispatched later.
+            if (! motionEventDispatchEntry->inProgress) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Not streaming because the motion event has "
+                        "not yet been dispatched.  "
+                        "(Waiting for earlier events to be consumed.)",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+            // If the dispatch entry is in progress but it already has a tail of pending
+            // motion samples, then it must mean that the shared memory buffer filled up.
+            // Not a problem, when this dispatch cycle is finished, we will eventually start
+            // a new dispatch cycle to process the tail and that tail includes the newly
+            // appended motion sample.
+            if (motionEventDispatchEntry->tailMotionSample) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Not streaming because no new samples can "
+                        "be appended to the motion event in this dispatch cycle.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+            // The dispatch entry is in progress and is still potentially open for streaming.
+            // Try to stream the new motion sample.  This might fail if the consumer has already
+            // consumed the motion event (or if the channel is broken).
+            MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
+            status_t status = connection->inputPublisher.appendMotionSample(
+                    appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
+            if (status == OK) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Successfully streamed new motion sample.",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+#if DEBUG_BATCHING
+            if (status == NO_MEMORY) {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event because the shared memory buffer is full.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+            } else if (status == status_t(FAILED_TRANSACTION)) {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatchedmove event because the event has already been consumed.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+            } else {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event due to an error, status=%d.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName(), status);
+            }
+#endif
+            // Failed to stream.  Start a new tail of pending motion samples to dispatch
+            // in the next cycle.
+            motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
+            return;
+        }
+    }
+
+    // This is a new event.
+    // Enqueue a new dispatch entry onto the outbound queue for this connection.
+    DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry); // increments ref
+    dispatchEntry->targetFlags = inputTarget->flags;
+    dispatchEntry->xOffset = inputTarget->xOffset;
+    dispatchEntry->yOffset = inputTarget->yOffset;
+    dispatchEntry->timeout = inputTarget->timeout;
+    dispatchEntry->inProgress = false;
+    dispatchEntry->headMotionSample = NULL;
+    dispatchEntry->tailMotionSample = NULL;
+
+    // Handle the case where we could not stream a new motion sample because the consumer has
+    // already consumed the motion event (otherwise the corresponding dispatch entry would
+    // still be in the outbound queue for this connection).  We set the head motion sample
+    // to the list starting with the newly appended motion sample.
+    if (resumeWithAppendedMotionSample) {
+#if DEBUG_BATCHING
+        LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
+                "that cannot be streamed because the motion event has already been consumed.",
+                connection->getInputChannelName());
+#endif
+        MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
+        dispatchEntry->headMotionSample = appendedMotionSample;
+    }
+
+    // Enqueue the dispatch entry.
+    connection->outboundQueue.enqueueAtTail(dispatchEntry);
+
+    // If the outbound queue was previously empty, start the dispatch cycle going.
+    if (wasEmpty) {
+        activateConnectionLocked(connection);
+        startDispatchCycleLocked(currentTime, connection);
+    }
+}
+
+void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ startDispatchCycle",
+            connection->getInputChannelName());
+#endif
+
+    assert(connection->status == Connection::STATUS_NORMAL);
+    assert(! connection->outboundQueue.isEmpty());
+
+    DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
+    assert(! dispatchEntry->inProgress);
+
+    // TODO throttle successive ACTION_MOVE motion events for the same device
+    //      possible implementation could set a brief poll timeout here and resume starting the
+    //      dispatch cycle when elapsed
+
+    // Publish the event.
+    status_t status;
+    switch (dispatchEntry->eventEntry->type) {
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
+
+        // Apply target flags.
+        int32_t action = keyEntry->action;
+        int32_t flags = keyEntry->flags;
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
+            flags |= KEY_EVENT_FLAG_CANCELED;
+        }
+
+        // Publish the key event.
+        status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->nature,
+                action, flags, keyEntry->keyCode, keyEntry->scanCode,
+                keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
+                keyEntry->eventTime);
+
+        if (status) {
+            LOGE("channel '%s' ~ Could not publish key event, "
+                    "status=%d", connection->getInputChannelName(), status);
+            abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            return;
+        }
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
+
+        // Apply target flags.
+        int32_t action = motionEntry->action;
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
+            action = MOTION_EVENT_ACTION_OUTSIDE;
+        }
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
+            action = MOTION_EVENT_ACTION_CANCEL;
+        }
+
+        // If headMotionSample is non-NULL, then it points to the first new sample that we
+        // were unable to dispatch during the previous cycle so we resume dispatching from
+        // that point in the list of motion samples.
+        // Otherwise, we just start from the first sample of the motion event.
+        MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
+        if (! firstMotionSample) {
+            firstMotionSample = & motionEntry->firstSample;
+        }
+
+        // Publish the motion event and the first motion sample.
+        status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
+                motionEntry->nature, action, motionEntry->edgeFlags, motionEntry->metaState,
+                dispatchEntry->xOffset, dispatchEntry->yOffset,
+                motionEntry->xPrecision, motionEntry->yPrecision,
+                motionEntry->downTime, firstMotionSample->eventTime,
+                motionEntry->pointerCount, motionEntry->pointerIds,
+                firstMotionSample->pointerCoords);
+
+        if (status) {
+            LOGE("channel '%s' ~ Could not publish motion event, "
+                    "status=%d", connection->getInputChannelName(), status);
+            abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            return;
+        }
+
+        // Append additional motion samples.
+        MotionSample* nextMotionSample = firstMotionSample->next;
+        for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
+            status = connection->inputPublisher.appendMotionSample(
+                    nextMotionSample->eventTime, nextMotionSample->pointerCoords);
+            if (status == NO_MEMORY) {
+#if DEBUG_DISPATCH_CYCLE
+                    LOGD("channel '%s' ~ Shared memory buffer full.  Some motion samples will "
+                            "be sent in the next dispatch cycle.",
+                            connection->getInputChannelName());
+#endif
+                break;
+            }
+            if (status != OK) {
+                LOGE("channel '%s' ~ Could not append motion sample "
+                        "for a reason other than out of memory, status=%d",
+                        connection->getInputChannelName(), status);
+                abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+                return;
+            }
+        }
+
+        // Remember the next motion sample that we could not dispatch, in case we ran out
+        // of space in the shared memory buffer.
+        dispatchEntry->tailMotionSample = nextMotionSample;
+        break;
+    }
+
+    default: {
+        assert(false);
+    }
+    }
+
+    // Send the dispatch signal.
+    status = connection->inputPublisher.sendDispatchSignal();
+    if (status) {
+        LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
+                connection->getInputChannelName(), status);
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+        return;
+    }
+
+    // Record information about the newly started dispatch cycle.
+    dispatchEntry->inProgress = true;
+
+    connection->lastEventTime = dispatchEntry->eventEntry->eventTime;
+    connection->lastDispatchTime = currentTime;
+
+    nsecs_t timeout = dispatchEntry->timeout;
+    connection->nextTimeoutTime = (timeout >= 0) ? currentTime + timeout : LONG_LONG_MAX;
+
+    // Notify other system components.
+    onDispatchCycleStartedLocked(currentTime, connection);
+}
+
+void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ finishDispatchCycle: %01.1fms since event, "
+            "%01.1fms since dispatch",
+            connection->getInputChannelName(),
+            connection->getEventLatencyMillis(currentTime),
+            connection->getDispatchLatencyMillis(currentTime));
+#endif
+
+    if (connection->status == Connection::STATUS_BROKEN) {
+        return;
+    }
+
+    // Clear the pending timeout.
+    connection->nextTimeoutTime = LONG_LONG_MAX;
+
+    if (connection->status == Connection::STATUS_NOT_RESPONDING) {
+        // Recovering from an ANR.
+        connection->status = Connection::STATUS_NORMAL;
+
+        // Notify other system components.
+        onDispatchCycleFinishedLocked(currentTime, connection, true /*recoveredFromANR*/);
+    } else {
+        // Normal finish.  Not much to do here.
+
+        // Notify other system components.
+        onDispatchCycleFinishedLocked(currentTime, connection, false /*recoveredFromANR*/);
+    }
+
+    // Reset the publisher since the event has been consumed.
+    // We do this now so that the publisher can release some of its internal resources
+    // while waiting for the next dispatch cycle to begin.
+    status_t status = connection->inputPublisher.reset();
+    if (status) {
+        LOGE("channel '%s' ~ Could not reset publisher, status=%d",
+                connection->getInputChannelName(), status);
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+        return;
+    }
+
+    // Start the next dispatch cycle for this connection.
+    while (! connection->outboundQueue.isEmpty()) {
+        DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
+        if (dispatchEntry->inProgress) {
+             // Finish or resume current event in progress.
+            if (dispatchEntry->tailMotionSample) {
+                // We have a tail of undispatched motion samples.
+                // Reuse the same DispatchEntry and start a new cycle.
+                dispatchEntry->inProgress = false;
+                dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
+                dispatchEntry->tailMotionSample = NULL;
+                startDispatchCycleLocked(currentTime, connection);
+                return;
+            }
+            // Finished.
+            connection->outboundQueue.dequeueAtHead();
+            mAllocator.releaseDispatchEntry(dispatchEntry);
+        } else {
+            // If the head is not in progress, then we must have already dequeued the in
+            // progress event, which means we actually aborted it (due to ANR).
+            // So just start the next event for this connection.
+            startDispatchCycleLocked(currentTime, connection);
+            return;
+        }
+    }
+
+    // Outbound queue is empty, deactivate the connection.
+    deactivateConnectionLocked(connection);
+}
+
+bool InputDispatcher::timeoutDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ timeoutDispatchCycle",
+            connection->getInputChannelName());
+#endif
+
+    if (connection->status != Connection::STATUS_NORMAL) {
+        return false;
+    }
+
+    // Enter the not responding state.
+    connection->status = Connection::STATUS_NOT_RESPONDING;
+    connection->lastANRTime = currentTime;
+    bool deactivated = abortDispatchCycleLocked(currentTime, connection, false /*(not) broken*/);
+
+    // Notify other system components.
+    onDispatchCycleANRLocked(currentTime, connection);
+    return deactivated;
+}
+
+bool InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
+        bool broken) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ abortDispatchCycle, broken=%s",
+            connection->getInputChannelName(), broken ? "true" : "false");
+#endif
+
+    if (connection->status == Connection::STATUS_BROKEN) {
+        return false;
+    }
+
+    // Clear the pending timeout.
+    connection->nextTimeoutTime = LONG_LONG_MAX;
+
+    // Clear the outbound queue.
+    while (! connection->outboundQueue.isEmpty()) {
+        DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
+        mAllocator.releaseDispatchEntry(dispatchEntry);
+    }
+
+    // Outbound queue is empty, deactivate the connection.
+    deactivateConnectionLocked(connection);
+
+    // Handle the case where the connection appears to be unrecoverably broken.
+    if (broken) {
+        connection->status = Connection::STATUS_BROKEN;
+
+        // Notify other system components.
+        onDispatchCycleBrokenLocked(currentTime, connection);
+    }
+    return true; /*deactivated*/
+}
+
+bool InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
+    InputDispatcher* d = static_cast<InputDispatcher*>(data);
+
+    { // acquire lock
+        AutoMutex _l(d->mLock);
+
+        ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
+        if (connectionIndex < 0) {
+            LOGE("Received spurious receive callback for unknown input channel.  "
+                    "fd=%d, events=0x%x", receiveFd, events);
+            return false; // remove the callback
+        }
+
+        nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
+        sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
+        if (events & (POLLERR | POLLHUP | POLLNVAL)) {
+            LOGE("channel '%s' ~ Consumer closed input channel or an error occurred.  "
+                    "events=0x%x", connection->getInputChannelName(), events);
+            d->abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
+            return false; // remove the callback
+        }
+
+        if (! (events & POLLIN)) {
+            LOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
+                    "events=0x%x", connection->getInputChannelName(), events);
+            return true;
+        }
+
+        status_t status = connection->inputPublisher.receiveFinishedSignal();
+        if (status) {
+            LOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
+                    connection->getInputChannelName(), status);
+            d->abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
+            return false; // remove the callback
+        }
+
+        d->finishDispatchCycleLocked(currentTime, connection.get());
+        return true;
+    } // release lock
+}
+
+void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime, int32_t touchScreenConfig,
+        int32_t keyboardConfig, int32_t navigationConfig) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyConfigurationChanged - eventTime=%lld, touchScreenConfig=%d, "
+            "keyboardConfig=%d, navigationConfig=%d", eventTime,
+            touchScreenConfig, keyboardConfig, navigationConfig);
+#endif
+
+    bool wasEmpty;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry();
+        newEntry->eventTime = eventTime;
+        newEntry->touchScreenConfig = touchScreenConfig;
+        newEntry->keyboardConfig = keyboardConfig;
+        newEntry->navigationConfig = navigationConfig;
+
+        wasEmpty = mInboundQueue.isEmpty();
+        mInboundQueue.enqueueAtTail(newEntry);
+    } // release lock
+
+    if (wasEmpty) {
+        mPollLoop->wake();
+    }
+}
+
+void InputDispatcher::notifyLidSwitchChanged(nsecs_t eventTime, bool lidOpen) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyLidSwitchChanged - eventTime=%lld, open=%s", eventTime,
+            lidOpen ? "true" : "false");
+#endif
+
+    // Send lid switch notification immediately and synchronously.
+    mPolicy->notifyLidSwitchChanged(eventTime, lidOpen);
+}
+
+void InputDispatcher::notifyAppSwitchComing(nsecs_t eventTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyAppSwitchComing - eventTime=%lld", eventTime);
+#endif
+
+    // Remove movement keys from the queue from most recent to least recent, stopping at the
+    // first non-movement key.
+    // TODO: Include a detailed description of why we do this...
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        for (EventEntry* entry = mInboundQueue.tail.prev; entry != & mInboundQueue.head; ) {
+            EventEntry* prev = entry->prev;
+
+            if (entry->type == EventEntry::TYPE_KEY) {
+                KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
+                if (isMovementKey(keyEntry->keyCode)) {
+                    LOGV("Dropping movement key during app switch: keyCode=%d, action=%d",
+                            keyEntry->keyCode, keyEntry->action);
+                    mInboundQueue.dequeue(keyEntry);
+                    mAllocator.releaseKeyEntry(keyEntry);
+                } else {
+                    // stop at last non-movement key
+                    break;
+                }
+            }
+
+            entry = prev;
+        }
+    } // release lock
+}
+
+void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
+        uint32_t policyFlags, int32_t action, int32_t flags,
+        int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, "
+            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
+            eventTime, deviceId, nature, policyFlags, action, flags,
+            keyCode, scanCode, metaState, downTime);
+#endif
+
+    bool wasEmpty;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        KeyEntry* newEntry = mAllocator.obtainKeyEntry();
+        newEntry->eventTime = eventTime;
+        newEntry->deviceId = deviceId;
+        newEntry->nature = nature;
+        newEntry->policyFlags = policyFlags;
+        newEntry->action = action;
+        newEntry->flags = flags;
+        newEntry->keyCode = keyCode;
+        newEntry->scanCode = scanCode;
+        newEntry->metaState = metaState;
+        newEntry->repeatCount = 0;
+        newEntry->downTime = downTime;
+
+        wasEmpty = mInboundQueue.isEmpty();
+        mInboundQueue.enqueueAtTail(newEntry);
+    } // release lock
+
+    if (wasEmpty) {
+        mPollLoop->wake();
+    }
+}
+
+void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
+        uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
+        uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+        float xPrecision, float yPrecision, nsecs_t downTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, "
+            "action=0x%x, metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, "
+            "downTime=%lld",
+            eventTime, deviceId, nature, policyFlags, action, metaState, edgeFlags,
+            xPrecision, yPrecision, downTime);
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
+                i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
+                pointerCoords[i].pressure, pointerCoords[i].size);
+    }
+#endif
+
+    bool wasEmpty;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Attempt batching and streaming of move events.
+        if (action == MOTION_EVENT_ACTION_MOVE) {
+            // BATCHING CASE
+            //
+            // Try to append a move sample to the tail of the inbound queue for this device.
+            // Give up if we encounter a non-move motion event for this device since that
+            // means we cannot append any new samples until a new motion event has started.
+            for (EventEntry* entry = mInboundQueue.tail.prev;
+                    entry != & mInboundQueue.head; entry = entry->prev) {
+                if (entry->type != EventEntry::TYPE_MOTION) {
+                    // Keep looking for motion events.
+                    continue;
+                }
+
+                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+                if (motionEntry->deviceId != deviceId) {
+                    // Keep looking for this device.
+                    continue;
+                }
+
+                if (motionEntry->action != MOTION_EVENT_ACTION_MOVE
+                        || motionEntry->pointerCount != pointerCount) {
+                    // Last motion event in the queue for this device is not compatible for
+                    // appending new samples.  Stop here.
+                    goto NoBatchingOrStreaming;
+                }
+
+                // The last motion event is a move and is compatible for appending.
+                // Do the batching magic and exit.
+                mAllocator.appendMotionSample(motionEntry, eventTime, pointerCount, pointerCoords);
+#if DEBUG_BATCHING
+                LOGD("Appended motion sample onto batch for most recent "
+                        "motion event for this device in the inbound queue.");
+#endif
+                return; // done
+            }
+
+            // STREAMING CASE
+            //
+            // There is no pending motion event (of any kind) for this device in the inbound queue.
+            // Search the outbound queues for a synchronously dispatched motion event for this
+            // device.  If found, then we append the new sample to that event and then try to
+            // push it out to all current targets.  It is possible that some targets will already
+            // have consumed the motion event.  This case is automatically handled by the
+            // logic in prepareDispatchCycleLocked by tracking where resumption takes place.
+            //
+            // The reason we look for a synchronously dispatched motion event is because we
+            // want to be sure that no other motion events have been dispatched since the move.
+            // It's also convenient because it means that the input targets are still valid.
+            // This code could be improved to support streaming of asynchronously dispatched
+            // motion events (which might be significantly more efficient) but it may become
+            // a little more complicated as a result.
+            //
+            // Note: This code crucially depends on the invariant that an outbound queue always
+            //       contains at most one synchronous event and it is always last (but it might
+            //       not be first!).
+            for (size_t i = 0; i < mActiveConnections.size(); i++) {
+                Connection* connection = mActiveConnections.itemAt(i);
+                if (! connection->outboundQueue.isEmpty()) {
+                    DispatchEntry* dispatchEntry = connection->outboundQueue.tail.prev;
+                    if (dispatchEntry->targetFlags & InputTarget::FLAG_SYNC) {
+                        if (dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION) {
+                            goto NoBatchingOrStreaming;
+                        }
+
+                        MotionEntry* syncedMotionEntry = static_cast<MotionEntry*>(
+                                dispatchEntry->eventEntry);
+                        if (syncedMotionEntry->action != MOTION_EVENT_ACTION_MOVE
+                                || syncedMotionEntry->deviceId != deviceId
+                                || syncedMotionEntry->pointerCount != pointerCount) {
+                            goto NoBatchingOrStreaming;
+                        }
+
+                        // Found synced move entry.  Append sample and resume dispatch.
+                        mAllocator.appendMotionSample(syncedMotionEntry, eventTime,
+                                pointerCount, pointerCoords);
+#if DEBUG_BATCHING
+                        LOGD("Appended motion sample onto batch for most recent synchronously "
+                                "dispatched motion event for this device in the outbound queues.");
+#endif
+                        nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
+                        dispatchEventToCurrentInputTargetsLocked(currentTime, syncedMotionEntry,
+                                true /*resumeWithAppendedMotionSample*/);
+                        return; // done!
+                    }
+                }
+            }
+
+NoBatchingOrStreaming:;
+        }
+
+        // Just enqueue a new motion event.
+        MotionEntry* newEntry = mAllocator.obtainMotionEntry();
+        newEntry->eventTime = eventTime;
+        newEntry->deviceId = deviceId;
+        newEntry->nature = nature;
+        newEntry->policyFlags = policyFlags;
+        newEntry->action = action;
+        newEntry->metaState = metaState;
+        newEntry->edgeFlags = edgeFlags;
+        newEntry->xPrecision = xPrecision;
+        newEntry->yPrecision = yPrecision;
+        newEntry->downTime = downTime;
+        newEntry->pointerCount = pointerCount;
+        newEntry->firstSample.eventTime = eventTime;
+        newEntry->lastSample = & newEntry->firstSample;
+        for (uint32_t i = 0; i < pointerCount; i++) {
+            newEntry->pointerIds[i] = pointerIds[i];
+            newEntry->firstSample.pointerCoords[i] = pointerCoords[i];
+        }
+
+        wasEmpty = mInboundQueue.isEmpty();
+        mInboundQueue.enqueueAtTail(newEntry);
+    } // release lock
+
+    if (wasEmpty) {
+        mPollLoop->wake();
+    }
+}
+
+void InputDispatcher::resetKeyRepeatLocked() {
+    if (mKeyRepeatState.lastKeyEntry) {
+        mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
+        mKeyRepeatState.lastKeyEntry = NULL;
+    }
+}
+
+status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
+    int receiveFd;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        receiveFd = inputChannel->getReceivePipeFd();
+        if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) {
+            LOGW("Attempted to register already registered input channel '%s'",
+                    inputChannel->getName().string());
+            return BAD_VALUE;
+        }
+
+        sp<Connection> connection = new Connection(inputChannel);
+        status_t status = connection->initialize();
+        if (status) {
+            LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
+                    inputChannel->getName().string(), status);
+            return status;
+        }
+
+        mConnectionsByReceiveFd.add(receiveFd, connection);
+    } // release lock
+
+    mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
+    return OK;
+}
+
+status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
+    int32_t receiveFd;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        receiveFd = inputChannel->getReceivePipeFd();
+        ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
+        if (connectionIndex < 0) {
+            LOGW("Attempted to unregister already unregistered input channel '%s'",
+                    inputChannel->getName().string());
+            return BAD_VALUE;
+        }
+
+        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+        mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
+
+        connection->status = Connection::STATUS_ZOMBIE;
+
+        nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
+        abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
+    } // release lock
+
+    mPollLoop->removeCallback(receiveFd);
+
+    // Wake the poll loop because removing the connection may have changed the current
+    // synchronization state.
+    mPollLoop->wake();
+    return OK;
+}
+
+void InputDispatcher::activateConnectionLocked(Connection* connection) {
+    for (size_t i = 0; i < mActiveConnections.size(); i++) {
+        if (mActiveConnections.itemAt(i) == connection) {
+            return;
+        }
+    }
+    mActiveConnections.add(connection);
+}
+
+void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
+    for (size_t i = 0; i < mActiveConnections.size(); i++) {
+        if (mActiveConnections.itemAt(i) == connection) {
+            mActiveConnections.removeAt(i);
+            return;
+        }
+    }
+}
+
+void InputDispatcher::onDispatchCycleStartedLocked(nsecs_t currentTime, Connection* connection) {
+}
+
+void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
+        Connection* connection, bool recoveredFromANR) {
+    if (recoveredFromANR) {
+        LOGI("channel '%s' ~ Recovered from ANR.  %01.1fms since event, "
+                "%01.1fms since dispatch, %01.1fms since ANR",
+                connection->getInputChannelName(),
+                connection->getEventLatencyMillis(currentTime),
+                connection->getDispatchLatencyMillis(currentTime),
+                connection->getANRLatencyMillis(currentTime));
+
+        // TODO tell framework
+    }
+}
+
+void InputDispatcher::onDispatchCycleANRLocked(nsecs_t currentTime, Connection* connection) {
+    LOGI("channel '%s' ~ Not responding!  %01.1fms since event, %01.1fms since dispatch",
+            connection->getInputChannelName(),
+            connection->getEventLatencyMillis(currentTime),
+            connection->getDispatchLatencyMillis(currentTime));
+
+    // TODO tell framework
+}
+
+void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime, Connection* connection) {
+    LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
+            connection->getInputChannelName());
+
+    // TODO tell framework
+}
+
+// --- InputDispatcher::Allocator ---
+
+InputDispatcher::Allocator::Allocator() {
+}
+
+InputDispatcher::ConfigurationChangedEntry*
+InputDispatcher::Allocator::obtainConfigurationChangedEntry() {
+    ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
+    entry->refCount = 1;
+    entry->type = EventEntry::TYPE_CONFIGURATION_CHANGED;
+    return entry;
+}
+
+InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry() {
+    KeyEntry* entry = mKeyEntryPool.alloc();
+    entry->refCount = 1;
+    entry->type = EventEntry::TYPE_KEY;
+    return entry;
+}
+
+InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry() {
+    MotionEntry* entry = mMotionEntryPool.alloc();
+    entry->refCount = 1;
+    entry->type = EventEntry::TYPE_MOTION;
+    entry->firstSample.next = NULL;
+    return entry;
+}
+
+InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
+        EventEntry* eventEntry) {
+    DispatchEntry* entry = mDispatchEntryPool.alloc();
+    entry->eventEntry = eventEntry;
+    eventEntry->refCount += 1;
+    return entry;
+}
+
+void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
+    switch (entry->type) {
+    case EventEntry::TYPE_CONFIGURATION_CHANGED:
+        releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
+        break;
+    case EventEntry::TYPE_KEY:
+        releaseKeyEntry(static_cast<KeyEntry*>(entry));
+        break;
+    case EventEntry::TYPE_MOTION:
+        releaseMotionEntry(static_cast<MotionEntry*>(entry));
+        break;
+    default:
+        assert(false);
+        break;
+    }
+}
+
+void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
+        ConfigurationChangedEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        mConfigurationChangeEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        mKeyEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        freeMotionSampleList(entry->firstSample.next);
+        mMotionEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
+    releaseEventEntry(entry->eventEntry);
+    mDispatchEntryPool.free(entry);
+}
+
+void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
+        nsecs_t eventTime, int32_t pointerCount, const PointerCoords* pointerCoords) {
+    MotionSample* sample = mMotionSamplePool.alloc();
+    sample->eventTime = eventTime;
+    for (int32_t i = 0; i < pointerCount; i++) {
+        sample->pointerCoords[i] = pointerCoords[i];
+    }
+
+    sample->next = NULL;
+    motionEntry->lastSample->next = sample;
+    motionEntry->lastSample = sample;
+}
+
+void InputDispatcher::Allocator::freeMotionSample(MotionSample* sample) {
+    mMotionSamplePool.free(sample);
+}
+
+void InputDispatcher::Allocator::freeMotionSampleList(MotionSample* head) {
+    while (head) {
+        MotionSample* next = head->next;
+        mMotionSamplePool.free(head);
+        head = next;
+    }
+}
+
+// --- InputDispatcher::Connection ---
+
+InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
+        status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
+        nextTimeoutTime(LONG_LONG_MAX),
+        lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
+        lastANRTime(LONG_LONG_MAX) {
+}
+
+InputDispatcher::Connection::~Connection() {
+}
+
+status_t InputDispatcher::Connection::initialize() {
+    return inputPublisher.initialize();
+}
+
+InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
+        const EventEntry* eventEntry) const {
+    for (DispatchEntry* dispatchEntry = outboundQueue.tail.prev;
+            dispatchEntry != & outboundQueue.head; dispatchEntry = dispatchEntry->prev) {
+        if (dispatchEntry->eventEntry == eventEntry) {
+            return dispatchEntry;
+        }
+    }
+    return NULL;
+}
+
+
+// --- InputDispatcherThread ---
+
+InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
+        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
+}
+
+InputDispatcherThread::~InputDispatcherThread() {
+}
+
+bool InputDispatcherThread::threadLoop() {
+    mDispatcher->dispatchOnce();
+    return true;
+}
+
+} // namespace android
diff --git a/libs/ui/InputManager.cpp b/libs/ui/InputManager.cpp
new file mode 100644
index 0000000..ab354a5
--- /dev/null
+++ b/libs/ui/InputManager.cpp
@@ -0,0 +1,114 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// The input manager.
+//
+#define LOG_TAG "InputManager"
+
+//#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+#include <ui/InputManager.h>
+#include <ui/InputReader.h>
+#include <ui/InputDispatcher.h>
+
+namespace android {
+
+InputManager::InputManager(const sp<EventHubInterface>& eventHub,
+        const sp<InputDispatchPolicyInterface>& policy) :
+        mEventHub(eventHub), mPolicy(policy) {
+    mDispatcher = new InputDispatcher(policy);
+    mReader = new InputReader(eventHub, policy, mDispatcher);
+
+    mDispatcherThread = new InputDispatcherThread(mDispatcher);
+    mReaderThread = new InputReaderThread(mReader);
+
+    configureExcludedDevices();
+}
+
+InputManager::~InputManager() {
+    stop();
+}
+
+void InputManager::configureExcludedDevices() {
+    Vector<String8> excludedDeviceNames;
+    mPolicy->getExcludedDeviceNames(excludedDeviceNames);
+
+    for (size_t i = 0; i < excludedDeviceNames.size(); i++) {
+        mEventHub->addExcludedDevice(excludedDeviceNames[i]);
+    }
+}
+
+status_t InputManager::start() {
+    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
+    if (result) {
+        LOGE("Could not start InputDispatcher thread due to error %d.", result);
+        return result;
+    }
+
+    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
+    if (result) {
+        LOGE("Could not start InputReader thread due to error %d.", result);
+
+        mDispatcherThread->requestExit();
+        return result;
+    }
+
+    return OK;
+}
+
+status_t InputManager::stop() {
+    status_t result = mReaderThread->requestExitAndWait();
+    if (result) {
+        LOGW("Could not stop InputReader thread due to error %d.", result);
+    }
+
+    result = mDispatcherThread->requestExitAndWait();
+    if (result) {
+        LOGW("Could not stop InputDispatcher thread due to error %d.", result);
+    }
+
+    return OK;
+}
+
+status_t InputManager::registerInputChannel(const sp<InputChannel>& inputChannel) {
+    return mDispatcher->registerInputChannel(inputChannel);
+}
+
+status_t InputManager::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
+    return mDispatcher->unregisterInputChannel(inputChannel);
+}
+
+int32_t InputManager::getScanCodeState(int32_t deviceId, int32_t deviceClasses, int32_t scanCode)
+    const {
+    int32_t vkKeyCode, vkScanCode;
+    if (mReader->getCurrentVirtualKey(& vkKeyCode, & vkScanCode)) {
+        if (vkScanCode == scanCode) {
+            return KEY_STATE_VIRTUAL;
+        }
+    }
+
+    return mEventHub->getScanCodeState(deviceId, deviceClasses, scanCode);
+}
+
+int32_t InputManager::getKeyCodeState(int32_t deviceId, int32_t deviceClasses, int32_t keyCode)
+    const {
+    int32_t vkKeyCode, vkScanCode;
+    if (mReader->getCurrentVirtualKey(& vkKeyCode, & vkScanCode)) {
+        if (vkKeyCode == keyCode) {
+            return KEY_STATE_VIRTUAL;
+        }
+    }
+
+    return mEventHub->getKeyCodeState(deviceId, deviceClasses, keyCode);
+}
+
+int32_t InputManager::getSwitchState(int32_t deviceId, int32_t deviceClasses, int32_t sw) const {
+    return mEventHub->getSwitchState(deviceId, deviceClasses, sw);
+}
+
+bool InputManager::hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const {
+    return mEventHub->hasKeys(numCodes, keyCodes, outFlags);
+}
+
+} // namespace android
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
new file mode 100644
index 0000000..796abd0
--- /dev/null
+++ b/libs/ui/InputReader.cpp
@@ -0,0 +1,1843 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// The input reader.
+//
+#define LOG_TAG "InputReader"
+
+//#define LOG_NDEBUG 0
+
+// Log debug messages for each raw event received from the EventHub.
+#define DEBUG_RAW_EVENTS 0
+
+// Log debug messages about touch screen filtering hacks.
+#define DEBUG_HACKS 1
+
+// Log debug messages about virtual key processing.
+#define DEBUG_VIRTUAL_KEYS 1
+
+// Log debug messages about pointers.
+#define DEBUG_POINTERS 1
+
+#include <cutils/log.h>
+#include <ui/InputReader.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+namespace android {
+
+// --- Static Functions ---
+
+template<typename T>
+inline static T abs(const T& value) {
+    return value < 0 ? - value : value;
+}
+
+template<typename T>
+inline static T min(const T& a, const T& b) {
+    return a < b ? a : b;
+}
+
+int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
+    int32_t mask;
+    switch (keyCode) {
+    case KEYCODE_ALT_LEFT:
+        mask = META_ALT_LEFT_ON;
+        break;
+    case KEYCODE_ALT_RIGHT:
+        mask = META_ALT_RIGHT_ON;
+        break;
+    case KEYCODE_SHIFT_LEFT:
+        mask = META_SHIFT_LEFT_ON;
+        break;
+    case KEYCODE_SHIFT_RIGHT:
+        mask = META_SHIFT_RIGHT_ON;
+        break;
+    case KEYCODE_SYM:
+        mask = META_SYM_ON;
+        break;
+    default:
+        return oldMetaState;
+    }
+
+    int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask
+            & ~ (META_ALT_ON | META_SHIFT_ON);
+
+    if (newMetaState & (META_ALT_LEFT_ON | META_ALT_RIGHT_ON)) {
+        newMetaState |= META_ALT_ON;
+    }
+
+    if (newMetaState & (META_SHIFT_LEFT_ON | META_SHIFT_RIGHT_ON)) {
+        newMetaState |= META_SHIFT_ON;
+    }
+
+    return newMetaState;
+}
+
+static const int32_t keyCodeRotationMap[][4] = {
+        // key codes enumerated counter-clockwise with the original (unrotated) key first
+        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
+        { KEYCODE_DPAD_DOWN,   KEYCODE_DPAD_RIGHT,  KEYCODE_DPAD_UP,     KEYCODE_DPAD_LEFT },
+        { KEYCODE_DPAD_RIGHT,  KEYCODE_DPAD_UP,     KEYCODE_DPAD_LEFT,   KEYCODE_DPAD_DOWN },
+        { KEYCODE_DPAD_UP,     KEYCODE_DPAD_LEFT,   KEYCODE_DPAD_DOWN,   KEYCODE_DPAD_RIGHT },
+        { KEYCODE_DPAD_LEFT,   KEYCODE_DPAD_DOWN,   KEYCODE_DPAD_RIGHT,  KEYCODE_DPAD_UP },
+};
+static const int keyCodeRotationMapSize =
+        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
+
+int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
+    if (orientation != InputDispatchPolicyInterface::ROTATION_0) {
+        for (int i = 0; i < keyCodeRotationMapSize; i++) {
+            if (keyCode == keyCodeRotationMap[i][0]) {
+                return keyCodeRotationMap[i][orientation];
+            }
+        }
+    }
+    return keyCode;
+}
+
+
+// --- InputDevice ---
+
+InputDevice::InputDevice(int32_t id, uint32_t classes, String8 name) :
+    id(id), classes(classes), name(name), ignored(false) {
+}
+
+void InputDevice::reset() {
+    if (isKeyboard()) {
+        keyboard.reset();
+    }
+
+    if (isTrackball()) {
+        trackball.reset();
+    }
+
+    if (isMultiTouchScreen()) {
+        multiTouchScreen.reset();
+    } else if (isSingleTouchScreen()) {
+        singleTouchScreen.reset();
+    }
+
+    if (isTouchScreen()) {
+        touchScreen.reset();
+    }
+}
+
+
+// --- InputDevice::TouchData ---
+
+void InputDevice::TouchData::copyFrom(const TouchData& other) {
+    pointerCount = other.pointerCount;
+    idBits = other.idBits;
+
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        pointers[i] = other.pointers[i];
+        idToIndex[i] = other.idToIndex[i];
+    }
+}
+
+
+// --- InputDevice::KeyboardState ---
+
+void InputDevice::KeyboardState::reset() {
+    current.metaState = META_NONE;
+    current.downTime = 0;
+}
+
+
+// --- InputDevice::TrackballState ---
+
+void InputDevice::TrackballState::reset() {
+    accumulator.clear();
+    current.down = false;
+    current.downTime = 0;
+}
+
+
+// --- InputDevice::TouchScreenState ---
+
+void InputDevice::TouchScreenState::reset() {
+    lastTouch.clear();
+    downTime = 0;
+    currentVirtualKey.down = false;
+
+    for (uint32_t i = 0; i < MAX_POINTERS; i++) {
+        averagingTouchFilter.historyStart[i] = 0;
+        averagingTouchFilter.historyEnd[i] = 0;
+    }
+
+    jumpyTouchFilter.jumpyPointsDropped = 0;
+}
+
+void InputDevice::TouchScreenState::calculatePointerIds() {
+    uint32_t currentPointerCount = currentTouch.pointerCount;
+    uint32_t lastPointerCount = lastTouch.pointerCount;
+
+    if (currentPointerCount == 0) {
+        // No pointers to assign.
+        currentTouch.idBits.clear();
+    } else if (lastPointerCount == 0) {
+        // All pointers are new.
+        currentTouch.idBits.clear();
+        for (uint32_t i = 0; i < currentPointerCount; i++) {
+            currentTouch.pointers[i].id = i;
+            currentTouch.idToIndex[i] = i;
+            currentTouch.idBits.markBit(i);
+        }
+    } else if (currentPointerCount == 1 && lastPointerCount == 1) {
+        // Only one pointer and no change in count so it must have the same id as before.
+        uint32_t id = lastTouch.pointers[0].id;
+        currentTouch.pointers[0].id = id;
+        currentTouch.idToIndex[id] = 0;
+        currentTouch.idBits.value = BitSet32::valueForBit(id);
+    } else {
+        // General case.
+        // We build a heap of squared euclidean distances between current and last pointers
+        // associated with the current and last pointer indices.  Then, we find the best
+        // match (by distance) for each current pointer.
+        struct {
+            uint32_t currentPointerIndex : 8;
+            uint32_t lastPointerIndex : 8;
+            uint64_t distance : 48; // squared distance
+        } heap[MAX_POINTERS * MAX_POINTERS];
+
+        uint32_t heapSize = 0;
+        for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
+                currentPointerIndex++) {
+            for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
+                    lastPointerIndex++) {
+                int64_t deltaX = currentTouch.pointers[currentPointerIndex].x
+                        - lastTouch.pointers[lastPointerIndex].x;
+                int64_t deltaY = currentTouch.pointers[currentPointerIndex].y
+                        - lastTouch.pointers[lastPointerIndex].y;
+
+                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
+
+                // Insert new element into the heap (sift up).
+                heapSize += 1;
+                uint32_t insertionIndex = heapSize;
+                while (insertionIndex > 1) {
+                    uint32_t parentIndex = (insertionIndex - 1) / 2;
+                    if (distance < heap[parentIndex].distance) {
+                        heap[insertionIndex] = heap[parentIndex];
+                        insertionIndex = parentIndex;
+                    } else {
+                        break;
+                    }
+                }
+                heap[insertionIndex].currentPointerIndex = currentPointerIndex;
+                heap[insertionIndex].lastPointerIndex = lastPointerIndex;
+                heap[insertionIndex].distance = distance;
+            }
+        }
+
+        // Pull matches out by increasing order of distance.
+        // To avoid reassigning pointers that have already been matched, the loop keeps track
+        // of which last and current pointers have been matched using the matchedXXXBits variables.
+        // It also tracks the used pointer id bits.
+        BitSet32 matchedLastBits(0);
+        BitSet32 matchedCurrentBits(0);
+        BitSet32 usedIdBits(0);
+        bool first = true;
+        for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
+            for (;;) {
+                if (first) {
+                    // The first time through the loop, we just consume the root element of
+                    // the heap (the one with smalled distance).
+                    first = false;
+                } else {
+                    // Previous iterations consumed the root element of the heap.
+                    // Pop root element off of the heap (sift down).
+                    heapSize -= 1;
+                    assert(heapSize > 0);
+
+                    // Sift down to find where the element at index heapSize needs to be moved.
+                    uint32_t rootIndex = 0;
+                    for (;;) {
+                        uint32_t childIndex = rootIndex * 2 + 1;
+                        if (childIndex >= heapSize) {
+                            break;
+                        }
+
+                        if (childIndex + 1 < heapSize
+                                && heap[childIndex + 1].distance < heap[childIndex].distance) {
+                            childIndex += 1;
+                        }
+
+                        if (heap[heapSize].distance < heap[childIndex].distance) {
+                            break;
+                        }
+
+                        heap[rootIndex] = heap[childIndex];
+                        rootIndex = childIndex;
+                    }
+                    heap[rootIndex] = heap[heapSize];
+                }
+
+                uint32_t currentPointerIndex = heap[0].currentPointerIndex;
+                if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
+
+                uint32_t lastPointerIndex = heap[0].lastPointerIndex;
+                if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
+
+                matchedCurrentBits.markBit(currentPointerIndex);
+                matchedLastBits.markBit(lastPointerIndex);
+
+                uint32_t id = lastTouch.pointers[lastPointerIndex].id;
+                currentTouch.pointers[currentPointerIndex].id = id;
+                currentTouch.idToIndex[id] = currentPointerIndex;
+                usedIdBits.markBit(id);
+                break;
+            }
+        }
+
+        // Assign fresh ids to new pointers.
+        if (currentPointerCount > lastPointerCount) {
+            for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
+                uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
+                uint32_t id = usedIdBits.firstUnmarkedBit();
+
+                currentTouch.pointers[currentPointerIndex].id = id;
+                currentTouch.idToIndex[id] = currentPointerIndex;
+                usedIdBits.markBit(id);
+
+                if (--i == 0) break; // done
+                matchedCurrentBits.markBit(currentPointerIndex);
+            }
+        }
+
+        // Fix id bits.
+        currentTouch.idBits = usedIdBits;
+    }
+}
+
+/* Special hack for devices that have bad screen data: if one of the
+ * points has moved more than a screen height from the last position,
+ * then drop it. */
+bool InputDevice::TouchScreenState::applyBadTouchFilter() {
+    uint32_t pointerCount = currentTouch.pointerCount;
+
+    // Nothing to do if there are no points.
+    if (pointerCount == 0) {
+        return false;
+    }
+
+    // Don't do anything if a finger is going down or up.  We run
+    // here before assigning pointer IDs, so there isn't a good
+    // way to do per-finger matching.
+    if (pointerCount != lastTouch.pointerCount) {
+        return false;
+    }
+
+    // We consider a single movement across more than a 7/16 of
+    // the long size of the screen to be bad.  This was a magic value
+    // determined by looking at the maximum distance it is feasible
+    // to actually move in one sample.
+    int32_t maxDeltaY = parameters.yAxis.range * 7 / 16;
+
+    // XXX The original code in InputDevice.java included commented out
+    //     code for testing the X axis.  Note that when we drop a point
+    //     we don't actually restore the old X either.  Strange.
+    //     The old code also tries to track when bad points were previously
+    //     detected but it turns out that due to the placement of a "break"
+    //     at the end of the loop, we never set mDroppedBadPoint to true
+    //     so it is effectively dead code.
+    // Need to figure out if the old code is busted or just overcomplicated
+    // but working as intended.
+
+    // Look through all new points and see if any are farther than
+    // acceptable from all previous points.
+    for (uint32_t i = pointerCount; i-- > 0; ) {
+        int32_t y = currentTouch.pointers[i].y;
+        int32_t closestY = INT_MAX;
+        int32_t closestDeltaY = 0;
+
+#if DEBUG_HACKS
+        LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y);
+#endif
+
+        for (uint32_t j = pointerCount; j-- > 0; ) {
+            int32_t lastY = lastTouch.pointers[j].y;
+            int32_t deltaY = abs(y - lastY);
+
+#if DEBUG_HACKS
+            LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d",
+                    j, lastY, deltaY);
+#endif
+
+            if (deltaY < maxDeltaY) {
+                goto SkipSufficientlyClosePoint;
+            }
+            if (deltaY < closestDeltaY) {
+                closestDeltaY = deltaY;
+                closestY = lastY;
+            }
+        }
+
+        // Must not have found a close enough match.
+#if DEBUG_HACKS
+        LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d",
+                i, y, closestY, closestDeltaY, maxDeltaY);
+#endif
+
+        currentTouch.pointers[i].y = closestY;
+        return true; // XXX original code only corrects one point
+
+    SkipSufficientlyClosePoint: ;
+    }
+
+    // No change.
+    return false;
+}
+
+/* Special hack for devices that have bad screen data: drop points where
+ * the coordinate value for one axis has jumped to the other pointer's location.
+ */
+bool InputDevice::TouchScreenState::applyJumpyTouchFilter() {
+    uint32_t pointerCount = currentTouch.pointerCount;
+    if (lastTouch.pointerCount != pointerCount) {
+#if DEBUG_HACKS
+        LOGD("JumpyTouchFilter: Different pointer count %d -> %d",
+                lastTouch.pointerCount, pointerCount);
+        for (uint32_t i = 0; i < pointerCount; i++) {
+            LOGD("  Pointer %d (%d, %d)", i,
+                    currentTouch.pointers[i].x, currentTouch.pointers[i].y);
+        }
+#endif
+
+        if (jumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
+            if (lastTouch.pointerCount == 1 && pointerCount == 2) {
+                // Just drop the first few events going from 1 to 2 pointers.
+                // They're bad often enough that they're not worth considering.
+                currentTouch.pointerCount = 1;
+                jumpyTouchFilter.jumpyPointsDropped += 1;
+
+#if DEBUG_HACKS
+                LOGD("JumpyTouchFilter: Pointer 2 dropped");
+#endif
+                return true;
+            } else if (lastTouch.pointerCount == 2 && pointerCount == 1) {
+                // The event when we go from 2 -> 1 tends to be messed up too
+                currentTouch.pointerCount = 2;
+                currentTouch.pointers[0] = lastTouch.pointers[0];
+                currentTouch.pointers[1] = lastTouch.pointers[1];
+                jumpyTouchFilter.jumpyPointsDropped += 1;
+
+#if DEBUG_HACKS
+                for (int32_t i = 0; i < 2; i++) {
+                    LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i,
+                            currentTouch.pointers[i].x, currentTouch.pointers[i].y);
+                }
+#endif
+                return true;
+            }
+        }
+        // Reset jumpy points dropped on other transitions or if limit exceeded.
+        jumpyTouchFilter.jumpyPointsDropped = 0;
+
+#if DEBUG_HACKS
+        LOGD("JumpyTouchFilter: Transition - drop limit reset");
+#endif
+        return false;
+    }
+
+    // We have the same number of pointers as last time.
+    // A 'jumpy' point is one where the coordinate value for one axis
+    // has jumped to the other pointer's location. No need to do anything
+    // else if we only have one pointer.
+    if (pointerCount < 2) {
+        return false;
+    }
+
+    if (jumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
+        int jumpyEpsilon = parameters.yAxis.range / JUMPY_EPSILON_DIVISOR;
+
+        // We only replace the single worst jumpy point as characterized by pointer distance
+        // in a single axis.
+        int32_t badPointerIndex = -1;
+        int32_t badPointerReplacementIndex = -1;
+        int32_t badPointerDistance = INT_MIN; // distance to be corrected
+
+        for (uint32_t i = pointerCount; i-- > 0; ) {
+            int32_t x = currentTouch.pointers[i].x;
+            int32_t y = currentTouch.pointers[i].y;
+
+#if DEBUG_HACKS
+            LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y);
+#endif
+
+            // Check if a touch point is too close to another's coordinates
+            bool dropX = false, dropY = false;
+            for (uint32_t j = 0; j < pointerCount; j++) {
+                if (i == j) {
+                    continue;
+                }
+
+                if (abs(x - currentTouch.pointers[j].x) <= jumpyEpsilon) {
+                    dropX = true;
+                    break;
+                }
+
+                if (abs(y - currentTouch.pointers[j].y) <= jumpyEpsilon) {
+                    dropY = true;
+                    break;
+                }
+            }
+            if (! dropX && ! dropY) {
+                continue; // not jumpy
+            }
+
+            // Find a replacement candidate by comparing with older points on the
+            // complementary (non-jumpy) axis.
+            int32_t distance = INT_MIN; // distance to be corrected
+            int32_t replacementIndex = -1;
+
+            if (dropX) {
+                // X looks too close.  Find an older replacement point with a close Y.
+                int32_t smallestDeltaY = INT_MAX;
+                for (uint32_t j = 0; j < pointerCount; j++) {
+                    int32_t deltaY = abs(y - lastTouch.pointers[j].y);
+                    if (deltaY < smallestDeltaY) {
+                        smallestDeltaY = deltaY;
+                        replacementIndex = j;
+                    }
+                }
+                distance = abs(x - lastTouch.pointers[replacementIndex].x);
+            } else {
+                // Y looks too close.  Find an older replacement point with a close X.
+                int32_t smallestDeltaX = INT_MAX;
+                for (uint32_t j = 0; j < pointerCount; j++) {
+                    int32_t deltaX = abs(x - lastTouch.pointers[j].x);
+                    if (deltaX < smallestDeltaX) {
+                        smallestDeltaX = deltaX;
+                        replacementIndex = j;
+                    }
+                }
+                distance = abs(y - lastTouch.pointers[replacementIndex].y);
+            }
+
+            // If replacing this pointer would correct a worse error than the previous ones
+            // considered, then use this replacement instead.
+            if (distance > badPointerDistance) {
+                badPointerIndex = i;
+                badPointerReplacementIndex = replacementIndex;
+                badPointerDistance = distance;
+            }
+        }
+
+        // Correct the jumpy pointer if one was found.
+        if (badPointerIndex >= 0) {
+#if DEBUG_HACKS
+            LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)",
+                    badPointerIndex,
+                    lastTouch.pointers[badPointerReplacementIndex].x,
+                    lastTouch.pointers[badPointerReplacementIndex].y);
+#endif
+
+            currentTouch.pointers[badPointerIndex].x =
+                    lastTouch.pointers[badPointerReplacementIndex].x;
+            currentTouch.pointers[badPointerIndex].y =
+                    lastTouch.pointers[badPointerReplacementIndex].y;
+            jumpyTouchFilter.jumpyPointsDropped += 1;
+            return true;
+        }
+    }
+
+    jumpyTouchFilter.jumpyPointsDropped = 0;
+    return false;
+}
+
+/* Special hack for devices that have bad screen data: aggregate and
+ * compute averages of the coordinate data, to reduce the amount of
+ * jitter seen by applications. */
+void InputDevice::TouchScreenState::applyAveragingTouchFilter() {
+    for (uint32_t currentIndex = 0; currentIndex < currentTouch.pointerCount; currentIndex++) {
+        uint32_t id = currentTouch.pointers[currentIndex].id;
+        int32_t x = currentTouch.pointers[currentIndex].x;
+        int32_t y = currentTouch.pointers[currentIndex].y;
+        int32_t pressure = currentTouch.pointers[currentIndex].pressure;
+
+        if (lastTouch.idBits.hasBit(id)) {
+            // Pointer still down compute average.
+            uint32_t start = averagingTouchFilter.historyStart[id];
+            uint32_t end = averagingTouchFilter.historyEnd[id];
+
+            int64_t deltaX = x - averagingTouchFilter.historyData[end].pointers[id].x;
+            int64_t deltaY = y - averagingTouchFilter.historyData[end].pointers[id].y;
+            uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
+
+#if DEBUG_HACKS
+            LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld",
+                    id, distance);
+#endif
+
+            if (distance < AVERAGING_DISTANCE_LIMIT) {
+                end += 1;
+                if (end > AVERAGING_HISTORY_SIZE) {
+                    end = 0;
+                }
+
+                if (end == start) {
+                    start += 1;
+                    if (start > AVERAGING_HISTORY_SIZE) {
+                        start = 0;
+                    }
+                }
+
+                averagingTouchFilter.historyStart[id] = start;
+                averagingTouchFilter.historyEnd[id] = end;
+                averagingTouchFilter.historyData[end].pointers[id].x = x;
+                averagingTouchFilter.historyData[end].pointers[id].y = y;
+                averagingTouchFilter.historyData[end].pointers[id].pressure = pressure;
+
+                int32_t averagedX = 0;
+                int32_t averagedY = 0;
+                int32_t totalPressure = 0;
+                for (;;) {
+                    int32_t historicalX = averagingTouchFilter.historyData[start].pointers[id].x;
+                    int32_t historicalY = averagingTouchFilter.historyData[start].pointers[id].x;
+                    int32_t historicalPressure = averagingTouchFilter.historyData[start]
+                            .pointers[id].pressure;
+
+                    averagedX += historicalX;
+                    averagedY += historicalY;
+                    totalPressure += historicalPressure;
+
+                    if (start == end) {
+                        break;
+                    }
+
+                    start += 1;
+                    if (start > AVERAGING_HISTORY_SIZE) {
+                        start = 0;
+                    }
+                }
+
+                averagedX /= totalPressure;
+                averagedY /= totalPressure;
+
+#if DEBUG_HACKS
+                LOGD("AveragingTouchFilter: Pointer id %d - "
+                        "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
+                        averagedX, averagedY);
+#endif
+
+                currentTouch.pointers[currentIndex].x = averagedX;
+                currentTouch.pointers[currentIndex].y = averagedY;
+            } else {
+#if DEBUG_HACKS
+                LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
+#endif
+            }
+        } else {
+#if DEBUG_HACKS
+            LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id);
+#endif
+        }
+
+        // Reset pointer history.
+        averagingTouchFilter.historyStart[id] = 0;
+        averagingTouchFilter.historyEnd[id] = 0;
+        averagingTouchFilter.historyData[0].pointers[id].x = x;
+        averagingTouchFilter.historyData[0].pointers[id].y = y;
+        averagingTouchFilter.historyData[0].pointers[id].pressure = pressure;
+    }
+}
+
+bool InputDevice::TouchScreenState::isPointInsideDisplay(int32_t x, int32_t y) const {
+    return x >= parameters.xAxis.minValue
+        && x <= parameters.xAxis.maxValue
+        && y >= parameters.yAxis.minValue
+        && y <= parameters.yAxis.maxValue;
+}
+
+
+// --- InputDevice::SingleTouchScreenState ---
+
+void InputDevice::SingleTouchScreenState::reset() {
+    accumulator.clear();
+    current.down = false;
+    current.x = 0;
+    current.y = 0;
+    current.pressure = 0;
+    current.size = 0;
+}
+
+
+// --- InputDevice::MultiTouchScreenState ---
+
+void InputDevice::MultiTouchScreenState::reset() {
+    accumulator.clear();
+}
+
+
+// --- InputReader ---
+
+InputReader::InputReader(const sp<EventHubInterface>& eventHub,
+        const sp<InputDispatchPolicyInterface>& policy,
+        const sp<InputDispatcherInterface>& dispatcher) :
+        mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher) {
+    resetGlobalMetaState();
+    resetDisplayProperties();
+    updateGlobalVirtualKeyState();
+}
+
+InputReader::~InputReader() {
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        delete mDevices.valueAt(i);
+    }
+}
+
+void InputReader::loopOnce() {
+    RawEvent rawEvent;
+    mEventHub->getEvent(& rawEvent.deviceId, & rawEvent.type, & rawEvent.scanCode,
+            & rawEvent.keyCode, & rawEvent.flags, & rawEvent.value, & rawEvent.when);
+
+    // Replace the event timestamp so it is in same timebase as java.lang.System.nanoTime()
+    // and android.os.SystemClock.uptimeMillis() as expected by the rest of the system.
+    rawEvent.when = systemTime(SYSTEM_TIME_MONOTONIC);
+
+#if DEBUG_RAW_EVENTS
+    LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d",
+            rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
+            rawEvent.value);
+#endif
+
+    process(& rawEvent);
+}
+
+void InputReader::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EventHubInterface::DEVICE_ADDED:
+        handleDeviceAdded(rawEvent);
+        break;
+
+    case EventHubInterface::DEVICE_REMOVED:
+        handleDeviceRemoved(rawEvent);
+        break;
+
+    case EV_SYN:
+        handleSync(rawEvent);
+        break;
+
+    case EV_KEY:
+        handleKey(rawEvent);
+        break;
+
+    case EV_REL:
+        handleRelativeMotion(rawEvent);
+        break;
+
+    case EV_ABS:
+        handleAbsoluteMotion(rawEvent);
+        break;
+
+    case EV_SW:
+        handleSwitch(rawEvent);
+        break;
+    }
+}
+
+void InputReader::handleDeviceAdded(const RawEvent* rawEvent) {
+    InputDevice* device = getDevice(rawEvent->deviceId);
+    if (device) {
+        LOGW("Ignoring spurious device added event for deviceId %d.", rawEvent->deviceId);
+        return;
+    }
+
+    addDevice(rawEvent->when, rawEvent->deviceId);
+}
+
+void InputReader::handleDeviceRemoved(const RawEvent* rawEvent) {
+    InputDevice* device = getDevice(rawEvent->deviceId);
+    if (! device) {
+        LOGW("Ignoring spurious device removed event for deviceId %d.", rawEvent->deviceId);
+        return;
+    }
+
+    removeDevice(rawEvent->when, device);
+}
+
+void InputReader::handleSync(const RawEvent* rawEvent) {
+    InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
+    if (! device) return;
+
+    if (rawEvent->scanCode == SYN_MT_REPORT) {
+        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
+        // We drop pointers with pressure <= 0 since that indicates they are not down.
+        if (device->isMultiTouchScreen()) {
+            uint32_t pointerIndex = device->multiTouchScreen.accumulator.pointerCount;
+
+            if (device->multiTouchScreen.accumulator.pointers[pointerIndex].fields) {
+                if (pointerIndex == MAX_POINTERS) {
+                    LOGW("MultiTouch device driver returned more than maximum of %d pointers.",
+                            MAX_POINTERS);
+                } else {
+                    pointerIndex += 1;
+                    device->multiTouchScreen.accumulator.pointerCount = pointerIndex;
+                }
+            }
+
+            device->multiTouchScreen.accumulator.pointers[pointerIndex].clear();
+        }
+    } else if (rawEvent->scanCode == SYN_REPORT) {
+        // General Sync: The driver has returned all data for the current event update.
+        if (device->isMultiTouchScreen()) {
+            if (device->multiTouchScreen.accumulator.isDirty()) {
+                onMultiTouchScreenStateChanged(rawEvent->when, device);
+                device->multiTouchScreen.accumulator.clear();
+            }
+        } else if (device->isSingleTouchScreen()) {
+            if (device->singleTouchScreen.accumulator.isDirty()) {
+                onSingleTouchScreenStateChanged(rawEvent->when, device);
+                device->singleTouchScreen.accumulator.clear();
+            }
+        }
+
+        if (device->trackball.accumulator.isDirty()) {
+            onTrackballStateChanged(rawEvent->when, device);
+            device->trackball.accumulator.clear();
+        }
+    }
+}
+
+void InputReader::handleKey(const RawEvent* rawEvent) {
+    InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
+    if (! device) return;
+
+    bool down = rawEvent->value != 0;
+    int32_t scanCode = rawEvent->scanCode;
+
+    if (device->isKeyboard() && (scanCode < BTN_FIRST || scanCode > BTN_LAST)) {
+        int32_t keyCode = rawEvent->keyCode;
+        onKey(rawEvent->when, device, down, keyCode, scanCode, rawEvent->flags);
+    } else if (device->isSingleTouchScreen()) {
+        switch (rawEvent->scanCode) {
+        case BTN_TOUCH:
+            device->singleTouchScreen.accumulator.fields |=
+                    InputDevice::SingleTouchScreenState::Accumulator::FIELD_BTN_TOUCH;
+            device->singleTouchScreen.accumulator.btnTouch = down;
+            break;
+        }
+    } else if (device->isTrackball()) {
+        switch (rawEvent->scanCode) {
+        case BTN_MOUSE:
+            device->trackball.accumulator.fields |=
+                    InputDevice::TrackballState::Accumulator::FIELD_BTN_MOUSE;
+            device->trackball.accumulator.btnMouse = down;
+
+            // send the down immediately
+            // XXX this emulates the old behavior of KeyInputQueue, unclear whether it is
+            //     necessary or if we can wait until the next sync
+            onTrackballStateChanged(rawEvent->when, device);
+            device->trackball.accumulator.clear();
+            break;
+        }
+    }
+}
+
+void InputReader::handleRelativeMotion(const RawEvent* rawEvent) {
+    InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
+    if (! device) return;
+
+    if (device->isTrackball()) {
+        switch (rawEvent->scanCode) {
+        case REL_X:
+            device->trackball.accumulator.fields |=
+                    InputDevice::TrackballState::Accumulator::FIELD_REL_X;
+            device->trackball.accumulator.relX = rawEvent->value;
+            break;
+        case REL_Y:
+            device->trackball.accumulator.fields |=
+                    InputDevice::TrackballState::Accumulator::FIELD_REL_Y;
+            device->trackball.accumulator.relY = rawEvent->value;
+            break;
+        }
+    }
+}
+
+void InputReader::handleAbsoluteMotion(const RawEvent* rawEvent) {
+    InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
+    if (! device) return;
+
+    if (device->isMultiTouchScreen()) {
+        uint32_t pointerIndex = device->multiTouchScreen.accumulator.pointerCount;
+        InputDevice::MultiTouchScreenState::Accumulator::Pointer* pointer =
+                & device->multiTouchScreen.accumulator.pointers[pointerIndex];
+
+        switch (rawEvent->scanCode) {
+        case ABS_MT_POSITION_X:
+            pointer->fields |=
+                    InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_X;
+            pointer->absMTPositionX = rawEvent->value;
+            break;
+        case ABS_MT_POSITION_Y:
+            pointer->fields |=
+                    InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_Y;
+            pointer->absMTPositionY = rawEvent->value;
+            break;
+        case ABS_MT_TOUCH_MAJOR:
+            pointer->fields |=
+                    InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MAJOR;
+            pointer->absMTTouchMajor = rawEvent->value;
+            break;
+        case ABS_MT_WIDTH_MAJOR:
+            pointer->fields |=
+                    InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
+            pointer->absMTWidthMajor = rawEvent->value;
+            break;
+        case ABS_MT_TRACKING_ID:
+            pointer->fields |=
+                    InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TRACKING_ID;
+            pointer->absMTTrackingId = rawEvent->value;
+            break;
+        }
+    } else if (device->isSingleTouchScreen()) {
+        switch (rawEvent->scanCode) {
+        case ABS_X:
+            device->singleTouchScreen.accumulator.fields |=
+                    InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_X;
+            device->singleTouchScreen.accumulator.absX = rawEvent->value;
+            break;
+        case ABS_Y:
+            device->singleTouchScreen.accumulator.fields |=
+                    InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_Y;
+            device->singleTouchScreen.accumulator.absY = rawEvent->value;
+            break;
+        case ABS_PRESSURE:
+            device->singleTouchScreen.accumulator.fields |=
+                    InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_PRESSURE;
+            device->singleTouchScreen.accumulator.absPressure = rawEvent->value;
+            break;
+        case ABS_TOOL_WIDTH:
+            device->singleTouchScreen.accumulator.fields |=
+                    InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_TOOL_WIDTH;
+            device->singleTouchScreen.accumulator.absToolWidth = rawEvent->value;
+            break;
+        }
+    }
+}
+
+void InputReader::handleSwitch(const RawEvent* rawEvent) {
+    InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
+    if (! device) return;
+
+    onSwitch(rawEvent->when, device, rawEvent->value != 0, rawEvent->scanCode);
+}
+
+void InputReader::onKey(nsecs_t when, InputDevice* device,
+        bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) {
+    /* Refresh display properties so we can rotate key codes according to display orientation */
+
+    if (! refreshDisplayProperties()) {
+        return;
+    }
+
+    /* Update device state */
+
+    int32_t oldMetaState = device->keyboard.current.metaState;
+    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
+    if (oldMetaState != newMetaState) {
+        device->keyboard.current.metaState = newMetaState;
+        resetGlobalMetaState();
+    }
+
+    // FIXME if we send a down event about a rotated key press we should ensure that we send
+    //       a corresponding up event about the rotated key press even if the orientation
+    //       has changed in the meantime
+    keyCode = rotateKeyCode(keyCode, mDisplayOrientation);
+
+    if (down) {
+        device->keyboard.current.downTime = when;
+    }
+
+    /* Apply policy */
+
+    int32_t policyActions = mPolicy->interceptKey(when, device->id,
+            down, keyCode, scanCode, policyFlags);
+
+    if (! applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) {
+        return; // event dropped
+    }
+
+    /* Enqueue key event for dispatch */
+
+    int32_t keyEventAction;
+    if (down) {
+        device->keyboard.current.downTime = when;
+        keyEventAction = KEY_EVENT_ACTION_DOWN;
+    } else {
+        keyEventAction = KEY_EVENT_ACTION_UP;
+    }
+
+    int32_t keyEventFlags = KEY_EVENT_FLAG_FROM_SYSTEM;
+    if (policyActions & InputDispatchPolicyInterface::ACTION_WOKE_HERE) {
+        keyEventFlags = keyEventFlags | KEY_EVENT_FLAG_WOKE_HERE;
+    }
+
+    mDispatcher->notifyKey(when, device->id, INPUT_EVENT_NATURE_KEY, policyFlags,
+            keyEventAction, keyEventFlags, keyCode, scanCode,
+            device->keyboard.current.metaState,
+            device->keyboard.current.downTime);
+}
+
+void InputReader::onSwitch(nsecs_t when, InputDevice* device, bool down,
+        int32_t code) {
+    switch (code) {
+    case SW_LID:
+        mDispatcher->notifyLidSwitchChanged(when, ! down);
+    }
+}
+
+void InputReader::onMultiTouchScreenStateChanged(nsecs_t when,
+        InputDevice* device) {
+    static const uint32_t REQUIRED_FIELDS =
+            InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_X
+            | InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_Y
+            | InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MAJOR
+            | InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
+
+    /* Refresh display properties so we can map touch screen coords into display coords */
+
+    if (! refreshDisplayProperties()) {
+        return;
+    }
+
+    /* Update device state */
+
+    InputDevice::MultiTouchScreenState* in = & device->multiTouchScreen;
+    InputDevice::TouchData* out = & device->touchScreen.currentTouch;
+
+    uint32_t inCount = in->accumulator.pointerCount;
+    uint32_t outCount = 0;
+    bool havePointerIds = true;
+
+    out->clear();
+
+    for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
+        uint32_t fields = in->accumulator.pointers[inIndex].fields;
+
+        if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
+#if DEBUG_POINTERS
+            LOGD("Pointers: Missing required multitouch pointer fields: index=%d, fields=%d",
+                    inIndex, fields);
+            continue;
+#endif
+        }
+
+        if (in->accumulator.pointers[inIndex].absMTTouchMajor <= 0) {
+            // Pointer is not down.  Drop it.
+            continue;
+        }
+
+        // FIXME assignment of pressure may be incorrect, probably better to let
+        // pressure = touch / width.  Later on we pass width to MotionEvent as a size, which
+        // isn't quite right either.  Should be using touch for that.
+        out->pointers[outCount].x = in->accumulator.pointers[inIndex].absMTPositionX;
+        out->pointers[outCount].y = in->accumulator.pointers[inIndex].absMTPositionY;
+        out->pointers[outCount].pressure = in->accumulator.pointers[inIndex].absMTTouchMajor;
+        out->pointers[outCount].size = in->accumulator.pointers[inIndex].absMTWidthMajor;
+
+        if (havePointerIds) {
+            if (fields & InputDevice::MultiTouchScreenState::Accumulator::
+                    FIELD_ABS_MT_TRACKING_ID) {
+                uint32_t id = uint32_t(in->accumulator.pointers[inIndex].absMTTrackingId);
+
+                if (id > MAX_POINTER_ID) {
+#if DEBUG_POINTERS
+                    LOGD("Pointers: Ignoring driver provided pointer id %d because "
+                            "it is larger than max supported id %d for optimizations",
+                            id, MAX_POINTER_ID);
+#endif
+                    havePointerIds = false;
+                }
+                else {
+                    out->pointers[outCount].id = id;
+                    out->idToIndex[id] = outCount;
+                    out->idBits.markBit(id);
+                }
+            } else {
+                havePointerIds = false;
+            }
+        }
+
+        outCount += 1;
+    }
+
+    out->pointerCount = outCount;
+
+    onTouchScreenChanged(when, device, havePointerIds);
+}
+
+void InputReader::onSingleTouchScreenStateChanged(nsecs_t when,
+        InputDevice* device) {
+    static const uint32_t POSITION_FIELDS =
+            InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_X
+            | InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_Y
+            | InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_PRESSURE
+            | InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_TOOL_WIDTH;
+
+    /* Refresh display properties so we can map touch screen coords into display coords */
+
+    if (! refreshDisplayProperties()) {
+        return;
+    }
+
+    /* Update device state */
+
+    InputDevice::SingleTouchScreenState* in = & device->singleTouchScreen;
+    InputDevice::TouchData* out = & device->touchScreen.currentTouch;
+
+    uint32_t fields = in->accumulator.fields;
+
+    if (fields & InputDevice::SingleTouchScreenState::Accumulator::FIELD_BTN_TOUCH) {
+        in->current.down = in->accumulator.btnTouch;
+    }
+
+    if ((fields & POSITION_FIELDS) == POSITION_FIELDS) {
+        in->current.x = in->accumulator.absX;
+        in->current.y = in->accumulator.absY;
+        in->current.pressure = in->accumulator.absPressure;
+        in->current.size = in->accumulator.absToolWidth;
+    }
+
+    out->clear();
+
+    if (in->current.down) {
+        out->pointerCount = 1;
+        out->pointers[0].id = 0;
+        out->pointers[0].x = in->current.x;
+        out->pointers[0].y = in->current.y;
+        out->pointers[0].pressure = in->current.pressure;
+        out->pointers[0].size = in->current.size;
+        out->idToIndex[0] = 0;
+        out->idBits.markBit(0);
+    }
+
+    onTouchScreenChanged(when, device, true);
+}
+
+void InputReader::onTouchScreenChanged(nsecs_t when,
+        InputDevice* device, bool havePointerIds) {
+    /* Apply policy */
+
+    int32_t policyActions = mPolicy->interceptTouch(when);
+
+    uint32_t policyFlags = 0;
+    if (! applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) {
+        device->touchScreen.lastTouch.clear();
+        return; // event dropped
+    }
+
+    /* Preprocess pointer data */
+
+    if (device->touchScreen.parameters.useBadTouchFilter) {
+        if (device->touchScreen.applyBadTouchFilter()) {
+            havePointerIds = false;
+        }
+    }
+
+    if (device->touchScreen.parameters.useJumpyTouchFilter) {
+        if (device->touchScreen.applyJumpyTouchFilter()) {
+            havePointerIds = false;
+        }
+    }
+
+    if (! havePointerIds) {
+        device->touchScreen.calculatePointerIds();
+    }
+
+    InputDevice::TouchData temp;
+    InputDevice::TouchData* savedTouch;
+    if (device->touchScreen.parameters.useAveragingTouchFilter) {
+        temp.copyFrom(device->touchScreen.currentTouch);
+        savedTouch = & temp;
+
+        device->touchScreen.applyAveragingTouchFilter();
+    } else {
+        savedTouch = & device->touchScreen.currentTouch;
+    }
+
+    /* Process virtual keys or touches */
+
+    if (! consumeVirtualKeyTouches(when, device, policyFlags)) {
+        dispatchTouches(when, device, policyFlags);
+    }
+
+    // Copy current touch to last touch in preparation for the next cycle.
+    device->touchScreen.lastTouch.copyFrom(*savedTouch);
+}
+
+bool InputReader::consumeVirtualKeyTouches(nsecs_t when,
+        InputDevice* device, uint32_t policyFlags) {
+    if (device->touchScreen.currentVirtualKey.down) {
+        if (device->touchScreen.currentTouch.pointerCount == 0) {
+            // Pointer went up while virtual key was down.  Send key up event.
+            device->touchScreen.currentVirtualKey.down = false;
+
+#if DEBUG_VIRTUAL_KEYS
+            LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
+                    device->touchScreen.currentVirtualKey.keyCode,
+                    device->touchScreen.currentVirtualKey.scanCode);
+#endif
+
+            dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
+                    KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
+            return true; // consumed
+        }
+
+        int32_t x = device->touchScreen.currentTouch.pointers[0].x;
+        int32_t y = device->touchScreen.currentTouch.pointers[0].y;
+        if (device->touchScreen.isPointInsideDisplay(x, y)) {
+            // Pointer moved inside the display area.  Send key cancellation.
+            device->touchScreen.currentVirtualKey.down = false;
+
+#if DEBUG_VIRTUAL_KEYS
+            LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
+                    device->touchScreen.currentVirtualKey.keyCode,
+                    device->touchScreen.currentVirtualKey.scanCode);
+#endif
+
+            dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
+                    KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+                            | KEY_EVENT_FLAG_CANCELED);
+
+            // Clear the last touch data so we will consider the pointer as having just been
+            // pressed down when generating subsequent motion events.
+            device->touchScreen.lastTouch.clear();
+            return false; // not consumed
+        }
+    } else if (device->touchScreen.currentTouch.pointerCount > 0
+            && device->touchScreen.lastTouch.pointerCount == 0) {
+        int32_t x = device->touchScreen.currentTouch.pointers[0].x;
+        int32_t y = device->touchScreen.currentTouch.pointers[0].y;
+        for (size_t i = 0; i < device->touchScreen.virtualKeys.size(); i++) {
+            const InputDevice::VirtualKey& virtualKey = device->touchScreen.virtualKeys[i];
+
+#if DEBUG_VIRTUAL_KEYS
+            LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
+                    "left=%d, top=%d, right=%d, bottom=%d",
+                    x, y,
+                    virtualKey.keyCode, virtualKey.scanCode,
+                    virtualKey.hitLeft, virtualKey.hitTop,
+                    virtualKey.hitRight, virtualKey.hitBottom);
+#endif
+
+            if (virtualKey.isHit(x, y)) {
+                device->touchScreen.currentVirtualKey.down = true;
+                device->touchScreen.currentVirtualKey.downTime = when;
+                device->touchScreen.currentVirtualKey.keyCode = virtualKey.keyCode;
+                device->touchScreen.currentVirtualKey.scanCode = virtualKey.scanCode;
+
+#if DEBUG_VIRTUAL_KEYS
+                    LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
+                            device->touchScreen.currentVirtualKey.keyCode,
+                            device->touchScreen.currentVirtualKey.scanCode);
+#endif
+
+                dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_DOWN,
+                        KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
+                return true; // consumed
+            }
+        }
+    }
+
+    return false; // not consumed
+}
+
+void InputReader::dispatchVirtualKey(nsecs_t when,
+        InputDevice* device, uint32_t policyFlags,
+        int32_t keyEventAction, int32_t keyEventFlags) {
+    int32_t keyCode = device->touchScreen.currentVirtualKey.keyCode;
+    int32_t scanCode = device->touchScreen.currentVirtualKey.scanCode;
+    nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime;
+    int32_t metaState = globalMetaState();
+
+    updateGlobalVirtualKeyState();
+
+    mPolicy->virtualKeyFeedback(when, device->id, keyEventAction, keyEventFlags,
+            keyCode, scanCode, metaState, downTime);
+
+    mDispatcher->notifyKey(when, device->id, INPUT_EVENT_NATURE_KEY, policyFlags,
+            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+}
+
+void InputReader::dispatchTouches(nsecs_t when,
+        InputDevice* device, uint32_t policyFlags) {
+    uint32_t currentPointerCount = device->touchScreen.currentTouch.pointerCount;
+    uint32_t lastPointerCount = device->touchScreen.lastTouch.pointerCount;
+    if (currentPointerCount == 0 && lastPointerCount == 0) {
+        return; // nothing to do!
+    }
+
+    BitSet32 currentIdBits = device->touchScreen.currentTouch.idBits;
+    BitSet32 lastIdBits = device->touchScreen.lastTouch.idBits;
+
+    if (currentIdBits == lastIdBits) {
+        // No pointer id changes so this is a move event.
+        // The dispatcher takes care of batching moves so we don't have to deal with that here.
+        int32_t motionEventAction = MOTION_EVENT_ACTION_MOVE;
+        dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch,
+                currentIdBits, motionEventAction);
+    } else {
+        // There may be pointers going up and pointers going down at the same time when pointer
+        // ids are reported by the device driver.
+        BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
+        BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
+        BitSet32 activeIdBits(lastIdBits.value);
+
+        while (! upIdBits.isEmpty()) {
+            uint32_t upId = upIdBits.firstMarkedBit();
+            upIdBits.clearBit(upId);
+            BitSet32 oldActiveIdBits = activeIdBits;
+            activeIdBits.clearBit(upId);
+
+            int32_t motionEventAction;
+            if (activeIdBits.isEmpty()) {
+                motionEventAction = MOTION_EVENT_ACTION_UP;
+            } else {
+                motionEventAction = MOTION_EVENT_ACTION_POINTER_UP
+                        | (upId << MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+            }
+
+            dispatchTouch(when, device, policyFlags, & device->touchScreen.lastTouch,
+                    oldActiveIdBits, motionEventAction);
+        }
+
+        while (! downIdBits.isEmpty()) {
+            uint32_t downId = downIdBits.firstMarkedBit();
+            downIdBits.clearBit(downId);
+            BitSet32 oldActiveIdBits = activeIdBits;
+            activeIdBits.markBit(downId);
+
+            int32_t motionEventAction;
+            if (oldActiveIdBits.isEmpty()) {
+                motionEventAction = MOTION_EVENT_ACTION_DOWN;
+                device->touchScreen.downTime = when;
+            } else {
+                motionEventAction = MOTION_EVENT_ACTION_POINTER_DOWN
+                        | (downId << MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+            }
+
+            dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch,
+                    activeIdBits, motionEventAction);
+        }
+    }
+}
+
+void InputReader::dispatchTouch(nsecs_t when, InputDevice* device, uint32_t policyFlags,
+        InputDevice::TouchData* touch, BitSet32 idBits,
+        int32_t motionEventAction) {
+    int32_t orientedWidth, orientedHeight;
+    switch (mDisplayOrientation) {
+    case InputDispatchPolicyInterface::ROTATION_90:
+    case InputDispatchPolicyInterface::ROTATION_270:
+        orientedWidth = mDisplayHeight;
+        orientedHeight = mDisplayWidth;
+        break;
+    default:
+        orientedWidth = mDisplayWidth;
+        orientedHeight = mDisplayHeight;
+        break;
+    }
+
+    uint32_t pointerCount = 0;
+    int32_t pointerIds[MAX_POINTERS];
+    PointerCoords pointerCoords[MAX_POINTERS];
+
+    // Walk through the the active pointers and map touch screen coordinates (TouchData) into
+    // display coordinates (PointerCoords) and adjust for display orientation.
+    while (! idBits.isEmpty()) {
+        uint32_t id = idBits.firstMarkedBit();
+        idBits.clearBit(id);
+        uint32_t index = touch->idToIndex[id];
+
+        float x = (float(touch->pointers[index].x)
+                        - device->touchScreen.parameters.xAxis.minValue)
+                * device->touchScreen.precalculated.xScale;
+        float y = (float(touch->pointers[index].y)
+                        - device->touchScreen.parameters.yAxis.minValue)
+                * device->touchScreen.precalculated.yScale;
+        float pressure = (float(touch->pointers[index].pressure)
+                        - device->touchScreen.parameters.pressureAxis.minValue)
+                * device->touchScreen.precalculated.pressureScale;
+        float size = (float(touch->pointers[index].size)
+                        - device->touchScreen.parameters.sizeAxis.minValue)
+                * device->touchScreen.precalculated.sizeScale;
+
+        switch (mDisplayOrientation) {
+        case InputDispatchPolicyInterface::ROTATION_90: {
+            float xTemp = x;
+            x = y;
+            y = mDisplayHeight - xTemp;
+            break;
+        }
+        case InputDispatchPolicyInterface::ROTATION_180: {
+            x = mDisplayWidth - x;
+            y = mDisplayHeight - y;
+            break;
+        }
+        case InputDispatchPolicyInterface::ROTATION_270: {
+            float xTemp = x;
+            x = mDisplayWidth - y;
+            y = xTemp;
+            break;
+        }
+        }
+
+        pointerIds[pointerCount] = int32_t(id);
+
+        pointerCoords[pointerCount].x = x;
+        pointerCoords[pointerCount].y = y;
+        pointerCoords[pointerCount].pressure = pressure;
+        pointerCoords[pointerCount].size = size;
+
+        pointerCount += 1;
+    }
+
+    // Check edge flags by looking only at the first pointer since the flags are
+    // global to the event.
+    // XXX Maybe we should revise the edge flags API to work on a per-pointer basis.
+    int32_t motionEventEdgeFlags = 0;
+    if (motionEventAction == MOTION_EVENT_ACTION_DOWN) {
+        if (pointerCoords[0].x <= 0) {
+            motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_LEFT;
+        } else if (pointerCoords[0].x >= orientedWidth) {
+            motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_RIGHT;
+        }
+        if (pointerCoords[0].y <= 0) {
+            motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_TOP;
+        } else if (pointerCoords[0].y >= orientedHeight) {
+            motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_BOTTOM;
+        }
+    }
+
+    nsecs_t downTime = device->touchScreen.downTime;
+    mDispatcher->notifyMotion(when, device->id, INPUT_EVENT_NATURE_TOUCH, policyFlags,
+            motionEventAction, globalMetaState(), motionEventEdgeFlags,
+            pointerCount, pointerIds, pointerCoords,
+            0, 0, downTime);
+}
+
+void InputReader::onTrackballStateChanged(nsecs_t when,
+        InputDevice* device) {
+    static const uint32_t DELTA_FIELDS =
+            InputDevice::TrackballState::Accumulator::FIELD_REL_X
+            | InputDevice::TrackballState::Accumulator::FIELD_REL_Y;
+
+    /* Refresh display properties so we can trackball moves according to display orientation */
+
+    if (! refreshDisplayProperties()) {
+        return;
+    }
+
+    /* Update device state */
+
+    uint32_t fields = device->trackball.accumulator.fields;
+    bool downChanged = fields & InputDevice::TrackballState::Accumulator::FIELD_BTN_MOUSE;
+    bool deltaChanged = (fields & DELTA_FIELDS) == DELTA_FIELDS;
+
+    bool down;
+    if (downChanged) {
+        if (device->trackball.accumulator.btnMouse) {
+            device->trackball.current.down = true;
+            device->trackball.current.downTime = when;
+            down = true;
+        } else {
+            device->trackball.current.down = false;
+            down = false;
+        }
+    } else {
+        down = device->trackball.current.down;
+    }
+
+    /* Apply policy */
+
+    int32_t policyActions = mPolicy->interceptTrackball(when, downChanged, down, deltaChanged);
+
+    uint32_t policyFlags = 0;
+    if (! applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) {
+        return; // event dropped
+    }
+
+    /* Enqueue motion event for dispatch */
+
+    int32_t motionEventAction;
+    if (downChanged) {
+        motionEventAction = down ? MOTION_EVENT_ACTION_DOWN : MOTION_EVENT_ACTION_UP;
+    } else {
+        motionEventAction = MOTION_EVENT_ACTION_MOVE;
+    }
+
+    int32_t pointerId = 0;
+    PointerCoords pointerCoords;
+    pointerCoords.x = device->trackball.accumulator.relX
+            * device->trackball.precalculated.xScale;
+    pointerCoords.y = device->trackball.accumulator.relY
+            * device->trackball.precalculated.yScale;
+    pointerCoords.pressure = 1.0f; // XXX Consider making this 1.0f if down, 0 otherwise.
+    pointerCoords.size = 0;
+
+    float temp;
+    switch (mDisplayOrientation) {
+    case InputDispatchPolicyInterface::ROTATION_90:
+        temp = pointerCoords.x;
+        pointerCoords.x = pointerCoords.y;
+        pointerCoords.y = - temp;
+        break;
+
+    case InputDispatchPolicyInterface::ROTATION_180:
+        pointerCoords.x = - pointerCoords.x;
+        pointerCoords.y = - pointerCoords.y;
+        break;
+
+    case InputDispatchPolicyInterface::ROTATION_270:
+        temp = pointerCoords.x;
+        pointerCoords.x = - pointerCoords.y;
+        pointerCoords.y = temp;
+        break;
+    }
+
+    mDispatcher->notifyMotion(when, device->id, INPUT_EVENT_NATURE_TRACKBALL, policyFlags,
+            motionEventAction, globalMetaState(), MOTION_EVENT_EDGE_FLAG_NONE,
+            1, & pointerId, & pointerCoords,
+            device->trackball.precalculated.xPrecision,
+            device->trackball.precalculated.yPrecision,
+            device->trackball.current.downTime);
+}
+
+void InputReader::onConfigurationChanged(nsecs_t when) {
+    // Reset global meta state because it depends on the list of all configured devices.
+    resetGlobalMetaState();
+
+    // Reset virtual keys, just in case.
+    updateGlobalVirtualKeyState();
+
+    // Enqueue configuration changed.
+    // XXX This stuff probably needs to be tracked elsewhere in an input device registry
+    //     of some kind that can be asynchronously updated and queried.  (Same as above?)
+    int32_t touchScreenConfig = InputDispatchPolicyInterface::TOUCHSCREEN_NOTOUCH;
+    int32_t keyboardConfig = InputDispatchPolicyInterface::KEYBOARD_NOKEYS;
+    int32_t navigationConfig = InputDispatchPolicyInterface::NAVIGATION_NONAV;
+
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        InputDevice* device = mDevices.valueAt(i);
+        int32_t deviceClasses = device->classes;
+
+        if (deviceClasses & INPUT_DEVICE_CLASS_TOUCHSCREEN) {
+            touchScreenConfig = InputDispatchPolicyInterface::TOUCHSCREEN_FINGER;
+        }
+        if (deviceClasses & INPUT_DEVICE_CLASS_ALPHAKEY) {
+            keyboardConfig = InputDispatchPolicyInterface::KEYBOARD_QWERTY;
+        }
+        if (deviceClasses & INPUT_DEVICE_CLASS_TRACKBALL) {
+            navigationConfig = InputDispatchPolicyInterface::NAVIGATION_TRACKBALL;
+        } else if (deviceClasses & INPUT_DEVICE_CLASS_DPAD) {
+            navigationConfig = InputDispatchPolicyInterface::NAVIGATION_DPAD;
+        }
+    }
+
+    mDispatcher->notifyConfigurationChanged(when, touchScreenConfig,
+            keyboardConfig, navigationConfig);
+}
+
+bool InputReader::applyStandardInputDispatchPolicyActions(nsecs_t when,
+        int32_t policyActions, uint32_t* policyFlags) {
+    if (policyActions & InputDispatchPolicyInterface::ACTION_APP_SWITCH_COMING) {
+        mDispatcher->notifyAppSwitchComing(when);
+    }
+
+    if (policyActions & InputDispatchPolicyInterface::ACTION_WOKE_HERE) {
+        *policyFlags |= POLICY_FLAG_WOKE_HERE;
+    }
+
+    if (policyActions & InputDispatchPolicyInterface::ACTION_BRIGHT_HERE) {
+        *policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+    }
+
+    return policyActions & InputDispatchPolicyInterface::ACTION_DISPATCH;
+}
+
+void InputReader::resetDisplayProperties() {
+    mDisplayWidth = mDisplayHeight = -1;
+    mDisplayOrientation = -1;
+}
+
+bool InputReader::refreshDisplayProperties() {
+    int32_t newWidth, newHeight, newOrientation;
+    if (mPolicy->getDisplayInfo(0, & newWidth, & newHeight, & newOrientation)) {
+        if (newWidth != mDisplayWidth || newHeight != mDisplayHeight) {
+            LOGD("Display size changed from %dx%d to %dx%d, updating device configuration",
+                    mDisplayWidth, mDisplayHeight, newWidth, newHeight);
+
+            mDisplayWidth = newWidth;
+            mDisplayHeight = newHeight;
+
+            for (size_t i = 0; i < mDevices.size(); i++) {
+                configureDeviceForCurrentDisplaySize(mDevices.valueAt(i));
+            }
+        }
+
+        mDisplayOrientation = newOrientation;
+        return true;
+    } else {
+        resetDisplayProperties();
+        return false;
+    }
+}
+
+InputDevice* InputReader::getDevice(int32_t deviceId) {
+    ssize_t index = mDevices.indexOfKey(deviceId);
+    return index >= 0 ? mDevices.valueAt((size_t) index) : NULL;
+}
+
+InputDevice* InputReader::getNonIgnoredDevice(int32_t deviceId) {
+    InputDevice* device = getDevice(deviceId);
+    return device && ! device->ignored ? device : NULL;
+}
+
+void InputReader::addDevice(nsecs_t when, int32_t deviceId) {
+    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+    String8 name = mEventHub->getDeviceName(deviceId);
+    InputDevice* device = new InputDevice(deviceId, classes, name);
+
+    if (classes != 0) {
+        LOGI("Device added: id=0x%x, name=%s, classes=%02x", device->id,
+                device->name.string(), device->classes);
+
+        configureDevice(device);
+    } else {
+        LOGI("Device added: id=0x%x, name=%s (ignored non-input device)", device->id,
+                device->name.string());
+
+        device->ignored = true;
+    }
+
+    device->reset();
+
+    mDevices.add(deviceId, device);
+
+    if (! device->ignored) {
+        onConfigurationChanged(when);
+    }
+}
+
+void InputReader::removeDevice(nsecs_t when, InputDevice* device) {
+    mDevices.removeItem(device->id);
+
+    if (! device->ignored) {
+        LOGI("Device removed: id=0x%x, name=%s, classes=%02x", device->id,
+                device->name.string(), device->classes);
+
+        onConfigurationChanged(when);
+    } else {
+        LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)", device->id,
+                device->name.string());
+    }
+
+    delete device;
+}
+
+void InputReader::configureDevice(InputDevice* device) {
+    if (device->isMultiTouchScreen()) {
+        configureAbsoluteAxisInfo(device, ABS_MT_POSITION_X, "X",
+                & device->touchScreen.parameters.xAxis);
+        configureAbsoluteAxisInfo(device, ABS_MT_POSITION_Y, "Y",
+                & device->touchScreen.parameters.yAxis);
+        configureAbsoluteAxisInfo(device, ABS_MT_TOUCH_MAJOR, "Pressure",
+                & device->touchScreen.parameters.pressureAxis);
+        configureAbsoluteAxisInfo(device, ABS_MT_WIDTH_MAJOR, "Size",
+                & device->touchScreen.parameters.sizeAxis);
+    } else if (device->isSingleTouchScreen()) {
+        configureAbsoluteAxisInfo(device, ABS_X, "X",
+                & device->touchScreen.parameters.xAxis);
+        configureAbsoluteAxisInfo(device, ABS_Y, "Y",
+                & device->touchScreen.parameters.yAxis);
+        configureAbsoluteAxisInfo(device, ABS_PRESSURE, "Pressure",
+                & device->touchScreen.parameters.pressureAxis);
+        configureAbsoluteAxisInfo(device, ABS_TOOL_WIDTH, "Size",
+                & device->touchScreen.parameters.sizeAxis);
+    }
+
+    if (device->isTouchScreen()) {
+        device->touchScreen.parameters.useBadTouchFilter =
+                mPolicy->filterTouchEvents();
+        device->touchScreen.parameters.useAveragingTouchFilter =
+                mPolicy->filterTouchEvents();
+        device->touchScreen.parameters.useJumpyTouchFilter =
+                mPolicy->filterJumpyTouchEvents();
+
+        device->touchScreen.precalculated.pressureScale =
+                1.0f / device->touchScreen.parameters.pressureAxis.range;
+        device->touchScreen.precalculated.sizeScale =
+                1.0f / device->touchScreen.parameters.sizeAxis.range;
+    }
+
+    if (device->isTrackball()) {
+        device->trackball.precalculated.xPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+        device->trackball.precalculated.yPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+        device->trackball.precalculated.xScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+        device->trackball.precalculated.yScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+    }
+
+    configureDeviceForCurrentDisplaySize(device);
+}
+
+void InputReader::configureDeviceForCurrentDisplaySize(InputDevice* device) {
+    if (device->isTouchScreen()) {
+        if (mDisplayWidth < 0) {
+            LOGD("Skipping part of touch screen configuration since display size is unknown.");
+        } else {
+            LOGI("Device configured: id=0x%x, name=%s (display size was changed)", device->id,
+                    device->name.string());
+            configureVirtualKeys(device);
+
+            device->touchScreen.precalculated.xScale =
+                    float(mDisplayWidth) / device->touchScreen.parameters.xAxis.range;
+            device->touchScreen.precalculated.yScale =
+                    float(mDisplayHeight) / device->touchScreen.parameters.yAxis.range;
+        }
+    }
+}
+
+void InputReader::configureVirtualKeys(InputDevice* device) {
+    device->touchScreen.virtualKeys.clear();
+
+    Vector<InputDispatchPolicyInterface::VirtualKeyDefinition> virtualKeyDefinitions;
+    mPolicy->getVirtualKeyDefinitions(device->name, virtualKeyDefinitions);
+    if (virtualKeyDefinitions.size() == 0) {
+        return;
+    }
+
+    device->touchScreen.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+
+    int32_t touchScreenLeft = device->touchScreen.parameters.xAxis.minValue;
+    int32_t touchScreenTop = device->touchScreen.parameters.yAxis.minValue;
+    int32_t touchScreenWidth = device->touchScreen.parameters.xAxis.range;
+    int32_t touchScreenHeight = device->touchScreen.parameters.yAxis.range;
+
+    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
+        const InputDispatchPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
+                virtualKeyDefinitions[i];
+
+        device->touchScreen.virtualKeys.add();
+        InputDevice::VirtualKey& virtualKey =
+                device->touchScreen.virtualKeys.editTop();
+
+        virtualKey.scanCode = virtualKeyDefinition.scanCode;
+        int32_t keyCode;
+        uint32_t flags;
+        if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode,
+                & keyCode, & flags)) {
+            LOGI("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
+            device->touchScreen.virtualKeys.pop(); // drop the key
+            continue;
+        }
+
+        virtualKey.keyCode = keyCode;
+        virtualKey.flags = flags;
+
+        // convert the key definition's display coordinates into touch coordinates for a hit box
+        int32_t halfWidth = virtualKeyDefinition.width / 2;
+        int32_t halfHeight = virtualKeyDefinition.height / 2;
+
+        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
+                * touchScreenWidth / mDisplayWidth + touchScreenLeft;
+        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
+                * touchScreenWidth / mDisplayWidth + touchScreenLeft;
+        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
+                * touchScreenHeight / mDisplayHeight + touchScreenTop;
+        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
+                * touchScreenHeight / mDisplayHeight + touchScreenTop;
+
+        LOGI("  VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+                virtualKey.scanCode, virtualKey.keyCode,
+                virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
+    }
+}
+
+void InputReader::configureAbsoluteAxisInfo(InputDevice* device,
+        int axis, const char* name, InputDevice::AbsoluteAxisInfo* out) {
+    if (! mEventHub->getAbsoluteInfo(device->id, axis,
+            & out->minValue, & out->maxValue, & out->flat, &out->fuzz)) {
+        out->range = out->maxValue - out->minValue;
+        if (out->range != 0) {
+            LOGI("  %s: min=%d max=%d flat=%d fuzz=%d",
+                    name, out->minValue, out->maxValue, out->flat, out->fuzz);
+            return;
+        }
+    }
+
+    out->minValue = 0;
+    out->maxValue = 0;
+    out->flat = 0;
+    out->fuzz = 0;
+    out->range = 0;
+    LOGI("  %s: unknown axis values, setting to zero", name);
+}
+
+void InputReader::resetGlobalMetaState() {
+    mGlobalMetaState = -1;
+}
+
+int32_t InputReader::globalMetaState() {
+    if (mGlobalMetaState == -1) {
+        mGlobalMetaState = 0;
+        for (size_t i = 0; i < mDevices.size(); i++) {
+            InputDevice* device = mDevices.valueAt(i);
+            if (device->isKeyboard()) {
+                mGlobalMetaState |= device->keyboard.current.metaState;
+            }
+        }
+    }
+    return mGlobalMetaState;
+}
+
+void InputReader::updateGlobalVirtualKeyState() {
+    int32_t keyCode = -1, scanCode = -1;
+
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        InputDevice* device = mDevices.valueAt(i);
+        if (device->isTouchScreen()) {
+            if (device->touchScreen.currentVirtualKey.down) {
+                keyCode = device->touchScreen.currentVirtualKey.keyCode;
+                scanCode = device->touchScreen.currentVirtualKey.scanCode;
+            }
+        }
+    }
+
+    {
+        AutoMutex _l(mExportedStateLock);
+
+        mGlobalVirtualKeyCode = keyCode;
+        mGlobalVirtualScanCode = scanCode;
+    }
+}
+
+bool InputReader::getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const {
+    AutoMutex _l(mExportedStateLock);
+
+    *outKeyCode = mGlobalVirtualKeyCode;
+    *outScanCode = mGlobalVirtualScanCode;
+    return mGlobalVirtualKeyCode != -1;
+}
+
+
+// --- InputReaderThread ---
+
+InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
+        Thread(/*canCallJava*/ true), mReader(reader) {
+}
+
+InputReaderThread::~InputReaderThread() {
+}
+
+bool InputReaderThread::threadLoop() {
+    mReader->loopOnce();
+    return true;
+}
+
+} // namespace android
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
new file mode 100644
index 0000000..a24180f
--- /dev/null
+++ b/libs/ui/InputTransport.cpp
@@ -0,0 +1,684 @@
+//
+// 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 signalling (send signal, receive signal)
+#define DEBUG_CHANNEL_SIGNALS 1
+
+// Log debug messages whenever InputChannel objects are created/destroyed
+#define DEBUG_CHANNEL_LIFECYCLE 1
+
+// Log debug messages about transport actions (initialize, reset, publish, ...)
+#define DEBUG_TRANSPORT_ACTIONS 1
+
+
+#include <cutils/ashmem.h>
+#include <cutils/log.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <ui/InputTransport.h>
+#include <unistd.h>
+
+namespace android {
+
+// Must be at least sizeof(InputMessage) + sufficient space for pointer data
+static const int DEFAULT_MESSAGE_BUFFER_SIZE = 16384;
+
+// Signal sent by the producer to the consumer to inform it that a new message is
+// available to be consumed in the shared memory buffer.
+static const char INPUT_SIGNAL_DISPATCH = 'D';
+
+// Signal sent by the consumer to the producer to inform it that it has finished
+// consuming the most recent message.
+static const char INPUT_SIGNAL_FINISHED = 'f';
+
+
+// --- InputChannel ---
+
+InputChannel::InputChannel(const String8& name, int32_t ashmemFd, int32_t receivePipeFd,
+        int32_t sendPipeFd) :
+        mName(name), mAshmemFd(ashmemFd), mReceivePipeFd(receivePipeFd), mSendPipeFd(sendPipeFd) {
+#if DEBUG_CHANNEL_LIFECYCLE
+    LOGD("Input channel constructed: name='%s', ashmemFd=%d, receivePipeFd=%d, sendPipeFd=%d",
+            mName.string(), ashmemFd, receivePipeFd, sendPipeFd);
+#endif
+
+    int result = fcntl(mReceivePipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make receive pipe "
+            "non-blocking.  errno=%d", mName.string(), errno);
+
+    result = fcntl(mSendPipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make send pipe "
+            "non-blocking.  errno=%d", mName.string(), errno);
+}
+
+InputChannel::~InputChannel() {
+#if DEBUG_CHANNEL_LIFECYCLE
+    LOGD("Input channel destroyed: name='%s', ashmemFd=%d, receivePipeFd=%d, sendPipeFd=%d",
+            mName.string(), mAshmemFd, mReceivePipeFd, mSendPipeFd);
+#endif
+
+    ::close(mAshmemFd);
+    ::close(mReceivePipeFd);
+    ::close(mSendPipeFd);
+}
+
+status_t InputChannel::openInputChannelPair(const String8& name,
+        InputChannel** outServerChannel, InputChannel** outClientChannel) {
+    status_t result;
+
+    int serverAshmemFd = ashmem_create_region(name.string(), DEFAULT_MESSAGE_BUFFER_SIZE);
+    if (serverAshmemFd < 0) {
+        result = -errno;
+        LOGE("channel '%s' ~ Could not create shared memory region. errno=%d",
+                name.string(), errno);
+    } else {
+        result = ashmem_set_prot_region(serverAshmemFd, PROT_READ | PROT_WRITE);
+        if (result < 0) {
+            LOGE("channel '%s' ~ Error %d trying to set protection of ashmem fd %d.",
+                    name.string(), result, serverAshmemFd);
+        } else {
+            // Dup the file descriptor because the server and client input channel objects that
+            // are returned may have different lifetimes but they share the same shared memory region.
+            int clientAshmemFd;
+            clientAshmemFd = dup(serverAshmemFd);
+            if (clientAshmemFd < 0) {
+                result = -errno;
+                LOGE("channel '%s' ~ Could not dup() shared memory region fd. errno=%d",
+                        name.string(), errno);
+            } else {
+                int forward[2];
+                if (pipe(forward)) {
+                    result = -errno;
+                    LOGE("channel '%s' ~ Could not create forward pipe.  errno=%d",
+                            name.string(), errno);
+                } else {
+                    int reverse[2];
+                    if (pipe(reverse)) {
+                        result = -errno;
+                        LOGE("channel '%s' ~ Could not create reverse pipe.  errno=%d",
+                                name.string(), errno);
+                    } else {
+                        String8 serverChannelName = name;
+                        serverChannelName.append(" (server)");
+                        *outServerChannel = new InputChannel(serverChannelName,
+                                serverAshmemFd, reverse[0], forward[1]);
+
+                        String8 clientChannelName = name;
+                        clientChannelName.append(" (client)");
+                        *outClientChannel = new InputChannel(clientChannelName,
+                                clientAshmemFd, forward[0], reverse[1]);
+                        return OK;
+                    }
+                    ::close(forward[0]);
+                    ::close(forward[1]);
+                }
+                ::close(clientAshmemFd);
+            }
+        }
+        ::close(serverAshmemFd);
+    }
+
+    *outServerChannel = NULL;
+    *outClientChannel = NULL;
+    return result;
+}
+
+status_t InputChannel::sendSignal(char signal) {
+    ssize_t nWrite = ::write(mSendPipeFd, & signal, 1);
+
+    if (nWrite == 1) {
+#if DEBUG_CHANNEL_SIGNALS
+        LOGD("channel '%s' ~ sent signal '%c'", mName.string(), signal);
+#endif
+        return OK;
+    }
+
+#if DEBUG_CHANNEL_SIGNALS
+    LOGD("channel '%s' ~ error sending signal '%c', errno=%d", mName.string(), signal, errno);
+#endif
+    return -errno;
+}
+
+status_t InputChannel::receiveSignal(char* outSignal) {
+    ssize_t nRead = ::read(mReceivePipeFd, outSignal, 1);
+    if (nRead == 1) {
+#if DEBUG_CHANNEL_SIGNALS
+        LOGD("channel '%s' ~ received signal '%c'", mName.string(), *outSignal);
+#endif
+        return OK;
+    }
+
+    if (errno == EAGAIN) {
+#if DEBUG_CHANNEL_SIGNALS
+        LOGD("channel '%s' ~ receive signal failed because no signal available", mName.string());
+#endif
+        return WOULD_BLOCK;
+    }
+
+#if DEBUG_CHANNEL_SIGNALS
+    LOGD("channel '%s' ~ receive signal failed, errno=%d", mName.string(), errno);
+#endif
+    return -errno;
+}
+
+
+// --- InputPublisher ---
+
+InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
+        mChannel(channel), mSharedMessage(NULL),
+        mPinned(false), mSemaphoreInitialized(false), mWasDispatched(false),
+        mMotionEventSampleDataTail(NULL) {
+}
+
+InputPublisher::~InputPublisher() {
+    reset();
+
+    if (mSharedMessage) {
+        munmap(mSharedMessage, mAshmemSize);
+    }
+}
+
+status_t InputPublisher::initialize() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ initialize",
+            mChannel->getName().string());
+#endif
+
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_get_size_region(ashmemFd);
+    if (result < 0) {
+        LOGE("channel '%s' publisher ~ Error %d getting size of ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+    mAshmemSize = (size_t) result;
+
+    mSharedMessage = static_cast<InputMessage*>(mmap(NULL, mAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0));
+    if (! mSharedMessage) {
+        LOGE("channel '%s' publisher ~ mmap failed on ashmem fd %d.",
+                mChannel->getName().string(), ashmemFd);
+        return NO_MEMORY;
+    }
+
+    mPinned = true;
+    mSharedMessage->consumed = false;
+
+    return reset();
+}
+
+status_t InputPublisher::reset() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ reset",
+        mChannel->getName().string());
+#endif
+
+    if (mPinned) {
+        // Destroy the semaphore since we are about to unpin the memory region that contains it.
+        int result;
+        if (mSemaphoreInitialized) {
+            if (mSharedMessage->consumed) {
+                result = sem_post(& mSharedMessage->semaphore);
+                if (result < 0) {
+                    LOGE("channel '%s' publisher ~ Error %d in sem_post.",
+                            mChannel->getName().string(), errno);
+                    return UNKNOWN_ERROR;
+                }
+            }
+
+            result = sem_destroy(& mSharedMessage->semaphore);
+            if (result < 0) {
+                LOGE("channel '%s' publisher ~ Error %d in sem_destroy.",
+                        mChannel->getName().string(), errno);
+                return UNKNOWN_ERROR;
+            }
+
+            mSemaphoreInitialized = false;
+        }
+
+        // Unpin the region since we no longer care about its contents.
+        int ashmemFd = mChannel->getAshmemFd();
+        result = ashmem_unpin_region(ashmemFd, 0, 0);
+        if (result < 0) {
+            LOGE("channel '%s' publisher ~ Error %d unpinning ashmem fd %d.",
+                    mChannel->getName().string(), result, ashmemFd);
+            return UNKNOWN_ERROR;
+        }
+
+        mPinned = false;
+    }
+
+    mMotionEventSampleDataTail = NULL;
+    mWasDispatched = false;
+    return OK;
+}
+
+status_t InputPublisher::publishInputEvent(
+        int32_t type,
+        int32_t deviceId,
+        int32_t nature) {
+    if (mPinned) {
+        LOGE("channel '%s' publisher ~ Attempted to publish a new event but publisher has "
+                "not yet been reset.", mChannel->getName().string());
+        return INVALID_OPERATION;
+    }
+
+    // Pin the region.
+    // We do not check for ASHMEM_NOT_PURGED because we don't care about the previous
+    // contents of the buffer so it does not matter whether it was purged in the meantime.
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_pin_region(ashmemFd, 0, 0);
+    if (result < 0) {
+        LOGE("channel '%s' publisher ~ Error %d pinning ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+
+    mPinned = true;
+
+    result = sem_init(& mSharedMessage->semaphore, 1, 1);
+    if (result < 0) {
+        LOGE("channel '%s' publisher ~ Error %d in sem_init.",
+                mChannel->getName().string(), errno);
+        return UNKNOWN_ERROR;
+    }
+
+    mSemaphoreInitialized = true;
+
+    mSharedMessage->consumed = false;
+    mSharedMessage->type = type;
+    mSharedMessage->deviceId = deviceId;
+    mSharedMessage->nature = nature;
+    return OK;
+}
+
+status_t InputPublisher::publishKeyEvent(
+        int32_t deviceId,
+        int32_t nature,
+        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
+    LOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, nature=%d, "
+            "action=%d, flags=%d, keyCode=%d, scanCode=%d, metaState=%d, repeatCount=%d,"
+            "downTime=%lld, eventTime=%lld",
+            mChannel->getName().string(),
+            deviceId, nature, action, flags, keyCode, scanCode, metaState, repeatCount,
+            downTime, eventTime);
+#endif
+
+    status_t result = publishInputEvent(INPUT_EVENT_TYPE_KEY, deviceId, nature);
+    if (result < 0) {
+        return result;
+    }
+
+    mSharedMessage->key.action = action;
+    mSharedMessage->key.flags = flags;
+    mSharedMessage->key.keyCode = keyCode;
+    mSharedMessage->key.scanCode = scanCode;
+    mSharedMessage->key.metaState = metaState;
+    mSharedMessage->key.repeatCount = repeatCount;
+    mSharedMessage->key.downTime = downTime;
+    mSharedMessage->key.eventTime = eventTime;
+    return OK;
+}
+
+status_t InputPublisher::publishMotionEvent(
+        int32_t deviceId,
+        int32_t nature,
+        int32_t action,
+        int32_t edgeFlags,
+        int32_t metaState,
+        float xOffset,
+        float yOffset,
+        float xPrecision,
+        float yPrecision,
+        nsecs_t downTime,
+        nsecs_t eventTime,
+        size_t pointerCount,
+        const int32_t* pointerIds,
+        const PointerCoords* pointerCoords) {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, nature=%d, "
+            "action=%d, edgeFlags=%d, metaState=%d, xOffset=%f, yOffset=%f, "
+            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
+            "pointerCount=%d",
+            mChannel->getName().string(),
+            deviceId, nature, action, edgeFlags, metaState, xOffset, yOffset,
+            xPrecision, yPrecision, downTime, eventTime, pointerCount);
+#endif
+
+    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
+        LOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
+                mChannel->getName().string(), pointerCount);
+        return BAD_VALUE;
+    }
+
+    status_t result = publishInputEvent(INPUT_EVENT_TYPE_MOTION, deviceId, nature);
+    if (result < 0) {
+        return result;
+    }
+
+    mSharedMessage->motion.action = action;
+    mSharedMessage->motion.edgeFlags = edgeFlags;
+    mSharedMessage->motion.metaState = metaState;
+    mSharedMessage->motion.xOffset = xOffset;
+    mSharedMessage->motion.yOffset = yOffset;
+    mSharedMessage->motion.xPrecision = xPrecision;
+    mSharedMessage->motion.yPrecision = yPrecision;
+    mSharedMessage->motion.downTime = downTime;
+    mSharedMessage->motion.pointerCount = pointerCount;
+
+    mSharedMessage->motion.sampleCount = 1;
+    mSharedMessage->motion.sampleData[0].eventTime = eventTime;
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        mSharedMessage->motion.pointerIds[i] = pointerIds[i];
+        mSharedMessage->motion.sampleData[0].coords[i] = pointerCoords[i];
+    }
+
+    // Cache essential information about the motion event to ensure that a malicious consumer
+    // cannot confuse the publisher by modifying the contents of the shared memory buffer while
+    // it is being updated.
+    if (action == MOTION_EVENT_ACTION_MOVE) {
+        mMotionEventPointerCount = pointerCount;
+        mMotionEventSampleDataStride = InputMessage::sampleDataStride(pointerCount);
+        mMotionEventSampleDataTail = InputMessage::sampleDataPtrIncrement(
+                mSharedMessage->motion.sampleData, mMotionEventSampleDataStride);
+    } else {
+        mMotionEventSampleDataTail = NULL;
+    }
+    return OK;
+}
+
+status_t InputPublisher::appendMotionSample(
+        nsecs_t eventTime,
+        const PointerCoords* pointerCoords) {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ appendMotionSample: eventTime=%lld",
+            mChannel->getName().string(), eventTime);
+#endif
+
+    if (! mPinned || ! mMotionEventSampleDataTail) {
+        LOGE("channel '%s' publisher ~ Cannot append motion sample because there is no current "
+                "MOTION_EVENT_ACTION_MOVE event.", mChannel->getName().string());
+        return INVALID_OPERATION;
+    }
+
+    InputMessage::SampleData* newTail = InputMessage::sampleDataPtrIncrement(
+            mMotionEventSampleDataTail, mMotionEventSampleDataStride);
+    size_t newBytesUsed = reinterpret_cast<char*>(newTail) -
+            reinterpret_cast<char*>(mSharedMessage);
+
+    if (newBytesUsed > mAshmemSize) {
+        LOGD("channel '%s' publisher ~ Cannot append motion sample because the shared memory "
+                "buffer is full.  Buffer size: %d bytes, pointers: %d, samples: %d",
+                mChannel->getName().string(),
+                mAshmemSize, mMotionEventPointerCount, mSharedMessage->motion.sampleCount);
+        return NO_MEMORY;
+    }
+
+    int result;
+    if (mWasDispatched) {
+        result = sem_trywait(& mSharedMessage->semaphore);
+        if (result < 0) {
+            if (errno == EAGAIN) {
+                // Only possible source of contention is the consumer having consumed (or being in the
+                // process of consuming) the message and left the semaphore count at 0.
+                LOGD("channel '%s' publisher ~ Cannot append motion sample because the message has "
+                        "already been consumed.", mChannel->getName().string());
+                return FAILED_TRANSACTION;
+            } else {
+                LOGE("channel '%s' publisher ~ Error %d in sem_trywait.",
+                        mChannel->getName().string(), errno);
+                return UNKNOWN_ERROR;
+            }
+        }
+    }
+
+    mMotionEventSampleDataTail->eventTime = eventTime;
+    for (size_t i = 0; i < mMotionEventPointerCount; i++) {
+        mMotionEventSampleDataTail->coords[i] = pointerCoords[i];
+    }
+    mMotionEventSampleDataTail = newTail;
+
+    mSharedMessage->motion.sampleCount += 1;
+
+    if (mWasDispatched) {
+        result = sem_post(& mSharedMessage->semaphore);
+        if (result < 0) {
+            LOGE("channel '%s' publisher ~ Error %d in sem_post.",
+                    mChannel->getName().string(), errno);
+            return UNKNOWN_ERROR;
+        }
+    }
+    return OK;
+}
+
+status_t InputPublisher::sendDispatchSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ sendDispatchSignal",
+            mChannel->getName().string());
+#endif
+
+    mWasDispatched = true;
+    return mChannel->sendSignal(INPUT_SIGNAL_DISPATCH);
+}
+
+status_t InputPublisher::receiveFinishedSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ receiveFinishedSignal",
+            mChannel->getName().string());
+#endif
+
+    char signal;
+    status_t result = mChannel->receiveSignal(& signal);
+    if (result) {
+        return result;
+    }
+    if (signal != INPUT_SIGNAL_FINISHED) {
+        LOGE("channel '%s' publisher ~ Received unexpected signal '%c' from consumer",
+                mChannel->getName().string(), signal);
+        return UNKNOWN_ERROR;
+    }
+    return OK;
+}
+
+// --- InputConsumer ---
+
+InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
+        mChannel(channel), mSharedMessage(NULL) {
+}
+
+InputConsumer::~InputConsumer() {
+    if (mSharedMessage) {
+        munmap(mSharedMessage, mAshmemSize);
+    }
+}
+
+status_t InputConsumer::initialize() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ initialize",
+            mChannel->getName().string());
+#endif
+
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_get_size_region(ashmemFd);
+    if (result < 0) {
+        LOGE("channel '%s' consumer ~ Error %d getting size of ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+
+    mAshmemSize = (size_t) result;
+
+    mSharedMessage = static_cast<InputMessage*>(mmap(NULL, mAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0));
+    if (! mSharedMessage) {
+        LOGE("channel '%s' consumer ~ mmap failed on ashmem fd %d.",
+                mChannel->getName().string(), ashmemFd);
+        return NO_MEMORY;
+    }
+
+    return OK;
+}
+
+status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent** event) {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ consume",
+            mChannel->getName().string());
+#endif
+
+    *event = NULL;
+
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_pin_region(ashmemFd, 0, 0);
+    if (result != ASHMEM_NOT_PURGED) {
+        if (result == ASHMEM_WAS_PURGED) {
+            LOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d because it was purged "
+                    "which probably indicates that the publisher and consumer are out of sync.",
+                    mChannel->getName().string(), result, ashmemFd);
+            return INVALID_OPERATION;
+        }
+
+        LOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+
+    if (mSharedMessage->consumed) {
+        LOGE("channel '%s' consumer ~ The current message has already been consumed.",
+                mChannel->getName().string());
+        return INVALID_OPERATION;
+    }
+
+    // Acquire but *never release* the semaphore.  Contention on the semaphore is used to signal
+    // to the publisher that the message has been consumed (or is in the process of being
+    // consumed).  Eventually the publisher will reinitialize the semaphore for the next message.
+    result = sem_wait(& mSharedMessage->semaphore);
+    if (result < 0) {
+        LOGE("channel '%s' consumer ~ Error %d in sem_wait.",
+                mChannel->getName().string(), errno);
+        return UNKNOWN_ERROR;
+    }
+
+    mSharedMessage->consumed = true;
+
+    switch (mSharedMessage->type) {
+    case INPUT_EVENT_TYPE_KEY: {
+        KeyEvent* keyEvent = factory->createKeyEvent();
+        if (! keyEvent) return NO_MEMORY;
+
+        populateKeyEvent(keyEvent);
+
+        *event = keyEvent;
+        break;
+    }
+
+    case INPUT_EVENT_TYPE_MOTION: {
+        MotionEvent* motionEvent = factory->createMotionEvent();
+        if (! motionEvent) return NO_MEMORY;
+
+        populateMotionEvent(motionEvent);
+
+        *event = motionEvent;
+        break;
+    }
+
+    default:
+        LOGE("channel '%s' consumer ~ Received message of unknown type %d",
+                mChannel->getName().string(), mSharedMessage->type);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t InputConsumer::sendFinishedSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ sendFinishedSignal",
+            mChannel->getName().string());
+#endif
+
+    return mChannel->sendSignal(INPUT_SIGNAL_FINISHED);
+}
+
+status_t InputConsumer::receiveDispatchSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ receiveDispatchSignal",
+            mChannel->getName().string());
+#endif
+
+    char signal;
+    status_t result = mChannel->receiveSignal(& signal);
+    if (result) {
+        return result;
+    }
+    if (signal != INPUT_SIGNAL_DISPATCH) {
+        LOGE("channel '%s' consumer ~ Received unexpected signal '%c' from publisher",
+                mChannel->getName().string(), signal);
+        return UNKNOWN_ERROR;
+    }
+    return OK;
+}
+
+void InputConsumer::populateKeyEvent(KeyEvent* keyEvent) const {
+    keyEvent->initialize(
+            mSharedMessage->deviceId,
+            mSharedMessage->nature,
+            mSharedMessage->key.action,
+            mSharedMessage->key.flags,
+            mSharedMessage->key.keyCode,
+            mSharedMessage->key.scanCode,
+            mSharedMessage->key.metaState,
+            mSharedMessage->key.repeatCount,
+            mSharedMessage->key.downTime,
+            mSharedMessage->key.eventTime);
+}
+
+void InputConsumer::populateMotionEvent(MotionEvent* motionEvent) const {
+    motionEvent->initialize(
+            mSharedMessage->deviceId,
+            mSharedMessage->nature,
+            mSharedMessage->motion.action,
+            mSharedMessage->motion.edgeFlags,
+            mSharedMessage->motion.metaState,
+            mSharedMessage->motion.sampleData[0].coords[0].x,
+            mSharedMessage->motion.sampleData[0].coords[0].y,
+            mSharedMessage->motion.xPrecision,
+            mSharedMessage->motion.yPrecision,
+            mSharedMessage->motion.downTime,
+            mSharedMessage->motion.sampleData[0].eventTime,
+            mSharedMessage->motion.pointerCount,
+            mSharedMessage->motion.pointerIds,
+            mSharedMessage->motion.sampleData[0].coords);
+
+    size_t sampleCount = mSharedMessage->motion.sampleCount;
+    if (sampleCount > 1) {
+        InputMessage::SampleData* sampleData = mSharedMessage->motion.sampleData;
+        size_t sampleDataStride = InputMessage::sampleDataStride(
+                mSharedMessage->motion.pointerCount);
+
+        while (--sampleCount > 0) {
+            sampleData = InputMessage::sampleDataPtrIncrement(sampleData, sampleDataStride);
+            motionEvent->addSample(sampleData->eventTime, sampleData->coords);
+        }
+    }
+
+    motionEvent->offsetLocation(mSharedMessage->motion.xOffset,
+            mSharedMessage->motion.yOffset);
+}
+
+} // namespace android
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 6cc4a5a..018f18d 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -1,16 +1,38 @@
+# Build the unit tests.
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-	region.cpp
+test_src_files := \
+    InputDispatcher_test.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libutils \
-    libui
+	libEGL \
+	libbinder \
+	libpixelflinger \
+	libhardware \
+	libhardware_legacy \
+	libui \
+	libstlport
 
-LOCAL_MODULE:= test-region
+LOCAL_STATIC_LIBRARIES := \
+	libgtest \
+	libgtest_main
 
-LOCAL_MODULE_TAGS := tests
+LOCAL_C_INCLUDES := \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport
 
-include $(BUILD_EXECUTABLE)
+LOCAL_MODULE_TAGS := eng tests
+
+$(foreach file,$(test_src_files), \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+# Build the manual test programs.
+include $(call all-subdir-makefiles)
diff --git a/libs/ui/tests/InputDispatcher_test.cpp b/libs/ui/tests/InputDispatcher_test.cpp
new file mode 100644
index 0000000..3d92043
--- /dev/null
+++ b/libs/ui/tests/InputDispatcher_test.cpp
@@ -0,0 +1,19 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputDispatcher.h>
+#include <gtest/gtest.h>
+
+namespace android {
+
+class InputDispatcherTest : public testing::Test {
+public:
+};
+
+TEST_F(InputDispatcherTest, Dummy) {
+    SCOPED_TRACE("Trace");
+    ASSERT_FALSE(true);
+}
+
+} // namespace android
diff --git a/libs/ui/tests/region/Android.mk b/libs/ui/tests/region/Android.mk
new file mode 100644
index 0000000..6cc4a5a
--- /dev/null
+++ b/libs/ui/tests/region/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	region.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-region
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/ui/tests/region.cpp b/libs/ui/tests/region/region.cpp
similarity index 100%
rename from libs/ui/tests/region.cpp
rename to libs/ui/tests/region/region.cpp
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index afecdcb..7d4524a 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -26,6 +26,7 @@
 	Debug.cpp \
 	FileMap.cpp \
 	Flattenable.cpp \
+	Pool.cpp \
 	RefBase.cpp \
 	ResourceTypes.cpp \
 	SharedBuffer.cpp \
@@ -39,7 +40,7 @@
 	Threads.cpp \
 	Timers.cpp \
 	VectorImpl.cpp \
-    ZipFileCRO.cpp \
+	ZipFileCRO.cpp \
 	ZipFileRO.cpp \
 	ZipUtils.cpp \
 	misc.cpp
@@ -76,8 +77,9 @@
 # we have the common sources, plus some device-specific stuff
 LOCAL_SRC_FILES:= \
 	$(commonSources) \
-    BackupData.cpp \
-	BackupHelpers.cpp
+	BackupData.cpp \
+	BackupHelpers.cpp \
+	PollLoop.cpp
 
 ifeq ($(TARGET_OS),linux)
 LOCAL_LDLIBS += -lrt -ldl
diff --git a/libs/utils/PollLoop.cpp b/libs/utils/PollLoop.cpp
new file mode 100644
index 0000000..90a3e8b
--- /dev/null
+++ b/libs/utils/PollLoop.cpp
@@ -0,0 +1,267 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// A select loop implementation.
+//
+#define LOG_TAG "PollLoop"
+
+//#define LOG_NDEBUG 0
+
+// Debugs poll and wake interactions.
+#define DEBUG_POLL_AND_WAKE 0
+
+// Debugs callback registration and invocation.
+#define DEBUG_CALLBACKS 1
+
+#include <cutils/log.h>
+#include <utils/PollLoop.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+namespace android {
+
+PollLoop::PollLoop() :
+        mPolling(false) {
+    openWakePipe();
+}
+
+PollLoop::~PollLoop() {
+    closeWakePipe();
+}
+
+void PollLoop::openWakePipe() {
+    int wakeFds[2];
+    int result = pipe(wakeFds);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
+
+    mWakeReadPipeFd = wakeFds[0];
+    mWakeWritePipeFd = wakeFds[1];
+
+    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
+            errno);
+
+    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
+            errno);
+
+    // Add the wake pipe to the head of the request list with a null callback.
+    struct pollfd requestedFd;
+    requestedFd.fd = mWakeReadPipeFd;
+    requestedFd.events = POLLIN;
+    mRequestedFds.insertAt(requestedFd, 0);
+
+    RequestedCallback requestedCallback;
+    requestedCallback.callback = NULL;
+    requestedCallback.data = NULL;
+    mRequestedCallbacks.insertAt(requestedCallback, 0);
+}
+
+void PollLoop::closeWakePipe() {
+    close(mWakeReadPipeFd);
+    close(mWakeWritePipeFd);
+
+    // Note: We don't need to remove the poll structure or callback entry because this
+    //       method is currently only called by the destructor.
+}
+
+bool PollLoop::pollOnce(int timeoutMillis) {
+    mLock.lock();
+    mPolling = true;
+    mLock.unlock();
+
+    bool result;
+    size_t requestedCount = mRequestedFds.size();
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - waiting on %d fds", this, requestedCount);
+    for (size_t i = 0; i < requestedCount; i++) {
+        LOGD("  fd %d - events %d", mRequestedFds[i].fd, mRequestedFds[i].events);
+    }
+#endif
+
+    int respondedCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis);
+
+    if (respondedCount == 0) {
+        // Timeout
+#if DEBUG_POLL_AND_WAKE
+        LOGD("%p ~ pollOnce - timeout", this);
+#endif
+        result = false;
+        goto Done;
+    }
+
+    if (respondedCount < 0) {
+        // Error
+#if DEBUG_POLL_AND_WAKE
+        LOGD("%p ~ pollOnce - error, errno=%d", this, errno);
+#endif
+        if (errno != EINTR) {
+            LOGW("Poll failed with an unexpected error, errno=%d", errno);
+        }
+        result = false;
+        goto Done;
+    }
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - handling responses from %d fds", this, respondedCount);
+    for (size_t i = 0; i < requestedCount; i++) {
+        LOGD("  fd %d - events %d, revents %d", mRequestedFds[i].fd, mRequestedFds[i].events,
+                mRequestedFds[i].revents);
+    }
+#endif
+
+    mPendingCallbacks.clear();
+    for (size_t i = 0; i < requestedCount; i++) {
+        const struct pollfd& requestedFd = mRequestedFds.itemAt(i);
+
+        short revents = requestedFd.revents;
+        if (revents) {
+            const RequestedCallback& requestedCallback = mRequestedCallbacks.itemAt(i);
+            Callback callback = requestedCallback.callback;
+
+            if (callback) {
+                PendingCallback pendingCallback;
+                pendingCallback.fd = requestedFd.fd;
+                pendingCallback.events = requestedFd.revents;
+                pendingCallback.callback = callback;
+                pendingCallback.data = requestedCallback.data;
+                mPendingCallbacks.push(pendingCallback);
+            } else {
+                if (requestedFd.fd == mWakeReadPipeFd) {
+#if DEBUG_POLL_AND_WAKE
+                    LOGD("%p ~ pollOnce - awoken", this);
+#endif
+                    char buffer[16];
+                    ssize_t nRead;
+                    do {
+                        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
+                    } while (nRead == sizeof(buffer));
+                } else {
+#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
+                    LOGD("%p ~ pollOnce - fd %d has no callback!", this, requestedFd.fd);
+#endif
+                }
+            }
+
+            respondedCount -= 1;
+            if (respondedCount == 0) {
+                break;
+            }
+        }
+    }
+    result = true;
+
+Done:
+    mLock.lock();
+    mPolling = false;
+    mAwake.broadcast();
+    mLock.unlock();
+
+    if (result) {
+        size_t pendingCount = mPendingCallbacks.size();
+        for (size_t i = 0; i < pendingCount; i++) {
+            const PendingCallback& pendingCallback = mPendingCallbacks.itemAt(i);
+#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
+            LOGD("%p ~ pollOnce - invoking callback for fd %d", this, pendingCallback.fd);
+#endif
+
+            bool keep = pendingCallback.callback(pendingCallback.fd, pendingCallback.events,
+                    pendingCallback.data);
+            if (! keep) {
+                removeCallback(pendingCallback.fd);
+            }
+        }
+    }
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - done", this);
+#endif
+    return result;
+}
+
+void PollLoop::wake() {
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ wake", this);
+#endif
+
+    ssize_t nWrite = write(mWakeWritePipeFd, "W", 1);
+    if (nWrite != 1) {
+        if (errno != EAGAIN) {
+            LOGW("Could not write wake signal, errno=%d", errno);
+        }
+    }
+}
+
+void PollLoop::setCallback(int fd, int events, Callback callback, void* data) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ setCallback - fd=%d, events=%d", this, fd, events);
+#endif
+
+    if (! events || ! callback) {
+        LOGE("Invalid attempt to set a callback with no selected poll events or no callback.");
+        removeCallback(fd);
+        return;
+    }
+
+    wakeAndLock();
+
+    struct pollfd requestedFd;
+    requestedFd.fd = fd;
+    requestedFd.events = events;
+
+    RequestedCallback requestedCallback;
+    requestedCallback.callback = callback;
+    requestedCallback.data = data;
+
+    ssize_t index = getRequestIndexLocked(fd);
+    if (index < 0) {
+        mRequestedFds.push(requestedFd);
+        mRequestedCallbacks.push(requestedCallback);
+    } else {
+        mRequestedFds.replaceAt(requestedFd, size_t(index));
+        mRequestedCallbacks.replaceAt(requestedCallback, size_t(index));
+    }
+
+    mLock.unlock();
+}
+
+bool PollLoop::removeCallback(int fd) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ removeCallback - fd=%d", this, fd);
+#endif
+
+    wakeAndLock();
+
+    ssize_t index = getRequestIndexLocked(fd);
+    if (index >= 0) {
+        mRequestedFds.removeAt(size_t(index));
+        mRequestedCallbacks.removeAt(size_t(index));
+    }
+
+    mLock.unlock();
+    return index >= 0;
+}
+
+ssize_t PollLoop::getRequestIndexLocked(int fd) {
+    size_t requestCount = mRequestedFds.size();
+
+    for (size_t i = 0; i < requestCount; i++) {
+        if (mRequestedFds.itemAt(i).fd == fd) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+void PollLoop::wakeAndLock() {
+    mLock.lock();
+    while (mPolling) {
+        wake();
+        mAwake.wait(mLock);
+    }
+}
+
+} // namespace android
diff --git a/libs/utils/Pool.cpp b/libs/utils/Pool.cpp
new file mode 100644
index 0000000..8f18cb9
--- /dev/null
+++ b/libs/utils/Pool.cpp
@@ -0,0 +1,37 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// A simple memory pool.
+//
+#define LOG_TAG "Pool"
+
+//#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+#include <utils/Pool.h>
+
+#include <stdlib.h>
+
+namespace android {
+
+// TODO Provide a real implementation of a pool.  This is just a stub for initial development.
+
+PoolImpl::PoolImpl(size_t objSize) :
+    mObjSize(objSize) {
+}
+
+PoolImpl::~PoolImpl() {
+}
+
+void* PoolImpl::allocImpl() {
+    void* ptr = malloc(mObjSize);
+    LOG_ALWAYS_FATAL_IF(ptr == NULL, "Cannot allocate new pool object.");
+    return ptr;
+}
+
+void PoolImpl::freeImpl(void* obj) {
+    LOG_ALWAYS_FATAL_IF(obj == NULL, "Caller attempted to free NULL pool object.");
+    return free(obj);
+}
+
+} // namespace android
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
index 68a1c52..b5dda2f 100644
--- a/libs/utils/StopWatch.cpp
+++ b/libs/utils/StopWatch.cpp
@@ -30,10 +30,9 @@
 
 
 StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
-    :   mName(name), mClock(clock), mFlags(flags),
-        mStartTime(0), mNumLaps(0)
+    :   mName(name), mClock(clock), mFlags(flags)
 {
-    mStartTime = systemTime(mClock);
+    reset();
 }
 
 StopWatch::~StopWatch()
@@ -72,6 +71,12 @@
     return systemTime(mClock) - mStartTime;
 }
 
+void StopWatch::reset()
+{
+    mNumLaps = 0;
+    mStartTime = systemTime(mClock);
+}
+
 
 /*****************************************************************************/
 
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index 0322af7..b09c6ca 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -108,13 +108,7 @@
 
 ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
 {
-    if (index > size())
-        return BAD_INDEX;
-    void* where = _grow(index, vector.size());
-    if (where) {
-        _do_copy(where, vector.arrayImpl(), vector.size());
-    }
-    return where ? index : (ssize_t)NO_MEMORY;
+    return insertAt(vector.arrayImpl(), index, vector.size());
 }
 
 ssize_t VectorImpl::appendVector(const VectorImpl& vector)
@@ -226,9 +220,9 @@
     return add(0);
 }
 
-ssize_t VectorImpl::add(const void* item)
+ssize_t VectorImpl::add(const void* item, size_t numItems)
 {
-    return insertAt(item, size());
+    return insertAt(item, size(), numItems);
 }
 
 ssize_t VectorImpl::replaceAt(size_t index)
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
new file mode 100644
index 0000000..45e8061
--- /dev/null
+++ b/libs/utils/tests/Android.mk
@@ -0,0 +1,33 @@
+# Build the unit tests.
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+test_src_files := \
+	PollLoop_test.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libz \
+	liblog \
+	libcutils \
+	libutils \
+	libstlport
+
+LOCAL_STATIC_LIBRARIES := \
+	libgtest \
+	libgtest_main
+
+LOCAL_C_INCLUDES := \
+    external/zlib \
+    external/icu4c/common \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport
+
+LOCAL_MODULE_TAGS := eng tests
+
+$(foreach file,$(test_src_files), \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval include $(BUILD_EXECUTABLE)) \
+)
diff --git a/libs/utils/tests/PollLoop_test.cpp b/libs/utils/tests/PollLoop_test.cpp
new file mode 100644
index 0000000..6c719c8
--- /dev/null
+++ b/libs/utils/tests/PollLoop_test.cpp
@@ -0,0 +1,398 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <utils/PollLoop.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "TestHelpers.h"
+
+// # of milliseconds to fudge stopwatch measurements
+#define TIMING_TOLERANCE_MS 25
+
+namespace android {
+
+class Pipe {
+public:
+    int sendFd;
+    int receiveFd;
+
+    Pipe() {
+        int fds[2];
+        ::pipe(fds);
+
+        receiveFd = fds[0];
+        sendFd = fds[1];
+    }
+
+    ~Pipe() {
+        ::close(sendFd);
+        ::close(receiveFd);
+    }
+
+    bool writeSignal() {
+        return ::write(sendFd, "*", 1) == 1;
+    }
+
+    bool readSignal() {
+        char buf[1];
+        return ::read(receiveFd, buf, 1) == 1;
+    }
+};
+
+class DelayedWake : public DelayedTask {
+    sp<PollLoop> mPollLoop;
+
+public:
+    DelayedWake(int delayMillis, const sp<PollLoop> pollLoop) :
+        DelayedTask(delayMillis), mPollLoop(pollLoop) {
+    }
+
+protected:
+    virtual void doTask() {
+        mPollLoop->wake();
+    }
+};
+
+class DelayedWriteSignal : public DelayedTask {
+    Pipe* mPipe;
+
+public:
+    DelayedWriteSignal(int delayMillis, Pipe* pipe) :
+        DelayedTask(delayMillis), mPipe(pipe) {
+    }
+
+protected:
+    virtual void doTask() {
+        mPipe->writeSignal();
+    }
+};
+
+class CallbackHandler {
+public:
+    void setCallback(const sp<PollLoop>& pollLoop, int fd, int events) {
+        pollLoop->setCallback(fd, events, staticHandler, this);
+    }
+
+protected:
+    virtual ~CallbackHandler() { }
+
+    virtual bool handler(int fd, int events) = 0;
+
+private:
+    static bool staticHandler(int fd, int events, void* data) {
+        return static_cast<CallbackHandler*>(data)->handler(fd, events);
+    }
+};
+
+class StubCallbackHandler : public CallbackHandler {
+public:
+    bool nextResult;
+    int callbackCount;
+
+    int fd;
+    int events;
+
+    StubCallbackHandler(bool nextResult) : nextResult(nextResult),
+            callbackCount(0), fd(-1), events(-1) {
+    }
+
+protected:
+    virtual bool handler(int fd, int events) {
+        callbackCount += 1;
+        this->fd = fd;
+        this->events = events;
+        return nextResult;
+    }
+};
+
+class PollLoopTest : public testing::Test {
+protected:
+    sp<PollLoop> mPollLoop;
+
+    virtual void SetUp() {
+        mPollLoop = new PollLoop();
+    }
+
+    virtual void TearDown() {
+        mPollLoop.clear();
+    }
+};
+
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeoutAndReturnsFalse) {
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout";
+    EXPECT_FALSE(result)
+            << "pollOnce result should be false because timeout occurred";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturnsTrue) {
+    mPollLoop->wake();
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because wake() was called before waiting";
+    EXPECT_TRUE(result)
+            << "pollOnce result should be true because loop was awoken";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturnsTrue) {
+    sp<DelayedWake> delayedWake = new DelayedWake(100, mPollLoop);
+    delayedWake->run();
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal wake delay";
+    EXPECT_TRUE(result)
+            << "pollOnce result should be true because loop was awoken";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturnsFalse) {
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_FALSE(result)
+            << "pollOnce result should be false because timeout occurred";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturnsFalse) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_FALSE(result)
+            << "pollOnce result should be false because timeout occurred";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not have been invoked because FD was not signalled";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturnsTrue) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    ASSERT_TRUE(pipe.writeSignal());
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_TRUE(result)
+            << "pollOnce result should be true because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked exactly once";
+    EXPECT_EQ(pipe.receiveFd, handler.fd)
+            << "callback should have received pipe fd as parameter";
+    EXPECT_EQ(POLL_IN, handler.events)
+            << "callback should have received POLL_IN as events";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturnsFalse) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout";
+    EXPECT_FALSE(result)
+            << "pollOnce result should be false because timeout occurred";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not have been invoked because FD was not signalled";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturnsTrue) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    pipe.writeSignal();
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_TRUE(pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_TRUE(result)
+            << "pollOnce result should be true because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked exactly once";
+    EXPECT_EQ(pipe.receiveFd, handler.fd)
+            << "callback should have received pipe fd as parameter";
+    EXPECT_EQ(POLL_IN, handler.events)
+            << "callback should have received POLL_IN as events";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturnsTrue) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+    sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+    delayedWriteSignal->run();
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_TRUE(pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal signal delay";
+    EXPECT_TRUE(result)
+            << "pollOnce result should be true because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked exactly once";
+    EXPECT_EQ(pipe.receiveFd, handler.fd)
+            << "callback should have received pipe fd as parameter";
+    EXPECT_EQ(POLL_IN, handler.events)
+            << "callback should have received POLL_IN as events";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+    pipe.writeSignal(); // would cause FD to be considered signalled
+    mPollLoop->removeCallback(pipe.receiveFd);
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_TRUE(pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout because FD was no longer registered";
+    EXPECT_FALSE(result)
+            << "pollOnce result should be false because timeout occurred";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not be invoked";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {
+    Pipe pipe;
+    StubCallbackHandler handler(false);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    // First loop: Callback is registered and FD is signalled.
+    pipe.writeSignal();
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_TRUE(pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal zero because FD was already signalled";
+    EXPECT_TRUE(result)
+            << "pollOnce result should be true because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked";
+
+    // Second loop: Callback is no longer registered and FD is signalled.
+    pipe.writeSignal();
+
+    stopWatch.reset();
+    result = mPollLoop->pollOnce(0);
+    elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_TRUE(pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal zero because timeout was zero";
+    EXPECT_FALSE(result)
+            << "pollOnce result should be false because timeout occurred";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should not be invoked this time";
+}
+
+TEST_F(PollLoopTest, RemoveCallback_WhenCallbackNotAdded_ReturnsFalse) {
+    bool result = mPollLoop->removeCallback(1);
+
+    EXPECT_FALSE(result)
+            << "removeCallback should return false because FD not registered";
+}
+
+TEST_F(PollLoopTest, RemoveCallback_WhenCallbackAddedThenRemovedTwice_ReturnsTrueFirstTimeAndReturnsFalseSecondTime) {
+    Pipe pipe;
+    StubCallbackHandler handler(false);
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    // First time.
+    bool result = mPollLoop->removeCallback(pipe.receiveFd);
+
+    EXPECT_TRUE(result)
+            << "removeCallback should return true first time because FD was registered";
+
+    // Second time.
+    result = mPollLoop->removeCallback(pipe.receiveFd);
+
+    EXPECT_FALSE(result)
+            << "removeCallback should return false second time because FD was no longer registered";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {
+    Pipe pipe;
+    StubCallbackHandler handler1(true);
+    StubCallbackHandler handler2(true);
+
+    handler1.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+    handler2.setCallback(mPollLoop, pipe.receiveFd, POLL_IN); // replace it
+    pipe.writeSignal(); // would cause FD to be considered signalled
+
+    StopWatch stopWatch("pollOnce");
+    bool result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_TRUE(pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because FD was already signalled";
+    EXPECT_TRUE(result)
+            << "pollOnce result should be true because FD was signalled";
+    EXPECT_EQ(0, handler1.callbackCount)
+            << "original handler callback should not be invoked because it was replaced";
+    EXPECT_EQ(1, handler2.callbackCount)
+            << "replacement handler callback should be invoked";
+}
+
+
+} // namespace android
diff --git a/libs/utils/tests/TestHelpers.h b/libs/utils/tests/TestHelpers.h
new file mode 100644
index 0000000..e55af3c
--- /dev/null
+++ b/libs/utils/tests/TestHelpers.h
@@ -0,0 +1,44 @@
+/*
+ * 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 <utils/threads.h>
+
+namespace android {
+
+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
