diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index d394a46..df30c76 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -16,13 +16,11 @@
 
 package android.os;
 
-import java.util.ArrayList;
-
 import android.util.AndroidRuntimeException;
 import android.util.Config;
 import android.util.Log;
 
-import com.android.internal.os.RuntimeInit;
+import java.util.ArrayList;
 
 /**
  * Low-level class holding the list of messages to be dispatched by a
@@ -34,11 +32,18 @@
  */
 public class MessageQueue {
     Message mMessages;
-    private final ArrayList mIdleHandlers = new ArrayList();
+    private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
     private boolean mQuiting = false;
-    private int mObject = 0;    // used by native code
     boolean mQuitAllowed = true;
 
+    @SuppressWarnings("unused")
+    private int mPtr; // used by native code
+    
+    private native void nativeInit();
+    private native void nativeDestroy();
+    private native boolean nativePollOnce(int timeoutMillis);
+    private native void nativeWake();
+
     /**
      * Callback interface for discovering when a thread is going to block
      * waiting for more messages.
@@ -85,55 +90,39 @@
             mIdleHandlers.remove(handler);
         }
     }
-
-    // Add an input pipe to the set being selected over.  If token is
-    // negative, remove 'handler's entry from the current set and forget
-    // about it.
-    void setInputToken(int token, int region, Handler handler) {
-        if (token >= 0) nativeRegisterInputStream(token, region, handler);
-        else nativeUnregisterInputStream(token);
-    }
-
+    
     MessageQueue() {
         nativeInit();
     }
-    private native void nativeInit();
-
-    /**
-     * @param token fd of the readable end of the input stream
-     * @param region fd of the ashmem region used for data transport alongside the 'token' fd
-     * @param handler Handler from which to make input messages based on data read from the fd
-     */
-    private native void nativeRegisterInputStream(int token, int region, Handler handler);
-    private native void nativeUnregisterInputStream(int token);
-    private native void nativeSignal();
-
-    /**
-     * Wait until the designated time for new messages to arrive.
-     *
-     * @param when Timestamp in SystemClock.uptimeMillis() base of the next message in the queue.
-     *    If 'when' is zero, the method will check for incoming messages without blocking.  If
-     *    'when' is negative, the method will block forever waiting for the next message.
-     * @return
-     */
-    private native int nativeWaitForNext(long when);
+    
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            nativeDestroy();
+        } finally {
+            super.finalize();
+        }
+    }
 
     final Message next() {
         boolean tryIdle = true;
         // when we start out, we'll just touch the input pipes and then go from there
-        long timeToNextEventMillis = 0;
+        int timeToNextEventMillis = 0;
 
         while (true) {
             long now;
             Object[] idlers = null;
 
-            nativeWaitForNext(timeToNextEventMillis);
+            boolean dispatched = nativePollOnce(timeToNextEventMillis);
 
             // Try to retrieve the next message, returning if found.
             synchronized (this) {
                 now = SystemClock.uptimeMillis();
                 Message msg = pullNextLocked(now);
-                if (msg != null) return msg;
+                if (msg != null) {
+                    return msg;
+                }
+                
                 if (tryIdle && mIdleHandlers.size() > 0) {
                     idlers = mIdleHandlers.toArray();
                 }
@@ -170,9 +159,14 @@
             synchronized (this) {
                 // No messages, nobody to tell about it...  time to wait!
                 if (mMessages != null) {
-                    if (mMessages.when - now > 0) {
+                    long longTimeToNextEventMillis = mMessages.when - now;
+                    
+                    if (longTimeToNextEventMillis > 0) {
                         Binder.flushPendingCommands();
-                        timeToNextEventMillis = mMessages.when - now;
+                        timeToNextEventMillis = (int) Math.min(longTimeToNextEventMillis,
+                                Integer.MAX_VALUE);
+                    } else {
+                        timeToNextEventMillis = 0;
                     }
                 } else {
                     Binder.flushPendingCommands();
@@ -230,7 +224,7 @@
                 msg.next = prev.next;
                 prev.next = msg;
             }
-            nativeSignal();
+            nativeWake();
         }
         return true;
     }
@@ -351,7 +345,7 @@
     void poke()
     {
         synchronized (this) {
-            nativeSignal();
+            nativeWake();
         }
     }
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 2ade44e..3f5d6ca 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.view.BaseIWindow;
+import com.android.internal.view.BaseInputHandler;
 import com.android.internal.view.BaseSurfaceHolder;
 
 import android.annotation.SdkConstant;
@@ -39,6 +40,10 @@
 import android.util.LogPrinter;
 import android.view.Gravity;
 import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.InputHandler;
+import android.view.InputQueue;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.View;
@@ -46,6 +51,7 @@
 import android.view.ViewRoot;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
+import android.view.WindowManagerPolicy;
 
 import java.util.ArrayList;
 
@@ -146,6 +152,7 @@
         final WindowManager.LayoutParams mLayout
                 = new WindowManager.LayoutParams();
         IWindowSession mSession;
+        InputChannel mInputChannel;
 
         final Object mLock = new Object();
         boolean mOffsetMessageEnqueued;
@@ -205,6 +212,30 @@
             
         };
         
+        final InputHandler mInputHandler = new BaseInputHandler() {
+            @Override
+            public void handleTouch(MotionEvent event, Runnable finishedCallback) {
+                try {
+                    synchronized (mLock) {
+                        if (event.getAction() == MotionEvent.ACTION_MOVE) {
+                            if (mPendingMove != null) {
+                                mCaller.removeMessages(MSG_TOUCH_EVENT, mPendingMove);
+                                mPendingMove.recycle();
+                            }
+                            mPendingMove = event;
+                        } else {
+                            mPendingMove = null;
+                        }
+                        Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT,
+                                event);
+                        mCaller.sendMessage(msg);
+                    }
+                } finally {
+                    finishedCallback.run();
+                }
+            }
+        };
+        
         final BaseIWindow mWindow = new BaseIWindow() {
             @Override
             public boolean onDispatchPointer(MotionEvent event, long eventTime,
@@ -487,8 +518,15 @@
                         mLayout.setTitle(WallpaperService.this.getClass().getName());
                         mLayout.windowAnimations =
                                 com.android.internal.R.style.Animation_Wallpaper;
-                        mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets);
+                        mInputChannel = new InputChannel();
+                        mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets,
+                                mInputChannel);
                         mCreated = true;
+
+                        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+                            InputQueue.registerInputChannel(mInputChannel, mInputHandler,
+                                    Looper.myQueue());
+                        }
                     }
                     
                     mSurfaceHolder.mSurfaceLock.lock();
@@ -587,6 +625,7 @@
             mSurfaceHolder.setSizeFromLayout();
             mInitializing = true;
             mSession = ViewRoot.getWindowSession(getMainLooper());
+            
             mWindow.setSession(mSession);
             
             IntentFilter filter = new IntentFilter();
@@ -730,6 +769,15 @@
                 try {
                     if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
                             + mSurfaceHolder.getSurface() + " of: " + this);
+                    
+                    if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+                        if (mInputChannel != null) {
+                            InputQueue.unregisterInputChannel(mInputChannel);
+                            mInputChannel.dispose();
+                            mInputChannel = null;
+                        }
+                    }
+                    
                     mSession.remove(mWindow);
                 } catch (RemoteException e) {
                 }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 01f07d6..4647fb4 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -21,6 +21,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Bundle;
+import android.view.InputChannel;
 import android.view.IWindow;
 import android.view.MotionEvent;
 import android.view.WindowManager;
@@ -33,6 +34,9 @@
  */
 interface IWindowSession {
     int add(IWindow window, in WindowManager.LayoutParams attrs,
+            in int viewVisibility, out Rect outContentInsets,
+            out InputChannel outInputChannel);
+    int addWithoutInputChannel(IWindow window, in WindowManager.LayoutParams attrs,
             in int viewVisibility, out Rect outContentInsets);
     void remove(IWindow window);
     
diff --git a/core/java/android/view/InputChannel.aidl b/core/java/android/view/InputChannel.aidl
new file mode 100644
index 0000000..74c0aa4
--- /dev/null
+++ b/core/java/android/view/InputChannel.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/view/InputChannel.aidl
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package android.view;
+
+parcelable InputChannel;
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java
new file mode 100644
index 0000000..66a83b8
--- /dev/null
+++ b/core/java/android/view/InputChannel.java
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+package android.view;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Slog;
+
+/**
+ * An input channel specifies the file descriptors used to send input events to
+ * a window in another process.  It is Parcelable so that it can be transmitted
+ * to the ViewRoot through a Binder transaction as part of registering the Window.
+ * @hide
+ */
+public class InputChannel implements Parcelable {
+    private static final String TAG = "InputChannel";
+    
+    public static final Parcelable.Creator<InputChannel> CREATOR
+            = new Parcelable.Creator<InputChannel>() {
+        public InputChannel createFromParcel(Parcel source) {
+            InputChannel result = new InputChannel();
+            result.readFromParcel(source);
+            return result;
+        }
+        
+        public InputChannel[] newArray(int size) {
+            return new InputChannel[size];
+        }
+    };
+    
+    @SuppressWarnings("unused")
+    private int mPtr; // used by native code
+    
+    private boolean mDisposeAfterWriteToParcel;
+    
+    private static native InputChannel[] nativeOpenInputChannelPair(String name);
+    
+    private native void nativeDispose(boolean finalized);
+    private native void nativeTransferTo(InputChannel other);
+    private native void nativeReadFromParcel(Parcel parcel);
+    private native void nativeWriteToParcel(Parcel parcel);
+    
+    private native String nativeGetName();
+
+    /**
+     * Creates an uninitialized input channel.
+     * It can be initialized by reading from a Parcel or by transferring the state of
+     * another input channel into this one.
+     */
+    public InputChannel() {
+    }
+    
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            nativeDispose(true);
+        } finally {
+            super.finalize();
+        }
+    }
+    
+    /**
+     * Creates a new input channel pair.  One channel should be provided to the input
+     * dispatcher and the other to the application's input queue.
+     * @param name The descriptive (non-unique) name of the channel pair.
+     * @return A pair of input channels.  They are symmetric and indistinguishable.
+     */
+    public static InputChannel[] openInputChannelPair(String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("name must not be null");
+        }
+        
+        Slog.d(TAG, "Opening input channel pair '" + name + "'");
+        return nativeOpenInputChannelPair(name);
+    }
+    
+    /**
+     * Gets the name of the input channel.
+     * @return The input channel name.
+     */
+    public String getName() {
+        String name = nativeGetName();
+        return name != null ? name : "uninitialized";
+    }
+
+    /**
+     * Disposes the input channel.
+     * Explicitly releases the reference this object is holding on the input channel.
+     * When all references are released, the input channel will be closed.
+     */
+    public void dispose() {
+        nativeDispose(false);
+    }
+    
+    /**
+     * Transfers ownership of the internal state of the input channel to another
+     * instance and invalidates this instance.  This is used to pass an input channel
+     * as an out parameter in a binder call.
+     * @param other The other input channel instance.
+     */
+    public void transferToBinderOutParameter(InputChannel outParameter) {
+        if (outParameter == null) {
+            throw new IllegalArgumentException("outParameter must not be null");
+        }
+        
+        nativeTransferTo(outParameter);
+        outParameter.mDisposeAfterWriteToParcel = true;
+    }
+
+    public int describeContents() {
+        return Parcelable.CONTENTS_FILE_DESCRIPTOR;
+    }
+    
+    public void readFromParcel(Parcel in) {
+        if (in == null) {
+            throw new IllegalArgumentException("in must not be null");
+        }
+        
+        nativeReadFromParcel(in);
+    }
+    
+    public void writeToParcel(Parcel out, int flags) {
+        if (out == null) {
+            throw new IllegalArgumentException("out must not be null");
+        }
+        
+        nativeWriteToParcel(out);
+        
+        if (mDisposeAfterWriteToParcel) {
+            dispose();
+        }
+    }
+    
+    @Override
+    public String toString() {
+        return getName();
+    }
+}
diff --git a/core/java/android/view/InputHandler.java b/core/java/android/view/InputHandler.java
new file mode 100644
index 0000000..816f622
--- /dev/null
+++ b/core/java/android/view/InputHandler.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package android.view;
+
+/**
+ * Handles input messages that arrive on an input channel.
+ * @hide
+ */
+public interface InputHandler {
+    /**
+     * Handle a key event.
+     * It is the responsibility of the callee to ensure that the finished callback is
+     * eventually invoked when the event processing is finished and the input system
+     * can send the next event.
+     * @param event The key event data.
+     * @param finishedCallback The callback to invoke when event processing is finished.
+     */
+    public void handleKey(KeyEvent event, Runnable finishedCallback);
+    
+    /**
+     * Handle a touch event.
+     * It is the responsibility of the callee to ensure that the finished callback is
+     * eventually invoked when the event processing is finished and the input system
+     * can send the next event.
+     * @param event The motion event data.
+     * @param finishedCallback The callback to invoke when event processing is finished.
+     */
+    public void handleTouch(MotionEvent event, Runnable finishedCallback);
+    
+    /**
+     * Handle a trackball event.
+     * It is the responsibility of the callee to ensure that the finished callback is
+     * eventually invoked when the event processing is finished and the input system
+     * can send the next event.
+     * @param event The motion event data.
+     * @param finishedCallback The callback to invoke when event processing is finished.
+     */
+    public void handleTrackball(MotionEvent event, Runnable finishedCallback);
+}
diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java
new file mode 100644
index 0000000..b38f7d5
--- /dev/null
+++ b/core/java/android/view/InputQueue.java
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+package android.view;
+
+import android.os.MessageQueue;
+import android.util.Slog;
+
+/**
+ * An input queue provides a mechanism for an application to receive incoming
+ * input events sent over an input channel.  Signalling is implemented by MessageQueue.
+ * @hide
+ */
+public final class InputQueue {
+    private static final String TAG = "InputQueue";
+    
+    // Describes the interpretation of an event.
+    // XXX This concept is tentative.  See comments in android/input.h.
+    public static final int INPUT_EVENT_NATURE_KEY = 1;
+    public static final int INPUT_EVENT_NATURE_TOUCH = 2;
+    public static final int INPUT_EVENT_NATURE_TRACKBALL = 3;
+    
+    private static Object sLock = new Object();
+    
+    private static native void nativeRegisterInputChannel(InputChannel inputChannel,
+            InputHandler inputHandler, MessageQueue messageQueue);
+    private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
+    private static native void nativeFinished(long finishedToken);
+    
+    private InputQueue() {
+    }
+    
+    /**
+     * Registers an input channel and handler.
+     * @param inputChannel The input channel to register.
+     * @param inputHandler The input handler to input events send to the target.
+     * @param messageQueue The message queue on whose thread the handler should be invoked.
+     */
+    public static void registerInputChannel(InputChannel inputChannel, InputHandler inputHandler,
+            MessageQueue messageQueue) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null");
+        }
+        if (inputHandler == null) {
+            throw new IllegalArgumentException("inputHandler must not be null");
+        }
+        if (messageQueue == null) {
+            throw new IllegalArgumentException("messageQueue must not be null");
+        }
+        
+        synchronized (sLock) {
+            Slog.d(TAG, "Registering input channel '" + inputChannel + "'");
+            nativeRegisterInputChannel(inputChannel, inputHandler, messageQueue);
+        }
+    }
+    
+    /**
+     * Unregisters an input channel.
+     * Does nothing if the channel is not currently registered.
+     * @param inputChannel The input channel to unregister.
+     */
+    public static void unregisterInputChannel(InputChannel inputChannel) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null");
+        }
+
+        synchronized (sLock) {
+            Slog.d(TAG, "Unregistering input channel '" + inputChannel + "'");
+            nativeUnregisterInputChannel(inputChannel);
+        }
+    }
+    
+    @SuppressWarnings("unused")
+    private static void dispatchKeyEvent(InputHandler inputHandler,
+            KeyEvent event, int nature, long finishedToken) {
+        Runnable finishedCallback = new FinishedCallback(finishedToken);
+        
+        if (nature == INPUT_EVENT_NATURE_KEY) {
+            inputHandler.handleKey(event, finishedCallback);
+        } else {
+            Slog.d(TAG, "Unsupported nature for key event: " + nature);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void dispatchMotionEvent(InputHandler inputHandler,
+            MotionEvent event, int nature, long finishedToken) {
+        Runnable finishedCallback = new FinishedCallback(finishedToken);
+        
+        if (nature == INPUT_EVENT_NATURE_TOUCH) {
+            inputHandler.handleTouch(event, finishedCallback);
+        } else if (nature == INPUT_EVENT_NATURE_TRACKBALL) {
+            inputHandler.handleTrackball(event, finishedCallback);
+        } else {
+            Slog.d(TAG, "Unsupported nature for motion event: " + nature);
+        }
+    }
+    
+    // TODO consider recycling finished callbacks when done
+    private static class FinishedCallback implements Runnable {
+        private long mFinishedToken;
+        
+        public FinishedCallback(long finishedToken) {
+            mFinishedToken = finishedToken;
+        }
+        
+        public void run() {
+            synchronized (sLock) {
+                nativeFinished(mFinishedToken);
+            }
+        }
+    }
+}
diff --git a/core/java/android/view/InputTarget.java b/core/java/android/view/InputTarget.java
new file mode 100644
index 0000000..e56e03c
--- /dev/null
+++ b/core/java/android/view/InputTarget.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package android.view;
+
+/**
+ * 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.
+ * 
+ * These parameters are used by the native input dispatching code.
+ * @hide
+ */
+public class InputTarget {
+    public InputChannel mInputChannel;
+    public int mFlags;
+    public long mTimeoutNanos;
+    public float mXOffset;
+    public float mYOffset;
+    
+    /**
+     * This flag indicates that subsequent event delivery should be held until the
+     * current event is delivered to this target or a timeout occurs.
+     */
+    public static int 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.
+     */
+    public static int 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.
+     */
+    public static int FLAG_CANCEL = 0x04;
+    
+    public void recycle() {
+        mInputChannel = null;
+    }
+}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 9aa16b5..ae9746e 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -127,6 +127,7 @@
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
+    //  native/include/android/keycodes.h
     //  frameworks/base/include/ui/KeycodeLabels.h
     //  tools/puppet_master/PuppetMaster/nav_keys.py
     //  frameworks/base/core/res/res/values/attrs.xml
@@ -162,7 +163,7 @@
      * key code is not {#link {@link #KEYCODE_UNKNOWN} then the
      * {#link {@link #getRepeatCount()} method returns the number of times
      * the given key code should be executed.
-     * Otherwise, if the key code {@link #KEYCODE_UNKNOWN}, then
+     * Otherwise, if the key code is {@link #KEYCODE_UNKNOWN}, then
      * this is a sequence of characters as returned by {@link #getCharacters}.
      */
     public static final int ACTION_MULTIPLE         = 2;
@@ -330,7 +331,7 @@
     private int mMetaState;
     private int mAction;
     private int mKeyCode;
-    private int mScancode;
+    private int mScanCode;
     private int mRepeatCount;
     private int mDeviceId;
     private int mFlags;
@@ -480,7 +481,7 @@
         mRepeatCount = repeat;
         mMetaState = metaState;
         mDeviceId = device;
-        mScancode = scancode;
+        mScanCode = scancode;
     }
 
     /**
@@ -510,7 +511,7 @@
         mRepeatCount = repeat;
         mMetaState = metaState;
         mDeviceId = device;
-        mScancode = scancode;
+        mScanCode = scancode;
         mFlags = flags;
     }
 
@@ -547,7 +548,7 @@
         mRepeatCount = origEvent.mRepeatCount;
         mMetaState = origEvent.mMetaState;
         mDeviceId = origEvent.mDeviceId;
-        mScancode = origEvent.mScancode;
+        mScanCode = origEvent.mScanCode;
         mFlags = origEvent.mFlags;
         mCharacters = origEvent.mCharacters;
     }
@@ -572,7 +573,7 @@
         mRepeatCount = newRepeat;
         mMetaState = origEvent.mMetaState;
         mDeviceId = origEvent.mDeviceId;
-        mScancode = origEvent.mScancode;
+        mScanCode = origEvent.mScanCode;
         mFlags = origEvent.mFlags;
         mCharacters = origEvent.mCharacters;
     }
@@ -625,7 +626,7 @@
         mRepeatCount = origEvent.mRepeatCount;
         mMetaState = origEvent.mMetaState;
         mDeviceId = origEvent.mDeviceId;
-        mScancode = origEvent.mScancode;
+        mScanCode = origEvent.mScanCode;
         mFlags = origEvent.mFlags;
         // Don't copy mCharacters, since one way or the other we'll lose it
         // when changing the action.
@@ -859,7 +860,7 @@
      * Mostly this is here for debugging purposes.
      */
     public final int getScanCode() {
-        return mScancode;
+        return mScanCode;
     }
 
     /**
@@ -1183,7 +1184,7 @@
     public String toString() {
         return "KeyEvent{action=" + mAction + " code=" + mKeyCode
             + " repeat=" + mRepeatCount
-            + " meta=" + mMetaState + " scancode=" + mScancode
+            + " meta=" + mMetaState + " scancode=" + mScanCode
             + " mFlags=" + mFlags + "}";
     }
 
@@ -1208,7 +1209,7 @@
         out.writeInt(mRepeatCount);
         out.writeInt(mMetaState);
         out.writeInt(mDeviceId);
-        out.writeInt(mScancode);
+        out.writeInt(mScanCode);
         out.writeInt(mFlags);
         out.writeLong(mDownTime);
         out.writeLong(mEventTime);
@@ -1220,7 +1221,7 @@
         mRepeatCount = in.readInt();
         mMetaState = in.readInt();
         mDeviceId = in.readInt();
-        mScancode = in.readInt();
+        mScanCode = in.readInt();
         mFlags = in.readInt();
         mDownTime = in.readLong();
         mEventTime = in.readLong();
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index eefbf7a..1f06191 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -248,17 +248,17 @@
     private RuntimeException mRecycledLocation;
     private boolean mRecycled;
 
-    private MotionEvent() {
-        mPointerIdentifiers = new int[BASE_AVAIL_POINTERS];
-        mDataSamples = new float[BASE_AVAIL_POINTERS*BASE_AVAIL_SAMPLES*NUM_SAMPLE_DATA];
-        mTimeSamples = new long[BASE_AVAIL_SAMPLES];
+    private MotionEvent(int pointerCount, int sampleCount) {
+        mPointerIdentifiers = new int[pointerCount];
+        mDataSamples = new float[pointerCount * sampleCount * NUM_SAMPLE_DATA];
+        mTimeSamples = new long[sampleCount];
     }
 
     static private MotionEvent obtain() {
         final MotionEvent ev;
         synchronized (gRecyclerLock) {
             if (gRecyclerTop == null) {
-                return new MotionEvent();
+                return new MotionEvent(BASE_AVAIL_POINTERS, BASE_AVAIL_SAMPLES);
             }
             ev = gRecyclerTop;
             gRecyclerTop = ev.mNext;
@@ -269,6 +269,45 @@
         ev.mNext = null;
         return ev;
     }
+    
+    @SuppressWarnings("unused") // used by native code
+    static private MotionEvent obtain(int pointerCount, int sampleCount) {
+        final MotionEvent ev;
+        synchronized (gRecyclerLock) {
+            if (gRecyclerTop == null) {
+                if (pointerCount < BASE_AVAIL_POINTERS) {
+                    pointerCount = BASE_AVAIL_POINTERS;
+                }
+                if (sampleCount < BASE_AVAIL_SAMPLES) {
+                    sampleCount = BASE_AVAIL_SAMPLES;
+                }
+                return new MotionEvent(pointerCount, sampleCount);
+            }
+            ev = gRecyclerTop;
+            gRecyclerTop = ev.mNext;
+            gRecyclerUsed--;
+        }
+        ev.mRecycledLocation = null;
+        ev.mRecycled = false;
+        ev.mNext = null;
+        
+        if (ev.mPointerIdentifiers.length < pointerCount) {
+            ev.mPointerIdentifiers = new int[pointerCount];
+        }
+        
+        final int timeSamplesLength = ev.mTimeSamples.length;
+        if (timeSamplesLength < sampleCount) {
+            ev.mTimeSamples = new long[sampleCount];
+        }
+        
+        final int dataSamplesLength = ev.mDataSamples.length;
+        final int neededDataSamplesLength = pointerCount * sampleCount * NUM_SAMPLE_DATA;
+        if (dataSamplesLength < neededDataSamplesLength) {
+            ev.mDataSamples = new float[neededDataSamplesLength];
+        }
+        
+        return ev;
+    }
 
     /**
      * Create a new MotionEvent, filling in all of the basic values that
@@ -1022,7 +1061,7 @@
     }
 
     /**
-     * Returns a bitfield indicating which edges, if any, where touched by this
+     * Returns a bitfield indicating which edges, if any, were touched by this
      * MotionEvent. For touch events, clients can use this to determine if the
      * user's finger was touching the edge of the display.
      *
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 0f0cf60..8beceec 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -471,7 +471,7 @@
                     mWindow = new MyWindow(this);
                     mLayout.type = mWindowType;
                     mLayout.gravity = Gravity.LEFT|Gravity.TOP;
-                    mSession.add(mWindow, mLayout,
+                    mSession.addWithoutInputChannel(mWindow, mLayout,
                             mVisible ? VISIBLE : GONE, mContentInsets);
                 }
                 
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index aa124e6..a41c690 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -153,6 +153,7 @@
     CompatibilityInfo.Translator mTranslator;
 
     final View.AttachInfo mAttachInfo;
+    InputChannel mInputChannel;
 
     final Rect mTempRect; // used in the transaction to not thrash the heap.
     final Rect mVisRect; // used to retrieve visible rect of focused view.
@@ -219,7 +220,7 @@
     AudioManager mAudioManager;
 
     private final int mDensity;
-
+    
     public static IWindowSession getWindowSession(Looper mainLooper) {
         synchronized (mStaticInit) {
             if (!mInitialized) {
@@ -434,9 +435,6 @@
         }
     }
 
-    // fd [0] is the receiver, [1] is the sender
-    private native int[] makeInputChannel();
-
     /**
      * We have one child
      */
@@ -488,25 +486,20 @@
                 mAdded = true;
                 int res; /* = WindowManagerImpl.ADD_OKAY; */
 
-                // Set up the input event channel
-                if (false) {
-                int[] fds = makeInputChannel();
-                if (DEBUG_INPUT) {
-                    Log.v(TAG, "makeInputChannel() returned " + fds);
-                }
-                }
-
                 // Schedule the first layout -before- adding to the window
                 // manager, to make sure we do the relayout before receiving
                 // any other events from the system.
                 requestLayout();
+                mInputChannel = new InputChannel();
                 try {
                     res = sWindowSession.add(mWindow, mWindowAttributes,
-                            getHostVisibility(), mAttachInfo.mContentInsets);
+                            getHostVisibility(), mAttachInfo.mContentInsets,
+                            mInputChannel);
                 } catch (RemoteException e) {
                     mAdded = false;
                     mView = null;
                     mAttachInfo.mRootView = null;
+                    mInputChannel = null;
                     unscheduleTraversals();
                     throw new RuntimeException("Adding window failed", e);
                 } finally {
@@ -514,7 +507,7 @@
                         attrs.restore();
                     }
                 }
-
+                
                 if (mTranslator != null) {
                     mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
                 }
@@ -560,6 +553,12 @@
                     throw new RuntimeException(
                         "Unable to add window -- unknown error code " + res);
                 }
+
+                if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+                    InputQueue.registerInputChannel(mInputChannel, mInputHandler,
+                            Looper.myQueue());
+                }
+                
                 view.assignParent(this);
                 mAddedTouchMode = (res&WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE) != 0;
                 mAppVisible = (res&WindowManagerImpl.ADD_FLAG_APP_VISIBLE) != 0;
@@ -1735,6 +1734,14 @@
         }
         mSurface.release();
 
+        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+            if (mInputChannel != null) {
+                InputQueue.unregisterInputChannel(mInputChannel);
+                mInputChannel.dispose();
+                mInputChannel = null;
+            }
+        }
+        
         try {
             sWindowSession.remove(mWindow);
         } catch (RemoteException e) {
@@ -1841,19 +1848,16 @@
             boolean callWhenDone = msg.arg1 != 0;
             
             if (event == null) {
-                try {
-                    long timeBeforeGettingEvents;
-                    if (MEASURE_LATENCY) {
-                        timeBeforeGettingEvents = System.nanoTime();
-                    }
+                long timeBeforeGettingEvents;
+                if (MEASURE_LATENCY) {
+                    timeBeforeGettingEvents = System.nanoTime();
+                }
 
-                    event = sWindowSession.getPendingPointerMove(mWindow);
+                event = getPendingPointerMotionEvent();
 
-                    if (MEASURE_LATENCY && event != null) {
-                        lt.sample("9 Client got events      ", System.nanoTime() - event.getEventTimeNano());
-                        lt.sample("8 Client getting events  ", timeBeforeGettingEvents - event.getEventTimeNano());
-                    }
-                } catch (RemoteException e) {
+                if (MEASURE_LATENCY && event != null) {
+                    lt.sample("9 Client got events      ", System.nanoTime() - event.getEventTimeNano());
+                    lt.sample("8 Client getting events  ", timeBeforeGettingEvents - event.getEventTimeNano());
                 }
                 callWhenDone = false;
             }
@@ -1928,14 +1932,9 @@
                 }
             } finally {
                 if (callWhenDone) {
-                    try {
-                        sWindowSession.finishKey(mWindow);
-                    } catch (RemoteException e) {
-                    }
+                    finishMotionEvent();
                 }
-                if (event != null) {
-                    event.recycle();
-                }
+                recycleMotionEvent(event);
                 if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!");
                 // Let the exception fall through -- the looper will catch
                 // it and take care of the bad app for us.
@@ -2075,7 +2074,63 @@
         } break;
         }
     }
+    
+    private void finishKeyEvent(KeyEvent event) {
+        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+            if (mFinishedCallback != null) {
+                mFinishedCallback.run();
+                mFinishedCallback = null;
+            }
+        } else {
+            try {
+                sWindowSession.finishKey(mWindow);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+    
+    private void finishMotionEvent() {
+        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+            throw new IllegalStateException("Should not be reachable with native input dispatch.");
+        }
+        
+        try {
+            sWindowSession.finishKey(mWindow);
+        } catch (RemoteException e) {
+        }
+    }
 
+    private void recycleMotionEvent(MotionEvent event) {
+        if (event != null) {
+            event.recycle();
+        }
+    }
+    
+    private MotionEvent getPendingPointerMotionEvent() {
+        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+            throw new IllegalStateException("Should not be reachable with native input dispatch.");
+        }
+        
+        try {
+            return sWindowSession.getPendingPointerMove(mWindow);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    private MotionEvent getPendingTrackballMotionEvent() {
+        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
+            throw new IllegalStateException("Should not be reachable with native input dispatch.");
+        }
+        
+        try {
+            return sWindowSession.getPendingTrackballMove(mWindow);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+    
+    
     /**
      * Something in the current window tells us we need to change the touch mode.  For
      * example, we are not in touch mode, and the user touches the screen.
@@ -2200,10 +2255,7 @@
 
     private void deliverTrackballEvent(MotionEvent event, boolean callWhenDone) {
         if (event == null) {
-            try {
-                event = sWindowSession.getPendingTrackballMove(mWindow);
-            } catch (RemoteException e) {
-            }
+            event = getPendingTrackballMotionEvent();
             callWhenDone = false;
         }
 
@@ -2223,14 +2275,9 @@
         } finally {
             if (handled) {
                 if (callWhenDone) {
-                    try {
-                        sWindowSession.finishKey(mWindow);
-                    } catch (RemoteException e) {
-                    }
+                    finishMotionEvent();
                 }
-                if (event != null) {
-                    event.recycle();
-                }
+                recycleMotionEvent(event);
                 // If we reach this, we delivered a trackball event to mView and
                 // mView consumed it. Because we will not translate the trackball
                 // event into a key event, touch mode will not exit, so we exit
@@ -2339,13 +2386,8 @@
             }
         } finally {
             if (callWhenDone) {
-                try {
-                    sWindowSession.finishKey(mWindow);
-                } catch (RemoteException e) {
-                }
-                if (event != null) {
-                    event.recycle();
-                }
+                finishMotionEvent();
+                recycleMotionEvent(event);
             }
             // Let the exception fall through -- the looper will catch
             // it and take care of the bad app for us.
@@ -2503,10 +2545,7 @@
             if (sendDone) {
                 if (LOCAL_LOGV) Log.v(
                     "ViewRoot", "Telling window manager key is finished");
-                try {
-                    sWindowSession.finishKey(mWindow);
-                } catch (RemoteException e) {
-                }
+                finishKeyEvent(event);
             }
             return;
         }
@@ -2539,10 +2578,7 @@
             } else if (sendDone) {
                 if (LOCAL_LOGV) Log.v(
                         "ViewRoot", "Telling window manager key is finished");
-                try {
-                    sWindowSession.finishKey(mWindow);
-                } catch (RemoteException e) {
-                }
+                finishKeyEvent(event);
             } else {
                 Log.w("ViewRoot", "handleFinishedEvent(seq=" + seq
                         + " handled=" + handled + " ev=" + event
@@ -2617,10 +2653,7 @@
             if (sendDone) {
                 if (LOCAL_LOGV) Log.v(
                     "ViewRoot", "Telling window manager key is finished");
-                try {
-                    sWindowSession.finishKey(mWindow);
-                } catch (RemoteException e) {
-                }
+                finishKeyEvent(event);
             }
             // Let the exception fall through -- the looper will catch
             // it and take care of the bad app for us.
@@ -2798,6 +2831,53 @@
         msg.obj = ri;
         sendMessage(msg);
     }
+    
+    private Runnable mFinishedCallback;
+    
+    private final InputHandler mInputHandler = new InputHandler() {
+        public void handleKey(KeyEvent event, Runnable finishedCallback) {
+            mFinishedCallback = finishedCallback;
+            
+            if (event.getAction() == KeyEvent.ACTION_DOWN) {
+                //noinspection ConstantConditions
+                if (false && event.getKeyCode() == KeyEvent.KEYCODE_CAMERA) {
+                    if (Config.LOGD) Log.d("keydisp",
+                            "===================================================");
+                    if (Config.LOGD) Log.d("keydisp", "Focused view Hierarchy is:");
+                    debug();
+
+                    if (Config.LOGD) Log.d("keydisp",
+                            "===================================================");
+                }
+            }
+
+            Message msg = obtainMessage(DISPATCH_KEY);
+            msg.obj = event;
+
+            if (LOCAL_LOGV) Log.v(
+                "ViewRoot", "sending key " + event + " to " + mView);
+
+            sendMessageAtTime(msg, event.getEventTime());
+        }
+
+        public void handleTouch(MotionEvent event, Runnable finishedCallback) {
+            finishedCallback.run();
+            
+            Message msg = obtainMessage(DISPATCH_POINTER);
+            msg.obj = event;
+            msg.arg1 = 0;
+            sendMessageAtTime(msg, event.getEventTime());
+        }
+
+        public void handleTrackball(MotionEvent event, Runnable finishedCallback) {
+            finishedCallback.run();
+            
+            Message msg = obtainMessage(DISPATCH_TRACKBALL);
+            msg.obj = event;
+            msg.arg1 = 0;
+            sendMessageAtTime(msg, event.getEventTime());
+        }
+    };
 
     public void dispatchKey(KeyEvent event) {
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
@@ -2968,7 +3048,7 @@
         }
     }
 
-    static class EventCompletion extends Handler {
+    class EventCompletion extends Handler {
         final IWindow mWindow;
         final KeyEvent mKeyEvent;
         final boolean mIsPointer;
@@ -2987,40 +3067,25 @@
         @Override
         public void handleMessage(Message msg) {
             if (mKeyEvent != null) {
-                try {
-                    sWindowSession.finishKey(mWindow);
-                 } catch (RemoteException e) {
-                 }
+                finishKeyEvent(mKeyEvent);
            } else if (mIsPointer) {
                 boolean didFinish;
                 MotionEvent event = mMotionEvent;
                 if (event == null) {
-                    try {
-                        event = sWindowSession.getPendingPointerMove(mWindow);
-                    } catch (RemoteException e) {
-                    }
+                    event = getPendingPointerMotionEvent();
                     didFinish = true;
                 } else {
                     didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
                 }
                 if (!didFinish) {
-                    try {
-                        sWindowSession.finishKey(mWindow);
-                     } catch (RemoteException e) {
-                     }
+                    finishMotionEvent();
                 }
             } else {
                 MotionEvent event = mMotionEvent;
                 if (event == null) {
-                    try {
-                        event = sWindowSession.getPendingTrackballMove(mWindow);
-                    } catch (RemoteException e) {
-                    }
+                    event = getPendingTrackballMotionEvent();
                 } else {
-                    try {
-                        sWindowSession.finishKey(mWindow);
-                     } catch (RemoteException e) {
-                     }
+                    finishMotionEvent();
                 }
             }
         }
@@ -3050,7 +3115,7 @@
                 viewRoot.dispatchKey(event);
             } else {
                 Log.w("ViewRoot.W", "Key event " + event + " but no ViewRoot available!");
-                new EventCompletion(mMainLooper, this, event, false, null);
+                viewRoot.new EventCompletion(mMainLooper, this, event, false, null);
             }
         }
 
@@ -3064,7 +3129,7 @@
                 }
                 viewRoot.dispatchPointer(event, eventTime, callWhenDone);
             } else {
-                new EventCompletion(mMainLooper, this, null, true, event);
+                viewRoot.new EventCompletion(mMainLooper, this, null, true, event);
             }
         }
 
@@ -3074,7 +3139,7 @@
             if (viewRoot != null) {
                 viewRoot.dispatchTrackball(event, eventTime, callWhenDone);
             } else {
-                new EventCompletion(mMainLooper, this, null, false, event);
+                viewRoot.new EventCompletion(mMainLooper, this, null, false, event);
             }
         }
 
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index b39cb9d..431b786 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -78,6 +78,12 @@
     public final static int FLAG_BRIGHT_HERE = 0x20000000;
 
     public final static boolean WATCH_POINTER = false;
+    
+    /**
+     * Temporary flag added during the transition to the new native input dispatcher.
+     * This will be removed when the old input dispatch code is deleted.
+     */
+    public final static boolean ENABLE_NATIVE_INPUT_DISPATCH = false;
 
     // flags for interceptKeyTq
     /**
@@ -708,6 +714,8 @@
      */
     public boolean preprocessInputEventTq(RawInputEvent event);
     
+    public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
+    
     /**
      * Determine whether a given key code is used to cause an app switch
      * to occur (most often the HOME key, also often ENDCALL).  If you return
diff --git a/core/java/com/android/internal/view/BaseInputHandler.java b/core/java/com/android/internal/view/BaseInputHandler.java
new file mode 100644
index 0000000..6fe5063
--- /dev/null
+++ b/core/java/com/android/internal/view/BaseInputHandler.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.view;
+
+import android.view.InputHandler;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+/**
+ * Base do-nothing implementation of an input handler.
+ * @hide
+ */
+public abstract class BaseInputHandler implements InputHandler {
+    public void handleKey(KeyEvent event, Runnable finishedCallback) {
+        finishedCallback.run();
+    }
+    
+    public void handleTouch(MotionEvent event, Runnable finishedCallback) {
+        finishedCallback.run();
+    }
+    
+    public void handleTrackball(MotionEvent event, Runnable finishedCallback) {
+        finishedCallback.run();
+    }
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index d4545d7..d854e87 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -45,6 +45,11 @@
 	android_view_Display.cpp \
 	android_view_Surface.cpp \
 	android_view_ViewRoot.cpp \
+	android_view_InputChannel.cpp \
+	android_view_InputQueue.cpp \
+	android_view_InputTarget.cpp \
+	android_view_KeyEvent.cpp \
+	android_view_MotionEvent.cpp \
 	android_text_AndroidCharacter.cpp \
 	android_text_AndroidBidi.cpp \
 	android_text_KeyCharacterMap.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f66ed83..466642a 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -162,6 +162,11 @@
 extern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
 extern int register_android_backup_BackupHelperDispatcher(JNIEnv *env);
 extern int register_android_app_NativeActivity(JNIEnv *env);
+extern int register_android_view_InputChannel(JNIEnv* env);
+extern int register_android_view_InputQueue(JNIEnv* env);
+extern int register_android_view_InputTarget(JNIEnv* env);
+extern int register_android_view_KeyEvent(JNIEnv* env);
+extern int register_android_view_MotionEvent(JNIEnv* env);
 
 static AndroidRuntime* gCurRuntime = NULL;
 
@@ -1288,6 +1293,11 @@
     REG_JNI(register_android_backup_BackupHelperDispatcher),
     
     REG_JNI(register_android_app_NativeActivity),
+    REG_JNI(register_android_view_InputChannel),
+    REG_JNI(register_android_view_InputQueue),
+    REG_JNI(register_android_view_InputTarget),
+    REG_JNI(register_android_view_KeyEvent),
+    REG_JNI(register_android_view_MotionEvent),
 };
 
 /*
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index 8984057..030d6c7 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -14,325 +14,151 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "MQNative"
+#define LOG_TAG "MessageQueue-JNI"
 
 #include "JNIHelp.h"
 
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <fcntl.h>
-
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/SystemClock.h>
-#include <utils/Vector.h>
+#include <utils/PollLoop.h>
 #include <utils/Log.h>
-
-using namespace android;
-
-// ----------------------------------------------------------------------------
-
-static struct {
-    jclass mClass;
-
-    jfieldID mObject;   // native object attached to the DVM MessageQueue
-} gMessageQueueOffsets;
-
-static struct {
-    jclass mClass;
-    jmethodID mConstructor;
-} gKeyEventOffsets;
-
-// TODO: also MotionEvent offsets etc. a la gKeyEventOffsets
-
-static struct {
-    jclass mClass;
-    jmethodID mObtain;      // obtain(Handler h, int what, Object obj)
-} gMessageOffsets;
-
-// ----------------------------------------------------------------------------
-
-static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    if (jniThrowException(env, exc, msg) != 0)
-        assert(false);
-}
-
-// ----------------------------------------------------------------------------
-
-class MessageQueueNative {
-public:
-    MessageQueueNative(int readSocket, int writeSocket);
-    ~MessageQueueNative();
-
-    // select on all FDs until the designated time; forever if wakeupTime is < 0
-    int waitForSignal(jobject mqueue, jlong wakeupTime);
-
-    // signal the queue-ready pipe
-    void signalQueuePipe();
-
-    // Specify a new input pipe, passing in responsibility for the socket fd and
-    // ashmem region
-    int registerInputPipe(JNIEnv* env, int socketFd, int memRegionFd, jobject handler);
-
-    // Forget about this input pipe, closing the socket and ashmem region as well
-    int unregisterInputPipe(JNIEnv* env, int socketFd);
-
-    size_t numRegisteredPipes() const { return mInputPipes.size(); }
-
-private:
-    struct InputPipe {
-        int fd;
-        int region;
-        jobject handler;
-
-        InputPipe() {}
-        InputPipe(int _fd, int _r, jobject _h) : fd(_fd), region(_r), handler(_h) {}
-    };
-
-    // consume an event from a socket, put it on the DVM MessageQueue indicated,
-    // and notify the other end of the pipe that we've consumed it.
-    void queueEventFromPipe(const InputPipe& pipe, jobject mqueue);
-
-    int mQueueReadFd, mQueueWriteFd;
-    Vector<InputPipe> mInputPipes;
-};
-
-MessageQueueNative::MessageQueueNative(int readSocket, int writeSocket) 
-        : mQueueReadFd(readSocket), mQueueWriteFd(writeSocket) {
-}
-
-MessageQueueNative::~MessageQueueNative() {
-}
-
-int MessageQueueNative::waitForSignal(jobject mqueue, jlong timeoutMillis) {
-    struct timeval tv, *timeout;
-    fd_set fdset;
-
-    if (timeoutMillis < 0) {
-        timeout = NULL;
-    } else {
-        if (timeoutMillis == 0) {
-            tv.tv_sec = 0;
-            tv.tv_usec = 0;
-        } else {
-            tv.tv_sec = (timeoutMillis / 1000);
-            tv.tv_usec = (timeoutMillis - (1000 * tv.tv_sec)) * 1000;
-        }
-        timeout = &tv;
-    }
-
-    // always rebuild the fd set from scratch
-    FD_ZERO(&fdset);
-
-    // the queue signalling pipe
-    FD_SET(mQueueReadFd, &fdset);
-    int maxFd = mQueueReadFd;
-
-    // and the input sockets themselves
-    for (size_t i = 0; i < mInputPipes.size(); i++) {
-        FD_SET(mInputPipes[i].fd, &fdset);
-        if (maxFd < mInputPipes[i].fd) {
-            maxFd = mInputPipes[i].fd;
-        }
-    }
-
-    // now wait
-    int res = select(maxFd + 1, &fdset, NULL, NULL, timeout);
-
-    // Error?  Just return it and bail
-    if (res < 0) return res;
-
-    // What happened -- timeout or actual data arrived?
-    if (res == 0) {
-        // select() returned zero, which means we timed out, which means that it's time
-        // to deliver the head element that was already on the queue.  Just fall through
-        // without doing anything else.
-    } else {
-        // Data (or a queue signal) arrived!
-        //
-        // If it's data, pull the data off the pipe, build a new Message with it, put it on
-        // the DVM-side MessageQueue (pointed to by the 'mqueue' parameter), then proceed
-        // into the queue-signal case.
-        //
-        // If a queue signal arrived, just consume any data pending in that pipe and
-        // fall out.
-        bool queue_signalled = (FD_ISSET(mQueueReadFd, &fdset) != 0);
-
-        for (size_t i = 0; i < mInputPipes.size(); i++) {
-            if (FD_ISSET(mInputPipes[i].fd, &fdset)) {
-                queueEventFromPipe(mInputPipes[i], mqueue);
-                queue_signalled = true;     // we know a priori that queueing the event does this
-            }
-        }
-
-        // Okay, stuff went on the queue.  Consume the contents of the signal pipe
-        // now that we're awake and about to start dispatching messages again.
-        if (queue_signalled) {
-            uint8_t buf[16];
-            ssize_t nRead;
-            do {
-                nRead = read(mQueueReadFd, buf, sizeof(buf));
-            } while (nRead > 0); // in nonblocking mode we'll get -1 when it's drained
-        }
-    }
-
-    return 0;
-}
-
-// signals to the queue pipe are one undefined byte.  it's just a "data has arrived" token
-// and the pipe is drained on receipt of at least one signal
-void MessageQueueNative::signalQueuePipe() {
-    int dummy[1];
-    write(mQueueWriteFd, dummy, 1);
-}
-
-void MessageQueueNative::queueEventFromPipe(const InputPipe& inPipe, jobject mqueue) {
-    // !!! TODO: read the event data from the InputPipe's ashmem region, convert it to a DVM
-    // event object of the proper type [MotionEvent or KeyEvent], create a Message holding
-    // it as appropriate, point the Message to the Handler associated with this InputPipe,
-    // and call up to the DVM MessageQueue implementation to enqueue it for delivery.
-}
-
-// the number of registered pipes on success; < 0 on error
-int MessageQueueNative::registerInputPipe(JNIEnv* env,
-        int socketFd, int memRegionFd, jobject handler) {
-    // make sure this fd is not already known to us
-    for (size_t i = 0; i < mInputPipes.size(); i++) {
-        if (mInputPipes[i].fd == socketFd) {
-            LOGE("Attempt to re-register input fd %d", socketFd);
-            return -1;
-        }
-    }
-
-    mInputPipes.push( InputPipe(socketFd, memRegionFd, env->NewGlobalRef(handler)) );
-    return mInputPipes.size();
-}
-
-// Remove an input pipe from our bookkeeping.  Also closes the socket and ashmem
-// region file descriptor!
-//
-// returns the number of remaining input pipes on success; < 0 on error
-int MessageQueueNative::unregisterInputPipe(JNIEnv* env, int socketFd) {
-    for (size_t i = 0; i < mInputPipes.size(); i++) {
-        if (mInputPipes[i].fd == socketFd) {
-            close(mInputPipes[i].fd);
-            close(mInputPipes[i].region);
-            env->DeleteGlobalRef(mInputPipes[i].handler);
-            mInputPipes.removeAt(i);
-            return mInputPipes.size();
-        }
-    }
-    LOGW("Tried to unregister input pipe %d but not found!", socketFd);
-    return -1;
-}
-
-// ----------------------------------------------------------------------------
+#include "android_os_MessageQueue.h"
 
 namespace android {
-    
-static void android_os_MessageQueue_init(JNIEnv* env, jobject obj) {
-    // Create the pipe
-    int fds[2];
-    int err = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds);
-    if (err != 0) {
-        doThrow(env, "java/lang/RuntimeException", "Unable to create socket pair");
-    }
 
-    MessageQueueNative *mqn = new MessageQueueNative(fds[0], fds[1]);
-    if (mqn == NULL) {
-        close(fds[0]);
-        close(fds[1]);
-        doThrow(env, "java/lang/RuntimeException", "Unable to allocate native queue");
-    }
+// ----------------------------------------------------------------------------
 
-    int flags = fcntl(fds[0], F_GETFL);
-    fcntl(fds[0], F_SETFL, flags | O_NONBLOCK);
-    flags = fcntl(fds[1], F_GETFL);
-    fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
+static struct {
+    jclass clazz;
 
-    env->SetIntField(obj, gMessageQueueOffsets.mObject, (jint)mqn);
+    jfieldID mPtr;   // native object attached to the DVM MessageQueue
+} gMessageQueueClassInfo;
+
+// ----------------------------------------------------------------------------
+
+class NativeMessageQueue {
+public:
+    NativeMessageQueue();
+    ~NativeMessageQueue();
+
+    inline sp<PollLoop> getPollLoop() { return mPollLoop; }
+
+    bool pollOnce(int timeoutMillis);
+    void wake();
+
+private:
+    sp<PollLoop> mPollLoop;
+};
+
+// ----------------------------------------------------------------------------
+
+NativeMessageQueue::NativeMessageQueue() {
+    mPollLoop = new PollLoop();
 }
 
-static void android_os_MessageQueue_signal(JNIEnv* env, jobject obj) {
-    MessageQueueNative *mqn = (MessageQueueNative*) env->GetIntField(obj, gMessageQueueOffsets.mObject);
-    if (mqn != NULL) {
-        mqn->signalQueuePipe();
-    } else {
-        doThrow(env, "java/lang/IllegalStateException", "Queue not initialized");
-    }
+NativeMessageQueue::~NativeMessageQueue() {
 }
 
-static int android_os_MessageQueue_waitForNext(JNIEnv* env, jobject obj, jlong when) {
-    MessageQueueNative *mqn = (MessageQueueNative*) env->GetIntField(obj, gMessageQueueOffsets.mObject);
-    if (mqn != NULL) {
-        int res = mqn->waitForSignal(obj, when);
-        return res; // the DVM event, if any, has been constructed and queued now
-    }
-
-    return -1;
+bool NativeMessageQueue::pollOnce(int timeoutMillis) {
+    return mPollLoop->pollOnce(timeoutMillis);
 }
 
-static void android_os_MessageQueue_registerInputStream(JNIEnv* env, jobject obj,
-        jint socketFd, jint regionFd, jobject handler) {
-    MessageQueueNative *mqn = (MessageQueueNative*) env->GetIntField(obj, gMessageQueueOffsets.mObject);
-    if (mqn != NULL) {
-        mqn->registerInputPipe(env, socketFd, regionFd, handler);
-    } else {
-        doThrow(env, "java/lang/IllegalStateException", "Queue not initialized");
-    }
-}
-
-static void android_os_MessageQueue_unregisterInputStream(JNIEnv* env, jobject obj,
-        jint socketFd) {
-    MessageQueueNative *mqn = (MessageQueueNative*) env->GetIntField(obj, gMessageQueueOffsets.mObject);
-    if (mqn != NULL) {
-        mqn->unregisterInputPipe(env, socketFd);
-    } else {
-        doThrow(env, "java/lang/IllegalStateException", "Queue not initialized");
-    }
+void NativeMessageQueue::wake() {
+    mPollLoop->wake();
 }
 
 // ----------------------------------------------------------------------------
 
-const char* const kKeyEventPathName = "android/view/KeyEvent";
-const char* const kMessagePathName = "android/os/Message";
-const char* const kMessageQueuePathName = "android/os/MessageQueue";
+static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env,
+        jobject messageQueueObj) {
+    jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr);
+    return reinterpret_cast<NativeMessageQueue*>(intPtr);
+}
+
+static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj,
+        NativeMessageQueue* nativeMessageQueue) {
+    env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr,
+             reinterpret_cast<jint>(nativeMessageQueue));
+}
+
+sp<PollLoop> android_os_MessageQueue_getPollLoop(JNIEnv* env, jobject messageQueueObj) {
+    NativeMessageQueue* nativeMessageQueue =
+            android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj);
+    return nativeMessageQueue != NULL ? nativeMessageQueue->getPollLoop() : NULL;
+}
+
+static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) {
+    NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
+    if (! nativeMessageQueue) {
+        jniThrowRuntimeException(env, "Unable to allocate native queue");
+        return;
+    }
+
+    android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue);
+}
+
+static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) {
+    NativeMessageQueue* nativeMessageQueue =
+            android_os_MessageQueue_getNativeMessageQueue(env, obj);
+    if (nativeMessageQueue) {
+        android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL);
+        delete nativeMessageQueue;
+    }
+}
+
+static void throwQueueNotInitialized(JNIEnv* env) {
+    jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized");
+}
+
+static jboolean android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
+        jint timeoutMillis) {
+    NativeMessageQueue* nativeMessageQueue =
+            android_os_MessageQueue_getNativeMessageQueue(env, obj);
+    if (! nativeMessageQueue) {
+        throwQueueNotInitialized(env);
+        return false;
+    }
+    return nativeMessageQueue->pollOnce(timeoutMillis);
+}
+
+static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj) {
+    NativeMessageQueue* nativeMessageQueue =
+            android_os_MessageQueue_getNativeMessageQueue(env, obj);
+    if (! nativeMessageQueue) {
+        throwQueueNotInitialized(env);
+        return;
+    }
+    return nativeMessageQueue->wake();
+}
+
+// ----------------------------------------------------------------------------
 
 static JNINativeMethod gMessageQueueMethods[] = {
     /* name, signature, funcPtr */
-    { "nativeInit", "()V", (void*)android_os_MessageQueue_init },
-    { "nativeSignal", "()V", (void*)android_os_MessageQueue_signal },
-    { "nativeWaitForNext", "(J)I", (void*)android_os_MessageQueue_waitForNext },
-    { "nativeRegisterInputStream", "(IILandroid/os/Handler;)V", (void*)android_os_MessageQueue_registerInputStream },
-    { "nativeUnregisterInputStream", "(I)V", (void*)android_os_MessageQueue_unregisterInputStream },
+    { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit },
+    { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy },
+    { "nativePollOnce", "(I)Z", (void*)android_os_MessageQueue_nativePollOnce },
+    { "nativeWake", "()V", (void*)android_os_MessageQueue_nativeWake }
 };
 
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
 int register_android_os_MessageQueue(JNIEnv* env) {
-    jclass clazz;
-
-    clazz = env->FindClass(kMessageQueuePathName);
-    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.MessageQueue");
-    gMessageQueueOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
-    gMessageQueueOffsets.mObject = env->GetFieldID(clazz, "mObject", "I");
-    assert(gMessageQueueOffsets.mObject);
-
-    clazz = env->FindClass(kMessagePathName);
-    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Message");
-    gMessageOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
-    gMessageOffsets.mObtain = env->GetStaticMethodID(clazz, "obtain",
-            "(Landroid/os/Handler;ILjava/lang/Object;)Landroid/os/Message;");
-    assert(gMessageOffsets.mObtain);
-
-    clazz = env->FindClass(kKeyEventPathName);
-    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.view.KeyEvent");
-    gKeyEventOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
-    gKeyEventOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(JJIIIIIII)V");
-    assert(gKeyEventOffsets.mConstructor);
-    
-    return AndroidRuntime::registerNativeMethods(env, kMessageQueuePathName,
+    int res = jniRegisterNativeMethods(env, "android/os/MessageQueue",
             gMessageQueueMethods, NELEM(gMessageQueueMethods));
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    FIND_CLASS(gMessageQueueClassInfo.clazz, "android/os/MessageQueue");
+
+    GET_FIELD_ID(gMessageQueueClassInfo.mPtr, gMessageQueueClassInfo.clazz,
+            "mPtr", "I");
+    
+    return 0;
 }
 
-
-}; // end of namespace android
+} // namespace android
diff --git a/core/jni/android_os_MessageQueue.h b/core/jni/android_os_MessageQueue.h
new file mode 100644
index 0000000..5c742e2
--- /dev/null
+++ b/core/jni/android_os_MessageQueue.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_OS_MESSAGEQUEUE_H
+#define _ANDROID_OS_MESSAGEQUEUE_H
+
+#include "jni.h"
+
+namespace android {
+
+class PollLoop;
+
+extern sp<PollLoop> android_os_MessageQueue_getPollLoop(JNIEnv* env, jobject messageQueueObj);
+
+} // namespace android
+
+#endif // _ANDROID_OS_MESSAGEQUEUE_H
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
new file mode 100644
index 0000000..47bb073
--- /dev/null
+++ b/core/jni/android_view_InputChannel.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputChannel-JNI"
+
+#include "JNIHelp.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <binder/Parcel.h>
+#include <utils/Log.h>
+#include <ui/InputTransport.h>
+#include "android_view_InputChannel.h"
+#include "android_util_Binder.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+    jclass clazz;
+
+    jfieldID mPtr;   // native object attached to the DVM InputChannel
+    jmethodID ctor;
+} gInputChannelClassInfo;
+
+// ----------------------------------------------------------------------------
+
+class NativeInputChannel {
+public:
+    NativeInputChannel(const sp<InputChannel>& inputChannel);
+    ~NativeInputChannel();
+
+    inline sp<InputChannel> getInputChannel() { return mInputChannel; }
+
+    void setDisposeCallback(InputChannelObjDisposeCallback callback, void* data);
+    void invokeAndRemoveDisposeCallback(JNIEnv* env, jobject obj);
+
+private:
+    sp<InputChannel> mInputChannel;
+    InputChannelObjDisposeCallback mDisposeCallback;
+    void* mDisposeData;
+};
+
+// ----------------------------------------------------------------------------
+
+NativeInputChannel::NativeInputChannel(const sp<InputChannel>& inputChannel) :
+    mInputChannel(inputChannel), mDisposeCallback(NULL) {
+}
+
+NativeInputChannel::~NativeInputChannel() {
+}
+
+void NativeInputChannel::setDisposeCallback(InputChannelObjDisposeCallback callback, void* data) {
+    mDisposeCallback = callback;
+    mDisposeData = data;
+}
+
+void NativeInputChannel::invokeAndRemoveDisposeCallback(JNIEnv* env, jobject obj) {
+    if (mDisposeCallback) {
+        mDisposeCallback(env, obj, mInputChannel, mDisposeData);
+        mDisposeCallback = NULL;
+        mDisposeData = NULL;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+static NativeInputChannel* android_view_InputChannel_getNativeInputChannel(JNIEnv* env,
+        jobject inputChannelObj) {
+    jint intPtr = env->GetIntField(inputChannelObj, gInputChannelClassInfo.mPtr);
+    return reinterpret_cast<NativeInputChannel*>(intPtr);
+}
+
+static void android_view_InputChannel_setNativeInputChannel(JNIEnv* env, jobject inputChannelObj,
+        NativeInputChannel* nativeInputChannel) {
+    env->SetIntField(inputChannelObj, gInputChannelClassInfo.mPtr,
+             reinterpret_cast<jint>(nativeInputChannel));
+}
+
+sp<InputChannel> android_view_InputChannel_getInputChannel(JNIEnv* env, jobject inputChannelObj) {
+    NativeInputChannel* nativeInputChannel =
+            android_view_InputChannel_getNativeInputChannel(env, inputChannelObj);
+    return nativeInputChannel != NULL ? nativeInputChannel->getInputChannel() : NULL;
+}
+
+void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChannelObj,
+        InputChannelObjDisposeCallback callback, void* data) {
+    NativeInputChannel* nativeInputChannel =
+            android_view_InputChannel_getNativeInputChannel(env, inputChannelObj);
+    if (nativeInputChannel == NULL) {
+        LOGW("Cannot set dispose callback because input channel object has not been initialized.");
+    } else {
+        nativeInputChannel->setDisposeCallback(callback, data);
+    }
+}
+
+static jobject android_view_InputChannel_createInputChannel(JNIEnv* env,
+        NativeInputChannel* nativeInputChannel) {
+    jobject inputChannelObj = env->NewObject(gInputChannelClassInfo.clazz,
+            gInputChannelClassInfo.ctor);
+    android_view_InputChannel_setNativeInputChannel(env, inputChannelObj, nativeInputChannel);
+    return inputChannelObj;
+}
+
+static jobjectArray android_view_InputChannel_nativeOpenInputChannelPair(JNIEnv* env,
+        jclass clazz, jstring nameObj) {
+    const char* nameChars = env->GetStringUTFChars(nameObj, NULL);
+    String8 name(nameChars);
+    env->ReleaseStringUTFChars(nameObj, nameChars);
+
+    InputChannel* serverChannel;
+    InputChannel* clientChannel;
+    status_t result = InputChannel::openInputChannelPair(name, & serverChannel, & clientChannel);
+
+    if (result) {
+        LOGE("Could not open input channel pair.  status=%d", result);
+        jniThrowRuntimeException(env, "Could not open input channel pair.");
+        return NULL;
+    }
+
+    // TODO more robust error checking
+    jobject serverChannelObj = android_view_InputChannel_createInputChannel(env,
+            new NativeInputChannel(serverChannel));
+    jobject clientChannelObj = android_view_InputChannel_createInputChannel(env,
+            new NativeInputChannel(clientChannel));
+
+    jobjectArray channelPair = env->NewObjectArray(2, gInputChannelClassInfo.clazz, NULL);
+    env->SetObjectArrayElement(channelPair, 0, serverChannelObj);
+    env->SetObjectArrayElement(channelPair, 1, clientChannelObj);
+    return channelPair;
+}
+
+static void android_view_InputChannel_nativeDispose(JNIEnv* env, jobject obj, jboolean finalized) {
+    NativeInputChannel* nativeInputChannel =
+            android_view_InputChannel_getNativeInputChannel(env, obj);
+    if (nativeInputChannel) {
+        if (finalized) {
+            LOGW("Input channel object '%s' was finalized without being disposed!",
+                    nativeInputChannel->getInputChannel()->getName().string());
+        }
+
+        nativeInputChannel->invokeAndRemoveDisposeCallback(env, obj);
+
+        android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
+        delete nativeInputChannel;
+    }
+}
+
+static void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj,
+        jobject otherObj) {
+    if (android_view_InputChannel_getInputChannel(env, otherObj) != NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Other object already has a native input channel.");
+        return;
+    }
+
+    NativeInputChannel* nativeInputChannel =
+            android_view_InputChannel_getNativeInputChannel(env, obj);
+    android_view_InputChannel_setNativeInputChannel(env, otherObj, nativeInputChannel);
+    android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
+}
+
+static void android_view_InputChannel_nativeReadFromParcel(JNIEnv* env, jobject obj,
+        jobject parcelObj) {
+    if (android_view_InputChannel_getInputChannel(env, obj) != NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "This object already has a native input channel.");
+        return;
+    }
+
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel) {
+        bool isInitialized = parcel->readInt32();
+        if (isInitialized) {
+            String8 name = parcel->readString8();
+            int32_t ashmemFd = dup(parcel->readFileDescriptor());
+            int32_t receivePipeFd = dup(parcel->readFileDescriptor());
+            int32_t sendPipeFd = dup(parcel->readFileDescriptor());
+            if (ashmemFd < 0 || receivePipeFd < 0 || sendPipeFd < 0) {
+                if (ashmemFd >= 0) ::close(ashmemFd);
+                if (receivePipeFd >= 0) ::close(receivePipeFd);
+                if (sendPipeFd >= 0) ::close(sendPipeFd);
+                jniThrowRuntimeException(env,
+                        "Could not read input channel file descriptors from parcel.");
+                return;
+            }
+
+            InputChannel* inputChannel = new InputChannel(name, ashmemFd,
+                    receivePipeFd, sendPipeFd);
+            NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel);
+
+            android_view_InputChannel_setNativeInputChannel(env, obj, nativeInputChannel);
+        }
+    }
+}
+
+static void android_view_InputChannel_nativeWriteToParcel(JNIEnv* env, jobject obj,
+        jobject parcelObj) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel) {
+        NativeInputChannel* nativeInputChannel =
+                android_view_InputChannel_getNativeInputChannel(env, obj);
+        if (nativeInputChannel) {
+            sp<InputChannel> inputChannel = nativeInputChannel->getInputChannel();
+
+            parcel->writeInt32(1);
+            parcel->writeString8(inputChannel->getName());
+            parcel->writeDupFileDescriptor(inputChannel->getAshmemFd());
+            parcel->writeDupFileDescriptor(inputChannel->getReceivePipeFd());
+            parcel->writeDupFileDescriptor(inputChannel->getSendPipeFd());
+        } else {
+            parcel->writeInt32(0);
+        }
+    }
+}
+
+static jstring android_view_InputChannel_nativeGetName(JNIEnv* env, jobject obj) {
+    NativeInputChannel* nativeInputChannel =
+            android_view_InputChannel_getNativeInputChannel(env, obj);
+    if (! nativeInputChannel) {
+        return NULL;
+    }
+
+    jstring name = env->NewStringUTF(nativeInputChannel->getInputChannel()->getName().string());
+    return name;
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gInputChannelMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeOpenInputChannelPair", "(Ljava/lang/String;)[Landroid/view/InputChannel;",
+            (void*)android_view_InputChannel_nativeOpenInputChannelPair },
+    { "nativeDispose", "(Z)V",
+            (void*)android_view_InputChannel_nativeDispose },
+    { "nativeTransferTo", "(Landroid/view/InputChannel;)V",
+            (void*)android_view_InputChannel_nativeTransferTo },
+    { "nativeReadFromParcel", "(Landroid/os/Parcel;)V",
+            (void*)android_view_InputChannel_nativeReadFromParcel },
+    { "nativeWriteToParcel", "(Landroid/os/Parcel;)V",
+            (void*)android_view_InputChannel_nativeWriteToParcel },
+    { "nativeGetName", "()Ljava/lang/String;",
+            (void*)android_view_InputChannel_nativeGetName },
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method " methodName);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_view_InputChannel(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "android/view/InputChannel",
+            gInputChannelMethods, NELEM(gInputChannelMethods));
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    FIND_CLASS(gInputChannelClassInfo.clazz, "android/view/InputChannel");
+
+    GET_FIELD_ID(gInputChannelClassInfo.mPtr, gInputChannelClassInfo.clazz,
+            "mPtr", "I");
+    
+    GET_METHOD_ID(gInputChannelClassInfo.ctor, gInputChannelClassInfo.clazz,
+            "<init>", "()V");
+
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_InputChannel.h b/core/jni/android_view_InputChannel.h
new file mode 100644
index 0000000..ac1defb
--- /dev/null
+++ b/core/jni/android_view_InputChannel.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_VIEW_INPUTCHANNEL_H
+#define _ANDROID_VIEW_INPUTCHANNEL_H
+
+#include "jni.h"
+
+namespace android {
+
+class InputChannel;
+
+typedef void (*InputChannelObjDisposeCallback)(JNIEnv* env, jobject inputChannelObj,
+        const sp<InputChannel>& inputChannel, void* data);
+
+extern sp<InputChannel> android_view_InputChannel_getInputChannel(JNIEnv* env,
+        jobject inputChannelObj);
+
+/* Sets a callback that is invoked when the InputChannel DVM object is disposed (or finalized).
+ * This is used to automatically dispose of other native objects in the input dispatcher
+ * and input queue to prevent memory leaks. */
+extern void android_view_InputChannel_setDisposeCallback(JNIEnv* env, jobject inputChannelObj,
+        InputChannelObjDisposeCallback callback, void* data = NULL);
+
+} // namespace android
+
+#endif // _ANDROID_OS_INPUTCHANNEL_H
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
new file mode 100644
index 0000000..9cbde25
--- /dev/null
+++ b/core/jni/android_view_InputQueue.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputQueue-JNI"
+
+//#define LOG_NDEBUG 0
+
+// Log debug messages about the dispatch cycle.
+#define DEBUG_DISPATCH_CYCLE 1
+
+
+#include "JNIHelp.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/Log.h>
+#include <utils/PollLoop.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <ui/InputTransport.h>
+#include "android_os_MessageQueue.h"
+#include "android_view_InputChannel.h"
+#include "android_view_KeyEvent.h"
+#include "android_view_MotionEvent.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+    jclass clazz;
+
+    jmethodID dispatchKeyEvent;
+    jmethodID dispatchMotionEvent;
+} gInputQueueClassInfo;
+
+// ----------------------------------------------------------------------------
+
+class NativeInputQueue {
+public:
+    NativeInputQueue();
+    virtual ~NativeInputQueue();
+
+    status_t registerInputChannel(JNIEnv* env, jobject inputChannelObj,
+            jobject inputHandlerObj, jobject messageQueueObj);
+
+    status_t unregisterInputChannel(JNIEnv* env, jobject inputChannelObj);
+
+    status_t finished(JNIEnv* env, jlong finishedToken, bool ignoreSpuriousFinish);
+
+private:
+    class Connection : public RefBase {
+    protected:
+        virtual ~Connection();
+
+    public:
+        enum Status {
+            // Everything is peachy.
+            STATUS_NORMAL,
+            // The input channel has been unregistered.
+            STATUS_ZOMBIE
+        };
+
+        Connection(const sp<InputChannel>& inputChannel, const sp<PollLoop>& pollLoop);
+
+        inline const char* getInputChannelName() { return inputChannel->getName().string(); }
+
+        Status status;
+
+        sp<InputChannel> inputChannel;
+        InputConsumer inputConsumer;
+        sp<PollLoop> pollLoop;
+        jobject inputHandlerObjGlobal;
+        PreallocatedInputEventFactory inputEventFactory;
+
+        // The sequence number of the current event being dispatched.
+        // This is used as part of the finished token as a way to determine whether the finished
+        // token is still valid before sending a finished signal back to the publisher.
+        uint32_t messageSeqNum;
+
+        // True if a message has been received from the publisher but not yet finished.
+        bool messageInProgress;
+    };
+
+    Mutex mLock;
+    KeyedVector<int32_t, sp<Connection> > mConnectionsByReceiveFd;
+
+    static void handleInputChannelDisposed(JNIEnv* env,
+            jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data);
+
+    static bool handleReceiveCallback(int receiveFd, int events, void* data);
+
+    static jlong generateFinishedToken(int32_t receiveFd, int32_t messageSeqNum);
+
+    static void parseFinishedToken(jlong finishedToken,
+            int32_t* outReceiveFd, uint32_t* outMessageIndex);
+};
+
+// ----------------------------------------------------------------------------
+
+NativeInputQueue::NativeInputQueue() {
+}
+
+NativeInputQueue::~NativeInputQueue() {
+}
+
+status_t NativeInputQueue::registerInputChannel(JNIEnv* env, jobject inputChannelObj,
+        jobject inputHandlerObj, jobject messageQueueObj) {
+    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
+            inputChannelObj);
+    if (inputChannel == NULL) {
+        LOGW("Input channel is not initialized.");
+        return BAD_VALUE;
+    }
+
+    sp<PollLoop> pollLoop = android_os_MessageQueue_getPollLoop(env, messageQueueObj);
+
+    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, pollLoop);
+        status_t result = connection->inputConsumer.initialize();
+        if (result) {
+            LOGW("Failed to initialize input consumer for input channel '%s', status=%d",
+                    inputChannel->getName().string(), result);
+            return result;
+        }
+
+        connection->inputHandlerObjGlobal = env->NewGlobalRef(inputHandlerObj);
+
+        mConnectionsByReceiveFd.add(receiveFd, connection);
+    } // release lock
+
+    android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
+            handleInputChannelDisposed, this);
+
+    pollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, NULL);
+    return OK;
+}
+
+status_t NativeInputQueue::unregisterInputChannel(JNIEnv* env, jobject inputChannelObj) {
+    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
+            inputChannelObj);
+    if (inputChannel == NULL) {
+        LOGW("Input channel is not initialized.");
+        return BAD_VALUE;
+    }
+
+    int32_t receiveFd;
+    sp<Connection> connection;
+    { // 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;
+        }
+
+        connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+        mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
+
+        connection->status = Connection::STATUS_ZOMBIE;
+
+        env->DeleteGlobalRef(connection->inputHandlerObjGlobal);
+        connection->inputHandlerObjGlobal = NULL;
+    } // release lock
+
+    android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
+
+    connection->pollLoop->removeCallback(receiveFd);
+    return OK;
+}
+
+status_t NativeInputQueue::finished(JNIEnv* env, jlong finishedToken, bool ignoreSpuriousFinish) {
+    int32_t receiveFd;
+    uint32_t messageSeqNum;
+    parseFinishedToken(finishedToken, &receiveFd, &messageSeqNum);
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
+        if (connectionIndex < 0) {
+            if (! ignoreSpuriousFinish) {
+                LOGW("Attempted to finish input on channel that is no longer registered.");
+            }
+            return DEAD_OBJECT;
+        }
+
+        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+        if (messageSeqNum != connection->messageSeqNum || ! connection->messageInProgress) {
+            if (! ignoreSpuriousFinish) {
+                LOGW("Attempted to finish input twice on channel '%s'.",
+                        connection->getInputChannelName());
+            }
+            return INVALID_OPERATION;
+        }
+
+        connection->messageInProgress = false;
+
+        status_t status = connection->inputConsumer.sendFinishedSignal();
+        if (status) {
+            LOGW("Failed to send finished signal on channel '%s'.  status=%d",
+                    connection->getInputChannelName(), status);
+            return status;
+        }
+
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Finished event.",
+                connection->getInputChannelName());
+#endif
+    } // release lock
+
+    return OK;
+}
+
+void NativeInputQueue::handleInputChannelDisposed(JNIEnv* env,
+        jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
+    LOGW("Input channel object '%s' was disposed without first being unregistered with "
+            "the input queue!", inputChannel->getName().string());
+
+    NativeInputQueue* q = static_cast<NativeInputQueue*>(data);
+    q->unregisterInputChannel(env, inputChannelObj);
+}
+
+bool NativeInputQueue::handleReceiveCallback(int receiveFd, int events, void* data) {
+    NativeInputQueue* q = static_cast<NativeInputQueue*>(data);
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+    sp<Connection> connection;
+    InputEvent* inputEvent;
+    jobject inputHandlerObjLocal;
+    jlong finishedToken;
+    { // acquire lock
+        AutoMutex _l(q->mLock);
+
+        ssize_t connectionIndex = q->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
+        }
+
+        connection = q->mConnectionsByReceiveFd.valueAt(connectionIndex);
+        if (events & (POLLERR | POLLHUP | POLLNVAL)) {
+            LOGE("channel '%s' ~ Publisher closed input channel or an error occurred.  "
+                    "events=0x%x", connection->getInputChannelName(), events);
+            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->inputConsumer.receiveDispatchSignal();
+        if (status) {
+            LOGE("channel '%s' ~ Failed to receive dispatch signal.  status=%d",
+                    connection->getInputChannelName(), status);
+            return false; // remove the callback
+        }
+
+        if (connection->messageInProgress) {
+            LOGW("channel '%s' ~ Publisher sent spurious dispatch signal.",
+                    connection->getInputChannelName());
+            return true;
+        }
+
+        status = connection->inputConsumer.consume(& connection->inputEventFactory, & inputEvent);
+        if (status) {
+            LOGW("channel '%s' ~ Failed to consume input event.  status=%d",
+                    connection->getInputChannelName(), status);
+            connection->inputConsumer.sendFinishedSignal();
+            return true;
+        }
+
+        connection->messageInProgress = true;
+        connection->messageSeqNum += 1;
+
+        finishedToken = generateFinishedToken(receiveFd, connection->messageSeqNum);
+
+        inputHandlerObjLocal = env->NewLocalRef(connection->inputHandlerObjGlobal);
+    } // release lock
+
+    // Invoke the handler outside of the lock.
+    //
+    // Note: inputEvent is stored in a field of the connection object which could potentially
+    //       become disposed due to the input channel being unregistered concurrently.
+    //       For this reason, we explicitly keep the connection object alive by holding
+    //       a strong pointer to it within this scope.  We also grabbed a local reference to
+    //       the input handler object itself for the same reason.
+
+    int32_t inputEventType = inputEvent->getType();
+    int32_t inputEventNature = inputEvent->getNature();
+
+    jobject inputEventObj;
+    jmethodID dispatchMethodId;
+    switch (inputEventType) {
+    case INPUT_EVENT_TYPE_KEY:
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Received key event.", connection->getInputChannelName());
+#endif
+        inputEventObj = android_view_KeyEvent_fromNative(env,
+                static_cast<KeyEvent*>(inputEvent));
+        dispatchMethodId = gInputQueueClassInfo.dispatchKeyEvent;
+        break;
+
+    case INPUT_EVENT_TYPE_MOTION:
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Received motion event.", connection->getInputChannelName());
+#endif
+        inputEventObj = android_view_MotionEvent_fromNative(env,
+                static_cast<MotionEvent*>(inputEvent));
+        dispatchMethodId = gInputQueueClassInfo.dispatchMotionEvent;
+        break;
+
+    default:
+        assert(false); // InputConsumer should prevent this from ever happening
+        inputEventObj = NULL;
+    }
+
+    if (! inputEventObj) {
+        LOGW("channel '%s' ~ Failed to obtain DVM event object.",
+                connection->getInputChannelName());
+        env->DeleteLocalRef(inputHandlerObjLocal);
+        q->finished(env, finishedToken, false);
+        return true;
+    }
+
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("Invoking input handler.");
+#endif
+    env->CallStaticVoidMethod(gInputQueueClassInfo.clazz,
+            dispatchMethodId, inputHandlerObjLocal, inputEventObj,
+            jint(inputEventNature), jlong(finishedToken));
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("Returned from input handler.");
+#endif
+
+    if (env->ExceptionCheck()) {
+        LOGE("An exception occurred while invoking the input handler for an event.");
+        LOGE_EX(env);
+        env->ExceptionClear();
+
+        q->finished(env, finishedToken, true /*ignoreSpuriousFinish*/);
+    }
+
+    env->DeleteLocalRef(inputEventObj);
+    env->DeleteLocalRef(inputHandlerObjLocal);
+    return true;
+}
+
+jlong NativeInputQueue::generateFinishedToken(int32_t receiveFd, int32_t messageSeqNum) {
+    return (jlong(receiveFd) << 32) | jlong(messageSeqNum);
+}
+
+void NativeInputQueue::parseFinishedToken(jlong finishedToken,
+        int32_t* outReceiveFd, uint32_t* outMessageIndex) {
+    *outReceiveFd = int32_t(finishedToken >> 32);
+    *outMessageIndex = uint32_t(finishedToken & 0xffffffff);
+}
+
+// ----------------------------------------------------------------------------
+
+NativeInputQueue::Connection::Connection(const sp<InputChannel>& inputChannel, const sp<PollLoop>& pollLoop) :
+    status(STATUS_NORMAL), inputChannel(inputChannel), inputConsumer(inputChannel),
+    pollLoop(pollLoop), inputHandlerObjGlobal(NULL),
+    messageSeqNum(0), messageInProgress(false) {
+}
+
+NativeInputQueue::Connection::~Connection() {
+}
+
+// ----------------------------------------------------------------------------
+
+static NativeInputQueue gNativeInputQueue;
+
+static void android_view_InputQueue_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
+        jobject inputChannelObj, jobject inputHandlerObj, jobject messageQueueObj) {
+    status_t status = gNativeInputQueue.registerInputChannel(
+            env, inputChannelObj, inputHandlerObj, messageQueueObj);
+    if (status) {
+        jniThrowRuntimeException(env, "Failed to register input channel.  "
+                "Check logs for details.");
+    }
+}
+
+static void android_view_InputQueue_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
+        jobject inputChannelObj) {
+    status_t status = gNativeInputQueue.unregisterInputChannel(env, inputChannelObj);
+    if (status) {
+        jniThrowRuntimeException(env, "Failed to unregister input channel.  "
+                "Check logs for details.");
+    }
+}
+
+static void android_view_InputQueue_nativeFinished(JNIEnv* env, jclass clazz,
+        jlong finishedToken) {
+    status_t status = gNativeInputQueue.finished(
+            env, finishedToken, false /*ignoreSpuriousFinish*/);
+    if (status) {
+        jniThrowRuntimeException(env, "Failed to finish input event.  "
+                "Check logs for details.");
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gInputQueueMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeRegisterInputChannel",
+            "(Landroid/view/InputChannel;Landroid/view/InputHandler;Landroid/os/MessageQueue;)V",
+            (void*)android_view_InputQueue_nativeRegisterInputChannel },
+    { "nativeUnregisterInputChannel",
+            "(Landroid/view/InputChannel;)V",
+            (void*)android_view_InputQueue_nativeUnregisterInputChannel },
+    { "nativeFinished", "(J)V",
+            (void*)android_view_InputQueue_nativeFinished }
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find static method " methodName);
+
+int register_android_view_InputQueue(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "android/view/InputQueue",
+            gInputQueueMethods, NELEM(gInputQueueMethods));
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    FIND_CLASS(gInputQueueClassInfo.clazz, "android/view/InputQueue");
+
+    GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchKeyEvent, gInputQueueClassInfo.clazz,
+            "dispatchKeyEvent",
+            "(Landroid/view/InputHandler;Landroid/view/KeyEvent;IJ)V");
+
+    GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchMotionEvent, gInputQueueClassInfo.clazz,
+            "dispatchMotionEvent",
+            "(Landroid/view/InputHandler;Landroid/view/MotionEvent;IJ)V");
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_InputTarget.cpp b/core/jni/android_view_InputTarget.cpp
new file mode 100644
index 0000000..e2a1f23
--- /dev/null
+++ b/core/jni/android_view_InputTarget.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputTarget-JNI"
+
+#include "JNIHelp.h"
+
+#include <utils/Log.h>
+#include <ui/InputDispatchPolicy.h>
+#include <ui/InputTransport.h>
+#include "android_view_InputTarget.h"
+#include "android_view_InputChannel.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+    jclass clazz;
+
+    jfieldID mInputChannel;
+    jfieldID mFlags;
+    jfieldID mTimeoutNanos;
+    jfieldID mXOffset;
+    jfieldID mYOffset;
+} gInputTargetClassInfo;
+
+// ----------------------------------------------------------------------------
+
+void android_view_InputTarget_toNative(JNIEnv* env, jobject inputTargetObj,
+        InputTarget* outInputTarget) {
+    jobject inputChannelObj = env->GetObjectField(inputTargetObj,
+            gInputTargetClassInfo.mInputChannel);
+    jint flags = env->GetIntField(inputTargetObj,
+            gInputTargetClassInfo.mFlags);
+    jlong timeoutNanos = env->GetLongField(inputTargetObj,
+            gInputTargetClassInfo.mTimeoutNanos);
+    jfloat xOffset = env->GetFloatField(inputTargetObj,
+            gInputTargetClassInfo.mXOffset);
+    jfloat yOffset = env->GetFloatField(inputTargetObj,
+            gInputTargetClassInfo.mYOffset);
+
+    outInputTarget->inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj);
+    outInputTarget->flags = flags;
+    outInputTarget->timeout = timeoutNanos;
+    outInputTarget->xOffset = xOffset;
+    outInputTarget->yOffset = yOffset;
+
+    env->DeleteLocalRef(inputChannelObj);
+}
+
+// ----------------------------------------------------------------------------
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_view_InputTarget(JNIEnv* env) {
+    FIND_CLASS(gInputTargetClassInfo.clazz, "android/view/InputTarget");
+
+    GET_FIELD_ID(gInputTargetClassInfo.mInputChannel, gInputTargetClassInfo.clazz,
+            "mInputChannel", "Landroid/view/InputChannel;");
+
+    GET_FIELD_ID(gInputTargetClassInfo.mFlags, gInputTargetClassInfo.clazz,
+            "mFlags", "I");
+
+    GET_FIELD_ID(gInputTargetClassInfo.mTimeoutNanos, gInputTargetClassInfo.clazz,
+            "mTimeoutNanos", "J");
+
+    GET_FIELD_ID(gInputTargetClassInfo.mXOffset, gInputTargetClassInfo.clazz,
+            "mXOffset", "F");
+
+    GET_FIELD_ID(gInputTargetClassInfo.mYOffset, gInputTargetClassInfo.clazz,
+            "mYOffset", "F");
+    
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_InputTarget.h b/core/jni/android_view_InputTarget.h
new file mode 100644
index 0000000..9230b1b
--- /dev/null
+++ b/core/jni/android_view_InputTarget.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_VIEW_INPUTTARGET_H
+#define _ANDROID_VIEW_INPUTTARGET_H
+
+#include "jni.h"
+
+namespace android {
+
+class InputTarget;
+
+extern void android_view_InputTarget_toNative(JNIEnv* env, jobject inputTargetObj,
+        InputTarget* outInputTarget);
+
+} // namespace android
+
+#endif // _ANDROID_OS_INPUTTARGET_H
diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp
new file mode 100644
index 0000000..df3b952
--- /dev/null
+++ b/core/jni/android_view_KeyEvent.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "KeyEvent-JNI"
+
+#include "JNIHelp.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/Log.h>
+#include <ui/Input.h>
+#include "android_view_KeyEvent.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+    jclass clazz;
+
+    jmethodID ctor;
+
+    jfieldID mMetaState;
+    jfieldID mAction;
+    jfieldID mKeyCode;
+    jfieldID mScanCode;
+    jfieldID mRepeatCount;
+    jfieldID mDeviceId;
+    jfieldID mFlags;
+    jfieldID mDownTime;
+    jfieldID mEventTime;
+    jfieldID mCharacters;
+} gKeyEventClassInfo;
+
+// ----------------------------------------------------------------------------
+
+jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) {
+    return env->NewObject(gKeyEventClassInfo.clazz, gKeyEventClassInfo.ctor,
+            nanoseconds_to_milliseconds(event->getDownTime()),
+            nanoseconds_to_milliseconds(event->getEventTime()),
+            event->getAction(),
+            event->getKeyCode(),
+            event->getRepeatCount(),
+            event->getMetaState(),
+            event->getDeviceId(),
+            event->getScanCode(),
+            event->getFlags());
+}
+
+void android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature,
+        KeyEvent* event) {
+    jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState);
+    jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction);
+    jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode);
+    jint scanCode = env->GetIntField(eventObj, gKeyEventClassInfo.mScanCode);
+    jint repeatCount = env->GetIntField(eventObj, gKeyEventClassInfo.mRepeatCount);
+    jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId);
+    jint flags = env->GetIntField(eventObj, gKeyEventClassInfo.mFlags);
+    jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime);
+    jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime);
+
+    event->initialize(deviceId, nature, action, flags, keyCode, scanCode, metaState, repeatCount,
+            milliseconds_to_nanoseconds(downTime),
+            milliseconds_to_nanoseconds(eventTime));
+}
+
+// ----------------------------------------------------------------------------
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
+        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method" methodName);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_view_KeyEvent(JNIEnv* env) {
+    FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
+
+    GET_METHOD_ID(gKeyEventClassInfo.ctor, gKeyEventClassInfo.clazz,
+            "<init>", "(JJIIIIIII)V");
+
+    GET_FIELD_ID(gKeyEventClassInfo.mMetaState, gKeyEventClassInfo.clazz,
+            "mMetaState", "I");
+    GET_FIELD_ID(gKeyEventClassInfo.mAction, gKeyEventClassInfo.clazz,
+            "mAction", "I");
+    GET_FIELD_ID(gKeyEventClassInfo.mKeyCode, gKeyEventClassInfo.clazz,
+            "mKeyCode", "I");
+    GET_FIELD_ID(gKeyEventClassInfo.mScanCode, gKeyEventClassInfo.clazz,
+            "mScanCode", "I");
+    GET_FIELD_ID(gKeyEventClassInfo.mRepeatCount, gKeyEventClassInfo.clazz,
+            "mRepeatCount", "I");
+    GET_FIELD_ID(gKeyEventClassInfo.mDeviceId, gKeyEventClassInfo.clazz,
+            "mDeviceId", "I");
+    GET_FIELD_ID(gKeyEventClassInfo.mFlags, gKeyEventClassInfo.clazz,
+            "mFlags", "I");
+    GET_FIELD_ID(gKeyEventClassInfo.mDownTime, gKeyEventClassInfo.clazz,
+            "mDownTime", "J");
+    GET_FIELD_ID(gKeyEventClassInfo.mEventTime, gKeyEventClassInfo.clazz,
+            "mEventTime", "J");
+    GET_FIELD_ID(gKeyEventClassInfo.mCharacters, gKeyEventClassInfo.clazz,
+            "mCharacters", "Ljava/lang/String;");
+
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_KeyEvent.h b/core/jni/android_view_KeyEvent.h
new file mode 100644
index 0000000..3c71b1a
--- /dev/null
+++ b/core/jni/android_view_KeyEvent.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_VIEW_KEYEVENT_H
+#define _ANDROID_VIEW_KEYEVENT_H
+
+#include "jni.h"
+
+namespace android {
+
+class KeyEvent;
+
+/* Obtains an instance of a DVM KeyEvent object as a copy of a native KeyEvent instance. */
+extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event);
+
+/* Copies the contents of a DVM KeyEvent object to a native KeyEvent instance. */
+extern void android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature,
+        KeyEvent* event);
+
+} // namespace android
+
+#endif // _ANDROID_OS_KEYEVENT_H
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
new file mode 100644
index 0000000..629c8fe
--- /dev/null
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -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.
+ */
+
+#define LOG_TAG "MotionEvent-JNI"
+
+#include "JNIHelp.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/Log.h>
+#include <ui/Input.h>
+#include "android_view_MotionEvent.h"
+
+// Number of float items per entry in a DVM sample data array
+#define NUM_SAMPLE_DATA 4
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+    jclass clazz;
+
+    jmethodID obtain;
+    jmethodID recycle;
+
+    jfieldID mDownTime;
+    jfieldID mEventTimeNano;
+    jfieldID mAction;
+    jfieldID mRawX;
+    jfieldID mRawY;
+    jfieldID mXPrecision;
+    jfieldID mYPrecision;
+    jfieldID mDeviceId;
+    jfieldID mEdgeFlags;
+    jfieldID mMetaState;
+    jfieldID mNumPointers;
+    jfieldID mNumSamples;
+    jfieldID mPointerIdentifiers;
+    jfieldID mDataSamples;
+    jfieldID mTimeSamples;
+} gMotionEventClassInfo;
+
+// ----------------------------------------------------------------------------
+
+jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* event) {
+    jint numPointers = jint(event->getPointerCount());
+    jint numHistoricalSamples = jint(event->getHistorySize());
+    jint numSamples = numHistoricalSamples + 1;
+
+    jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
+            gMotionEventClassInfo.obtain, numPointers, numSamples);
+    if (env->ExceptionCheck()) {
+        LOGE("An exception occurred while obtaining a motion event.");
+        LOGE_EX(env);
+        env->ExceptionClear();
+        return NULL;
+    }
+
+    // MotionEvent.mEventTimeNano is the time of the oldest sample because
+    // MotionEvent.addBatch does not update it as successive samples are added.
+    jlong eventTimeNano = numHistoricalSamples != 0
+            ? event->getHistoricalEventTime(0)
+            : event->getEventTime();
+
+    env->SetLongField(eventObj, gMotionEventClassInfo.mDownTime,
+            nanoseconds_to_milliseconds(event->getDownTime()));
+    env->SetLongField(eventObj, gMotionEventClassInfo.mEventTimeNano,
+            eventTimeNano);
+    env->SetIntField(eventObj, gMotionEventClassInfo.mAction,
+            event->getAction());
+    env->SetFloatField(eventObj, gMotionEventClassInfo.mRawX,
+            event->getRawX());
+    env->SetFloatField(eventObj, gMotionEventClassInfo.mRawY,
+            event->getRawY());
+    env->SetFloatField(eventObj, gMotionEventClassInfo.mXPrecision,
+            event->getXPrecision());
+    env->SetFloatField(eventObj, gMotionEventClassInfo.mYPrecision,
+            event->getYPrecision());
+    env->SetIntField(eventObj, gMotionEventClassInfo.mDeviceId,
+            event->getDeviceId());
+    env->SetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags,
+            event->getEdgeFlags());
+    env->SetIntField(eventObj, gMotionEventClassInfo.mMetaState,
+            event->getMetaState());
+    env->SetIntField(eventObj, gMotionEventClassInfo.mNumPointers,
+            numPointers);
+    env->SetIntField(eventObj, gMotionEventClassInfo.mNumSamples,
+            numSamples);
+
+    jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj,
+            gMotionEventClassInfo.mPointerIdentifiers));
+    jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
+            gMotionEventClassInfo.mDataSamples));
+    jlongArray timeSampleArray = jlongArray(env->GetObjectField(eventObj,
+            gMotionEventClassInfo.mTimeSamples));
+
+    jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
+    jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
+    jlong* timeSamples = (jlong*)env->GetPrimitiveArrayCritical(timeSampleArray, NULL);
+
+    for (jint i = 0; i < numPointers; i++) {
+        pointerIdentifiers[i] = event->getPointerId(i);
+    }
+
+    // Most recent data is in first slot of the DVM array, followed by the oldest,
+    // and then all others are in order.
+
+    jfloat* currentDataSample = dataSamples;
+    jlong* currentTimeSample = timeSamples;
+
+    *(currentTimeSample++) = nanoseconds_to_milliseconds(event->getEventTime());
+    for (jint j = 0; j < numPointers; j++) {
+        *(currentDataSample++) = event->getX(j);
+        *(currentDataSample++) = event->getY(j);
+        *(currentDataSample++) = event->getPressure(j);
+        *(currentDataSample++) = event->getSize(j);
+    }
+
+    for (jint i = 0; i < numHistoricalSamples; i++) {
+        *(currentTimeSample++) = nanoseconds_to_milliseconds(event->getHistoricalEventTime(i));
+        for (jint j = 0; j < numPointers; j++) {
+            *(currentDataSample++) = event->getHistoricalX(j, i);
+            *(currentDataSample++) = event->getHistoricalY(j, i);
+            *(currentDataSample++) = event->getHistoricalPressure(j, i);
+            *(currentDataSample++) = event->getHistoricalSize(j, i);
+        }
+    }
+
+    env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, 0);
+    env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, 0);
+    env->ReleasePrimitiveArrayCritical(timeSampleArray, timeSamples, 0);
+
+    env->DeleteLocalRef(pointerIdentifierArray);
+    env->DeleteLocalRef(dataSampleArray);
+    env->DeleteLocalRef(timeSampleArray);
+    return eventObj;
+}
+
+void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature,
+        MotionEvent* event) {
+    // MotionEvent.mEventTimeNano is the time of the oldest sample because
+    // MotionEvent.addBatch does not update it as successive samples are added.
+    jlong downTime = env->GetLongField(eventObj, gMotionEventClassInfo.mDownTime);
+    jlong eventTimeNano = env->GetLongField(eventObj, gMotionEventClassInfo.mEventTimeNano);
+    jint action = env->GetIntField(eventObj, gMotionEventClassInfo.mAction);
+    jfloat rawX = env->GetFloatField(eventObj, gMotionEventClassInfo.mRawX);
+    jfloat rawY = env->GetFloatField(eventObj, gMotionEventClassInfo.mRawY);
+    jfloat xPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mXPrecision);
+    jfloat yPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mYPrecision);
+    jint deviceId = env->GetIntField(eventObj, gMotionEventClassInfo.mDeviceId);
+    jint edgeFlags = env->GetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags);
+    jint metaState = env->GetIntField(eventObj, gMotionEventClassInfo.mMetaState);
+    jint numPointers = env->GetIntField(eventObj, gMotionEventClassInfo.mNumPointers);
+    jint numSamples = env->GetIntField(eventObj, gMotionEventClassInfo.mNumSamples);
+    jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj,
+            gMotionEventClassInfo.mPointerIdentifiers));
+    jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
+            gMotionEventClassInfo.mDataSamples));
+    jlongArray timeSampleArray = jlongArray(env->GetObjectField(eventObj,
+            gMotionEventClassInfo.mTimeSamples));
+
+    LOG_FATAL_IF(numPointers == 0, "numPointers was zero");
+    LOG_FATAL_IF(numSamples == 0, "numSamples was zero");
+
+    jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
+    jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
+    jlong* timeSamples = (jlong*)env->GetPrimitiveArrayCritical(timeSampleArray, NULL);
+
+    // Most recent data is in first slot of the DVM array, followed by the oldest,
+    // and then all others are in order.  eventTimeNano is the time of the oldest sample
+    // since MotionEvent.addBatch does not update it.
+
+    jint numHistoricalSamples = numSamples - 1;
+    jint dataSampleStride = numPointers * NUM_SAMPLE_DATA;
+
+    const jfloat* currentDataSample;
+    const jlong* currentTimeSample;
+    if (numHistoricalSamples == 0) {
+        currentDataSample = dataSamples;
+        currentTimeSample = timeSamples;
+    } else {
+        currentDataSample = dataSamples + dataSampleStride;
+        currentTimeSample = timeSamples + 1;
+    }
+
+    PointerCoords pointerCoords[MAX_POINTERS];
+    for (jint j = 0; j < numPointers; j++) {
+        pointerCoords[j].x = *(currentDataSample++);
+        pointerCoords[j].y = *(currentDataSample++);
+        pointerCoords[j].pressure = *(currentDataSample++);
+        pointerCoords[j].size = *(currentDataSample++);
+    }
+
+    event->initialize(deviceId, nature, action, edgeFlags, metaState,
+            rawX, rawY, xPrecision, yPrecision,
+            milliseconds_to_nanoseconds(downTime), eventTimeNano,
+            numPointers, pointerIdentifiers, pointerCoords);
+
+    while (numHistoricalSamples > 0) {
+        numHistoricalSamples -= 1;
+        if (numHistoricalSamples == 0) {
+            currentDataSample = dataSamples;
+            currentTimeSample = timeSamples;
+        }
+
+        nsecs_t sampleEventTime = milliseconds_to_nanoseconds(*(currentTimeSample++));
+
+        for (jint j = 0; j < numPointers; j++) {
+            pointerCoords[j].x = *(currentDataSample++);
+            pointerCoords[j].y = *(currentDataSample++);
+            pointerCoords[j].pressure = *(currentDataSample++);
+            pointerCoords[j].size = *(currentDataSample++);
+        }
+
+        event->addSample(sampleEventTime, pointerCoords);
+    }
+
+    env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, JNI_ABORT);
+    env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, JNI_ABORT);
+    env->ReleasePrimitiveArrayCritical(timeSampleArray, timeSamples, JNI_ABORT);
+
+    env->DeleteLocalRef(pointerIdentifierArray);
+    env->DeleteLocalRef(dataSampleArray);
+    env->DeleteLocalRef(timeSampleArray);
+}
+
+void android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
+    env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
+    if (env->ExceptionCheck()) {
+        LOGW("An exception occurred while recycling a motion event.");
+        LOGW_EX(env);
+        env->ExceptionClear();
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
+        var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find static method" methodName);
+
+#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
+        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method" methodName);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_view_MotionEvent(JNIEnv* env) {
+    FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
+
+    GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
+            "obtain", "(II)Landroid/view/MotionEvent;");
+    GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
+            "recycle", "()V");
+
+    GET_FIELD_ID(gMotionEventClassInfo.mDownTime, gMotionEventClassInfo.clazz,
+            "mDownTime", "J");
+    GET_FIELD_ID(gMotionEventClassInfo.mEventTimeNano, gMotionEventClassInfo.clazz,
+            "mEventTimeNano", "J");
+    GET_FIELD_ID(gMotionEventClassInfo.mAction, gMotionEventClassInfo.clazz,
+            "mAction", "I");
+    GET_FIELD_ID(gMotionEventClassInfo.mRawX, gMotionEventClassInfo.clazz,
+            "mRawX", "F");
+    GET_FIELD_ID(gMotionEventClassInfo.mRawY, gMotionEventClassInfo.clazz,
+            "mRawY", "F");
+    GET_FIELD_ID(gMotionEventClassInfo.mXPrecision, gMotionEventClassInfo.clazz,
+            "mXPrecision", "F");
+    GET_FIELD_ID(gMotionEventClassInfo.mYPrecision, gMotionEventClassInfo.clazz,
+            "mYPrecision", "F");
+    GET_FIELD_ID(gMotionEventClassInfo.mDeviceId, gMotionEventClassInfo.clazz,
+            "mDeviceId", "I");
+    GET_FIELD_ID(gMotionEventClassInfo.mEdgeFlags, gMotionEventClassInfo.clazz,
+            "mEdgeFlags", "I");
+    GET_FIELD_ID(gMotionEventClassInfo.mMetaState, gMotionEventClassInfo.clazz,
+            "mMetaState", "I");
+    GET_FIELD_ID(gMotionEventClassInfo.mNumPointers, gMotionEventClassInfo.clazz,
+            "mNumPointers", "I");
+    GET_FIELD_ID(gMotionEventClassInfo.mNumSamples, gMotionEventClassInfo.clazz,
+            "mNumSamples", "I");
+    GET_FIELD_ID(gMotionEventClassInfo.mPointerIdentifiers, gMotionEventClassInfo.clazz,
+            "mPointerIdentifiers", "[I");
+    GET_FIELD_ID(gMotionEventClassInfo.mDataSamples, gMotionEventClassInfo.clazz,
+            "mDataSamples", "[F");
+    GET_FIELD_ID(gMotionEventClassInfo.mTimeSamples, gMotionEventClassInfo.clazz,
+            "mTimeSamples", "[J");
+
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_MotionEvent.h b/core/jni/android_view_MotionEvent.h
new file mode 100644
index 0000000..03ee32f
--- /dev/null
+++ b/core/jni/android_view_MotionEvent.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_VIEW_MOTIONEVENT_H
+#define _ANDROID_VIEW_MOTIONEVENT_H
+
+#include "jni.h"
+
+namespace android {
+
+class MotionEvent;
+
+/* Obtains an instance of a DVM MotionEvent object as a copy of a native MotionEvent instance. */
+extern jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* event);
+
+/* Copies the contents of a DVM MotionEvent object to a native MotionEvent instance. */
+extern void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature,
+        MotionEvent* event);
+
+/* Recycles a DVM MotionEvent object. */
+extern void android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj);
+
+} // namespace android
+
+#endif // _ANDROID_OS_KEYEVENT_H
diff --git a/core/jni/android_view_ViewRoot.cpp b/core/jni/android_view_ViewRoot.cpp
index 70ad8c5..5173bb8 100644
--- a/core/jni/android_view_ViewRoot.cpp
+++ b/core/jni/android_view_ViewRoot.cpp
@@ -80,38 +80,6 @@
     SkGLCanvas::AbandonAllTextures();
 }
 
-static jintArray android_view_ViewRoot_makeInputChannel(JNIEnv* env, jobject) {
-    int fd[2];
-    jint* arrayData = NULL;
-
-    // Create the pipe
-    int err = socketpair(AF_LOCAL, SOCK_STREAM, 0, fd);
-    if (err != 0) {
-        fprintf(stderr, "socketpair() failed: %d\n", errno);
-        doThrow(env, "java/lang/RuntimeException", "Unable to create pipe");
-        return NULL;
-    }
-
-    // Set up the return array
-    jintArray array = env->NewIntArray(2);
-    if (env->ExceptionCheck()) {
-        fprintf(stderr, "Exception allocating fd array");
-        goto bail;
-    }
-
-    arrayData = env->GetIntArrayElements(array, 0);
-    arrayData[0] = fd[0];
-    arrayData[1] = fd[1];
-    env->ReleaseIntArrayElements(array, arrayData, 0);
-
-    return array;
-
-bail:
-    env->DeleteLocalRef(array);
-    close(fd[0]);
-    close(fd[1]);
-    return NULL;
-}
 
 // ----------------------------------------------------------------------------
 
@@ -121,9 +89,7 @@
     {   "nativeShowFPS", "(Landroid/graphics/Canvas;I)V",
                                         (void*)android_view_ViewRoot_showFPS },
     {   "nativeAbandonGlCaches", "()V", 
-                                (void*)android_view_ViewRoot_abandonGlCaches },
-    {   "makeInputChannel", "()[I",
-                                        (void*)android_view_ViewRoot_makeInputChannel }
+                                (void*)android_view_ViewRoot_abandonGlCaches }
 };
 
 int register_android_view_ViewRoot(JNIEnv* env) {
diff --git a/include/private/README b/include/private/README
new file mode 100644
index 0000000..ee41492
--- /dev/null
+++ b/include/private/README
@@ -0,0 +1,4 @@
+This folder contains private include files.
+
+These include files are part of the private implementation details of
+various framework components.  Use at your peril.
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..2ec39fe
--- /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 <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..8e907da
--- /dev/null
+++ b/libs/ui/InputDispatcher.cpp
@@ -0,0 +1,1315 @@
+//
+// 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 <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <poll.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..76f9ec9
--- /dev/null
+++ b/libs/ui/InputReader.cpp
@@ -0,0 +1,1844 @@
+//
+// 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 <fcntl.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..945b039 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -26,6 +26,8 @@
 	Debug.cpp \
 	FileMap.cpp \
 	Flattenable.cpp \
+	PollLoop.cpp \
+	Pool.cpp \
 	RefBase.cpp \
 	ResourceTypes.cpp \
 	SharedBuffer.cpp \
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
diff --git a/native/include/android/input.h b/native/include/android/input.h
new file mode 100644
index 0000000..ee2f664
--- /dev/null
+++ b/native/include/android/input.h
@@ -0,0 +1,500 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_INPUT_H
+#define _ANDROID_INPUT_H
+
+/******************************************************************
+ *
+ * IMPORTANT NOTICE:
+ *
+ *   This file is part of Android's set of stable system headers
+ *   exposed by the Android NDK (Native Development Kit).
+ *
+ *   Third-party source AND binary code relies on the definitions
+ *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
+ *
+ *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
+ *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
+ *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
+ *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
+ */
+
+/*
+ * Structures and functions to receive and process input events in
+ * native code.
+ *
+ * NOTE: These functions MUST be implemented by /system/lib/libui.so
+ */
+
+#include <sys/types.h>
+#include <android/keycodes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Input device classes.
+ */
+enum {
+    /* The input device is a keyboard. */
+    INPUT_DEVICE_CLASS_KEYBOARD      = 0x00000001,
+
+    /* The input device is an alpha-numeric keyboard (not just a dial pad). */
+    INPUT_DEVICE_CLASS_ALPHAKEY      = 0x00000002,
+
+    /* The input device is a touchscreen (either single-touch or multi-touch). */
+    INPUT_DEVICE_CLASS_TOUCHSCREEN   = 0x00000004,
+
+    /* The input device is a trackball. */
+    INPUT_DEVICE_CLASS_TRACKBALL     = 0x00000008,
+
+    /* The input device is a multi-touch touchscreen. */
+    INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010,
+
+    /* The input device is a directional pad. */
+    INPUT_DEVICE_CLASS_DPAD          = 0x00000020
+};
+
+/*
+ * Key states (may be returned by queries about the current state of a
+ * particular key code, scan code or switch).
+ *
+ * XXX should we call this BUTTON_STATE_XXX?
+ */
+enum {
+    /* The key state is unknown or the requested key itself is not supported. */
+    KEY_STATE_UNKNOWN = -1,
+
+    /* The key is up. */
+    KEY_STATE_UP = 0,
+
+    /* The key is down. */
+    KEY_STATE_DOWN = 1,
+
+    /* The key is down but is a virtual key press that is being emulated by the system. */
+    KEY_STATE_VIRTUAL = 2
+};
+
+/*
+ * Meta key / modifer state.
+ */
+enum {
+    /* No meta keys are pressed. */
+    META_NONE = 0,
+
+    /* This mask is used to check whether one of the ALT meta keys is pressed. */
+    META_ALT_ON = 0x02,
+
+    /* This mask is used to check whether the left ALT meta key is pressed. */
+    META_ALT_LEFT_ON = 0x10,
+
+    /* This mask is used to check whether the right ALT meta key is pressed. */
+    META_ALT_RIGHT_ON = 0x20,
+
+    /* This mask is used to check whether one of the SHIFT meta keys is pressed. */
+    META_SHIFT_ON = 0x01,
+
+    /* This mask is used to check whether the left SHIFT meta key is pressed. */
+    META_SHIFT_LEFT_ON = 0x40,
+
+    /* This mask is used to check whether the right SHIFT meta key is pressed. */
+    META_SHIFT_RIGHT_ON = 0x80,
+
+    /* This mask is used to check whether the SYM meta key is pressed. */
+    META_SYM_ON = 0x04
+};
+
+/*
+ * Input events.
+ *
+ * Input events are opaque structures.  Use the provided accessors functions to
+ * read their properties.
+ */
+struct input_event_t;
+typedef struct input_event_t input_event_t;
+
+/*
+ * Input event types.
+ */
+enum {
+    /* Indicates that the input event is a key event. */
+    INPUT_EVENT_TYPE_KEY = 1,
+
+    /* Indicates that the input event is a motion event. */
+    INPUT_EVENT_TYPE_MOTION = 2
+};
+
+/*
+ * Key event actions.
+ */
+enum {
+    /* The key has been pressed down. */
+    KEY_EVENT_ACTION_DOWN = 0,
+
+    /* The key has been released. */
+    KEY_EVENT_ACTION_UP = 1,
+
+    /* Multiple duplicate key events have occurred in a row, or a complex string is
+     * being delivered.  The repeat_count property of the key event contains the number
+     * of times the given key code should be executed.
+     */
+    KEY_EVENT_ACTION_MULTIPLE = 2
+};
+
+/*
+ * Key event flags.
+ */
+enum {
+    /* This mask is set if the device woke because of this key event. */
+    KEY_EVENT_FLAG_WOKE_HERE = 0x1,
+
+    /* This mask is set if the key event was generated by a software keyboard. */
+    KEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,
+
+    /* This mask is set if we don't want the key event to cause us to leave touch mode. */
+    KEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,
+
+    /* This mask is set if an event was known to come from a trusted part
+     * of the system.  That is, the event is known to come from the user,
+     * and could not have been spoofed by a third party component. */
+    KEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
+
+    /* This mask is used for compatibility, to identify enter keys that are
+     * coming from an IME whose enter key has been auto-labelled "next" or
+     * "done".  This allows TextView to dispatch these as normal enter keys
+     * for old applications, but still do the appropriate action when
+     * receiving them. */
+    KEY_EVENT_FLAG_EDITOR_ACTION = 0x10,
+
+    /* When associated with up key events, this indicates that the key press
+     * has been canceled.  Typically this is used with virtual touch screen
+     * keys, where the user can slide from the virtual key area on to the
+     * display: in that case, the application will receive a canceled up
+     * event and should not perform the action normally associated with the
+     * key.  Note that for this to work, the application can not perform an
+     * action for a key until it receives an up or the long press timeout has
+     * expired. */
+    KEY_EVENT_FLAG_CANCELED = 0x20,
+
+    /* This key event was generated by a virtual (on-screen) hard key area.
+     * Typically this is an area of the touchscreen, outside of the regular
+     * display, dedicated to "hardware" buttons. */
+    KEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,
+
+    /* This flag is set for the first key repeat that occurs after the
+     * long press timeout. */
+    KEY_EVENT_FLAG_LONG_PRESS = 0x80,
+
+    /* Set when a key event has KEY_EVENT_FLAG_CANCELED set because a long
+     * press action was executed while it was down. */
+    KEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,
+
+    /* Set for KEY_EVENT_ACTION_UP when this event's key code is still being
+     * tracked from its initial down.  That is, somebody requested that tracking
+     * started on the key down and a long press has not caused
+     * the tracking to be canceled. */
+    KEY_EVENT_FLAG_TRACKING = 0x200
+};
+
+/*
+ * Motion event actions.
+ */
+
+/* Bit shift for the action bits holding the pointer index as
+ * defined by MOTION_EVENT_ACTION_POINTER_INDEX_MASK.
+ */
+#define MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8
+
+enum {
+    /* Bit mask of the parts of the action code that are the action itself.
+     */
+    MOTION_EVENT_ACTION_MASK = 0xff,
+
+    /* Bits in the action code that represent a pointer index, used with
+     * MOTION_EVENT_ACTION_POINTER_DOWN and MOTION_EVENT_ACTION_POINTER_UP.  Shifting
+     * down by MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
+     * index where the data for the pointer going up or down can be found.
+     */
+    MOTION_EVENT_ACTION_POINTER_INDEX_MASK  = 0xff00,
+
+    /* A pressed gesture has started, the motion contains the initial starting location.
+     */
+    MOTION_EVENT_ACTION_DOWN = 0,
+
+    /* A pressed gesture has finished, the motion contains the final release location
+     * as well as any intermediate points since the last down or move event.
+     */
+    MOTION_EVENT_ACTION_UP = 1,
+
+    /* A change has happened during a press gesture (between MOTION_EVENT_ACTION_DOWN and
+     * MOTION_EVENT_ACTION_UP).  The motion contains the most recent point, as well as
+     * any intermediate points since the last down or move event.
+     */
+    MOTION_EVENT_ACTION_MOVE = 2,
+
+    /* The current gesture has been aborted.
+     * You will not receive any more points in it.  You should treat this as
+     * an up event, but not perform any action that you normally would.
+     */
+    MOTION_EVENT_ACTION_CANCEL = 3,
+
+    /* A movement has happened outside of the normal bounds of the UI element.
+     * This does not provide a full gesture, but only the initial location of the movement/touch.
+     */
+    MOTION_EVENT_ACTION_OUTSIDE = 4,
+
+    /* A non-primary pointer has gone down.
+     * The bits in MOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
+     */
+    MOTION_EVENT_ACTION_POINTER_DOWN = 5,
+
+    /* A non-primary pointer has gone up.
+     * The bits in MOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
+     */
+    MOTION_EVENT_ACTION_POINTER_UP = 6
+};
+
+/*
+ * Motion event edge touch flags.
+ */
+enum {
+    /* No edges intersected */
+    MOTION_EVENT_EDGE_FLAG_NONE = 0,
+
+    /* Flag indicating the motion event intersected the top edge of the screen. */
+    MOTION_EVENT_EDGE_FLAG_TOP = 0x01,
+
+    /* Flag indicating the motion event intersected the bottom edge of the screen. */
+    MOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,
+
+    /* Flag indicating the motion event intersected the left edge of the screen. */
+    MOTION_EVENT_EDGE_FLAG_LEFT = 0x04,
+
+    /* Flag indicating the motion event intersected the right edge of the screen. */
+    MOTION_EVENT_EDGE_FLAG_RIGHT = 0x08
+};
+
+/*
+ * Specifies the logical nature of an input event.
+ * For example, the nature distinguishes between motion events that represent touches and
+ * those that represent trackball moves.
+ *
+ * XXX This concept is tentative.  Another idea would be to associate events with logical
+ *     controllers rather than physical devices.   The interpretation of an event would
+ *     be made with respect to the nature of the controller that is considered the logical
+ *     source of an event.  The decoupling is beneficial since multiple physical (and virtual)
+ *     devices could be responsible for producing events that would be associated with
+ *     various logical controllers.  For example, the hard keyboard, on screen keyboard,
+ *     and peripheral keyboard could be mapped onto a single logical "keyboard" controller
+ *     (or treated independently, if desired).
+ */
+enum {
+    INPUT_EVENT_NATURE_KEY = 1,
+    INPUT_EVENT_NATURE_TOUCH = 2,
+    INPUT_EVENT_NATURE_TRACKBALL = 3
+};
+
+/*
+ * Input event accessors.
+ *
+ * Note that most functions can only be used on input events that are of a given type.
+ * Calling these functions on input events of other types will yield undefined behavior.
+ */
+
+/*** Accessors for all input events. ***/
+
+/* Get the input event type. */
+int32_t input_event_get_type(const input_event_t* event);
+
+/* Get the id for the device that an input event came from.
+ *
+ * Input events can be generated by multiple different input devices.
+ * Use the input device id to obtain information about the input
+ * device that was responsible for generating a particular event.
+ *
+ * An input device id of 0 indicates that the event didn't come from a physical device;
+ * other numbers are arbitrary and you shouldn't depend on the values.
+ * Use the provided input device query API to obtain information about input devices.
+ */
+int32_t input_event_get_device_id(const input_event_t* event);
+
+/* Get the input event nature. */
+int32_t input_event_get_nature(const input_event_t* event);
+
+/*** Accessors for key events only. ***/
+
+/* Get the key event action. */
+int32_t key_event_get_action(const input_event_t* key_event);
+
+/* Get the key event flags. */
+int32_t key_event_get_flags(const input_event_t* key_event);
+
+/* Get the key code of the key event.
+ * This is the physical key that was pressed, not the Unicode character. */
+int32_t key_event_get_key_code(const input_event_t* key_event);
+
+/* Get the hardware key id of this key event.
+ * These values are not reliable and vary from device to device. */
+int32_t key_event_get_scan_code(const input_event_t* key_event);
+
+/* Get the meta key state. */
+int32_t key_event_get_meta_state(const input_event_t* key_event);
+
+/* Get the repeat count of the event.
+ * For both key up an key down events, this is the number of times the key has
+ * repeated with the first down starting at 0 and counting up from there.  For
+ * multiple key events, this is the number of down/up pairs that have occurred. */
+int32_t key_event_get_repeat_count(const input_event_t* key_event);
+
+/* Get the time of the most recent key down event, in the
+ * java.lang.System.nanoTime() time base.  If this is a down event,
+ * this will be the same as eventTime.
+ * Note that when chording keys, this value is the down time of the most recently
+ * pressed key, which may not be the same physical key of this event. */
+int64_t key_event_get_down_time(const input_event_t* key_event);
+
+/* Get the time this event occurred, in the
+ * java.lang.System.nanoTime() time base. */
+int64_t key_event_get_event_time(const input_event_t* key_event);
+
+/*** Accessors for motion events only. ***/
+
+/* Get the combined motion event action code and pointer index. */
+int32_t motion_event_get_action(const input_event_t* motion_event);
+
+/* Get the state of any meta / modifier keys that were in effect when the
+ * event was generated. */
+int32_t motion_event_get_meta_state(const input_event_t* motion_event);
+
+/* Get a bitfield indicating which edges, if any, were touched by this motion event.
+ * For touch events, clients can use this to determine if the user's finger was
+ * touching the edge of the display. */
+int32_t motion_event_get_edge_flags(const input_event_t* motion_event);
+
+/* Get the time when the user originally pressed down to start a stream of
+ * position events, in the java.lang.System.nanoTime() time base. */
+int64_t motion_event_get_down_time(const input_event_t* motion_event);
+
+/* Get the time when this specific event was generated,
+ * in the java.lang.System.nanoTime() time base. */
+int64_t motion_event_get_event_time(const input_event_t* motion_event);
+
+/* Get the precision of the X coordinates being reported.
+ * You can multiply this number with an X coordinate sample to find the
+ * actual hardware value of the X coordinate. */
+float motion_event_get_x_precision(const input_event_t* motion_event);
+
+/* Get the precision of the Y coordinates being reported.
+ * You can multiply this number with a Y coordinate sample to find the
+ * actual hardware value of the Y coordinate. */
+float motion_event_get_y_precision(const input_event_t* motion_event);
+
+/* Get the number of pointers of data contained in this event.
+ * Always >= 1. */
+size_t motion_event_get_pointer_count(const input_event_t* motion_event);
+
+/* Get the pointer identifier associated with a particular pointer
+ * data index is this event.  The identifier tells you the actual pointer
+ * number associated with the data, accounting for individual pointers
+ * going up and down since the start of the current gesture. */
+int32_t motion_event_get_pointer_id(const input_event_t* motion_event, size_t pointer_index);
+
+/* Get the original raw X coordinate of this event.  For touch
+ * events on the screen, this is the original location of the event
+ * on the screen, before it had been adjusted for the containing window
+ * and views. */
+float motion_event_get_raw_x(const input_event_t* motion_event);
+
+/* Get the original raw X coordinate of this event.  For touch
+ * events on the screen, this is the original location of the event
+ * on the screen, before it had been adjusted for the containing window
+ * and views. */
+float motion_event_get_raw_y(const input_event_t* motion_event);
+
+/* Get the current X coordinate of this event for the given pointer index.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float motion_event_get_x(const input_event_t* motion_event, size_t pointer_index);
+
+/* Get the current Y coordinate of this event for the given pointer index.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float motion_event_get_y(const input_event_t* motion_event, size_t pointer_index);
+
+/* Get the current pressure of this event for the given pointer index.
+ * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
+ * however values higher than 1 may be generated depending on the calibration of
+ * the input device. */
+float motion_event_get_pressure(const input_event_t* motion_event, size_t pointer_index);
+
+/* Get the current scaled value of the approximate size for the given pointer index.
+ * This represents some approximation of the area of the screen being
+ * pressed; the actual value in pixels corresponding to the
+ * touch is normalized with the device specific range of values
+ * and scaled to a value between 0 and 1.  The value of size can be used to
+ * determine fat touch events. */
+float motion_event_get_size(const input_event_t* motion_event, size_t pointer_index);
+
+/* Get the number of historical points in this event.  These are movements that
+ * have occurred between this event and the previous event.  This only applies
+ * to MOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.
+ * Historical samples are indexed from oldest to newest. */
+size_t motion_event_get_history_size(const input_event_t* motion_event);
+
+/* Get the time that a historical movement occurred between this event and
+ * the previous event, in the java.lang.System.nanoTime() time base. */
+int64_t motion_event_get_historical_event_time(input_event_t* motion_event,
+        size_t history_index);
+
+/* Get the historical X coordinate of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float motion_event_get_historical_x(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical Y coordinate of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * Whole numbers are pixels; the value may have a fraction for input devices
+ * that are sub-pixel precise. */
+float motion_event_get_historical_y(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the historical pressure of this event for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
+ * however values higher than 1 may be generated depending on the calibration of
+ * the input device. */
+float motion_event_get_historical_pressure(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index);
+
+/* Get the current scaled value of the approximate size for the given pointer index that
+ * occurred between this event and the previous motion event.
+ * This represents some approximation of the area of the screen being
+ * pressed; the actual value in pixels corresponding to the
+ * touch is normalized with the device specific range of values
+ * and scaled to a value between 0 and 1.  The value of size can be used to
+ * determine fat touch events. */
+float motion_event_get_historical_size(input_event_t* motion_event, size_t pointer_index,
+        size_t history_index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ANDROID_INPUT_H
diff --git a/native/include/android/keycodes.h b/native/include/android/keycodes.h
new file mode 100644
index 0000000..36855c5
--- /dev/null
+++ b/native/include/android/keycodes.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_KEYCODES_H
+#define _ANDROID_KEYCODES_H
+
+/******************************************************************
+ *
+ * IMPORTANT NOTICE:
+ *
+ *   This file is part of Android's set of stable system headers
+ *   exposed by the Android NDK (Native Development Kit).
+ *
+ *   Third-party source AND binary code relies on the definitions
+ *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
+ *
+ *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
+ *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
+ *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
+ *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
+ */
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Key codes.
+ *
+ * XXX: The declarations in <ui/KeycodeLabel.h> should be updated to use these instead.
+ *      We should probably move this into android/keycodes.h and add some new API for
+ *      getting labels so that we can remove the other tables also in KeycodeLabel.h.
+ */
+enum {
+    KEYCODE_UNKNOWN         = 0,
+    KEYCODE_SOFT_LEFT       = 1,
+    KEYCODE_SOFT_RIGHT      = 2,
+    KEYCODE_HOME            = 3,
+    KEYCODE_BACK            = 4,
+    KEYCODE_CALL            = 5,
+    KEYCODE_ENDCALL         = 6,
+    KEYCODE_0               = 7,
+    KEYCODE_1               = 8,
+    KEYCODE_2               = 9,
+    KEYCODE_3               = 10,
+    KEYCODE_4               = 11,
+    KEYCODE_5               = 12,
+    KEYCODE_6               = 13,
+    KEYCODE_7               = 14,
+    KEYCODE_8               = 15,
+    KEYCODE_9               = 16,
+    KEYCODE_STAR            = 17,
+    KEYCODE_POUND           = 18,
+    KEYCODE_DPAD_UP         = 19,
+    KEYCODE_DPAD_DOWN       = 20,
+    KEYCODE_DPAD_LEFT       = 21,
+    KEYCODE_DPAD_RIGHT      = 22,
+    KEYCODE_DPAD_CENTER     = 23,
+    KEYCODE_VOLUME_UP       = 24,
+    KEYCODE_VOLUME_DOWN     = 25,
+    KEYCODE_POWER           = 26,
+    KEYCODE_CAMERA          = 27,
+    KEYCODE_CLEAR           = 28,
+    KEYCODE_A               = 29,
+    KEYCODE_B               = 30,
+    KEYCODE_C               = 31,
+    KEYCODE_D               = 32,
+    KEYCODE_E               = 33,
+    KEYCODE_F               = 34,
+    KEYCODE_G               = 35,
+    KEYCODE_H               = 36,
+    KEYCODE_I               = 37,
+    KEYCODE_J               = 38,
+    KEYCODE_K               = 39,
+    KEYCODE_L               = 40,
+    KEYCODE_M               = 41,
+    KEYCODE_N               = 42,
+    KEYCODE_O               = 43,
+    KEYCODE_P               = 44,
+    KEYCODE_Q               = 45,
+    KEYCODE_R               = 46,
+    KEYCODE_S               = 47,
+    KEYCODE_T               = 48,
+    KEYCODE_U               = 49,
+    KEYCODE_V               = 50,
+    KEYCODE_W               = 51,
+    KEYCODE_X               = 52,
+    KEYCODE_Y               = 53,
+    KEYCODE_Z               = 54,
+    KEYCODE_COMMA           = 55,
+    KEYCODE_PERIOD          = 56,
+    KEYCODE_ALT_LEFT        = 57,
+    KEYCODE_ALT_RIGHT       = 58,
+    KEYCODE_SHIFT_LEFT      = 59,
+    KEYCODE_SHIFT_RIGHT     = 60,
+    KEYCODE_TAB             = 61,
+    KEYCODE_SPACE           = 62,
+    KEYCODE_SYM             = 63,
+    KEYCODE_EXPLORER        = 64,
+    KEYCODE_ENVELOPE        = 65,
+    KEYCODE_ENTER           = 66,
+    KEYCODE_DEL             = 67,
+    KEYCODE_GRAVE           = 68,
+    KEYCODE_MINUS           = 69,
+    KEYCODE_EQUALS          = 70,
+    KEYCODE_LEFT_BRACKET    = 71,
+    KEYCODE_RIGHT_BRACKET   = 72,
+    KEYCODE_BACKSLASH       = 73,
+    KEYCODE_SEMICOLON       = 74,
+    KEYCODE_APOSTROPHE      = 75,
+    KEYCODE_SLASH           = 76,
+    KEYCODE_AT              = 77,
+    KEYCODE_NUM             = 78,
+    KEYCODE_HEADSETHOOK     = 79,
+    KEYCODE_FOCUS           = 80,   // *Camera* focus
+    KEYCODE_PLUS            = 81,
+    KEYCODE_MENU            = 82,
+    KEYCODE_NOTIFICATION    = 83,
+    KEYCODE_SEARCH          = 84,
+    KEYCODE_MEDIA_PLAY_PAUSE= 85,
+    KEYCODE_MEDIA_STOP      = 86,
+    KEYCODE_MEDIA_NEXT      = 87,
+    KEYCODE_MEDIA_PREVIOUS  = 88,
+    KEYCODE_MEDIA_REWIND    = 89,
+    KEYCODE_MEDIA_FAST_FORWARD = 90,
+    KEYCODE_MUTE            = 91,
+    KEYCODE_PAGE_UP         = 92,
+    KEYCODE_PAGE_DOWN       = 93
+
+    /* NOTE: If you add a new keycode here you must also add it to:
+     *  native/include/android/keycodes.h
+     *  frameworks/base/include/ui/KeycodeLabels.h
+     *   frameworks/base/core/java/android/view/KeyEvent.java
+     *   tools/puppet_master/PuppetMaster.nav_keys.py
+     *   frameworks/base/core/res/res/values/attrs.xml
+     */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ANDROID_KEYCODES_H
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
index eb61f5e..88203c3 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -86,7 +86,7 @@
  * This class is created by the initialization routine of the {@link WindowManagerPolicy},
  * and runs on its thread.  The keyguard UI is created from that thread in the
  * constructor of this class.  The apis may be called from other threads, including the
- * {@link com.android.server.KeyInputQueue}'s and {@link android.view.WindowManager}'s.
+ * {@link com.android.server.InputManager}'s and {@link android.view.WindowManager}'s.
  * Therefore, methods on this class are synchronized, and any action that is pointed
  * directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
  * thread of the keyguard.
diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
index d152bc4..a01e25b 100755
--- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1641,6 +1641,36 @@
         }
         return false;
     }
+    
+    public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+        // lid changed state
+        mLidOpen = lidOpen;
+        boolean awakeNow = mKeyguardMediator.doLidChangeTq(mLidOpen);
+        updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
+        if (awakeNow) {
+            // If the lid opening and we don't have to keep the
+            // keyguard up, then we can turn on the screen
+            // immediately.
+            mKeyguardMediator.pokeWakelock();
+        } else if (keyguardIsShowingTq()) {
+            if (mLidOpen) {
+                // If we are opening the lid and not hiding the
+                // keyguard, then we need to have it turn on the
+                // screen once it is shown.
+                mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(
+                        KeyEvent.KEYCODE_POWER);
+            }
+        } else {
+            // Light up the keyboard if we are sliding up.
+            if (mLidOpen) {
+                mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
+                        LocalPowerManager.BUTTON_EVENT);
+            } else {
+                mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
+                        LocalPowerManager.OTHER_EVENT);
+            }
+        }
+    }
 
     
     /** {@inheritDoc} */
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
new file mode 100644
index 0000000..72c4166
--- /dev/null
+++ b/services/java/com/android/server/InputManager.java
@@ -0,0 +1,460 @@
+/*
+ * 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.
+ */
+
+package com.android.server;
+
+import com.android.internal.util.XmlUtils;
+import com.android.server.KeyInputQueue.VirtualKey;
+
+import org.xmlpull.v1.XmlPullParser;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.Environment;
+import android.os.LocalPowerManager;
+import android.os.PowerManager;
+import android.util.Log;
+import android.util.Slog;
+import android.util.Xml;
+import android.view.InputChannel;
+import android.view.InputTarget;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.RawInputEvent;
+import android.view.Surface;
+import android.view.WindowManagerPolicy;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/*
+ * Wraps the C++ InputManager and provides its callbacks.
+ * 
+ * XXX Tempted to promote this to a first-class service, ie. InputManagerService, to
+ *     improve separation of concerns with respect to the window manager.
+ */
+public class InputManager {
+    static final String TAG = "InputManager";
+    
+    private final Callbacks mCallbacks;
+    private final Context mContext;
+    private final WindowManagerService mWindowManagerService;
+    private final WindowManagerPolicy mWindowManagerPolicy;
+    private final PowerManager mPowerManager;
+    private final PowerManagerService mPowerManagerService;
+    
+    private int mTouchScreenConfig;
+    private int mKeyboardConfig;
+    private int mNavigationConfig;
+    
+    private static native void nativeInit(Callbacks callbacks);
+    private static native void nativeStart();
+    private static native void nativeSetDisplaySize(int displayId, int width, int height);
+    private static native void nativeSetDisplayOrientation(int displayId, int rotation);
+    
+    private static native int nativeGetScanCodeState(int deviceId, int deviceClasses,
+            int scanCode);
+    private static native int nativeGetKeyCodeState(int deviceId, int deviceClasses,
+            int keyCode);
+    private static native int nativeGetSwitchState(int deviceId, int deviceClasses,
+            int sw);
+    private static native boolean nativeHasKeys(int[] keyCodes, boolean[] keyExists);
+    private static native void nativeRegisterInputChannel(InputChannel inputChannel);
+    private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
+    
+    // Device class as defined by EventHub.
+    private static final int CLASS_KEYBOARD = 0x00000001;
+    private static final int CLASS_ALPHAKEY = 0x00000002;
+    private static final int CLASS_TOUCHSCREEN = 0x00000004;
+    private static final int CLASS_TRACKBALL = 0x00000008;
+    private static final int CLASS_TOUCHSCREEN_MT = 0x00000010;
+    private static final int CLASS_DPAD = 0x00000020;
+    
+    public InputManager(Context context,
+            WindowManagerService windowManagerService,
+            WindowManagerPolicy windowManagerPolicy,
+            PowerManager powerManager,
+            PowerManagerService powerManagerService) {
+        this.mContext = context;
+        this.mWindowManagerService = windowManagerService;
+        this.mWindowManagerPolicy = windowManagerPolicy;
+        this.mPowerManager = powerManager;
+        this.mPowerManagerService = powerManagerService;
+        
+        this.mCallbacks = new Callbacks();
+        
+        mTouchScreenConfig = Configuration.TOUCHSCREEN_NOTOUCH;
+        mKeyboardConfig = Configuration.KEYBOARD_NOKEYS;
+        mNavigationConfig = Configuration.NAVIGATION_NONAV;
+        
+        init();
+    }
+    
+    private void init() {
+        Slog.i(TAG, "Initializing input manager");
+        nativeInit(mCallbacks);
+    }
+    
+    public void start() {
+        Slog.i(TAG, "Starting input manager");
+        nativeStart();
+    }
+    
+    public void setDisplaySize(int displayId, int width, int height) {
+        if (width <= 0 || height <= 0) {
+            throw new IllegalArgumentException("Invalid display id or dimensions.");
+        }
+        
+        Slog.i(TAG, "Setting display #" + displayId + " size to " + width + "x" + height);
+        nativeSetDisplaySize(displayId, width, height);
+    }
+    
+    public void setDisplayOrientation(int displayId, int rotation) {
+        if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
+            throw new IllegalArgumentException("Invalid rotation.");
+        }
+        
+        Slog.i(TAG, "Setting display #" + displayId + " orientation to " + rotation);
+        nativeSetDisplayOrientation(displayId, rotation);
+    }
+    
+    public void getInputConfiguration(Configuration config) {
+        if (config == null) {
+            throw new IllegalArgumentException("config must not be null.");
+        }
+        
+        config.touchscreen = mTouchScreenConfig;
+        config.keyboard = mKeyboardConfig;
+        config.navigation = mNavigationConfig;
+    }
+    
+    public int getScancodeState(int code) {
+        return nativeGetScanCodeState(0, -1, code);
+    }
+    
+    public int getScancodeState(int deviceId, int code) {
+        return nativeGetScanCodeState(deviceId, -1, code);
+    }
+    
+    public int getTrackballScancodeState(int code) {
+        return nativeGetScanCodeState(-1, CLASS_TRACKBALL, code);
+    }
+    
+    public int getDPadScancodeState(int code) {
+        return nativeGetScanCodeState(-1, CLASS_DPAD, code);
+    }
+    
+    public int getKeycodeState(int code) {
+        return nativeGetKeyCodeState(0, -1, code);
+    }
+    
+    public int getKeycodeState(int deviceId, int code) {
+        return nativeGetKeyCodeState(deviceId, -1, code);
+    }
+    
+    public int getTrackballKeycodeState(int code) {
+        return nativeGetKeyCodeState(-1, CLASS_TRACKBALL, code);
+    }
+    
+    public int getDPadKeycodeState(int code) {
+        return nativeGetKeyCodeState(-1, CLASS_DPAD, code);
+    }
+
+    public int getSwitchState(int sw) {
+        return nativeGetSwitchState(-1, -1, sw);
+    }
+    
+    public int getSwitchState(int deviceId, int sw) {
+        return nativeGetSwitchState(deviceId, -1, sw);
+    }
+
+    public boolean hasKeys(int[] keyCodes, boolean[] keyExists) {
+        if (keyCodes == null) {
+            throw new IllegalArgumentException("keyCodes must not be null.");
+        }
+        if (keyExists == null) {
+            throw new IllegalArgumentException("keyExists must not be null.");
+        }
+        
+        return nativeHasKeys(keyCodes, keyExists);
+    }
+    
+    public void registerInputChannel(InputChannel inputChannel) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null.");
+        }
+        
+        nativeRegisterInputChannel(inputChannel);
+    }
+    
+    public void unregisterInputChannel(InputChannel inputChannel) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null.");
+        }
+        
+        nativeUnregisterInputChannel(inputChannel);
+    }
+    
+    // TBD where this really belongs, duplicate copy in WindowManagerService
+    static final int INJECT_FAILED = 0;
+    static final int INJECT_SUCCEEDED = 1;
+    static final int INJECT_NO_PERMISSION = -1;
+    
+    /**
+     * Injects a key event into the event system on behalf of an application.
+     * @param event The event to inject.
+     * @param nature The nature of the event.
+     * @param sync If true, waits for the event to be completed before returning.
+     * @param pid The pid of the injecting application.
+     * @param uid The uid of the injecting application.
+     * @return INJECT_SUCCEEDED, INJECT_FAILED or INJECT_NO_PERMISSION
+     */
+    public int injectKeyEvent(KeyEvent event, int nature, boolean sync, int pid, int uid) {
+        // TODO
+        return INJECT_FAILED;
+    }
+    
+    /**
+     * Injects a motion event into the event system on behalf of an application.
+     * @param event The event to inject.
+     * @param nature The nature of the event.
+     * @param sync If true, waits for the event to be completed before returning.
+     * @param pid The pid of the injecting application.
+     * @param uid The uid of the injecting application.
+     * @return INJECT_SUCCEEDED, INJECT_FAILED or INJECT_NO_PERMISSION
+     */
+    public int injectMotionEvent(MotionEvent event, int nature, boolean sync, int pid, int uid) {
+        // TODO
+        return INJECT_FAILED;
+    }
+    
+    public void dump(PrintWriter pw) {
+        // TODO
+    }
+    
+    private static final class VirtualKeyDefinition {
+        public int scanCode;
+        
+        // configured position data, specified in display coords
+        public int centerX;
+        public int centerY;
+        public int width;
+        public int height;
+    }
+    
+    /*
+     * Callbacks from native.
+     */
+    private class Callbacks {
+        static final String TAG = "InputManager-Callbacks";
+        
+        private static final boolean DEBUG_VIRTUAL_KEYS = false;
+        private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
+        
+        private final InputTargetList mReusableInputTargetList = new InputTargetList();
+        
+        @SuppressWarnings("unused")
+        public boolean isScreenOn() {
+            return mPowerManagerService.isScreenOn();
+        }
+        
+        @SuppressWarnings("unused")
+        public boolean isScreenBright() {
+            return mPowerManagerService.isScreenBright();
+        }
+        
+        @SuppressWarnings("unused")
+        public void virtualKeyFeedback(long whenNanos, int deviceId, int action, int flags,
+                int keyCode, int scanCode, int metaState, long downTimeNanos) {
+            KeyEvent keyEvent = new KeyEvent(downTimeNanos / 1000000,
+                    whenNanos / 1000000, action, keyCode, 0, metaState, scanCode, deviceId,
+                    flags);
+            
+            mWindowManagerService.virtualKeyFeedback(keyEvent);
+        }
+        
+        @SuppressWarnings("unused")
+        public void notifyConfigurationChanged(long whenNanos,
+                int touchScreenConfig, int keyboardConfig, int navigationConfig) {
+            mTouchScreenConfig = touchScreenConfig;
+            mKeyboardConfig = keyboardConfig;
+            mNavigationConfig = navigationConfig;
+            
+            mWindowManagerService.sendNewConfiguration();
+        }
+        
+        @SuppressWarnings("unused")
+        public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+            mWindowManagerPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
+        }
+        
+        @SuppressWarnings("unused")
+        public int hackInterceptKey(int deviceId, int type, int scanCode,
+                int keyCode, int policyFlags, int value, long whenNanos, boolean isScreenOn) {
+            RawInputEvent event = new RawInputEvent();
+            event.deviceId = deviceId;
+            event.type = type;
+            event.scancode = scanCode;
+            event.keycode = keyCode;
+            event.flags = policyFlags;
+            event.value = value;
+            event.when = whenNanos / 1000000;
+            
+            return mWindowManagerPolicy.interceptKeyTq(event, isScreenOn);
+        }
+        
+        @SuppressWarnings("unused")
+        public void goToSleep(long whenNanos) {
+            long when = whenNanos / 1000000;
+            mPowerManager.goToSleep(when);
+        }
+        
+        @SuppressWarnings("unused")
+        public void pokeUserActivityForKey(long whenNanos) {
+            long when = whenNanos / 1000000;
+            mPowerManagerService.userActivity(when, false,
+                    LocalPowerManager.BUTTON_EVENT, false);
+        }
+        
+        @SuppressWarnings("unused")
+        public void notifyAppSwitchComing() {
+            mWindowManagerService.mKeyWaiter.appSwitchComing();
+        }
+        
+        @SuppressWarnings("unused")
+        public boolean filterTouchEvents() {
+            return mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_filterTouchEvents);
+        }
+        
+        @SuppressWarnings("unused")
+        public boolean filterJumpyTouchEvents() {
+            return mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_filterJumpyTouchEvents);
+        }
+        
+        @SuppressWarnings("unused")
+        public VirtualKeyDefinition[] getVirtualKeyDefinitions(String deviceName) {
+            ArrayList<VirtualKeyDefinition> keys = new ArrayList<VirtualKeyDefinition>();
+            
+            try {
+                FileInputStream fis = new FileInputStream(
+                        "/sys/board_properties/virtualkeys." + deviceName);
+                InputStreamReader isr = new InputStreamReader(fis);
+                BufferedReader br = new BufferedReader(isr, 2048);
+                String str = br.readLine();
+                if (str != null) {
+                    String[] it = str.split(":");
+                    if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "***** VIRTUAL KEYS: " + it);
+                    final int N = it.length-6;
+                    for (int i=0; i<=N; i+=6) {
+                        if (!"0x01".equals(it[i])) {
+                            Slog.w(TAG, "Unknown virtual key type at elem #" + i
+                                    + ": " + it[i]);
+                            continue;
+                        }
+                        try {
+                            VirtualKeyDefinition key = new VirtualKeyDefinition();
+                            key.scanCode = Integer.parseInt(it[i+1]);
+                            key.centerX = Integer.parseInt(it[i+2]);
+                            key.centerY = Integer.parseInt(it[i+3]);
+                            key.width = Integer.parseInt(it[i+4]);
+                            key.height = Integer.parseInt(it[i+5]);
+                            if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Virtual key "
+                                    + key.scanCode + ": center=" + key.centerX + ","
+                                    + key.centerY + " size=" + key.width + "x"
+                                    + key.height);
+                            keys.add(key);
+                        } catch (NumberFormatException e) {
+                            Slog.w(TAG, "Bad number at region " + i + " in: "
+                                    + str, e);
+                        }
+                    }
+                }
+                br.close();
+            } catch (FileNotFoundException e) {
+                Slog.i(TAG, "No virtual keys found");
+            } catch (IOException e) {
+                Slog.w(TAG, "Error reading virtual keys", e);
+            }
+            
+            return keys.toArray(new VirtualKeyDefinition[keys.size()]);
+        }
+        
+        @SuppressWarnings("unused")
+        public String[] getExcludedDeviceNames() {
+            ArrayList<String> names = new ArrayList<String>();
+            
+            // Read partner-provided list of excluded input devices
+            XmlPullParser parser = null;
+            // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
+            File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
+            FileReader confreader = null;
+            try {
+                confreader = new FileReader(confFile);
+                parser = Xml.newPullParser();
+                parser.setInput(confreader);
+                XmlUtils.beginDocument(parser, "devices");
+
+                while (true) {
+                    XmlUtils.nextElement(parser);
+                    if (!"device".equals(parser.getName())) {
+                        break;
+                    }
+                    String name = parser.getAttributeValue(null, "name");
+                    if (name != null) {
+                        names.add(name);
+                    }
+                }
+            } catch (FileNotFoundException e) {
+                // It's ok if the file does not exist.
+            } catch (Exception e) {
+                Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
+            } finally {
+                try { if (confreader != null) confreader.close(); } catch (IOException e) { }
+            }
+            
+            return names.toArray(new String[names.size()]);
+        }
+        
+        @SuppressWarnings("unused")
+        public InputTarget[] getKeyEventTargets(KeyEvent event, int nature, int policyFlags) {
+            mReusableInputTargetList.clear();
+            
+            mWindowManagerService.getKeyEventTargets(mReusableInputTargetList,
+                    event, nature, policyFlags);
+            
+            return mReusableInputTargetList.toNullTerminatedArray();
+        }
+        
+        @SuppressWarnings("unused")
+        public InputTarget[] getMotionEventTargets(MotionEvent event, int nature, int policyFlags) {
+            mReusableInputTargetList.clear();
+            
+            mWindowManagerService.getMotionEventTargets(mReusableInputTargetList,
+                    event, nature, policyFlags);
+            
+            return mReusableInputTargetList.toNullTerminatedArray();
+        }
+    }
+}
diff --git a/services/java/com/android/server/InputTargetList.java b/services/java/com/android/server/InputTargetList.java
new file mode 100644
index 0000000..1575612
--- /dev/null
+++ b/services/java/com/android/server/InputTargetList.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+package com.android.server;
+
+import android.view.InputChannel;
+import android.view.InputTarget;
+
+/**
+ * A specialized list of input targets backed by an array.
+ * 
+ * This class is part of an InputManager optimization to avoid allocating and copying
+ * input target arrays unnecessarily on return from JNI callbacks.  Internally, it keeps
+ * an array full of demand-allocated InputTarget objects that it recycles each time the
+ * list is cleared.  The used portion of the array is padded with a null.
+ * 
+ * @hide
+ */
+public class InputTargetList {
+    private InputTarget[] mArray;
+    private int mCount;
+    
+    /**
+     * Creates an empty input target list.
+     */
+    public InputTargetList() {
+        mArray = new InputTarget[8];
+    }
+    
+    /**
+     * Clears the input target list.
+     */
+    public void clear() {
+        if (mCount == 0) {
+            return;
+        }
+        
+        int count = mCount;
+        mCount = 0;
+        mArray[count] = mArray[0];
+        while (count > 0) {
+            count -= 1;
+            mArray[count].recycle();
+        }
+        // mArray[0] could be set to null here but we do it in toNullTerminatedArray()
+    }
+    
+    /**
+     * Adds a new input target to the input target list.
+     * @param inputChannel The input channel of the target window.
+     * @param flags Input target flags.
+     * @param timeoutNanos The input dispatch timeout (before ANR) in nanoseconds or -1 if none.
+     * @param xOffset An offset to add to motion X coordinates during delivery.
+     * @param yOffset An offset to add to motion Y coordinates during delivery.
+     */
+    public void add(InputChannel inputChannel, int flags, long timeoutNanos,
+            float xOffset, float yOffset) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null");
+        }
+        
+        if (mCount + 1 == mArray.length) {
+            InputTarget[] oldArray = mArray;
+            mArray = new InputTarget[oldArray.length * 2];
+            System.arraycopy(oldArray, 0, mArray, 0, mCount);
+        }
+        
+        // Grab InputTarget from tail (after used section) if available.
+        InputTarget inputTarget = mArray[mCount + 1];
+        if (inputTarget == null) {
+            inputTarget = new InputTarget();
+        }
+        inputTarget.mInputChannel = inputChannel;
+        inputTarget.mFlags = flags;
+        inputTarget.mTimeoutNanos = timeoutNanos;
+        inputTarget.mXOffset = xOffset;
+        inputTarget.mYOffset = yOffset;
+        
+        mArray[mCount] = inputTarget;
+        mCount += 1;
+        // mArray[mCount] could be set to null here but we do it in toNullTerminatedArray()
+    }
+    
+    /**
+     * Gets the input targets as a null-terminated array.
+     * @return The input target array.
+     */
+    public InputTarget[] toNullTerminatedArray() {
+        mArray[mCount] = null;
+        return mArray;
+    }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index f30346b..f62c7ee 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -298,7 +298,9 @@
         
         mHapticFeedbackCallback = hapticFeedbackCallback;
         
-        readExcludedDevices();
+        if (! WindowManagerService.ENABLE_NATIVE_INPUT_DISPATCH) {
+            readExcludedDevices();
+        }
         
         PowerManager pm = (PowerManager)context.getSystemService(
                                                         Context.POWER_SERVICE);
@@ -311,7 +313,9 @@
         mFirst.next = mLast;
         mLast.prev = mFirst;
 
-        mThread.start();
+        if (! WindowManagerService.ENABLE_NATIVE_INPUT_DISPATCH) {
+            mThread.start();
+        }
     }
 
     public void setDisplay(Display display) {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index ac5e3f1..9bc3931 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -101,6 +101,9 @@
 import android.view.IWindow;
 import android.view.IWindowManager;
 import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.InputQueue;
+import android.view.InputTarget;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.RawInputEvent;
@@ -157,6 +160,8 @@
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean HIDE_STACK_CRAWLS = true;
     static final boolean MEASURE_LATENCY = false;
+    static final boolean ENABLE_NATIVE_INPUT_DISPATCH =
+        WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH;
     static private LatencyTimer lt;
 
     static final boolean PROFILE_ORIENTATION = false;
@@ -497,10 +502,12 @@
 
     final KeyWaiter mKeyWaiter = new KeyWaiter();
     final KeyQ mQueue;
+    final InputManager mInputManager;
     final InputDispatcherThread mInputThread;
 
     // Who is holding the screen on.
     Session mHoldingScreenOn;
+    PowerManager.WakeLock mHoldingScreenWakeLock;
 
     boolean mTurnOnScreen;
 
@@ -650,8 +657,16 @@
         }
         mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
 
-        mQueue = new KeyQ();
+        mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
+                "KEEP_SCREEN_ON_FLAG");
+        mHoldingScreenWakeLock.setReferenceCounted(false);
 
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            mInputManager = new InputManager(context, this, mPolicy, pmc, mPowerManager);
+        } else {
+            mInputManager = null;
+        }
+        mQueue = new KeyQ();
         mInputThread = new InputDispatcherThread();
 
         PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
@@ -666,7 +681,11 @@
             }
         }
 
-        mInputThread.start();
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            mInputManager.start();
+        } else {
+            mInputThread.start();
+        }
 
         // Add ourself to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
@@ -1859,7 +1878,7 @@
     
     public int addWindow(Session session, IWindow client,
             WindowManager.LayoutParams attrs, int viewVisibility,
-            Rect outContentInsets) {
+            Rect outContentInsets, InputChannel outInputChannel) {
         int res = mPolicy.checkAddPermission(attrs);
         if (res != WindowManagerImpl.ADD_OKAY) {
             return res;
@@ -1878,7 +1897,12 @@
                 mDisplay = wm.getDefaultDisplay();
                 mInitialDisplayWidth = mDisplay.getWidth();
                 mInitialDisplayHeight = mDisplay.getHeight();
-                mQueue.setDisplay(mDisplay);
+                if (ENABLE_NATIVE_INPUT_DISPATCH) {
+                    mInputManager.setDisplaySize(0,
+                            mInitialDisplayWidth, mInitialDisplayHeight);
+                } else {
+                    mQueue.setDisplay(mDisplay);
+                }
                 reportNewConfig = true;
             }
 
@@ -1971,6 +1995,17 @@
             if (res != WindowManagerImpl.ADD_OKAY) {
                 return res;
             }
+            
+            if (ENABLE_NATIVE_INPUT_DISPATCH) {
+                if (outInputChannel != null) {
+                    String name = win.makeInputChannelName();
+                    InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
+                    win.mInputChannel = inputChannels[0];
+                    inputChannels[1].transferToBinderOutParameter(outInputChannel);
+                    
+                    mInputManager.registerInputChannel(win.mInputChannel);
+                }
+            }
 
             // From now on, no exceptions or errors allowed!
 
@@ -4354,7 +4389,11 @@
                 "getSwitchState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return KeyInputQueue.getSwitchState(sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getSwitchState(sw);
+        } else {
+            return KeyInputQueue.getSwitchState(sw);
+        }
     }
 
     public int getSwitchStateForDevice(int devid, int sw) {
@@ -4362,7 +4401,11 @@
                 "getSwitchStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return KeyInputQueue.getSwitchState(devid, sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getSwitchState(devid, sw);
+        } else {
+            return KeyInputQueue.getSwitchState(devid, sw);
+        }
     }
 
     public int getScancodeState(int sw) {
@@ -4370,7 +4413,11 @@
                 "getScancodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getScancodeState(sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getScancodeState(sw);
+        } else {
+            return mQueue.getScancodeState(sw);
+        }
     }
 
     public int getScancodeStateForDevice(int devid, int sw) {
@@ -4378,7 +4425,11 @@
                 "getScancodeStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getScancodeState(devid, sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getScancodeState(devid, sw);
+        } else {
+            return mQueue.getScancodeState(devid, sw);
+        }
     }
 
     public int getTrackballScancodeState(int sw) {
@@ -4386,7 +4437,11 @@
                 "getTrackballScancodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getTrackballScancodeState(sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getTrackballScancodeState(sw);
+        } else {
+            return mQueue.getTrackballScancodeState(sw);
+        }
     }
 
     public int getDPadScancodeState(int sw) {
@@ -4394,7 +4449,11 @@
                 "getDPadScancodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getDPadScancodeState(sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getDPadScancodeState(sw);
+        } else {
+            return mQueue.getDPadScancodeState(sw);
+        }
     }
 
     public int getKeycodeState(int sw) {
@@ -4402,7 +4461,11 @@
                 "getKeycodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getKeycodeState(sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getKeycodeState(sw);
+        } else {
+            return mQueue.getKeycodeState(sw);
+        }
     }
 
     public int getKeycodeStateForDevice(int devid, int sw) {
@@ -4410,7 +4473,11 @@
                 "getKeycodeStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getKeycodeState(devid, sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getKeycodeState(devid, sw);
+        } else {
+            return mQueue.getKeycodeState(devid, sw);
+        }
     }
 
     public int getTrackballKeycodeState(int sw) {
@@ -4418,7 +4485,11 @@
                 "getTrackballKeycodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getTrackballKeycodeState(sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getTrackballKeycodeState(sw);
+        } else {
+            return mQueue.getTrackballKeycodeState(sw);
+        }
     }
 
     public int getDPadKeycodeState(int sw) {
@@ -4426,11 +4497,19 @@
                 "getDPadKeycodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        return mQueue.getDPadKeycodeState(sw);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.getDPadKeycodeState(sw);
+        } else {
+            return mQueue.getDPadKeycodeState(sw);
+        }
     }
 
     public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
-        return KeyInputQueue.hasKeys(keycodes, keyExists);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            return mInputManager.hasKeys(keycodes, keyExists);
+        } else {
+            return KeyInputQueue.hasKeys(keycodes, keyExists);
+        }
     }
 
     public void enableScreenAfterBoot() {
@@ -4575,7 +4654,11 @@
             mLayoutNeeded = true;
             startFreezingDisplayLocked();
             Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
-            mQueue.setOrientation(rotation);
+            if (ENABLE_NATIVE_INPUT_DISPATCH) {
+                mInputManager.setDisplayOrientation(0, rotation);
+            } else {
+                mQueue.setOrientation(rotation);
+            }
             if (mDisplayEnabled) {
                 Surface.setOrientation(0, rotation, animFlags);
             }
@@ -4906,7 +4989,11 @@
         if (mDisplay == null) {
             return false;
         }
-        mQueue.getInputConfiguration(config);
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            mInputManager.getInputConfiguration(config);
+        } else {
+            mQueue.getInputConfiguration(config);
+        }
 
         // Use the effective "visual" dimensions based on current rotation
         final boolean rotated = (mRotation == Surface.ROTATION_90
@@ -4989,6 +5076,291 @@
     // -------------------------------------------------------------
     // Input Events and Focus Management
     // -------------------------------------------------------------
+    
+    public void getKeyEventTargets(InputTargetList inputTargets,
+            KeyEvent event, int nature, int policyFlags) {
+        if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
+
+        // TODO what do we do with mDisplayFrozen?
+        // TODO what do we do with focus.mToken.paused?
+        
+        WindowState focus = getFocusedWindow();
+        wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
+        
+        addInputTarget(inputTargets, focus, InputTarget.FLAG_SYNC);
+    }
+    
+    // Target of Motion events
+    WindowState mTouchFocus;
+
+    // Windows above the target who would like to receive an "outside"
+    // touch event for any down events outside of them.
+    // (This is a linked list by way of WindowState.mNextOutsideTouch.)
+    WindowState mOutsideTouchTargets;
+    
+    private void clearTouchFocus() {
+        mTouchFocus = null;
+        mOutsideTouchTargets = null;
+    }
+    
+    public void getMotionEventTargets(InputTargetList inputTargets,
+            MotionEvent event, int nature, int policyFlags) {
+        if (nature == InputQueue.INPUT_EVENT_NATURE_TRACKBALL) {
+            // More or less the same as for keys...
+            WindowState focus = getFocusedWindow();
+            wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
+            
+            addInputTarget(inputTargets, focus, InputTarget.FLAG_SYNC);
+            return;
+        }
+        
+        int action = event.getAction();
+
+        // TODO detect cheek presses somewhere... either here or in native code
+        
+        final boolean screenWasOff = (policyFlags & WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
+        
+        WindowState target = mTouchFocus;
+        
+        if (action == MotionEvent.ACTION_UP) {
+            // let go of our target
+            mPowerManager.logPointerUpEvent();
+            clearTouchFocus();
+        } else if (action == MotionEvent.ACTION_DOWN) {
+            // acquire a new target
+            mPowerManager.logPointerDownEvent();
+        
+            synchronized (mWindowMap) {
+                if (mTouchFocus != null) {
+                    // this is weird, we got a pen down, but we thought it was
+                    // already down!
+                    // XXX: We should probably send an ACTION_UP to the current
+                    // target.
+                    Slog.w(TAG, "Pointer down received while already down in: "
+                            + mTouchFocus);
+                    clearTouchFocus();
+                }
+
+                // ACTION_DOWN is special, because we need to lock next events to
+                // the window we'll land onto.
+                final int x = (int) event.getX();
+                final int y = (int) event.getY();
+
+                final ArrayList windows = mWindows;
+                final int N = windows.size();
+                WindowState topErrWindow = null;
+                final Rect tmpRect = mTempRect;
+                for (int i=N-1; i>=0; i--) {
+                    WindowState child = (WindowState)windows.get(i);
+                    //Slog.i(TAG, "Checking dispatch to: " + child);
+                    final int flags = child.mAttrs.flags;
+                    if ((flags & WindowManager.LayoutParams.FLAG_SYSTEM_ERROR) != 0) {
+                        if (topErrWindow == null) {
+                            topErrWindow = child;
+                        }
+                    }
+                    if (!child.isVisibleLw()) {
+                        //Slog.i(TAG, "Not visible!");
+                        continue;
+                    }
+                    if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
+                        //Slog.i(TAG, "Not touchable!");
+                        if ((flags & WindowManager.LayoutParams
+                                .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
+                            child.mNextOutsideTouch = mOutsideTouchTargets;
+                            mOutsideTouchTargets = child;
+                        }
+                        continue;
+                    }
+                    tmpRect.set(child.mFrame);
+                    if (child.mTouchableInsets == ViewTreeObserver
+                                .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) {
+                        // The touch is inside of the window if it is
+                        // inside the frame, AND the content part of that
+                        // frame that was given by the application.
+                        tmpRect.left += child.mGivenContentInsets.left;
+                        tmpRect.top += child.mGivenContentInsets.top;
+                        tmpRect.right -= child.mGivenContentInsets.right;
+                        tmpRect.bottom -= child.mGivenContentInsets.bottom;
+                    } else if (child.mTouchableInsets == ViewTreeObserver
+                                .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) {
+                        // The touch is inside of the window if it is
+                        // inside the frame, AND the visible part of that
+                        // frame that was given by the application.
+                        tmpRect.left += child.mGivenVisibleInsets.left;
+                        tmpRect.top += child.mGivenVisibleInsets.top;
+                        tmpRect.right -= child.mGivenVisibleInsets.right;
+                        tmpRect.bottom -= child.mGivenVisibleInsets.bottom;
+                    }
+                    final int touchFlags = flags &
+                        (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
+                    if (tmpRect.contains(x, y) || touchFlags == 0) {
+                        //Slog.i(TAG, "Using this target!");
+                        if (!screenWasOff || (flags &
+                                WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING) != 0) {
+                            mTouchFocus = child;
+                        } else {
+                            //Slog.i(TAG, "Waking, skip!");
+                            mTouchFocus = null;
+                        }
+                        break;
+                    }
+
+                    if ((flags & WindowManager.LayoutParams
+                            .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
+                        child.mNextOutsideTouch = mOutsideTouchTargets;
+                        mOutsideTouchTargets = child;
+                        //Slog.i(TAG, "Adding to outside target list: " + child);
+                    }
+                }
+
+                // if there's an error window but it's not accepting
+                // focus (typically because it is not yet visible) just
+                // wait for it -- any other focused window may in fact
+                // be in ANR state.
+                if (topErrWindow != null && mTouchFocus != topErrWindow) {
+                    mTouchFocus = null;
+                }
+            }
+            
+            target = mTouchFocus;
+        }
+        
+        if (target != null) {
+            wakeupIfNeeded(target, eventType(event));
+        }
+        
+        int targetFlags = 0;
+        if (target == null) {
+            // In this case we are either dropping the event, or have received
+            // a move or up without a down.  It is common to receive move
+            // events in such a way, since this means the user is moving the
+            // pointer without actually pressing down.  All other cases should
+            // be atypical, so let's log them.
+            if (action != MotionEvent.ACTION_MOVE) {
+                Slog.w(TAG, "No window to dispatch pointer action " + action);
+            }
+        } else {
+            if ((target.mAttrs.flags &
+                    WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
+                //target wants to ignore fat touch events
+                boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(event);
+                //explicit flag to return without processing event further
+                boolean returnFlag = false;
+                if((action == MotionEvent.ACTION_DOWN)) {
+                    mFatTouch = false;
+                    if(cheekPress) {
+                        mFatTouch = true;
+                        returnFlag = true;
+                    }
+                } else {
+                    if(action == MotionEvent.ACTION_UP) {
+                        if(mFatTouch) {
+                            //earlier even was invalid doesnt matter if current up is cheekpress or not
+                            mFatTouch = false;
+                            returnFlag = true;
+                        } else if(cheekPress) {
+                            //cancel the earlier event
+                            targetFlags |= InputTarget.FLAG_CANCEL;
+                            action = MotionEvent.ACTION_CANCEL;
+                        }
+                    } else if(action == MotionEvent.ACTION_MOVE) {
+                        if(mFatTouch) {
+                            //two cases here
+                            //an invalid down followed by 0 or moves(valid or invalid)
+                            //a valid down,  invalid move, more moves. want to ignore till up
+                            returnFlag = true;
+                        } else if(cheekPress) {
+                            //valid down followed by invalid moves
+                            //an invalid move have to cancel earlier action
+                            targetFlags |= InputTarget.FLAG_CANCEL;
+                            action = MotionEvent.ACTION_CANCEL;
+                            if (DEBUG_INPUT) Slog.v(TAG, "Sending cancel for invalid ACTION_MOVE");
+                            //note that the subsequent invalid moves will not get here
+                            mFatTouch = true;
+                        }
+                    }
+                } //else if action
+                if(returnFlag) {
+                    return;
+                }
+            } //end if target
+        }        
+        
+        synchronized (mWindowMap) {
+            if (target != null && ! target.isVisibleLw()) {
+                target = null;
+            }
+            
+            if (action == MotionEvent.ACTION_DOWN) {
+                while (mOutsideTouchTargets != null) {
+                    addInputTarget(inputTargets, mOutsideTouchTargets,
+                            InputTarget.FLAG_OUTSIDE | targetFlags);
+                    mOutsideTouchTargets = mOutsideTouchTargets.mNextOutsideTouch;
+                }
+            }
+            
+            // If we sent an initial down to the wallpaper, then continue
+            // sending events until the final up.
+            // Alternately if we are on top of the wallpaper, then the wallpaper also
+            // gets to see this movement.
+            if (mSendingPointersToWallpaper ||
+                    (target != null && action == MotionEvent.ACTION_DOWN
+                            && mWallpaperTarget == target
+                            && target.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD)) {
+                int curTokenIndex = mWallpaperTokens.size();
+                while (curTokenIndex > 0) {
+                    curTokenIndex--;
+                    WindowToken token = mWallpaperTokens.get(curTokenIndex);
+                    int curWallpaperIndex = token.windows.size();
+                    while (curWallpaperIndex > 0) {
+                        curWallpaperIndex--;
+                        WindowState wallpaper = token.windows.get(curWallpaperIndex);
+                        if ((wallpaper.mAttrs.flags &
+                                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
+                            continue;
+                        }
+                        
+                        switch (action) {
+                            case MotionEvent.ACTION_DOWN:
+                                mSendingPointersToWallpaper = true;
+                                break;
+                            case MotionEvent.ACTION_UP:
+                                mSendingPointersToWallpaper = false;
+                                break;
+                        }
+                        
+                        addInputTarget(inputTargets, wallpaper, targetFlags);
+                    }
+                }
+            }
+            
+            if (target != null) {
+                addInputTarget(inputTargets, target, InputTarget.FLAG_SYNC | targetFlags);
+            }
+        }
+    }
+    
+    private void addInputTarget(InputTargetList inputTargets, WindowState window, int flags) {
+        if (window.mInputChannel == null) {
+            return;
+        }
+        
+        long timeoutNanos = -1;
+        IApplicationToken appToken = window.getAppToken();
+
+        if (appToken != null) {
+            try {
+                timeoutNanos = appToken.getKeyDispatchingTimeout() * 1000000;
+            } catch (RemoteException ex) {
+                Slog.w(TAG, "Could not get key dispatching timeout.", ex);
+            }
+        }
+        
+        inputTargets.add(window.mInputChannel, flags, timeoutNanos,
+                - window.mFrame.left, - window.mFrame.top);
+    }
 
     private final void wakeupIfNeeded(WindowState targetWin, int eventType) {
         long curTime = SystemClock.uptimeMillis();
@@ -5499,10 +5871,18 @@
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
-        final int result = dispatchKey(newEvent, pid, uid);
-        if (sync) {
-            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
+        
+        final int result;
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            result = mInputManager.injectKeyEvent(newEvent,
+                    InputQueue.INPUT_EVENT_NATURE_KEY, sync, pid, uid);
+        } else {
+            result = dispatchKey(newEvent, pid, uid);
+            if (sync) {
+                mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
+            }
         }
+        
         Binder.restoreCallingIdentity(ident);
         switch (result) {
             case INJECT_NO_PERMISSION:
@@ -5527,10 +5907,18 @@
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
-        final int result = dispatchPointer(null, ev, pid, uid);
-        if (sync) {
-            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
+        
+        final int result;
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            result = mInputManager.injectMotionEvent(ev,
+                    InputQueue.INPUT_EVENT_NATURE_TOUCH, sync, pid, uid);
+        } else {
+            result = dispatchPointer(null, ev, pid, uid);
+            if (sync) {
+                mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
+            }
         }
+        
         Binder.restoreCallingIdentity(ident);
         switch (result) {
             case INJECT_NO_PERMISSION:
@@ -5555,10 +5943,18 @@
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
-        final int result = dispatchTrackball(null, ev, pid, uid);
-        if (sync) {
-            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
+        
+        final int result;
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            result = mInputManager.injectMotionEvent(ev,
+                    InputQueue.INPUT_EVENT_NATURE_TRACKBALL, sync, pid, uid);
+        } else {
+            result = dispatchTrackball(null, ev, pid, uid);
+            if (sync) {
+                mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
+            }
         }
+        
         Binder.restoreCallingIdentity(ident);
         switch (result) {
             case INJECT_NO_PERMISSION:
@@ -6326,14 +6722,8 @@
 
     private class KeyQ extends KeyInputQueue
             implements KeyInputQueue.FilterCallback {
-        PowerManager.WakeLock mHoldingScreen;
-
         KeyQ() {
             super(mContext, WindowManagerService.this);
-            PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-            mHoldingScreen = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
-                    "KEEP_SCREEN_ON_FLAG");
-            mHoldingScreen.setReferenceCounted(false);
         }
 
         @Override
@@ -6445,21 +6835,6 @@
                     return FILTER_KEEP;
             }
         }
-
-        /**
-         * Must be called with the main window manager lock held.
-         */
-        void setHoldScreenLocked(boolean holding) {
-            boolean state = mHoldingScreen.isHeld();
-            if (holding != state) {
-                if (holding) {
-                    mHoldingScreen.acquire();
-                } else {
-                    mPolicy.screenOnStoppedLw();
-                    mHoldingScreen.release();
-                }
-            }
-        }
     }
 
     public boolean detectSafeMode() {
@@ -6788,8 +7163,14 @@
         }
 
         public int add(IWindow window, WindowManager.LayoutParams attrs,
+                int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
+            return addWindow(this, window, attrs, viewVisibility, outContentInsets,
+                    outInputChannel);
+        }
+        
+        public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
                 int viewVisibility, Rect outContentInsets) {
-            return addWindow(this, window, attrs, viewVisibility, outContentInsets);
+            return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
         }
 
         public void remove(IWindow window) {
@@ -7158,6 +7539,9 @@
         int mSurfaceLayer;
         float mSurfaceAlpha;
         
+        // Input channel
+        InputChannel mInputChannel;
+        
         WindowState(Session s, IWindow c, WindowToken token,
                WindowState attachedWindow, WindowManager.LayoutParams a,
                int viewVisibility) {
@@ -8182,6 +8566,15 @@
                 // Ignore if it has already been removed (usually because
                 // we are doing this as part of processing a death note.)
             }
+            
+            if (ENABLE_NATIVE_INPUT_DISPATCH) {
+                if (mInputChannel != null) {
+                    mInputManager.unregisterInputChannel(mInputChannel);
+                    
+                    mInputChannel.dispose();
+                    mInputChannel = null;
+                }
+            }
         }
 
         private class DeathRecipient implements IBinder.DeathRecipient {
@@ -8424,6 +8817,11 @@
                         pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
             }
         }
+        
+        String makeInputChannelName() {
+            return Integer.toHexString(System.identityHashCode(this))
+                + " " + mAttrs.getTitle();
+        }
 
         @Override
         public String toString() {
@@ -9275,7 +9673,8 @@
             IInputContext inputContext) {
         if (client == null) throw new IllegalArgumentException("null client");
         if (inputContext == null) throw new IllegalArgumentException("null inputContext");
-        return new Session(client, inputContext);
+        Session session = new Session(client, inputContext);
+        return session;
     }
 
     public boolean inputMethodClientHasFocus(IInputMethodClient client) {
@@ -10773,7 +11172,7 @@
         if (DEBUG_FREEZE) Slog.v(TAG, "Layout: mDisplayFrozen=" + mDisplayFrozen
                 + " holdScreen=" + holdScreen);
         if (!mDisplayFrozen) {
-            mQueue.setHoldScreenLocked(holdScreen != null);
+            setHoldScreenLocked(holdScreen != null);
             if (screenBrightness < 0 || screenBrightness > 1.0f) {
                 mPowerManager.setScreenBrightnessOverride(-1);
             } else {
@@ -10804,6 +11203,21 @@
         // be enabled, because the window obscured flags have changed.
         enableScreenIfNeededLocked();
     }
+    
+    /**
+     * Must be called with the main window manager lock held.
+     */
+    void setHoldScreenLocked(boolean holding) {
+        boolean state = mHoldingScreenWakeLock.isHeld();
+        if (holding != state) {
+            if (holding) {
+                mHoldingScreenWakeLock.acquire();
+            } else {
+                mPolicy.screenOnStoppedLw();
+                mHoldingScreenWakeLock.release();
+            }
+        }
+    }
 
     void requestAnimationLocked(long delay) {
         if (!mAnimationPending) {
@@ -11138,8 +11552,13 @@
             return;
         }
 
-        pw.println("Input State:");
-        mQueue.dump(pw, "  ");
+        if (ENABLE_NATIVE_INPUT_DISPATCH) {
+            pw.println("Input Dispatcher State:");
+            mInputManager.dump(pw);
+        } else {
+            pw.println("Input State:");
+            mQueue.dump(pw, "  ");
+        }
         pw.println(" ");
         
         synchronized(mWindowMap) {
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index b90e327..499ca86 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -5,6 +5,7 @@
     com_android_server_AlarmManagerService.cpp \
     com_android_server_BatteryService.cpp \
     com_android_server_KeyInputQueue.cpp \
+    com_android_server_InputManager.cpp \
     com_android_server_LightsService.cpp \
     com_android_server_SensorService.cpp \
     com_android_server_SystemServer.cpp \
@@ -16,6 +17,7 @@
 	$(JNI_H_INCLUDE)
 
 LOCAL_SHARED_LIBRARIES := \
+    libandroid_runtime \
 	libcutils \
 	libhardware \
 	libhardware_legacy \
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
new file mode 100644
index 0000000..53262ae
--- /dev/null
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -0,0 +1,746 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputManager-JNI"
+
+#include "JNIHelp.h"
+#include "jni.h"
+#include <android_runtime/AndroidRuntime.h>
+#include <ui/InputManager.h>
+#include <ui/InputTransport.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include "../../core/jni/android_view_KeyEvent.h"
+#include "../../core/jni/android_view_MotionEvent.h"
+#include "../../core/jni/android_view_InputChannel.h"
+#include "../../core/jni/android_view_InputTarget.h"
+
+namespace android {
+
+class InputDispatchPolicy : public InputDispatchPolicyInterface {
+public:
+    InputDispatchPolicy(JNIEnv* env, jobject callbacks);
+    virtual ~InputDispatchPolicy();
+
+    void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
+    void setDisplayOrientation(int32_t displayId, int32_t orientation);
+
+    virtual bool getDisplayInfo(int32_t displayId,
+            int32_t* width, int32_t* height, int32_t* orientation);
+
+    virtual void notifyConfigurationChanged(nsecs_t when,
+            int32_t touchScreenConfig, int32_t keyboardConfig, int32_t navigationConfig);
+
+    virtual void notifyLidSwitchChanged(nsecs_t when, bool lidOpen);
+
+    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);
+
+    virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
+            bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags);
+    virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown,
+            bool rolled);
+    virtual int32_t interceptTouch(nsecs_t when);
+
+    virtual bool filterTouchEvents();
+    virtual bool filterJumpyTouchEvents();
+    virtual void getVirtualKeyDefinitions(const String8& deviceName,
+            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
+    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
+
+    virtual bool allowKeyRepeat();
+    virtual nsecs_t getKeyRepeatTimeout();
+
+    virtual void getKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
+            Vector<InputTarget>& outTargets);
+    virtual void getMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
+            Vector<InputTarget>& outTargets);
+
+private:
+    bool isScreenOn();
+    bool isScreenBright();
+
+private:
+    jobject mCallbacks;
+
+    int32_t mFilterTouchEvents;
+    int32_t mFilterJumpyTouchEvents;
+
+    Mutex mDisplayLock;
+    int32_t mDisplayWidth, mDisplayHeight;
+    int32_t mDisplayOrientation;
+
+    inline JNIEnv* threadEnv() const {
+        return AndroidRuntime::getJNIEnv();
+    }
+};
+
+
+// globals
+
+static sp<EventHub> gEventHub;
+static sp<InputDispatchPolicy> gInputDispatchPolicy;
+static sp<InputManager> gInputManager;
+
+// JNI
+
+static struct {
+    jclass clazz;
+
+    jmethodID isScreenOn;
+    jmethodID isScreenBright;
+    jmethodID notifyConfigurationChanged;
+    jmethodID notifyLidSwitchChanged;
+    jmethodID virtualKeyFeedback;
+    jmethodID hackInterceptKey;
+    jmethodID goToSleep;
+    jmethodID pokeUserActivityForKey;
+    jmethodID notifyAppSwitchComing;
+    jmethodID filterTouchEvents;
+    jmethodID filterJumpyTouchEvents;
+    jmethodID getVirtualKeyDefinitions;
+    jmethodID getExcludedDeviceNames;
+    jmethodID getKeyEventTargets;
+    jmethodID getMotionEventTargets;
+} gCallbacksClassInfo;
+
+static struct {
+    jclass clazz;
+
+    jfieldID scanCode;
+    jfieldID centerX;
+    jfieldID centerY;
+    jfieldID width;
+    jfieldID height;
+} gVirtualKeyDefinitionClassInfo;
+
+static bool checkInputManagerUnitialized(JNIEnv* env) {
+    if (gInputManager == NULL) {
+        LOGE("Input manager not initialized.");
+        jniThrowRuntimeException(env, "Input manager not initialized.");
+        return true;
+    }
+    return false;
+}
+
+static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
+        jobject callbacks) {
+    if (gEventHub == NULL) {
+        gEventHub = new EventHub();
+    }
+
+    if (gInputDispatchPolicy == NULL) {
+        gInputDispatchPolicy = new InputDispatchPolicy(env, callbacks);
+    }
+
+    if (gInputManager == NULL) {
+        gInputManager = new InputManager(gEventHub, gInputDispatchPolicy);
+    }
+}
+
+static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
+    if (checkInputManagerUnitialized(env)) {
+        return;
+    }
+
+    status_t result = gInputManager->start();
+    if (result) {
+        jniThrowRuntimeException(env, "Input manager could not be started.");
+    }
+}
+
+static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
+        jint displayId, jint width, jint height) {
+    if (checkInputManagerUnitialized(env)) {
+        return;
+    }
+
+    // XXX we could get this from the SurfaceFlinger directly instead of requiring it
+    // to be passed in like this, not sure which is better but leaving it like this
+    // keeps the window manager in direct control of when display transitions propagate down
+    // to the input dispatcher
+    gInputDispatchPolicy->setDisplaySize(displayId, width, height);
+}
+
+static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
+        jint displayId, jint orientation) {
+    if (checkInputManagerUnitialized(env)) {
+        return;
+    }
+
+    gInputDispatchPolicy->setDisplayOrientation(displayId, orientation);
+}
+
+static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
+        jint deviceId, jint deviceClasses, jint scanCode) {
+    if (checkInputManagerUnitialized(env)) {
+        return KEY_STATE_UNKNOWN;
+    }
+
+    return gInputManager->getScanCodeState(deviceId, deviceClasses, scanCode);
+}
+
+static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
+        jint deviceId, jint deviceClasses, jint keyCode) {
+    if (checkInputManagerUnitialized(env)) {
+        return KEY_STATE_UNKNOWN;
+    }
+
+    return gInputManager->getKeyCodeState(deviceId, deviceClasses, keyCode);
+}
+
+static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
+        jint deviceId, jint deviceClasses, jint sw) {
+    if (checkInputManagerUnitialized(env)) {
+        return KEY_STATE_UNKNOWN;
+    }
+
+    return gInputManager->getSwitchState(deviceId, deviceClasses, sw);
+}
+
+static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
+        jintArray keyCodes, jbooleanArray outFlags) {
+    if (checkInputManagerUnitialized(env)) {
+        return JNI_FALSE;
+    }
+
+    int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
+    uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
+    jsize numCodes = env->GetArrayLength(keyCodes);
+    jboolean result;
+    if (numCodes == env->GetArrayLength(outFlags)) {
+        result = gInputManager->hasKeys(numCodes, codes, flags);
+    } else {
+        result = JNI_FALSE;
+    }
+
+    env->ReleaseBooleanArrayElements(outFlags, flags, 0);
+    env->ReleaseIntArrayElements(keyCodes, codes, 0);
+    return result;
+}
+
+static void throwInputChannelNotInitialized(JNIEnv* env) {
+    jniThrowException(env, "java/lang/IllegalStateException",
+             "inputChannel is not initialized");
+}
+
+static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
+        jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
+    LOGW("Input channel object '%s' was disposed without first being unregistered with "
+            "the input manager!", inputChannel->getName().string());
+
+    gInputManager->unregisterInputChannel(inputChannel);
+}
+
+static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
+        jobject inputChannelObj) {
+    if (checkInputManagerUnitialized(env)) {
+        return;
+    }
+
+    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
+            inputChannelObj);
+    if (inputChannel == NULL) {
+        throwInputChannelNotInitialized(env);
+        return;
+    }
+
+    status_t status = gInputManager->registerInputChannel(inputChannel);
+    if (status) {
+        jniThrowRuntimeException(env, "Failed to register input channel.  "
+                "Check logs for details.");
+        return;
+    }
+
+    android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
+            android_server_InputManager_handleInputChannelDisposed, NULL);
+}
+
+static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
+        jobject inputChannelObj) {
+    if (checkInputManagerUnitialized(env)) {
+        return;
+    }
+
+    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
+            inputChannelObj);
+    if (inputChannel == NULL) {
+        throwInputChannelNotInitialized(env);
+        return;
+    }
+
+    android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
+
+    status_t status = gInputManager->unregisterInputChannel(inputChannel);
+    if (status) {
+        jniThrowRuntimeException(env, "Failed to unregister input channel.  "
+                "Check logs for details.");
+    }
+}
+
+static JNINativeMethod gInputManagerMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
+            (void*) android_server_InputManager_nativeInit },
+    { "nativeStart", "()V",
+            (void*) android_server_InputManager_nativeStart },
+    { "nativeSetDisplaySize", "(III)V",
+            (void*) android_server_InputManager_nativeSetDisplaySize },
+    { "nativeSetDisplayOrientation", "(II)V",
+            (void*) android_server_InputManager_nativeSetDisplayOrientation },
+    { "nativeGetScanCodeState", "(III)I",
+            (void*) android_server_InputManager_nativeGetScanCodeState },
+    { "nativeGetKeyCodeState", "(III)I",
+            (void*) android_server_InputManager_nativeGetKeyCodeState },
+    { "nativeGetSwitchState", "(III)I",
+            (void*) android_server_InputManager_nativeGetSwitchState },
+    { "nativeHasKeys", "([I[Z)Z",
+            (void*) android_server_InputManager_nativeHasKeys },
+    { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;)V",
+            (void*) android_server_InputManager_nativeRegisterInputChannel },
+    { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
+            (void*) android_server_InputManager_nativeUnregisterInputChannel }
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method " methodName);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_server_InputManager(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
+            gInputManagerMethods, NELEM(gInputManagerMethods));
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    // Policy
+
+    FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
+
+    GET_METHOD_ID(gCallbacksClassInfo.isScreenOn, gCallbacksClassInfo.clazz,
+            "isScreenOn", "()Z");
+
+    GET_METHOD_ID(gCallbacksClassInfo.isScreenBright, gCallbacksClassInfo.clazz,
+            "isScreenBright", "()Z");
+
+    GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
+            "notifyConfigurationChanged", "(JIII)V");
+
+    GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
+            "notifyLidSwitchChanged", "(JZ)V");
+
+    GET_METHOD_ID(gCallbacksClassInfo.virtualKeyFeedback, gCallbacksClassInfo.clazz,
+            "virtualKeyFeedback", "(JIIIIIIJ)V");
+
+    GET_METHOD_ID(gCallbacksClassInfo.hackInterceptKey, gCallbacksClassInfo.clazz,
+            "hackInterceptKey", "(IIIIIIJZ)I");
+
+    GET_METHOD_ID(gCallbacksClassInfo.goToSleep, gCallbacksClassInfo.clazz,
+            "goToSleep", "(J)V");
+
+    GET_METHOD_ID(gCallbacksClassInfo.pokeUserActivityForKey, gCallbacksClassInfo.clazz,
+            "pokeUserActivityForKey", "(J)V");
+
+    GET_METHOD_ID(gCallbacksClassInfo.notifyAppSwitchComing, gCallbacksClassInfo.clazz,
+            "notifyAppSwitchComing", "()V");
+
+    GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
+            "filterTouchEvents", "()Z");
+
+    GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
+            "filterJumpyTouchEvents", "()Z");
+
+    GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
+            "getVirtualKeyDefinitions",
+            "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
+
+    GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
+            "getExcludedDeviceNames", "()[Ljava/lang/String;");
+
+    GET_METHOD_ID(gCallbacksClassInfo.getKeyEventTargets, gCallbacksClassInfo.clazz,
+            "getKeyEventTargets", "(Landroid/view/KeyEvent;II)[Landroid/view/InputTarget;");
+
+    GET_METHOD_ID(gCallbacksClassInfo.getMotionEventTargets, gCallbacksClassInfo.clazz,
+            "getMotionEventTargets", "(Landroid/view/MotionEvent;II)[Landroid/view/InputTarget;");
+
+    // VirtualKeyDefinition
+
+    FIND_CLASS(gVirtualKeyDefinitionClassInfo.clazz,
+            "com/android/server/InputManager$VirtualKeyDefinition");
+
+    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.scanCode, gVirtualKeyDefinitionClassInfo.clazz,
+            "scanCode", "I");
+
+    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerX, gVirtualKeyDefinitionClassInfo.clazz,
+            "centerX", "I");
+
+    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerY, gVirtualKeyDefinitionClassInfo.clazz,
+            "centerY", "I");
+
+    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.width, gVirtualKeyDefinitionClassInfo.clazz,
+            "width", "I");
+
+    GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
+            "height", "I");
+
+    return 0;
+}
+
+// static functions
+
+static bool isAppSwitchKey(int32_t keyCode) {
+    return keyCode == KEYCODE_HOME || keyCode == KEYCODE_ENDCALL;
+}
+
+static bool checkException(JNIEnv* env, const char* methodName) {
+    if (env->ExceptionCheck()) {
+        LOGE("An exception was thrown by an InputDispatchPolicy callback '%s'.", methodName);
+        LOGE_EX(env);
+        env->ExceptionClear();
+        return true;
+    }
+    return false;
+}
+
+
+// InputDispatchPolicy implementation
+
+InputDispatchPolicy::InputDispatchPolicy(JNIEnv* env, jobject callbacks) :
+        mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
+        mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(-1) {
+    mCallbacks = env->NewGlobalRef(callbacks);
+}
+
+InputDispatchPolicy::~InputDispatchPolicy() {
+    JNIEnv* env = threadEnv();
+
+    env->DeleteGlobalRef(mCallbacks);
+}
+
+void InputDispatchPolicy::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
+    if (displayId == 0) {
+        AutoMutex _l(mDisplayLock);
+
+        mDisplayWidth = width;
+        mDisplayHeight = height;
+    }
+}
+
+void InputDispatchPolicy::setDisplayOrientation(int32_t displayId, int32_t orientation) {
+    if (displayId == 0) {
+        AutoMutex _l(mDisplayLock);
+
+        mDisplayOrientation = orientation;
+    }
+}
+
+bool InputDispatchPolicy::getDisplayInfo(int32_t displayId,
+        int32_t* width, int32_t* height, int32_t* orientation) {
+    bool result = false;
+    if (displayId == 0) {
+        AutoMutex _l(mDisplayLock);
+
+        if (mDisplayWidth > 0) {
+            *width = mDisplayWidth;
+            *height = mDisplayHeight;
+            *orientation = mDisplayOrientation;
+            result = true;
+        }
+    }
+    return result;
+}
+
+bool InputDispatchPolicy::isScreenOn() {
+    JNIEnv* env = threadEnv();
+
+    jboolean result = env->CallBooleanMethod(mCallbacks, gCallbacksClassInfo.isScreenOn);
+    if (checkException(env, "isScreenOn")) {
+        return true;
+    }
+    return result;
+}
+
+bool InputDispatchPolicy::isScreenBright() {
+    JNIEnv* env = threadEnv();
+
+    jboolean result = env->CallBooleanMethod(mCallbacks, gCallbacksClassInfo.isScreenBright);
+    if (checkException(env, "isScreenBright")) {
+        return true;
+    }
+    return result;
+}
+
+void InputDispatchPolicy::notifyConfigurationChanged(nsecs_t when,
+        int32_t touchScreenConfig, int32_t keyboardConfig, int32_t navigationConfig) {
+    JNIEnv* env = threadEnv();
+
+    env->CallVoidMethod(mCallbacks, gCallbacksClassInfo.notifyConfigurationChanged,
+            when, touchScreenConfig, keyboardConfig, navigationConfig);
+    checkException(env, "notifyConfigurationChanged");
+}
+
+void InputDispatchPolicy::notifyLidSwitchChanged(nsecs_t when, bool lidOpen) {
+    JNIEnv* env = threadEnv();
+    env->CallVoidMethod(mCallbacks, gCallbacksClassInfo.notifyLidSwitchChanged,
+            when, lidOpen);
+    checkException(env, "notifyLidSwitchChanged");
+}
+
+void InputDispatchPolicy::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) {
+    JNIEnv* env = threadEnv();
+
+    env->CallVoidMethod(mCallbacks, gCallbacksClassInfo.virtualKeyFeedback,
+            when, deviceId, action, flags, keyCode, scanCode, metaState, downTime);
+    checkException(env, "virtualKeyFeedback");
+}
+
+int32_t InputDispatchPolicy::interceptKey(nsecs_t when,
+        int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) {
+    const int32_t WM_ACTION_PASS_TO_USER = 1;
+    const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
+    const int32_t WM_ACTION_GO_TO_SLEEP = 4;
+
+    JNIEnv* env = threadEnv();
+
+    bool isScreenOn = this->isScreenOn();
+    bool isScreenBright = this->isScreenBright();
+
+    jint wmActions = env->CallIntMethod(mCallbacks, gCallbacksClassInfo.hackInterceptKey,
+            deviceId, EV_KEY, scanCode, keyCode, policyFlags, down ? 1 : 0, when, isScreenOn);
+    if (checkException(env, "hackInterceptKey")) {
+        wmActions = 0;
+    }
+
+    int32_t actions = ACTION_NONE;
+    if (! isScreenOn) {
+        // Key presses and releases wake the device.
+        actions |= ACTION_WOKE_HERE;
+    }
+
+    if (! isScreenBright) {
+        // Key presses and releases brighten the screen if dimmed.
+        actions |= ACTION_BRIGHT_HERE;
+    }
+
+    if (wmActions & WM_ACTION_GO_TO_SLEEP) {
+        env->CallVoidMethod(mCallbacks, gCallbacksClassInfo.goToSleep, when);
+        checkException(env, "goToSleep");
+    }
+
+    if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
+        env->CallVoidMethod(mCallbacks, gCallbacksClassInfo.pokeUserActivityForKey, when);
+        checkException(env, "pokeUserActivityForKey");
+    }
+
+    if (wmActions & WM_ACTION_PASS_TO_USER) {
+        actions |= ACTION_DISPATCH;
+    }
+
+    if (! (wmActions & WM_ACTION_PASS_TO_USER)) {
+        if (down && isAppSwitchKey(keyCode)) {
+            env->CallVoidMethod(mCallbacks, gCallbacksClassInfo.notifyAppSwitchComing);
+            checkException(env, "notifyAppSwitchComing");
+
+            actions |= ACTION_APP_SWITCH_COMING;
+        }
+    }
+    return actions;
+}
+
+int32_t InputDispatchPolicy::interceptTouch(nsecs_t when) {
+    if (! isScreenOn()) {
+        // Touch events do not wake the device.
+        return ACTION_NONE;
+    }
+
+    return ACTION_DISPATCH;
+}
+
+int32_t InputDispatchPolicy::interceptTrackball(nsecs_t when,
+        bool buttonChanged, bool buttonDown, bool rolled) {
+    if (! isScreenOn()) {
+        // Trackball motions and button presses do not wake the device.
+        return ACTION_NONE;
+    }
+
+    return ACTION_DISPATCH;
+}
+
+bool InputDispatchPolicy::filterTouchEvents() {
+    if (mFilterTouchEvents < 0) {
+        JNIEnv* env = threadEnv();
+
+        jboolean result = env->CallBooleanMethod(mCallbacks,
+                gCallbacksClassInfo.filterTouchEvents);
+        if (checkException(env, "filterTouchEvents")) {
+            result = false;
+        }
+
+        mFilterTouchEvents = result ? 1 : 0;
+    }
+    return mFilterTouchEvents;
+}
+
+bool InputDispatchPolicy::filterJumpyTouchEvents() {
+    if (mFilterJumpyTouchEvents < 0) {
+        JNIEnv* env = threadEnv();
+
+        jboolean result = env->CallBooleanMethod(mCallbacks,
+                gCallbacksClassInfo.filterJumpyTouchEvents);
+        if (checkException(env, "filterJumpyTouchEvents")) {
+            result = false;
+        }
+
+        mFilterJumpyTouchEvents = result ? 1 : 0;
+    }
+    return mFilterJumpyTouchEvents;
+}
+
+void InputDispatchPolicy::getVirtualKeyDefinitions(const String8& deviceName,
+        Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+    JNIEnv* env = threadEnv();
+
+    jstring deviceNameStr = env->NewStringUTF(deviceName.string());
+    if (! checkException(env, "getVirtualKeyDefinitions")) {
+        jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacks,
+                gCallbacksClassInfo.getVirtualKeyDefinitions, deviceNameStr));
+        if (! checkException(env, "getVirtualKeyDefinitions") && result) {
+            jsize length = env->GetArrayLength(result);
+            for (jsize i = 0; i < length; i++) {
+                jobject item = env->GetObjectArrayElement(result, i);
+
+                outVirtualKeyDefinitions.add();
+                outVirtualKeyDefinitions.editTop().scanCode =
+                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.scanCode));
+                outVirtualKeyDefinitions.editTop().centerX =
+                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerX));
+                outVirtualKeyDefinitions.editTop().centerY =
+                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerY));
+                outVirtualKeyDefinitions.editTop().width =
+                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.width));
+                outVirtualKeyDefinitions.editTop().height =
+                        int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.height));
+
+                env->DeleteLocalRef(item);
+            }
+            env->DeleteLocalRef(result);
+        }
+        env->DeleteLocalRef(deviceNameStr);
+    }
+}
+
+void InputDispatchPolicy::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
+    JNIEnv* env = threadEnv();
+
+    jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacks,
+            gCallbacksClassInfo.getExcludedDeviceNames));
+    if (! checkException(env, "getExcludedDeviceNames") && result) {
+        jsize length = env->GetArrayLength(result);
+        for (jsize i = 0; i < length; i++) {
+            jstring item = jstring(env->GetObjectArrayElement(result, i));
+
+            const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
+            outExcludedDeviceNames.add(String8(deviceNameChars));
+            env->ReleaseStringUTFChars(item, deviceNameChars);
+
+            env->DeleteLocalRef(item);
+        }
+        env->DeleteLocalRef(result);
+    }
+}
+
+bool InputDispatchPolicy::allowKeyRepeat() {
+    // Disable key repeat when the screen is off.
+    return isScreenOn();
+}
+
+nsecs_t InputDispatchPolicy::getKeyRepeatTimeout() {
+    // TODO use ViewConfiguration.getLongPressTimeout()
+    return milliseconds_to_nanoseconds(500);
+}
+
+void InputDispatchPolicy::getKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
+        Vector<InputTarget>& outTargets) {
+    JNIEnv* env = threadEnv();
+
+    jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
+    if (! keyEventObj) {
+        LOGE("Could not obtain DVM KeyEvent object to get key event targets.");
+    } else {
+        jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacks,
+                gCallbacksClassInfo.getKeyEventTargets,
+                keyEventObj, jint(keyEvent->getNature()), jint(policyFlags)));
+        if (! checkException(env, "getKeyEventTargets") && result) {
+            jsize length = env->GetArrayLength(result);
+            for (jsize i = 0; i < length; i++) {
+                jobject item = env->GetObjectArrayElement(result, i);
+                if (! item) {
+                    break; // found null element indicating end of used portion of the array
+                }
+
+                outTargets.add();
+                android_view_InputTarget_toNative(env, item, & outTargets.editTop());
+
+                env->DeleteLocalRef(item);
+            }
+            env->DeleteLocalRef(result);
+        }
+        env->DeleteLocalRef(keyEventObj);
+    }
+}
+
+void InputDispatchPolicy::getMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
+        Vector<InputTarget>& outTargets) {
+    JNIEnv* env = threadEnv();
+
+    jobject motionEventObj = android_view_MotionEvent_fromNative(env, motionEvent);
+    if (! motionEventObj) {
+        LOGE("Could not obtain DVM MotionEvent object to get key event targets.");
+    } else {
+        jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacks,
+                gCallbacksClassInfo.getMotionEventTargets,
+                motionEventObj, jint(motionEvent->getNature()), jint(policyFlags)));
+        if (! checkException(env, "getMotionEventTargets") && result) {
+            jsize length = env->GetArrayLength(result);
+            for (jsize i = 0; i < length; i++) {
+                jobject item = env->GetObjectArrayElement(result, i);
+                if (! item) {
+                    break; // found null element indicating end of used portion of the array
+                }
+
+                outTargets.add();
+                android_view_InputTarget_toNative(env, item, & outTargets.editTop());
+
+                env->DeleteLocalRef(item);
+            }
+            env->DeleteLocalRef(result);
+        }
+        android_view_MotionEvent_recycle(env, motionEventObj);
+        env->DeleteLocalRef(motionEventObj);
+    }
+}
+
+} /* namespace android */
diff --git a/services/jni/com_android_server_KeyInputQueue.cpp b/services/jni/com_android_server_KeyInputQueue.cpp
index c92f8df..f9e3585 100644
--- a/services/jni/com_android_server_KeyInputQueue.cpp
+++ b/services/jni/com_android_server_KeyInputQueue.cpp
@@ -156,7 +156,7 @@
 {
     jint st = -1;
     gLock.lock();
-    if (gHub != NULL) st = gHub->getSwitchState(sw);
+    if (gHub != NULL) st = gHub->getSwitchState(-1, -1, sw);
     gLock.unlock();
     
     return st;
@@ -168,7 +168,7 @@
 {
     jint st = -1;
     gLock.lock();
-    if (gHub != NULL) st = gHub->getSwitchState(deviceId, sw);
+    if (gHub != NULL) st = gHub->getSwitchState(deviceId, -1, sw);
     gLock.unlock();
     
     return st;
@@ -180,7 +180,7 @@
 {
     jint st = -1;
     gLock.lock();
-    if (gHub != NULL) st = gHub->getScancodeState(sw);
+    if (gHub != NULL) st = gHub->getScanCodeState(0, -1, sw);
     gLock.unlock();
     
     return st;
@@ -192,7 +192,7 @@
 {
     jint st = -1;
     gLock.lock();
-    if (gHub != NULL) st = gHub->getScancodeState(deviceId, sw);
+    if (gHub != NULL) st = gHub->getScanCodeState(deviceId, -1, sw);
     gLock.unlock();
     
     return st;
@@ -204,7 +204,7 @@
 {
     jint st = -1;
     gLock.lock();
-    if (gHub != NULL) st = gHub->getKeycodeState(sw);
+    if (gHub != NULL) st = gHub->getKeyCodeState(0, -1, sw);
     gLock.unlock();
     
     return st;
@@ -216,7 +216,7 @@
 {
     jint st = -1;
     gLock.lock();
-    if (gHub != NULL) st = gHub->getKeycodeState(deviceId, sw);
+    if (gHub != NULL) st = gHub->getKeyCodeState(deviceId,-1, sw);
     gLock.unlock();
     
     return st;
@@ -247,7 +247,7 @@
 
     int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
     uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
-    size_t numCodes = env->GetArrayLength(keyCodes);
+    jsize numCodes = env->GetArrayLength(keyCodes);
     if (numCodes == env->GetArrayLength(outFlags)) {
         gLock.lock();
         if (gHub != NULL) ret = gHub->hasKeys(numCodes, codes, flags);
diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp
index d11e7e1..a1a6838 100644
--- a/services/jni/onload.cpp
+++ b/services/jni/onload.cpp
@@ -7,6 +7,7 @@
 int register_android_server_AlarmManagerService(JNIEnv* env);
 int register_android_server_BatteryService(JNIEnv* env);
 int register_android_server_KeyInputQueue(JNIEnv* env);
+int register_android_server_InputManager(JNIEnv* env);
 int register_android_server_LightsService(JNIEnv* env);
 int register_android_server_SensorService(JNIEnv* env);
 int register_android_server_VibratorService(JNIEnv* env);
@@ -28,6 +29,7 @@
     LOG_ASSERT(env, "Could not retrieve the env!");
 
     register_android_server_KeyInputQueue(env);
+    register_android_server_InputManager(env);
     register_android_server_LightsService(env);
     register_android_server_AlarmManagerService(env);
     register_android_server_BatteryService(env);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 4201e80..f91f601 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -46,6 +46,7 @@
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
 import android.view.BridgeInflater;
+import android.view.InputChannel;
 import android.view.IWindow;
 import android.view.IWindowSession;
 import android.view.KeyEvent;
@@ -990,13 +991,21 @@
     private static final class WindowSession implements IWindowSession {
 
         @SuppressWarnings("unused")
-        public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+        public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
+                InputChannel outInputchannel)
                 throws RemoteException {
             // pass for now.
             return 0;
         }
 
         @SuppressWarnings("unused")
+        public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+                throws RemoteException {
+            // pass for now.
+            return 0;
+        }
+        
+        @SuppressWarnings("unused")
         public void finishDrawing(IWindow arg0) throws RemoteException {
             // pass for now.
         }
