diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 249ad62..6f12f19 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -216,20 +216,7 @@
             @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);
-                    }
+                    dispatchPointer(event);
                 } finally {
                     finishedCallback.run();
                 }
@@ -238,26 +225,6 @@
         
         final BaseIWindow mWindow = new BaseIWindow() {
             @Override
-            public boolean onDispatchPointer(MotionEvent event, long eventTime,
-                    boolean callWhenDone) {
-                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);
-                }
-                return false;
-            }
-            
-            @Override
             public void resized(int w, int h, Rect coveredInsets,
                     Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
                 Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
@@ -466,6 +433,22 @@
          */
         public void onSurfaceDestroyed(SurfaceHolder holder) {
         }
+        
+        private void dispatchPointer(MotionEvent event) {
+            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);
+            }
+        }
 
         void updateSurface(boolean forceRelayout, boolean forceReport) {
             if (mDestroyed) {
@@ -523,10 +506,8 @@
                                 mInputChannel);
                         mCreated = true;
 
-                        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
-                            InputQueue.registerInputChannel(mInputChannel, mInputHandler,
-                                    Looper.myQueue());
-                        }
+                        InputQueue.registerInputChannel(mInputChannel, mInputHandler,
+                                Looper.myQueue());
                     }
                     
                     mSurfaceHolder.mSurfaceLock.lock();
@@ -770,10 +751,8 @@
                     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);
-                        }
+                    if (mInputChannel != null) {
+                        InputQueue.unregisterInputChannel(mInputChannel);
                     }
                     
                     mSession.remove(mWindow);
@@ -782,13 +761,11 @@
                 mSurfaceHolder.mSurface.release();
                 mCreated = false;
                 
-                if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
-                    // Dispose the input channel after removing the window so the Window Manager
-                    // doesn't interpret the input channel being closed as an abnormal termination.
-                    if (mInputChannel != null) {
-                        mInputChannel.dispose();
-                        mInputChannel = null;
-                    }
+                // Dispose the input channel after removing the window so the Window Manager
+                // doesn't interpret the input channel being closed as an abnormal termination.
+                if (mInputChannel != null) {
+                    mInputChannel.dispose();
+                    mInputChannel = null;
                 }
             }
         }
@@ -841,7 +818,7 @@
 
         public void dispatchPointer(MotionEvent event) {
             if (mEngine != null) {
-                mEngine.mWindow.onDispatchPointer(event, event.getEventTime(), false);
+                mEngine.dispatchPointer(event);
             }
         }
         
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 3b09808..921018a 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -46,9 +46,6 @@
 
     void resized(int w, int h, in Rect coveredInsets, in Rect visibleInsets,
             boolean reportDraw, in Configuration newConfig);
-    void dispatchKey(in KeyEvent event);
-    void dispatchPointer(in MotionEvent event, long eventTime, boolean callWhenDone);
-    void dispatchTrackball(in MotionEvent event, long eventTime, boolean callWhenDone);
     void dispatchAppVisibility(boolean visible);
     void dispatchGetNewSurface();
 
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 4647fb4..7f10b76 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -109,10 +109,6 @@
     void getDisplayFrame(IWindow window, out Rect outDisplayFrame);
     
     void finishDrawing(IWindow window);
-
-    void finishKey(IWindow window);
-    MotionEvent getPendingPointerMove(IWindow window);
-    MotionEvent getPendingTrackballMove(IWindow window);
     
     void setInTouchMode(boolean showFocus);
     boolean getInTouchMode();
diff --git a/core/java/android/view/RawInputEvent.java b/core/java/android/view/RawInputEvent.java
deleted file mode 100644
index 3bbfea8..0000000
--- a/core/java/android/view/RawInputEvent.java
+++ /dev/null
@@ -1,201 +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.
- */
-
-package android.view;
-
-/**
- * @hide
- * This really belongs in services.jar; WindowManagerPolicy should go there too.
- */
-public class RawInputEvent {
-    // Event class as defined by EventHub.
-    public static final int CLASS_KEYBOARD = 0x00000001;
-    public static final int CLASS_ALPHAKEY = 0x00000002;
-    public static final int CLASS_TOUCHSCREEN = 0x00000004;
-    public static final int CLASS_TRACKBALL = 0x00000008;
-    public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;
-    public static final int CLASS_DPAD = 0x00000020;
-    
-    // More special classes for QueuedEvent below.
-    public static final int CLASS_CONFIGURATION_CHANGED = 0x10000000;
-    
-    // Event types.
-
-    public static final int EV_SYN = 0x00;
-    public static final int EV_KEY = 0x01;
-    public static final int EV_REL = 0x02;
-    public static final int EV_ABS = 0x03;
-    public static final int EV_MSC = 0x04;
-    public static final int EV_SW = 0x05;
-    public static final int EV_LED = 0x11;
-    public static final int EV_SND = 0x12;
-    public static final int EV_REP = 0x14;
-    public static final int EV_FF = 0x15;
-    public static final int EV_PWR = 0x16;
-    public static final int EV_FF_STATUS = 0x17;
-
-    // Platform-specific event types.
-    
-    public static final int EV_DEVICE_ADDED = 0x10000000;
-    public static final int EV_DEVICE_REMOVED = 0x20000000;
-    
-    // Special key (EV_KEY) scan codes for pointer buttons.
-
-    public static final int BTN_FIRST = 0x100;
-
-    public static final int BTN_MISC = 0x100;
-    public static final int BTN_0 = 0x100;
-    public static final int BTN_1 = 0x101;
-    public static final int BTN_2 = 0x102;
-    public static final int BTN_3 = 0x103;
-    public static final int BTN_4 = 0x104;
-    public static final int BTN_5 = 0x105;
-    public static final int BTN_6 = 0x106;
-    public static final int BTN_7 = 0x107;
-    public static final int BTN_8 = 0x108;
-    public static final int BTN_9 = 0x109;
-
-    public static final int BTN_MOUSE = 0x110;
-    public static final int BTN_LEFT = 0x110;
-    public static final int BTN_RIGHT = 0x111;
-    public static final int BTN_MIDDLE = 0x112;
-    public static final int BTN_SIDE = 0x113;
-    public static final int BTN_EXTRA = 0x114;
-    public static final int BTN_FORWARD = 0x115;
-    public static final int BTN_BACK = 0x116;
-    public static final int BTN_TASK = 0x117;
-
-    public static final int BTN_JOYSTICK = 0x120;
-    public static final int BTN_TRIGGER = 0x120;
-    public static final int BTN_THUMB = 0x121;
-    public static final int BTN_THUMB2 = 0x122;
-    public static final int BTN_TOP = 0x123;
-    public static final int BTN_TOP2 = 0x124;
-    public static final int BTN_PINKIE = 0x125;
-    public static final int BTN_BASE = 0x126;
-    public static final int BTN_BASE2 = 0x127;
-    public static final int BTN_BASE3 = 0x128;
-    public static final int BTN_BASE4 = 0x129;
-    public static final int BTN_BASE5 = 0x12a;
-    public static final int BTN_BASE6 = 0x12b;
-    public static final int BTN_DEAD = 0x12f;
-
-    public static final int BTN_GAMEPAD = 0x130;
-    public static final int BTN_A = 0x130;
-    public static final int BTN_B = 0x131;
-    public static final int BTN_C = 0x132;
-    public static final int BTN_X = 0x133;
-    public static final int BTN_Y = 0x134;
-    public static final int BTN_Z = 0x135;
-    public static final int BTN_TL = 0x136;
-    public static final int BTN_TR = 0x137;
-    public static final int BTN_TL2 = 0x138;
-    public static final int BTN_TR2 = 0x139;
-    public static final int BTN_SELECT = 0x13a;
-    public static final int BTN_START = 0x13b;
-    public static final int BTN_MODE = 0x13c;
-    public static final int BTN_THUMBL = 0x13d;
-    public static final int BTN_THUMBR = 0x13e;
-
-    public static final int BTN_DIGI = 0x140;
-    public static final int BTN_TOOL_PEN = 0x140;
-    public static final int BTN_TOOL_RUBBER = 0x141;
-    public static final int BTN_TOOL_BRUSH = 0x142;
-    public static final int BTN_TOOL_PENCIL = 0x143;
-    public static final int BTN_TOOL_AIRBRUSH = 0x144;
-    public static final int BTN_TOOL_FINGER = 0x145;
-    public static final int BTN_TOOL_MOUSE = 0x146;
-    public static final int BTN_TOOL_LENS = 0x147;
-    public static final int BTN_TOUCH = 0x14a;
-    public static final int BTN_STYLUS = 0x14b;
-    public static final int BTN_STYLUS2 = 0x14c;
-    public static final int BTN_TOOL_DOUBLETAP = 0x14d;
-    public static final int BTN_TOOL_TRIPLETAP = 0x14e;
-
-    public static final int BTN_WHEEL = 0x150;
-    public static final int BTN_GEAR_DOWN = 0x150;
-    public static final int BTN_GEAR_UP = 0x151;
-
-    public static final int BTN_LAST = 0x15f;
-
-    // Relative axes (EV_REL) scan codes.
-
-    public static final int REL_X = 0x00;
-    public static final int REL_Y = 0x01;
-    public static final int REL_Z = 0x02;
-    public static final int REL_RX = 0x03;
-    public static final int REL_RY = 0x04;
-    public static final int REL_RZ = 0x05;
-    public static final int REL_HWHEEL = 0x06;
-    public static final int REL_DIAL = 0x07;
-    public static final int REL_WHEEL = 0x08;
-    public static final int REL_MISC = 0x09;
-    public static final int REL_MAX = 0x0f;
-
-    // Absolute axes (EV_ABS) scan codes.
-
-    public static final int ABS_X = 0x00;
-    public static final int ABS_Y = 0x01;
-    public static final int ABS_Z = 0x02;
-    public static final int ABS_RX = 0x03;
-    public static final int ABS_RY = 0x04;
-    public static final int ABS_RZ = 0x05;
-    public static final int ABS_THROTTLE = 0x06;
-    public static final int ABS_RUDDER = 0x07;
-    public static final int ABS_WHEEL = 0x08;
-    public static final int ABS_GAS = 0x09;
-    public static final int ABS_BRAKE = 0x0a;
-    public static final int ABS_HAT0X = 0x10;
-    public static final int ABS_HAT0Y = 0x11;
-    public static final int ABS_HAT1X = 0x12;
-    public static final int ABS_HAT1Y = 0x13;
-    public static final int ABS_HAT2X = 0x14;
-    public static final int ABS_HAT2Y = 0x15;
-    public static final int ABS_HAT3X = 0x16;
-    public static final int ABS_HAT3Y = 0x17;
-    public static final int ABS_PRESSURE = 0x18;
-    public static final int ABS_DISTANCE = 0x19;
-    public static final int ABS_TILT_X = 0x1a;
-    public static final int ABS_TILT_Y = 0x1b;
-    public static final int ABS_TOOL_WIDTH = 0x1c;
-    public static final int ABS_VOLUME = 0x20;
-    public static final int ABS_MISC = 0x28;
-    public static final int ABS_MT_TOUCH_MAJOR = 0x30;
-    public static final int ABS_MT_TOUCH_MINOR = 0x31;
-    public static final int ABS_MT_WIDTH_MAJOR = 0x32;
-    public static final int ABS_MT_WIDTH_MINOR = 0x33;
-    public static final int ABS_MT_ORIENTATION = 0x34;
-    public static final int ABS_MT_POSITION_X = 0x35;
-    public static final int ABS_MT_POSITION_Y = 0x36;
-    public static final int ABS_MT_TOOL_TYPE = 0x37;
-    public static final int ABS_MT_BLOB_ID = 0x38;
-    public static final int ABS_MAX = 0x3f;
-
-    // Switch events
-    public static final int SW_LID = 0x00;
-
-    public static final int SYN_REPORT = 0;
-    public static final int SYN_CONFIG = 1;
-    public static final int SYN_MT_REPORT = 2;
-    
-    public int deviceId;
-    public int type;
-    public int scancode;
-    public int keycode;
-    public int flags;
-    public int value;
-    public long when;
-}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index d1a0f75..e4d1ae1 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -625,41 +625,6 @@
             }
         }
 
-        public void dispatchKey(KeyEvent event) {
-            SurfaceView surfaceView = mSurfaceView.get();
-            if (surfaceView != null) {
-                //Log.w("SurfaceView", "Unexpected key event in surface: " + event);
-                if (surfaceView.mSession != null && surfaceView.mSurface != null) {
-                    try {
-                        surfaceView.mSession.finishKey(surfaceView.mWindow);
-                    } catch (RemoteException ex) {
-                    }
-                }
-            }
-        }
-
-        public void dispatchPointer(MotionEvent event, long eventTime,
-                boolean callWhenDone) {
-            Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
-            //if (mSession != null && mSurface != null) {
-            //    try {
-            //        //mSession.finishKey(mWindow);
-            //    } catch (RemoteException ex) {
-            //    }
-            //}
-        }
-
-        public void dispatchTrackball(MotionEvent event, long eventTime,
-                boolean callWhenDone) {
-            Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
-            //if (mSession != null && mSurface != null) {
-            //    try {
-            //        //mSession.finishKey(mWindow);
-            //    } catch (RemoteException ex) {
-            //    }
-            //}
-        }
-
         public void dispatchAppVisibility(boolean visible) {
             // The point of SurfaceView is to let the app control the surface.
         }
@@ -686,7 +651,6 @@
     private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
         
         private static final String LOG_TAG = "SurfaceHolder";
-        private int mSaveCount;
         
         public boolean isCreating() {
             return mIsCreating;
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 1dc82e8..e980b17 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -556,18 +556,16 @@
                         "Unable to add window -- unknown error code " + res);
                 }
 
-                if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
-                    if (view instanceof RootViewSurfaceTaker) {
-                        mInputQueueCallback =
-                            ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
-                    }
-                    if (mInputQueueCallback != null) {
-                        mInputQueue = new InputQueue(mInputChannel);
-                        mInputQueueCallback.onInputQueueCreated(mInputQueue);
-                    } else {
-                        InputQueue.registerInputChannel(mInputChannel, mInputHandler,
-                                Looper.myQueue());
-                    }
+                if (view instanceof RootViewSurfaceTaker) {
+                    mInputQueueCallback =
+                        ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
+                }
+                if (mInputQueueCallback != null) {
+                    mInputQueue = new InputQueue(mInputChannel);
+                    mInputQueueCallback.onInputQueueCreated(mInputQueue);
+                } else {
+                    InputQueue.registerInputChannel(mInputChannel, mInputHandler,
+                            Looper.myQueue());
                 }
                 
                 view.assignParent(this);
@@ -1745,16 +1743,12 @@
         }
         mSurface.release();
 
-        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
-            if (mInputChannel != null) {
-                if (mInputQueueCallback != null) {
-                    mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
-                    mInputQueueCallback = null;
-                } else {
-                    InputQueue.unregisterInputChannel(mInputChannel);
-                }
-                mInputChannel.dispose();
-                mInputChannel = null;
+        if (mInputChannel != null) {
+            if (mInputQueueCallback != null) {
+                mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
+                mInputQueueCallback = null;
+            } else {
+                InputQueue.unregisterInputChannel(mInputChannel);
             }
         }
         
@@ -1763,13 +1757,11 @@
         } catch (RemoteException e) {
         }
         
-        if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
-            // Dispose the input channel after removing the window so the Window Manager
-            // doesn't interpret the input channel being closed as an abnormal termination.
-            if (mInputChannel != null) {
-                mInputChannel.dispose();
-                mInputChannel = null;
-            }
+        // Dispose the input channel after removing the window so the Window Manager
+        // doesn't interpret the input channel being closed as an abnormal termination.
+        if (mInputChannel != null) {
+            mInputChannel.dispose();
+            mInputChannel = null;
         }
     }
 
@@ -1869,105 +1861,22 @@
             deliverKeyEvent((KeyEvent)msg.obj, true);
             break;
         case DISPATCH_POINTER: {
-            MotionEvent event = (MotionEvent)msg.obj;
-            boolean callWhenDone = msg.arg1 != 0;
-            
-            if (event == null) {
-                long timeBeforeGettingEvents;
-                if (MEASURE_LATENCY) {
-                    timeBeforeGettingEvents = System.nanoTime();
-                }
-
-                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());
-                }
-                callWhenDone = false;
-            }
-            if (event != null && mTranslator != null) {
-                mTranslator.translateEventInScreenToAppWindow(event);
-            }
+            MotionEvent event = (MotionEvent) msg.obj;
             try {
-                boolean handled;
-                if (mView != null && mAdded && event != null) {
-
-                    // enter touch mode on the down
-                    boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN;
-                    if (isDown) {
-                        ensureTouchMode(true);
-                    }
-                    if(Config.LOGV) {
-                        captureMotionLog("captureDispatchPointer", event);
-                    }
-                    if (mCurScrollY != 0) {
-                        event.offsetLocation(0, mCurScrollY);
-                    }
-                    if (MEASURE_LATENCY) {
-                        lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());
-                    }
-                    handled = mView.dispatchTouchEvent(event);
-                    if (MEASURE_LATENCY) {
-                        lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());
-                    }
-                    if (!handled && isDown) {
-                        int edgeSlop = mViewConfiguration.getScaledEdgeSlop();
-
-                        final int edgeFlags = event.getEdgeFlags();
-                        int direction = View.FOCUS_UP;
-                        int x = (int)event.getX();
-                        int y = (int)event.getY();
-                        final int[] deltas = new int[2];
-
-                        if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) {
-                            direction = View.FOCUS_DOWN;
-                            if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
-                                deltas[0] = edgeSlop;
-                                x += edgeSlop;
-                            } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
-                                deltas[0] = -edgeSlop;
-                                x -= edgeSlop;
-                            }
-                        } else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) {
-                            direction = View.FOCUS_UP;
-                            if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
-                                deltas[0] = edgeSlop;
-                                x += edgeSlop;
-                            } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
-                                deltas[0] = -edgeSlop;
-                                x -= edgeSlop;
-                            }
-                        } else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
-                            direction = View.FOCUS_RIGHT;
-                        } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
-                            direction = View.FOCUS_LEFT;
-                        }
-
-                        if (edgeFlags != 0 && mView instanceof ViewGroup) {
-                            View nearest = FocusFinder.getInstance().findNearestTouchable(
-                                    ((ViewGroup) mView), x, y, direction, deltas);
-                            if (nearest != null) {
-                                event.offsetLocation(deltas[0], deltas[1]);
-                                event.setEdgeFlags(0);
-                                mView.dispatchTouchEvent(event);
-                            }
-                        }
-                    }
-                }
+                deliverPointerEvent(event);
             } finally {
-                if (callWhenDone) {
-                    finishMotionEvent();
-                }
-                recycleMotionEvent(event);
+                event.recycle();
                 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.
             }
         } break;
-        case DISPATCH_TRACKBALL:
-            deliverTrackballEvent((MotionEvent)msg.obj, msg.arg1 != 0);
-            break;
+        case DISPATCH_TRACKBALL: {
+            MotionEvent event = (MotionEvent) msg.obj;
+            try {
+                deliverTrackballEvent(event);
+            } finally {
+                event.recycle();
+            }
+        } break;
         case DISPATCH_APP_VISIBILITY:
             handleAppVisibility(msg.arg1 != 0);
             break;
@@ -2101,61 +2010,12 @@
     }
     
     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) {
-            }
+        if (mFinishedCallback != null) {
+            mFinishedCallback.run();
+            mFinishedCallback = null;
         }
     }
     
-    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.
@@ -2277,42 +2137,95 @@
         return false;
     }
 
-
-    private void deliverTrackballEvent(MotionEvent event, boolean callWhenDone) {
-        if (event == null) {
-            event = getPendingTrackballMotionEvent();
-            callWhenDone = false;
+    private void deliverPointerEvent(MotionEvent event) {
+        if (mTranslator != null) {
+            mTranslator.translateEventInScreenToAppWindow(event);
         }
+        
+        boolean handled;
+        if (mView != null && mAdded) {
 
+            // enter touch mode on the down
+            boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN;
+            if (isDown) {
+                ensureTouchMode(true);
+            }
+            if(Config.LOGV) {
+                captureMotionLog("captureDispatchPointer", event);
+            }
+            if (mCurScrollY != 0) {
+                event.offsetLocation(0, mCurScrollY);
+            }
+            if (MEASURE_LATENCY) {
+                lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());
+            }
+            handled = mView.dispatchTouchEvent(event);
+            if (MEASURE_LATENCY) {
+                lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());
+            }
+            if (!handled && isDown) {
+                int edgeSlop = mViewConfiguration.getScaledEdgeSlop();
+
+                final int edgeFlags = event.getEdgeFlags();
+                int direction = View.FOCUS_UP;
+                int x = (int)event.getX();
+                int y = (int)event.getY();
+                final int[] deltas = new int[2];
+
+                if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) {
+                    direction = View.FOCUS_DOWN;
+                    if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
+                        deltas[0] = edgeSlop;
+                        x += edgeSlop;
+                    } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
+                        deltas[0] = -edgeSlop;
+                        x -= edgeSlop;
+                    }
+                } else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) {
+                    direction = View.FOCUS_UP;
+                    if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
+                        deltas[0] = edgeSlop;
+                        x += edgeSlop;
+                    } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
+                        deltas[0] = -edgeSlop;
+                        x -= edgeSlop;
+                    }
+                } else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
+                    direction = View.FOCUS_RIGHT;
+                } else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
+                    direction = View.FOCUS_LEFT;
+                }
+
+                if (edgeFlags != 0 && mView instanceof ViewGroup) {
+                    View nearest = FocusFinder.getInstance().findNearestTouchable(
+                            ((ViewGroup) mView), x, y, direction, deltas);
+                    if (nearest != null) {
+                        event.offsetLocation(deltas[0], deltas[1]);
+                        event.setEdgeFlags(0);
+                        mView.dispatchTouchEvent(event);
+                    }
+                }
+            }
+        }
+    }
+
+    private void deliverTrackballEvent(MotionEvent event) {
         if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
 
         boolean handled = false;
-        try {
-            if (event == null) {
-                handled = true;
-            } else if (mView != null && mAdded) {
-                handled = mView.dispatchTrackballEvent(event);
-                if (!handled) {
-                    // we could do something here, like changing the focus
-                    // or something?
-                }
-            }
-        } finally {
+        if (mView != null && mAdded) {
+            handled = mView.dispatchTrackballEvent(event);
             if (handled) {
-                if (callWhenDone) {
-                    finishMotionEvent();
-                }
-                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
                 // touch mode here.
                 ensureTouchMode(false);
-                //noinspection ReturnInsideFinallyBlock
                 return;
             }
-            // Let the exception fall through -- the looper will catch
-            // it and take care of the bad app for us.
+            
+            // Otherwise we could do something here, like changing the focus
+            // or something?
         }
 
         final TrackballAxis x = mTrackballAxisX;
@@ -2327,95 +2240,86 @@
             mLastTrackballTime = curTime;
         }
 
-        try {
-            final int action = event.getAction();
-            final int metastate = event.getMetaState();
-            switch (action) {
-                case MotionEvent.ACTION_DOWN:
-                    x.reset(2);
-                    y.reset(2);
-                    deliverKeyEvent(new KeyEvent(curTime, curTime,
-                            KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER,
-                            0, metastate), false);
-                    break;
-                case MotionEvent.ACTION_UP:
-                    x.reset(2);
-                    y.reset(2);
-                    deliverKeyEvent(new KeyEvent(curTime, curTime,
-                            KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER,
-                            0, metastate), false);
-                    break;
-            }
+        final int action = event.getAction();
+        final int metastate = event.getMetaState();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                x.reset(2);
+                y.reset(2);
+                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                        KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER,
+                        0, metastate), false);
+                break;
+            case MotionEvent.ACTION_UP:
+                x.reset(2);
+                y.reset(2);
+                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                        KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER,
+                        0, metastate), false);
+                break;
+        }
 
-            if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step="
-                    + x.step + " dir=" + x.dir + " acc=" + x.acceleration
-                    + " move=" + event.getX()
-                    + " / Y=" + y.position + " step="
-                    + y.step + " dir=" + y.dir + " acc=" + y.acceleration
-                    + " move=" + event.getY());
-            final float xOff = x.collect(event.getX(), event.getEventTime(), "X");
-            final float yOff = y.collect(event.getY(), event.getEventTime(), "Y");
+        if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step="
+                + x.step + " dir=" + x.dir + " acc=" + x.acceleration
+                + " move=" + event.getX()
+                + " / Y=" + y.position + " step="
+                + y.step + " dir=" + y.dir + " acc=" + y.acceleration
+                + " move=" + event.getY());
+        final float xOff = x.collect(event.getX(), event.getEventTime(), "X");
+        final float yOff = y.collect(event.getY(), event.getEventTime(), "Y");
 
-            // Generate DPAD events based on the trackball movement.
-            // We pick the axis that has moved the most as the direction of
-            // the DPAD.  When we generate DPAD events for one axis, then the
-            // other axis is reset -- we don't want to perform DPAD jumps due
-            // to slight movements in the trackball when making major movements
-            // along the other axis.
-            int keycode = 0;
-            int movement = 0;
-            float accel = 1;
-            if (xOff > yOff) {
-                movement = x.generate((2/event.getXPrecision()));
-                if (movement != 0) {
-                    keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT
-                            : KeyEvent.KEYCODE_DPAD_LEFT;
-                    accel = x.acceleration;
-                    y.reset(2);
-                }
-            } else if (yOff > 0) {
-                movement = y.generate((2/event.getYPrecision()));
-                if (movement != 0) {
-                    keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_DOWN
-                            : KeyEvent.KEYCODE_DPAD_UP;
-                    accel = y.acceleration;
-                    x.reset(2);
-                }
+        // Generate DPAD events based on the trackball movement.
+        // We pick the axis that has moved the most as the direction of
+        // the DPAD.  When we generate DPAD events for one axis, then the
+        // other axis is reset -- we don't want to perform DPAD jumps due
+        // to slight movements in the trackball when making major movements
+        // along the other axis.
+        int keycode = 0;
+        int movement = 0;
+        float accel = 1;
+        if (xOff > yOff) {
+            movement = x.generate((2/event.getXPrecision()));
+            if (movement != 0) {
+                keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT
+                        : KeyEvent.KEYCODE_DPAD_LEFT;
+                accel = x.acceleration;
+                y.reset(2);
             }
+        } else if (yOff > 0) {
+            movement = y.generate((2/event.getYPrecision()));
+            if (movement != 0) {
+                keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_DOWN
+                        : KeyEvent.KEYCODE_DPAD_UP;
+                accel = y.acceleration;
+                x.reset(2);
+            }
+        }
 
-            if (keycode != 0) {
-                if (movement < 0) movement = -movement;
-                int accelMovement = (int)(movement * accel);
-                if (DEBUG_TRACKBALL) Log.v(TAG, "Move: movement=" + movement
-                        + " accelMovement=" + accelMovement
-                        + " accel=" + accel);
-                if (accelMovement > movement) {
-                    if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
-                            + keycode);
-                    movement--;
-                    deliverKeyEvent(new KeyEvent(curTime, curTime,
-                            KeyEvent.ACTION_MULTIPLE, keycode,
-                            accelMovement-movement, metastate), false);
-                }
-                while (movement > 0) {
-                    if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
-                            + keycode);
-                    movement--;
-                    curTime = SystemClock.uptimeMillis();
-                    deliverKeyEvent(new KeyEvent(curTime, curTime,
-                            KeyEvent.ACTION_DOWN, keycode, 0, event.getMetaState()), false);
-                    deliverKeyEvent(new KeyEvent(curTime, curTime,
-                            KeyEvent.ACTION_UP, keycode, 0, metastate), false);
-                }
-                mLastTrackballTime = curTime;
+        if (keycode != 0) {
+            if (movement < 0) movement = -movement;
+            int accelMovement = (int)(movement * accel);
+            if (DEBUG_TRACKBALL) Log.v(TAG, "Move: movement=" + movement
+                    + " accelMovement=" + accelMovement
+                    + " accel=" + accel);
+            if (accelMovement > movement) {
+                if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
+                        + keycode);
+                movement--;
+                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                        KeyEvent.ACTION_MULTIPLE, keycode,
+                        accelMovement-movement, metastate), false);
             }
-        } finally {
-            if (callWhenDone) {
-                finishMotionEvent();
-                recycleMotionEvent(event);
+            while (movement > 0) {
+                if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
+                        + keycode);
+                movement--;
+                curTime = SystemClock.uptimeMillis();
+                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                        KeyEvent.ACTION_DOWN, keycode, 0, event.getMetaState()), false);
+                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                        KeyEvent.ACTION_UP, keycode, 0, metastate), false);
             }
-            // Let the exception fall through -- the looper will catch
-            // it and take care of the bad app for us.
+            mLastTrackballTime = curTime;
         }
     }
 
@@ -2862,45 +2766,20 @@
     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());
+            dispatchKey(event);
         }
 
         public void handleTouch(MotionEvent event, Runnable finishedCallback) {
             finishedCallback.run();
             
-            Message msg = obtainMessage(DISPATCH_POINTER);
-            msg.obj = event;
-            msg.arg1 = 0;
-            sendMessageAtTime(msg, event.getEventTime());
+            dispatchPointer(event);
         }
 
         public void handleTrackball(MotionEvent event, Runnable finishedCallback) {
             finishedCallback.run();
             
-            Message msg = obtainMessage(DISPATCH_TRACKBALL);
-            msg.obj = event;
-            msg.arg1 = 0;
-            sendMessageAtTime(msg, event.getEventTime());
+            dispatchTrackball(event);
         }
     };
 
@@ -2927,22 +2806,18 @@
         sendMessageAtTime(msg, event.getEventTime());
     }
 
-    public void dispatchPointer(MotionEvent event, long eventTime,
-            boolean callWhenDone) {
+    public void dispatchPointer(MotionEvent event) {
         Message msg = obtainMessage(DISPATCH_POINTER);
         msg.obj = event;
-        msg.arg1 = callWhenDone ? 1 : 0;
-        sendMessageAtTime(msg, eventTime);
+        sendMessageAtTime(msg, event.getEventTime());
     }
 
-    public void dispatchTrackball(MotionEvent event, long eventTime,
-            boolean callWhenDone) {
+    public void dispatchTrackball(MotionEvent event) {
         Message msg = obtainMessage(DISPATCH_TRACKBALL);
         msg.obj = event;
-        msg.arg1 = callWhenDone ? 1 : 0;
-        sendMessageAtTime(msg, eventTime);
+        sendMessageAtTime(msg, event.getEventTime());
     }
-
+    
     public void dispatchAppVisibility(boolean visible) {
         Message msg = obtainMessage(DISPATCH_APP_VISIBILITY);
         msg.arg1 = visible ? 1 : 0;
@@ -3073,56 +2948,11 @@
         }
     }
 
-    class EventCompletion extends Handler {
-        final IWindow mWindow;
-        final KeyEvent mKeyEvent;
-        final boolean mIsPointer;
-        final MotionEvent mMotionEvent;
-
-        EventCompletion(Looper looper, IWindow window, KeyEvent key,
-                boolean isPointer, MotionEvent motion) {
-            super(looper);
-            mWindow = window;
-            mKeyEvent = key;
-            mIsPointer = isPointer;
-            mMotionEvent = motion;
-            sendEmptyMessage(0);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (mKeyEvent != null) {
-                finishKeyEvent(mKeyEvent);
-           } else if (mIsPointer) {
-                boolean didFinish;
-                MotionEvent event = mMotionEvent;
-                if (event == null) {
-                    event = getPendingPointerMotionEvent();
-                    didFinish = true;
-                } else {
-                    didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
-                }
-                if (!didFinish) {
-                    finishMotionEvent();
-                }
-            } else {
-                MotionEvent event = mMotionEvent;
-                if (event == null) {
-                    event = getPendingTrackballMotionEvent();
-                } else {
-                    finishMotionEvent();
-                }
-            }
-        }
-    }
-
     static class W extends IWindow.Stub {
         private final WeakReference<ViewRoot> mViewRoot;
-        private final Looper mMainLooper;
 
         public W(ViewRoot viewRoot, Context context) {
             mViewRoot = new WeakReference<ViewRoot>(viewRoot);
-            mMainLooper = context.getMainLooper();
         }
 
         public void resized(int w, int h, Rect coveredInsets,
@@ -3134,40 +2964,6 @@
             }
         }
 
-        public void dispatchKey(KeyEvent event) {
-            final ViewRoot viewRoot = mViewRoot.get();
-            if (viewRoot != null) {
-                viewRoot.dispatchKey(event);
-            } else {
-                Log.w("ViewRoot.W", "Key event " + event + " but no ViewRoot available!");
-                viewRoot.new EventCompletion(mMainLooper, this, event, false, null);
-            }
-        }
-
-        public void dispatchPointer(MotionEvent event, long eventTime,
-                boolean callWhenDone) {
-            final ViewRoot viewRoot = mViewRoot.get();
-            if (viewRoot != null) {                
-                if (MEASURE_LATENCY) {
-                    // Note: eventTime is in milliseconds
-                    ViewRoot.lt.sample("* ViewRoot b4 dispatchPtr", System.nanoTime() - eventTime * 1000000);
-                }
-                viewRoot.dispatchPointer(event, eventTime, callWhenDone);
-            } else {
-                viewRoot.new EventCompletion(mMainLooper, this, null, true, event);
-            }
-        }
-
-        public void dispatchTrackball(MotionEvent event, long eventTime,
-                boolean callWhenDone) {
-            final ViewRoot viewRoot = mViewRoot.get();
-            if (viewRoot != null) {
-                viewRoot.dispatchTrackball(event, eventTime, callWhenDone);
-            } else {
-                viewRoot.new EventCompletion(mMainLooper, this, null, false, event);
-            }
-        }
-
         public void dispatchAppVisibility(boolean visible) {
             final ViewRoot viewRoot = mViewRoot.get();
             if (viewRoot != null) {
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index be1f6d2..33757f0 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -78,12 +78,6 @@
     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 = true;
 
     // flags for interceptKeyTq
     /**
@@ -555,23 +549,26 @@
     public Animation createForceHideEnterAnimation();
     
     /**
-     * Called from the key queue thread before a key is dispatched to the
-     * input thread.
+     * Called from the input reader thread before a key is enqueued.
      *
      * <p>There are some actions that need to be handled here because they
      * affect the power state of the device, for example, the power keys.
      * Generally, it's best to keep as little as possible in the queue thread
      * because it's the most fragile.
+     * @param whenNanos The event time in uptime nanoseconds.
+     * @param keyCode The key code.
+     * @param down True if the key is down.
+     * @param policyFlags The policy flags associated with the key.
+     * @param isScreenOn True if the screen is already on
      *
-     * @param event the raw input event as read from the driver
-     * @param screenIsOn true if the screen is already on
      * @return The bitwise or of the {@link #ACTION_PASS_TO_USER},
      *          {@link #ACTION_POKE_USER_ACTIVITY} and {@link #ACTION_GO_TO_SLEEP} flags.
      */
-    public int interceptKeyTq(RawInputEvent event, boolean screenIsOn);
+    public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down, int policyFlags,
+            boolean isScreenOn);
     
     /**
-     * Called from the input thread before a key is dispatched to a window.
+     * Called from the input dispatcher thread before a key is dispatched to a window.
      *
      * <p>Allows you to define
      * behavior for keys that can not be overridden by applications or redirect
@@ -583,16 +580,17 @@
      * 
      * @param win The window that currently has focus.  This is where the key
      *            event will normally go.
-     * @param code Key code.
-     * @param metaKeys bit mask of meta keys that are held.
-     * @param down Is this a key press (true) or release (false)?
+     * @param action The key event action.
+     * @param flags The key event flags.
+     * @param keyCode The key code.
+     * @param metaState bit mask of meta keys that are held.
      * @param repeatCount Number of times a key down has repeated.
-     * @param flags event's flags.
+     * @param policyFlags The policy flags associated with the key.
      * @return Returns true if the policy consumed the event and it should
      * not be further dispatched.
      */
-    public boolean interceptKeyTi(WindowState win, int code,
-                               int metaKeys, boolean down, int repeatCount, int flags);
+    public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
+            int keyCode, int metaState, int repeatCount, int policyFlags);
 
     /**
      * Called when layout of the windows is about to start.
@@ -701,85 +699,15 @@
      * Return whether the screen is currently on.
      */
     public boolean isScreenOn();
-    
+
     /**
-     * Perform any initial processing of a low-level input event before the
-     * window manager handles special keys and generates a high-level event
-     * that is dispatched to the application.
-     * 
-     * @param event The input event that has occurred.
-     * 
-     * @return Return true if you have consumed the event and do not want
-     * further processing to occur; return false for normal processing.
+     * Tell the policy that the lid switch has changed state.
+     * @param whenNanos The time when the change occurred in uptime nanoseconds.
+     * @param lidOpen True if the lid is now open.
      */
-    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
-     * true, then the system will go into a special key processing state
-     * where it drops any pending events that it cans and adjusts timeouts to
-     * try to get to this key as quickly as possible.
-     * 
-     * <p>Note that this function is called from the low-level input queue
-     * thread, with either/or the window or input lock held; be very careful
-     * about what you do here.  You absolutely should never acquire a lock
-     * that you would ever hold elsewhere while calling out into the window
-     * manager or view hierarchy.
-     * 
-     * @param keycode The key that should be checked for performing an
-     * app switch before delivering to the application.
-     * 
-     * @return Return true if this is an app switch key and special processing
-     * should happen; return false for normal processing.
-     */
-    public boolean isAppSwitchKeyTqTiLwLi(int keycode);
-    
-    /**
-     * Determine whether a given key code is used for movement within a UI,
-     * and does not generally cause actions to be performed (normally the DPAD
-     * movement keys, NOT the DPAD center press key).  This is called
-     * when {@link #isAppSwitchKeyTiLi} returns true to remove any pending events
-     * in the key queue that are not needed to switch applications.
-     * 
-     * <p>Note that this function is called from the low-level input queue
-     * thread; be very careful about what you do here.
-     * 
-     * @param keycode The key that is waiting to be delivered to the
-     * application.
-     * 
-     * @return Return true if this is a purely navigation key and can be
-     * dropped without negative consequences; return false to keep it.
-     */
-    public boolean isMovementKeyTi(int keycode);
-    
-    /**
-     * Given the current state of the world, should this relative movement
-     * wake up the device?
-     * 
-     * @param device The device the movement came from.
-     * @param classes The input classes associated with the device.
-     * @param event The input event that occurred.
-     * @return
-     */
-    public boolean isWakeRelMovementTq(int device, int classes,
-            RawInputEvent event);
-    
-    /**
-     * Given the current state of the world, should this absolute movement
-     * wake up the device?
-     * 
-     * @param device The device the movement came from.
-     * @param classes The input classes associated with the device.
-     * @param event The input event that occurred.
-     * @return
-     */
-    public boolean isWakeAbsMovementTq(int device, int classes,
-            RawInputEvent event);
-    
-    /**
      * Tell the policy if anyone is requesting that keyguard not come on.
      *
      * @param enabled Whether keyguard can be on or not.  does not actually
@@ -852,18 +780,6 @@
     public void enableScreenAfterBoot();
     
     /**
-     * Returns true if the user's cheek has been pressed against the phone. This is 
-     * determined by comparing the event's size attribute with a threshold value.
-     * For example for a motion event like down or up or move, if the size exceeds
-     * the threshold, it is considered as cheek press.
-     * @param ev the motion event generated when the cheek is pressed 
-     * against the phone
-     * @return Returns true if the user's cheek has been pressed against the phone
-     * screen resulting in an invalid motion event
-     */
-    public boolean isCheekPressedAgainstScreen(MotionEvent ev);
-    
-    /**
      * Called every time the window manager is dispatching a pointer event.
      */
     public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY);
@@ -876,13 +792,6 @@
     public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always);
     
     /**
-     * A special function that is called from the very low-level input queue
-     * to provide feedback to the user.  Currently only called for virtual
-     * keys.
-     */
-    public void keyFeedbackFromInput(KeyEvent event);
-    
-    /**
      * Called when we have stopped keeping the screen on because a window
      * requesting this is no longer visible.
      */
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index b13d656..4da74e6 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -43,59 +43,6 @@
         }
     }
 
-    public void dispatchKey(KeyEvent event) {
-        try {
-            mSession.finishKey(this);
-        } catch (RemoteException ex) {
-        }
-    }
-
-    public boolean onDispatchPointer(MotionEvent event, long eventTime,
-            boolean callWhenDone) {
-        event.recycle();
-        return false;
-    }
-    
-    public void dispatchPointer(MotionEvent event, long eventTime,
-            boolean callWhenDone) {
-        try {
-            if (event == null) {
-                event = mSession.getPendingPointerMove(this);
-                onDispatchPointer(event, eventTime, false);
-            } else if (callWhenDone) {
-                if (!onDispatchPointer(event, eventTime, true)) {
-                    mSession.finishKey(this);
-                }
-            } else {
-                onDispatchPointer(event, eventTime, false);
-            }
-        } catch (RemoteException ex) {
-        }
-    }
-
-    public boolean onDispatchTrackball(MotionEvent event, long eventTime,
-            boolean callWhenDone) {
-        event.recycle();
-        return false;
-    }
-    
-    public void dispatchTrackball(MotionEvent event, long eventTime,
-            boolean callWhenDone) {
-        try {
-            if (event == null) {
-                event = mSession.getPendingTrackballMove(this);
-                onDispatchTrackball(event, eventTime, false);
-            } else if (callWhenDone) {
-                if (!onDispatchTrackball(event, eventTime, true)) {
-                    mSession.finishKey(this);
-                }
-            } else {
-                onDispatchTrackball(event, eventTime, false);
-            }
-        } catch (RemoteException ex) {
-        }
-    }
-
     public void dispatchAppVisibility(boolean visible) {
     }
 
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 781da35..03c8112 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -250,7 +250,13 @@
         nsecs_t downTime;
 
         struct CurrentVirtualKeyState {
-            bool down;
+            enum Status {
+                STATUS_UP,
+                STATUS_DOWN,
+                STATUS_CANCELED
+            };
+
+            Status status;
             nsecs_t downTime;
             int32_t keyCode;
             int32_t scanCode;
@@ -295,6 +301,7 @@
         void calculatePointerIds();
 
         bool isPointInsideDisplay(int32_t x, int32_t y) const;
+        const InputDevice::VirtualKey* findVirtualKeyHit() const;
     };
 
     InputDevice(int32_t id, uint32_t classes, String8 name);
@@ -390,11 +397,9 @@
     virtual bool getDisplayInfo(int32_t displayId,
             int32_t* width, int32_t* height, int32_t* orientation) = 0;
 
-    /* Provides feedback for a virtual key.
+    /* Provides feedback for a virtual key down.
      */
-    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 void virtualKeyDownFeedback() = 0;
 
     /* Intercepts a key event.
      * The policy can use this method as an opportunity to perform power management functions
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 8f6d1fe..42a7fc6 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -299,14 +299,13 @@
     uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
     if (entry->refCount == 1) {
         entry->eventTime = currentTime;
-        entry->downTime = currentTime;
         entry->policyFlags = policyFlags;
         entry->repeatCount += 1;
     } else {
         KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
                 entry->deviceId, entry->nature, policyFlags,
                 entry->action, entry->flags, entry->keyCode, entry->scanCode,
-                entry->metaState, entry->repeatCount + 1, currentTime);
+                entry->metaState, entry->repeatCount + 1, entry->downTime);
 
         mKeyRepeatState.lastKeyEntry = newEntry;
         mAllocator.releaseKeyEntry(entry);
@@ -314,6 +313,10 @@
         entry = newEntry;
     }
 
+    if (entry->repeatCount == 1) {
+        entry->flags |= KEY_EVENT_FLAG_LONG_PRESS;
+    }
+
     mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout;
 
 #if DEBUG_OUTBOUND_EVENT_DETAILS
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 899027c..fced15c 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -189,7 +189,7 @@
 void InputDevice::TouchScreenState::reset() {
     lastTouch.clear();
     downTime = 0;
-    currentVirtualKey.down = false;
+    currentVirtualKey.status = CurrentVirtualKeyState::STATUS_UP;
 
     for (uint32_t i = 0; i < MAX_POINTERS; i++) {
         averagingTouchFilter.historyStart[i] = 0;
@@ -746,6 +746,29 @@
         && y <= parameters.yAxis.maxValue;
 }
 
+const InputDevice::VirtualKey* InputDevice::TouchScreenState::findVirtualKeyHit() const {
+    int32_t x = currentTouch.pointers[0].x;
+    int32_t y = currentTouch.pointers[0].y;
+    for (size_t i = 0; i < virtualKeys.size(); i++) {
+        const InputDevice::VirtualKey& virtualKey = 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)) {
+            return & virtualKey;
+        }
+    }
+
+    return NULL;
+}
+
 
 // --- InputDevice::SingleTouchScreenState ---
 
@@ -1269,81 +1292,76 @@
 
 bool InputReader::consumeVirtualKeyTouches(nsecs_t when,
         InputDevice* device, uint32_t policyFlags) {
-    if (device->touchScreen.currentVirtualKey.down) {
+    switch (device->touchScreen.currentVirtualKey.status) {
+    case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED:
         if (device->touchScreen.currentTouch.pointerCount == 0) {
-            // Pointer went up while virtual key was down.  Send key up event.
-            device->touchScreen.currentVirtualKey.down = false;
+            // Pointer went up after virtual key canceled.
+            device->touchScreen.currentVirtualKey.status =
+                    InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
+        }
+        return true; // consumed
 
+    case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN:
+        if (device->touchScreen.currentTouch.pointerCount == 0) {
+            // Pointer went up while virtual key was down.
+            device->touchScreen.currentVirtualKey.status =
+                    InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
 #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)
-                || device->touchScreen.currentTouch.pointerCount != 1) {
-            // Pointer moved inside the display area or another pointer also went down.
-            // 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
+        if (device->touchScreen.currentTouch.pointerCount == 1) {
+            const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
+            if (virtualKey
+                    && virtualKey->keyCode == device->touchScreen.currentVirtualKey.keyCode) {
+                // Pointer is still within the space of the virtual key.
+                return true; // consumed
+            }
         }
-    } else if (device->touchScreen.currentTouch.pointerCount == 1
-            && 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];
 
+        // Pointer left virtual key area or another pointer also went down.
+        // Send key cancellation.
+        device->touchScreen.currentVirtualKey.status =
+                InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED;
 #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);
+        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);
+        return true; // consumed
 
-            if (virtualKey.isHit(x, y)) {
-                device->touchScreen.currentVirtualKey.down = true;
+    default:
+        if (device->touchScreen.currentTouch.pointerCount == 1
+                && device->touchScreen.lastTouch.pointerCount == 0) {
+            // Pointer just went down.  Check for virtual key hit.
+            const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
+            if (virtualKey) {
+                device->touchScreen.currentVirtualKey.status =
+                        InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN;
                 device->touchScreen.currentVirtualKey.downTime = when;
-                device->touchScreen.currentVirtualKey.keyCode = virtualKey.keyCode;
-                device->touchScreen.currentVirtualKey.scanCode = virtualKey.scanCode;
-
+                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);
+                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
     }
-
-    return false; // not consumed
 }
 
 void InputReader::dispatchVirtualKey(nsecs_t when,
@@ -1356,8 +1374,9 @@
     nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime;
     int32_t metaState = globalMetaState();
 
-    mPolicy->virtualKeyFeedback(when, device->id, keyEventAction, keyEventFlags,
-            keyCode, scanCode, metaState, downTime);
+    if (keyEventAction == KEY_EVENT_ACTION_DOWN) {
+        mPolicy->virtualKeyDownFeedback();
+    }
 
     int32_t policyActions = mPolicy->interceptKey(when, device->id,
             keyEventAction == KEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
@@ -1852,7 +1871,7 @@
         uint32_t flags;
         if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode,
                 & keyCode, & flags)) {
-            LOGI("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
+            LOGW("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
             device->touchScreen.virtualKeys.pop(); // drop the key
             continue;
         }
@@ -1933,7 +1952,8 @@
     for (size_t i = 0; i < mDevices.size(); i++) {
         InputDevice* device = mDevices.valueAt(i);
         if (device->isTouchScreen()) {
-            if (device->touchScreen.currentVirtualKey.down) {
+            if (device->touchScreen.currentVirtualKey.status
+                    == InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN) {
                 keyCode = device->touchScreen.currentVirtualKey.keyCode;
                 scanCode = device->touchScreen.currentVirtualKey.scanCode;
             }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index a01e25b..83d9c47 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -60,7 +60,6 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.WindowOrientationListener;
-import android.view.RawInputEvent;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -153,8 +152,6 @@
     static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
     static final int APPLICATION_PANEL_SUBLAYER = 1;
     static final int APPLICATION_SUB_PANEL_SUBLAYER = 2;
-
-    static final float SLIDE_TOUCH_EVENT_SIZE_LIMIT = 0.6f;
     
     // Debugging: set this to have the system act like there is no hard keyboard.
     static final boolean KEYBOARD_ALWAYS_HIDDEN = false;
@@ -164,6 +161,10 @@
     static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
     static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
 
+    // Useful scan codes.
+    private static final int SW_LID = 0x00;
+    private static final int BTN_MOUSE = 0x110;
+    
     final Object mLock = new Object();
     
     Context mContext;
@@ -690,7 +691,7 @@
     
     void readLidState() {
         try {
-            int sw = mWindowManager.getSwitchState(RawInputEvent.SW_LID);
+            int sw = mWindowManager.getSwitchState(SW_LID);
             if (sw >= 0) {
                 mLidOpen = sw == 0;
             }
@@ -727,19 +728,6 @@
                 : Configuration.KEYBOARDHIDDEN_YES;
     }
     
-    public boolean isCheekPressedAgainstScreen(MotionEvent ev) {
-        if(ev.getSize() > SLIDE_TOUCH_EVENT_SIZE_LIMIT) {
-            return true;
-        }
-        int size = ev.getHistorySize();
-        for(int i = 0; i < size; i++) {
-            if(ev.getHistoricalSize(i) > SLIDE_TOUCH_EVENT_SIZE_LIMIT) {
-                return true;
-            }
-        }
-        return false;
-    }
-    
     public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY) {
         if (mPointerLocationView == null) {
             return;
@@ -1034,19 +1022,22 @@
         };
 
     /** {@inheritDoc} */
-    public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, 
-            int repeatCount, int flags) {
-        boolean keyguardOn = keyguardOn();
+    @Override
+    public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
+            int keyCode, int metaState, int repeatCount, int policyFlags) {
+        final boolean keyguardOn = keyguardOn();
+        final boolean down = (action == KeyEvent.ACTION_DOWN);
+        final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
 
         if (false) {
-            Log.d(TAG, "interceptKeyTi code=" + code + " down=" + down + " repeatCount="
+            Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
                     + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
         }
 
         // Clear a pending HOME longpress if the user releases Home
         // TODO: This could probably be inside the next bit of logic, but that code
         // turned out to be a bit fragile so I'm doing it here explicitly, for now.
-        if ((code == KeyEvent.KEYCODE_HOME) && !down) {
+        if ((keyCode == KeyEvent.KEYCODE_HOME) && !down) {
             mHandler.removeCallbacks(mHomeLongPress);
         }
 
@@ -1056,11 +1047,11 @@
             
             // If we have released the home key, and didn't do anything else
             // while it was pressed, then it is time to go home!
-            if (code == KeyEvent.KEYCODE_HOME) {
+            if (keyCode == KeyEvent.KEYCODE_HOME) {
                 if (!down) {
                     mHomePressed = false;
                     
-                    if ((flags&KeyEvent.FLAG_CANCELED) == 0) {
+                    if (! canceled) {
                         // If an incoming call is ringing, HOME is totally disabled.
                         // (The user is already on the InCallScreen at this point,
                         // and his ONLY options are to answer or reject the call.)
@@ -1094,7 +1085,7 @@
         // can never break it, although if keyguard is on, we do let
         // it handle it, because that gives us the correct 5 second
         // timeout.
-        if (code == KeyEvent.KEYCODE_HOME) {
+        if (keyCode == KeyEvent.KEYCODE_HOME) {
 
             // If a system window has focus, then it doesn't make sense
             // right now to interact with applications.
@@ -1122,17 +1113,17 @@
                 mHomePressed = true;
             }
             return true;
-        } else if (code == KeyEvent.KEYCODE_MENU) {
+        } else if (keyCode == KeyEvent.KEYCODE_MENU) {
             // Hijack modified menu keys for debugging features
             final int chordBug = KeyEvent.META_SHIFT_ON;
 
             if (down && repeatCount == 0) {
-                if (mEnableShiftMenuBugReports && (metaKeys & chordBug) == chordBug) {
+                if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
                     Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
                     mContext.sendOrderedBroadcast(intent, null);
                     return true;
                 } else if (SHOW_PROCESSES_ON_ALT_MENU &&
-                        (metaKeys & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
+                        (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
                     Intent service = new Intent();
                     service.setClassName(mContext, "com.android.server.LoadAverageService");
                     ContentResolver res = mContext.getContentResolver();
@@ -1148,7 +1139,7 @@
                     return true;
                 }
             }
-        } else if (code == KeyEvent.KEYCODE_SEARCH) {
+        } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
             if (down) {
                 if (repeatCount == 0) {
                     mSearchKeyPressed = true;
@@ -1167,7 +1158,7 @@
         // Shortcuts are invoked through Search+key, so intercept those here
         if (mSearchKeyPressed) {
             if (down && repeatCount == 0 && !keyguardOn) {
-                Intent shortcutIntent = mShortcutManager.getIntent(code, metaKeys);
+                Intent shortcutIntent = mShortcutManager.getIntent(keyCode, metaState);
                 if (shortcutIntent != null) {
                     shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     mContext.startActivity(shortcutIntent);
@@ -1606,42 +1597,6 @@
     }
 
     /** {@inheritDoc} */
-    public boolean preprocessInputEventTq(RawInputEvent event) {
-        switch (event.type) {
-            case RawInputEvent.EV_SW:
-                if (event.keycode == RawInputEvent.SW_LID) {
-                    // lid changed state
-                    mLidOpen = event.value == 0;
-                    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);
-                        }
-                    }
-                }
-        }
-        return false;
-    }
-    
     public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
         // lid changed state
         mLidOpen = lidOpen;
@@ -1672,26 +1627,6 @@
         }
     }
 
-    
-    /** {@inheritDoc} */
-    public boolean isAppSwitchKeyTqTiLwLi(int keycode) {
-        return keycode == KeyEvent.KEYCODE_HOME
-                || keycode == KeyEvent.KEYCODE_ENDCALL;
-    }
-    
-    /** {@inheritDoc} */
-    public boolean isMovementKeyTi(int keycode) {
-        switch (keycode) {
-            case KeyEvent.KEYCODE_DPAD_UP:
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                return true;
-        }
-        return false;
-    }
-
-
     /**
      * @return Whether a telephone call is in progress right now.
      */
@@ -1762,60 +1697,63 @@
     }
  
     /** {@inheritDoc} */
-    public int interceptKeyTq(RawInputEvent event, boolean screenIsOn) {
+    @Override
+    public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
+            int policyFlags, boolean isScreenOn) {
         int result = ACTION_PASS_TO_USER;
-        final boolean isWakeKey = isWakeKeyTq(event);
+        
+        final boolean isWakeKey = (policyFlags
+                & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
+        
         // If screen is off then we treat the case where the keyguard is open but hidden
         // the same as if it were open and in front.
         // This will prevent any keys other than the power button from waking the screen
         // when the keyguard is hidden by another activity.
-        final boolean keyguardActive = (screenIsOn ?
+        final boolean keyguardActive = (isScreenOn ?
                                         mKeyguardMediator.isShowingAndNotHidden() :
                                         mKeyguardMediator.isShowing());
 
         if (false) {
-            Log.d(TAG, "interceptKeyTq event=" + event + " keycode=" + event.keycode
-                  + " screenIsOn=" + screenIsOn + " keyguardActive=" + keyguardActive);
+            Log.d(TAG, "interceptKeyTq keycode=" + keyCode
+                  + " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
         }
 
         if (keyguardActive) {
-            if (screenIsOn) {
+            if (isScreenOn) {
                 // when the screen is on, always give the event to the keyguard
                 result |= ACTION_PASS_TO_USER;
             } else {
                 // otherwise, don't pass it to the user
                 result &= ~ACTION_PASS_TO_USER;
 
-                final boolean isKeyDown =
-                        (event.type == RawInputEvent.EV_KEY) && (event.value != 0);
-                if (isWakeKey && isKeyDown) {
+                if (isWakeKey && down) {
 
                     // tell the mediator about a wake key, it may decide to
                     // turn on the screen depending on whether the key is
                     // appropriate.
-                    if (!mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(event.keycode)
-                            && (event.keycode == KeyEvent.KEYCODE_VOLUME_DOWN
-                                || event.keycode == KeyEvent.KEYCODE_VOLUME_UP)) {
+                    if (!mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode)
+                            && (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+                                || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
                         // when keyguard is showing and screen off, we need
                         // to handle the volume key for calls and  music here
                         if (isInCall()) {
-                            handleVolumeKey(AudioManager.STREAM_VOICE_CALL, event.keycode);
+                            handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
                         } else if (isMusicActive()) {
-                            handleVolumeKey(AudioManager.STREAM_MUSIC, event.keycode);
+                            handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode);
                         }
                     }
                 }
             }
-        } else if (!screenIsOn) {
+        } else if (!isScreenOn) {
             // If we are in-call with screen off and keyguard is not showing,
             // then handle the volume key ourselves.
             // This is necessary because the phone app will disable the keyguard
             // when the proximity sensor is in use.
-            if (isInCall() && event.type == RawInputEvent.EV_KEY &&
-                     (event.keycode == KeyEvent.KEYCODE_VOLUME_DOWN
-                                || event.keycode == KeyEvent.KEYCODE_VOLUME_UP)) {
+            if (isInCall() &&
+                     (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+                                || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
                 result &= ~ACTION_PASS_TO_USER;
-                handleVolumeKey(AudioManager.STREAM_VOICE_CALL, event.keycode);
+                handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
             }
             if (isWakeKey) {
                 // a wake key has a sole purpose of waking the device; don't pass
@@ -1825,156 +1763,151 @@
             }
         }
 
-        int type = event.type;
-        int code = event.keycode;
-        boolean down = event.value != 0;
-
-        if (type == RawInputEvent.EV_KEY) {
-            if (code == KeyEvent.KEYCODE_ENDCALL
-                    || code == KeyEvent.KEYCODE_POWER) {
-                if (down) {
-                    boolean handled = false;
-                    boolean hungUp = false;
-                    // key repeats are generated by the window manager, and we don't see them
-                    // here, so unless the driver is doing something it shouldn't be, we know
-                    // this is the real press event.
-                    ITelephony phoneServ = getPhoneInterface();
-                    if (phoneServ != null) {
-                        try {
-                            if (code == KeyEvent.KEYCODE_ENDCALL) {
+        if (keyCode == KeyEvent.KEYCODE_ENDCALL
+                || keyCode == KeyEvent.KEYCODE_POWER) {
+            if (down) {
+                boolean handled = false;
+                boolean hungUp = false;
+                // key repeats are generated by the window manager, and we don't see them
+                // here, so unless the driver is doing something it shouldn't be, we know
+                // this is the real press event.
+                ITelephony phoneServ = getPhoneInterface();
+                if (phoneServ != null) {
+                    try {
+                        if (keyCode == KeyEvent.KEYCODE_ENDCALL) {
+                            handled = hungUp = phoneServ.endCall();
+                        } else if (keyCode == KeyEvent.KEYCODE_POWER) {
+                            if (phoneServ.isRinging()) {
+                                // Pressing Power while there's a ringing incoming
+                                // call should silence the ringer.
+                                phoneServ.silenceRinger();
+                                handled = true;
+                            } else if (phoneServ.isOffhook() &&
+                                       ((mIncallPowerBehavior
+                                         & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP)
+                                        != 0)) {
+                                // Otherwise, if "Power button ends call" is enabled,
+                                // the Power button will hang up any current active call.
                                 handled = hungUp = phoneServ.endCall();
-                            } else if (code == KeyEvent.KEYCODE_POWER) {
-                                if (phoneServ.isRinging()) {
-                                    // Pressing Power while there's a ringing incoming
-                                    // call should silence the ringer.
-                                    phoneServ.silenceRinger();
-                                    handled = true;
-                                } else if (phoneServ.isOffhook() &&
-                                           ((mIncallPowerBehavior
-                                             & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP)
-                                            != 0)) {
-                                    // Otherwise, if "Power button ends call" is enabled,
-                                    // the Power button will hang up any current active call.
-                                    handled = hungUp = phoneServ.endCall();
-                                }
                             }
-                        } catch (RemoteException ex) {
-                            Log.w(TAG, "ITelephony threw RemoteException" + ex);
                         }
-                    } else {
-                        Log.w(TAG, "!!! Unable to find ITelephony interface !!!");
-                    }
-
-                    if (!screenIsOn
-                            || (handled && code != KeyEvent.KEYCODE_POWER)
-                            || (handled && hungUp && code == KeyEvent.KEYCODE_POWER)) {
-                        mShouldTurnOffOnKeyUp = false;
-                    } else {
-                        // only try to turn off the screen if we didn't already hang up
-                        mShouldTurnOffOnKeyUp = true;
-                        mHandler.postDelayed(mPowerLongPress,
-                                ViewConfiguration.getGlobalActionKeyTimeout());
-                        result &= ~ACTION_PASS_TO_USER;
+                    } catch (RemoteException ex) {
+                        Log.w(TAG, "ITelephony threw RemoteException" + ex);
                     }
                 } else {
-                    mHandler.removeCallbacks(mPowerLongPress);
-                    if (mShouldTurnOffOnKeyUp) {
-                        mShouldTurnOffOnKeyUp = false;
-                        boolean gohome, sleeps;
-                        if (code == KeyEvent.KEYCODE_ENDCALL) {
-                            gohome = (mEndcallBehavior
-                                      & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0;
-                            sleeps = (mEndcallBehavior
-                                      & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0;
-                        } else {
-                            gohome = false;
-                            sleeps = true;
-                        }
-                        if (keyguardActive
-                                || (sleeps && !gohome)
-                                || (gohome && !goHome() && sleeps)) {
-                            // they must already be on the keyguad or home screen,
-                            // go to sleep instead
-                            Log.d(TAG, "I'm tired mEndcallBehavior=0x"
-                                    + Integer.toHexString(mEndcallBehavior));
-                            result &= ~ACTION_POKE_USER_ACTIVITY;
-                            result |= ACTION_GO_TO_SLEEP;
-                        }
-                        result &= ~ACTION_PASS_TO_USER;
-                    }
+                    Log.w(TAG, "!!! Unable to find ITelephony interface !!!");
                 }
-            } else if (isMediaKey(code)) {
-                // This key needs to be handled even if the screen is off.
-                // If others need to be handled while it's off, this is a reasonable
-                // pattern to follow.
-                if ((result & ACTION_PASS_TO_USER) == 0) {
-                    // Only do this if we would otherwise not pass it to the user. In that
-                    // case, the PhoneWindow class will do the same thing, except it will
-                    // only do it if the showing app doesn't process the key on its own.
-                    KeyEvent keyEvent = new KeyEvent(event.when, event.when,
-                            down ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP,
-                            code, 0);
-                    mBroadcastWakeLock.acquire();
-                    mHandler.post(new PassHeadsetKey(keyEvent));
+
+                if (!isScreenOn
+                        || (handled && keyCode != KeyEvent.KEYCODE_POWER)
+                        || (handled && hungUp && keyCode == KeyEvent.KEYCODE_POWER)) {
+                    mShouldTurnOffOnKeyUp = false;
+                } else {
+                    // only try to turn off the screen if we didn't already hang up
+                    mShouldTurnOffOnKeyUp = true;
+                    mHandler.postDelayed(mPowerLongPress,
+                            ViewConfiguration.getGlobalActionKeyTimeout());
+                    result &= ~ACTION_PASS_TO_USER;
                 }
-            } else if (code == KeyEvent.KEYCODE_CALL) {
-                // If an incoming call is ringing, answer it!
-                // (We handle this key here, rather than in the InCallScreen, to make
-                // sure we'll respond to the key even if the InCallScreen hasn't come to
-                // the foreground yet.)
-
-                // We answer the call on the DOWN event, to agree with
-                // the "fallback" behavior in the InCallScreen.
-                if (down) {
-                    try {
-                        ITelephony phoneServ = getPhoneInterface();
-                        if (phoneServ != null) {
-                            if (phoneServ.isRinging()) {
-                                Log.i(TAG, "interceptKeyTq:"
-                                      + " CALL key-down while ringing: Answer the call!");
-                                phoneServ.answerRingingCall();
-
-                                // And *don't* pass this key thru to the current activity
-                                // (which is presumably the InCallScreen.)
-                                result &= ~ACTION_PASS_TO_USER;
-                            }
-                        } else {
-                            Log.w(TAG, "CALL button: Unable to find ITelephony interface");
-                        }
-                    } catch (RemoteException ex) {
-                        Log.w(TAG, "CALL button: RemoteException from getPhoneInterface()", ex);
+            } else {
+                mHandler.removeCallbacks(mPowerLongPress);
+                if (mShouldTurnOffOnKeyUp) {
+                    mShouldTurnOffOnKeyUp = false;
+                    boolean gohome, sleeps;
+                    if (keyCode == KeyEvent.KEYCODE_ENDCALL) {
+                        gohome = (mEndcallBehavior
+                                  & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0;
+                        sleeps = (mEndcallBehavior
+                                  & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0;
+                    } else {
+                        gohome = false;
+                        sleeps = true;
                     }
+                    if (keyguardActive
+                            || (sleeps && !gohome)
+                            || (gohome && !goHome() && sleeps)) {
+                        // they must already be on the keyguad or home screen,
+                        // go to sleep instead
+                        Log.d(TAG, "I'm tired mEndcallBehavior=0x"
+                                + Integer.toHexString(mEndcallBehavior));
+                        result &= ~ACTION_POKE_USER_ACTIVITY;
+                        result |= ACTION_GO_TO_SLEEP;
+                    }
+                    result &= ~ACTION_PASS_TO_USER;
                 }
-            } else if ((code == KeyEvent.KEYCODE_VOLUME_UP)
-                       || (code == KeyEvent.KEYCODE_VOLUME_DOWN)) {
-                // If an incoming call is ringing, either VOLUME key means
-                // "silence ringer".  We handle these keys here, rather than
-                // in the InCallScreen, to make sure we'll respond to them
-                // even if the InCallScreen hasn't come to the foreground yet.
+            }
+        } else if (isMediaKey(keyCode)) {
+            // This key needs to be handled even if the screen is off.
+            // If others need to be handled while it's off, this is a reasonable
+            // pattern to follow.
+            if ((result & ACTION_PASS_TO_USER) == 0) {
+                // Only do this if we would otherwise not pass it to the user. In that
+                // case, the PhoneWindow class will do the same thing, except it will
+                // only do it if the showing app doesn't process the key on its own.
+                long when = whenNanos / 1000000;
+                KeyEvent keyEvent = new KeyEvent(when, when,
+                        down ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP,
+                        keyCode, 0);
+                mBroadcastWakeLock.acquire();
+                mHandler.post(new PassHeadsetKey(keyEvent));
+            }
+        } else if (keyCode == KeyEvent.KEYCODE_CALL) {
+            // If an incoming call is ringing, answer it!
+            // (We handle this key here, rather than in the InCallScreen, to make
+            // sure we'll respond to the key even if the InCallScreen hasn't come to
+            // the foreground yet.)
 
-                // Look for the DOWN event here, to agree with the "fallback"
-                // behavior in the InCallScreen.
-                if (down) {
-                    try {
-                        ITelephony phoneServ = getPhoneInterface();
-                        if (phoneServ != null) {
-                            if (phoneServ.isRinging()) {
-                                Log.i(TAG, "interceptKeyTq:"
-                                      + " VOLUME key-down while ringing: Silence ringer!");
-                                // Silence the ringer.  (It's safe to call this
-                                // even if the ringer has already been silenced.)
-                                phoneServ.silenceRinger();
+            // We answer the call on the DOWN event, to agree with
+            // the "fallback" behavior in the InCallScreen.
+            if (down) {
+                try {
+                    ITelephony phoneServ = getPhoneInterface();
+                    if (phoneServ != null) {
+                        if (phoneServ.isRinging()) {
+                            Log.i(TAG, "interceptKeyTq:"
+                                  + " CALL key-down while ringing: Answer the call!");
+                            phoneServ.answerRingingCall();
 
-                                // And *don't* pass this key thru to the current activity
-                                // (which is probably the InCallScreen.)
-                                result &= ~ACTION_PASS_TO_USER;
-                            }
-                        } else {
-                            Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
+                            // And *don't* pass this key thru to the current activity
+                            // (which is presumably the InCallScreen.)
+                            result &= ~ACTION_PASS_TO_USER;
                         }
-                    } catch (RemoteException ex) {
-                        Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
+                    } else {
+                        Log.w(TAG, "CALL button: Unable to find ITelephony interface");
                     }
+                } catch (RemoteException ex) {
+                    Log.w(TAG, "CALL button: RemoteException from getPhoneInterface()", ex);
+                }
+            }
+        } else if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP)
+                   || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
+            // If an incoming call is ringing, either VOLUME key means
+            // "silence ringer".  We handle these keys here, rather than
+            // in the InCallScreen, to make sure we'll respond to them
+            // even if the InCallScreen hasn't come to the foreground yet.
+
+            // Look for the DOWN event here, to agree with the "fallback"
+            // behavior in the InCallScreen.
+            if (down) {
+                try {
+                    ITelephony phoneServ = getPhoneInterface();
+                    if (phoneServ != null) {
+                        if (phoneServ.isRinging()) {
+                            Log.i(TAG, "interceptKeyTq:"
+                                  + " VOLUME key-down while ringing: Silence ringer!");
+                            // Silence the ringer.  (It's safe to call this
+                            // even if the ringer has already been silenced.)
+                            phoneServ.silenceRinger();
+
+                            // And *don't* pass this key thru to the current activity
+                            // (which is probably the InCallScreen.)
+                            result &= ~ACTION_PASS_TO_USER;
+                        }
+                    } else {
+                        Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
+                    }
+                } catch (RemoteException ex) {
+                    Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
                 }
             }
         }
@@ -2024,35 +1957,6 @@
     };
 
     /** {@inheritDoc} */
-    public boolean isWakeRelMovementTq(int device, int classes,
-            RawInputEvent event) {
-        // if it's tagged with one of the wake bits, it wakes up the device
-        return ((event.flags & (FLAG_WAKE | FLAG_WAKE_DROPPED)) != 0);
-    }
-
-    /** {@inheritDoc} */
-    public boolean isWakeAbsMovementTq(int device, int classes,
-            RawInputEvent event) {
-        // if it's tagged with one of the wake bits, it wakes up the device
-        return ((event.flags & (FLAG_WAKE | FLAG_WAKE_DROPPED)) != 0);
-    }
-
-    /**
-     * Given the current state of the world, should this key wake up the device?
-     */
-    protected boolean isWakeKeyTq(RawInputEvent event) {
-        // There are not key maps for trackball devices, but we'd still
-        // like to have pressing it wake the device up, so force it here.
-        int keycode = event.keycode;
-        int flags = event.flags;
-        if (keycode == RawInputEvent.BTN_MOUSE) {
-            flags |= WindowManagerPolicy.FLAG_WAKE;
-        }
-        return (flags
-                & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
-    }
-
-    /** {@inheritDoc} */
     public void screenTurnedOff(int why) {
         EventLog.writeEvent(70000, 0);
         mKeyguardMediator.onScreenTurnedOff(why);
@@ -2165,7 +2069,7 @@
             int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
             int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
             int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
-            int trackballState = mWindowManager.getTrackballScancodeState(RawInputEvent.BTN_MOUSE);
+            int trackballState = mWindowManager.getTrackballScancodeState(BTN_MOUSE);
             mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0;
             performHapticFeedbackLw(null, mSafeMode
                     ? HapticFeedbackConstants.SAFE_MODE_ENABLED
@@ -2413,13 +2317,6 @@
         return true;
     }
     
-    public void keyFeedbackFromInput(KeyEvent event) {
-        if (event.getAction() == KeyEvent.ACTION_DOWN
-                && (event.getFlags()&KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0) {
-            performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
-        }
-    }
-    
     public void screenOnStoppedLw() {
         if (!mKeyguardMediator.isShowingAndNotHidden() && mPowerManager.isScreenOn()) {
             long curTime = SystemClock.uptimeMillis();
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java
deleted file mode 100644
index 414b69f..0000000
--- a/services/java/com/android/server/InputDevice.java
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * Copyright (C) 2007 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.util.Slog;
-import android.view.Display;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.WindowManagerPolicy;
-
-import java.io.PrintWriter;
-
-public class InputDevice {
-    static final boolean DEBUG_POINTERS = false;
-    static final boolean DEBUG_HACKS = false;
-    
-    /** Amount that trackball needs to move in order to generate a key event. */
-    static final int TRACKBALL_MOVEMENT_THRESHOLD = 6;
-
-    /** Maximum number of pointers we will track and report. */
-    static final int MAX_POINTERS = 10;
-    
-    /**
-     * Slop distance for jumpy pointer detection.
-     * The vertical range of the screen divided by this is our epsilon value.
-     */
-    private static final int JUMPY_EPSILON_DIVISOR = 212;
-    
-    /** Number of jumpy points to drop for touchscreens that need it. */
-    private static final int JUMPY_TRANSITION_DROPS = 3;
-    private static final int JUMPY_DROP_LIMIT = 3;
-    
-    final int id;
-    final int classes;
-    final String name;
-    final AbsoluteInfo absX;
-    final AbsoluteInfo absY;
-    final AbsoluteInfo absPressure;
-    final AbsoluteInfo absSize;
-    
-    long mKeyDownTime = 0;
-    int mMetaKeysState = 0;
-    
-    // For use by KeyInputQueue for keeping track of the current touch
-    // data in the old non-multi-touch protocol.
-    final int[] curTouchVals = new int[MotionEvent.NUM_SAMPLE_DATA * 2];
-    
-    final MotionState mAbs = new MotionState(0, 0);
-    final MotionState mRel = new MotionState(TRACKBALL_MOVEMENT_THRESHOLD,
-            TRACKBALL_MOVEMENT_THRESHOLD);
-    
-    static class MotionState {
-        int xPrecision;
-        int yPrecision;
-        float xMoveScale;
-        float yMoveScale;
-        MotionEvent currentMove = null;
-        boolean changed = false;
-        boolean everChanged = false;
-        long mDownTime = 0;
-        
-        // The currently assigned pointer IDs, corresponding to the last data.
-        int[] mPointerIds = new int[MAX_POINTERS];
-        
-        // This is the last generated pointer data, ordered to match
-        // mPointerIds.
-        boolean mSkipLastPointers;
-        int mLastNumPointers = 0;
-        final int[] mLastData = new int[MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS];
-        
-        // This is the next set of pointer data being generated.  It is not
-        // in any known order, and will be propagated in to mLastData
-        // as part of mapping it to the appropriate pointer IDs.
-        // Note that we have one extra sample of data here, to help clients
-        // avoid doing bounds checking.
-        int mNextNumPointers = 0;
-        final int[] mNextData = new int[(MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS)
-                                        + MotionEvent.NUM_SAMPLE_DATA];
-        
-        // Used to determine whether we dropped bad data, to avoid doing
-        // it repeatedly.
-        final boolean[] mDroppedBadPoint = new boolean[MAX_POINTERS];
-
-        // Used to count the number of jumpy points dropped.
-        private int mJumpyPointsDropped = 0;
-        
-        // Used to perform averaging of reported coordinates, to smooth
-        // the data and filter out transients during a release.
-        static final int HISTORY_SIZE = 5;
-        int[] mHistoryDataStart = new int[MAX_POINTERS];
-        int[] mHistoryDataEnd = new int[MAX_POINTERS];
-        final int[] mHistoryData = new int[(MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS)
-                                        * HISTORY_SIZE];
-        final int[] mAveragedData = new int[MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS];
-        
-        // Temporary data structures for doing the pointer ID mapping.
-        final int[] mLast2Next = new int[MAX_POINTERS];
-        final int[] mNext2Last = new int[MAX_POINTERS];
-        final long[] mNext2LastDistance = new long[MAX_POINTERS];
-        
-        // Temporary data structure for generating the final motion data.
-        final float[] mReportData = new float[MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS];
-        
-        // This is not used here, but can be used by callers for state tracking.
-        int mAddingPointerOffset = 0;
-        final boolean[] mDown = new boolean[MAX_POINTERS];
-        
-        void dumpIntArray(PrintWriter pw, int[] array) {
-            pw.print("[");
-            for (int i=0; i<array.length; i++) {
-                if (i > 0) pw.print(", ");
-                pw.print(array[i]);
-            }
-            pw.print("]");
-        }
-        
-        void dumpBooleanArray(PrintWriter pw, boolean[] array) {
-            pw.print("[");
-            for (int i=0; i<array.length; i++) {
-                if (i > 0) pw.print(", ");
-                pw.print(array[i] ? "true" : "false");
-            }
-            pw.print("]");
-        }
-        
-        void dump(PrintWriter pw, String prefix) {
-            pw.print(prefix); pw.print("xPrecision="); pw.print(xPrecision);
-                    pw.print(" yPrecision="); pw.println(yPrecision);
-            pw.print(prefix); pw.print("xMoveScale="); pw.print(xMoveScale);
-                    pw.print(" yMoveScale="); pw.println(yMoveScale);
-            if (currentMove != null) {
-                pw.print(prefix); pw.print("currentMove="); pw.println(currentMove);
-            }
-            if (changed || mDownTime != 0) {
-                pw.print(prefix); pw.print("changed="); pw.print(changed);
-                        pw.print(" mDownTime="); pw.println(mDownTime);
-            }
-            pw.print(prefix); pw.print("mPointerIds="); dumpIntArray(pw, mPointerIds);
-                    pw.println("");
-            if (mSkipLastPointers || mLastNumPointers != 0) {
-                pw.print(prefix); pw.print("mSkipLastPointers="); pw.print(mSkipLastPointers);
-                        pw.print(" mLastNumPointers="); pw.println(mLastNumPointers);
-                pw.print(prefix); pw.print("mLastData="); dumpIntArray(pw, mLastData);
-                        pw.println("");
-            }
-            if (mNextNumPointers != 0) {
-                pw.print(prefix); pw.print("mNextNumPointers="); pw.println(mNextNumPointers);
-                pw.print(prefix); pw.print("mNextData="); dumpIntArray(pw, mNextData);
-                        pw.println("");
-            }
-            pw.print(prefix); pw.print("mDroppedBadPoint=");
-                    dumpBooleanArray(pw, mDroppedBadPoint); pw.println("");
-            pw.print(prefix); pw.print("mAddingPointerOffset="); pw.println(mAddingPointerOffset);
-            pw.print(prefix); pw.print("mDown=");
-                    dumpBooleanArray(pw, mDown); pw.println("");
-        }
-        
-        MotionState(int mx, int my) {
-            xPrecision = mx;
-            yPrecision = my;
-            xMoveScale = mx != 0 ? (1.0f/mx) : 1.0f;
-            yMoveScale = my != 0 ? (1.0f/my) : 1.0f;
-            for (int i=0; i<MAX_POINTERS; i++) {
-                mPointerIds[i] = i;
-            }
-        }
-        
-        /**
-         * 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.
-         */
-        void dropBadPoint(InputDevice dev) {
-            // We should always have absY, but let's be paranoid.
-            if (dev.absY == null) {
-                return;
-            }
-            // 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 (mNextNumPointers != mLastNumPointers) {
-                return;
-            }
-            
-            // 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.
-            final int maxDy = ((dev.absY.maxValue-dev.absY.minValue)*7)/16;
-            
-            // Look through all new points and see if any are farther than
-            // acceptable from all previous points.
-            for (int i=mNextNumPointers-1; i>=0; i--) {
-                final int ioff = i * MotionEvent.NUM_SAMPLE_DATA;
-                //final int x = mNextData[ioff + MotionEvent.SAMPLE_X];
-                final int y = mNextData[ioff + MotionEvent.SAMPLE_Y];
-                if (DEBUG_HACKS) Slog.v("InputDevice", "Looking at next point #" + i + ": y=" + y);
-                boolean dropped = false;
-                if (!mDroppedBadPoint[i] && mLastNumPointers > 0) {
-                    dropped = true;
-                    int closestDy = -1;
-                    int closestY = -1;
-                    // We will drop this new point if it is sufficiently
-                    // far away from -all- last points.
-                    for (int j=mLastNumPointers-1; j>=0; j--) {
-                        final int joff = j * MotionEvent.NUM_SAMPLE_DATA;
-                        //int dx = x - mLastData[joff + MotionEvent.SAMPLE_X];
-                        int dy = y - mLastData[joff + MotionEvent.SAMPLE_Y];
-                        //if (dx < 0) dx = -dx;
-                        if (dy < 0) dy = -dy;
-                        if (DEBUG_HACKS) Slog.v("InputDevice", "Comparing with last point #" + j
-                                + ": y=" + mLastData[joff] + " dy=" + dy);
-                        if (dy < maxDy) {
-                            dropped = false;
-                            break;
-                        } else if (closestDy < 0 || dy < closestDy) {
-                            closestDy = dy;
-                            closestY = mLastData[joff + MotionEvent.SAMPLE_Y];
-                        }
-                    }
-                    if (dropped) {
-                        dropped = true;
-                        Slog.i("InputDevice", "Dropping bad point #" + i
-                                + ": newY=" + y + " closestDy=" + closestDy
-                                + " maxDy=" + maxDy);
-                        mNextData[ioff + MotionEvent.SAMPLE_Y] = closestY;
-                        break;
-                    }
-                }
-                mDroppedBadPoint[i] = dropped;
-            }
-        }
-        
-        void dropJumpyPoint(InputDevice dev) {
-            // We should always have absY, but let's be paranoid.
-            if (dev.absY == null) {
-                return;
-            }
-            final int jumpyEpsilon = dev.absY.range / JUMPY_EPSILON_DIVISOR;
-            
-            final int nextNumPointers = mNextNumPointers;
-            final int lastNumPointers = mLastNumPointers;
-            final int[] nextData = mNextData;
-            final int[] lastData = mLastData;
-            
-            if (nextNumPointers != mLastNumPointers) {
-                if (DEBUG_HACKS) {
-                    Slog.d("InputDevice", "Different pointer count " + lastNumPointers + 
-                            " -> " + nextNumPointers);
-                    for (int i = 0; i < nextNumPointers; i++) {
-                        int ioff = i * MotionEvent.NUM_SAMPLE_DATA;
-                        Slog.d("InputDevice", "Pointer " + i + " (" + 
-                                mNextData[ioff + MotionEvent.SAMPLE_X] + ", " +
-                                mNextData[ioff + MotionEvent.SAMPLE_Y] + ")");
-                    }
-                }
-                
-                // Just drop the first few events going from 1 to 2 pointers.
-                // They're bad often enough that they're not worth considering.
-                if (lastNumPointers == 1 && nextNumPointers == 2
-                        && mJumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
-                    mNextNumPointers = 1;
-                    mJumpyPointsDropped++;
-                } else if (lastNumPointers == 2 && nextNumPointers == 1
-                        && mJumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
-                    // The event when we go from 2 -> 1 tends to be messed up too
-                    System.arraycopy(lastData, 0, nextData, 0, 
-                            lastNumPointers * MotionEvent.NUM_SAMPLE_DATA);
-                    mNextNumPointers = lastNumPointers;
-                    mJumpyPointsDropped++;
-                    
-                    if (DEBUG_HACKS) {
-                        for (int i = 0; i < mNextNumPointers; i++) {
-                            int ioff = i * MotionEvent.NUM_SAMPLE_DATA;
-                            Slog.d("InputDevice", "Pointer " + i + " replaced (" + 
-                                    mNextData[ioff + MotionEvent.SAMPLE_X] + ", " +
-                                    mNextData[ioff + MotionEvent.SAMPLE_Y] + ")");
-                        }
-                    }
-                } else {
-                    mJumpyPointsDropped = 0;
-                    
-                    if (DEBUG_HACKS) {
-                        Slog.d("InputDevice", "Transition - drop limit reset");
-                    }
-                }
-                return;
-            }
-            
-            // 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 (nextNumPointers < 2) {
-                return;
-            }
-            
-            int badPointerIndex = -1;
-            int badPointerReplaceXWith = 0;
-            int badPointerReplaceYWith = 0;
-            int badPointerDistance = Integer.MIN_VALUE;
-            for (int i = nextNumPointers - 1; i >= 0; i--) {
-                boolean dropx = false;
-                boolean dropy = false;
-                
-                // Limit how many times a jumpy point can get dropped.
-                if (mJumpyPointsDropped < JUMPY_DROP_LIMIT) {
-                    final int ioff = i * MotionEvent.NUM_SAMPLE_DATA;
-                    final int x = nextData[ioff + MotionEvent.SAMPLE_X];
-                    final int y = nextData[ioff + MotionEvent.SAMPLE_Y];
-                    
-                    if (DEBUG_HACKS) {
-                        Slog.d("InputDevice", "Point " + i + " (" + x + ", " + y + ")");
-                    }
-
-                    // Check if a touch point is too close to another's coordinates
-                    for (int j = 0; j < nextNumPointers && !dropx && !dropy; j++) {
-                        if (j == i) {
-                            continue;
-                        }
-
-                        final int joff = j * MotionEvent.NUM_SAMPLE_DATA;
-                        final int xOther = nextData[joff + MotionEvent.SAMPLE_X];
-                        final int yOther = nextData[joff + MotionEvent.SAMPLE_Y];
-
-                        dropx = Math.abs(x - xOther) <= jumpyEpsilon;
-                        dropy = Math.abs(y - yOther) <= jumpyEpsilon;
-                    }
-                    
-                    if (dropx) {
-                        int xreplace = lastData[MotionEvent.SAMPLE_X];
-                        int yreplace = lastData[MotionEvent.SAMPLE_Y];
-                        int distance = Math.abs(yreplace - y);
-                        for (int j = 1; j < lastNumPointers; j++) {
-                            final int joff = j * MotionEvent.NUM_SAMPLE_DATA;
-                            int lasty = lastData[joff + MotionEvent.SAMPLE_Y];   
-                            int currDist = Math.abs(lasty - y);
-                            if (currDist < distance) {
-                                xreplace = lastData[joff + MotionEvent.SAMPLE_X];
-                                yreplace = lasty;
-                                distance = currDist;
-                            }
-                        }
-                        
-                        int badXDelta = Math.abs(xreplace - x);
-                        if (badXDelta > badPointerDistance) {
-                            badPointerDistance = badXDelta;
-                            badPointerIndex = i;
-                            badPointerReplaceXWith = xreplace;
-                            badPointerReplaceYWith = yreplace;
-                        }
-                    } else if (dropy) {
-                        int xreplace = lastData[MotionEvent.SAMPLE_X];
-                        int yreplace = lastData[MotionEvent.SAMPLE_Y];
-                        int distance = Math.abs(xreplace - x);
-                        for (int j = 1; j < lastNumPointers; j++) {
-                            final int joff = j * MotionEvent.NUM_SAMPLE_DATA;
-                            int lastx = lastData[joff + MotionEvent.SAMPLE_X];   
-                            int currDist = Math.abs(lastx - x);
-                            if (currDist < distance) {
-                                xreplace = lastx;
-                                yreplace = lastData[joff + MotionEvent.SAMPLE_Y];
-                                distance = currDist;
-                            }
-                        }
-                        
-                        int badYDelta = Math.abs(yreplace - y);
-                        if (badYDelta > badPointerDistance) {
-                            badPointerDistance = badYDelta;
-                            badPointerIndex = i;
-                            badPointerReplaceXWith = xreplace;
-                            badPointerReplaceYWith = yreplace;
-                        }
-                    }
-                }
-            }
-            if (badPointerIndex >= 0) {
-                if (DEBUG_HACKS) {
-                    Slog.d("InputDevice", "Replacing bad pointer " + badPointerIndex +
-                            " with (" + badPointerReplaceXWith + ", " + badPointerReplaceYWith +
-                            ")");
-                }
-
-                final int offset = badPointerIndex * MotionEvent.NUM_SAMPLE_DATA;
-                nextData[offset + MotionEvent.SAMPLE_X] = badPointerReplaceXWith;
-                nextData[offset + MotionEvent.SAMPLE_Y] = badPointerReplaceYWith;
-                mJumpyPointsDropped++;
-            } else {
-                mJumpyPointsDropped = 0;
-            }
-        }
-        
-        /**
-         * 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.
-         */
-        int[] generateAveragedData(int upOrDownPointer, int lastNumPointers,
-                int nextNumPointers) {
-            final int numPointers = mLastNumPointers;
-            final int[] rawData = mLastData;
-            if (DEBUG_HACKS) Slog.v("InputDevice", "lastNumPointers=" + lastNumPointers
-                    + " nextNumPointers=" + nextNumPointers
-                    + " numPointers=" + numPointers);
-            for (int i=0; i<numPointers; i++) {
-                final int ioff = i * MotionEvent.NUM_SAMPLE_DATA;
-                // We keep the average data in offsets based on the pointer
-                // ID, so we don't need to move it around as fingers are
-                // pressed and released.
-                final int p = mPointerIds[i];
-                final int poff = p * MotionEvent.NUM_SAMPLE_DATA * HISTORY_SIZE;
-                if (i == upOrDownPointer && lastNumPointers != nextNumPointers) {
-                    if (lastNumPointers < nextNumPointers) {
-                        // This pointer is going down.  Clear its history
-                        // and start fresh.
-                        if (DEBUG_HACKS) Slog.v("InputDevice", "Pointer down @ index "
-                                + upOrDownPointer + " id " + mPointerIds[i]);
-                        mHistoryDataStart[i] = 0;
-                        mHistoryDataEnd[i] = 0;
-                        System.arraycopy(rawData, ioff, mHistoryData, poff,
-                                MotionEvent.NUM_SAMPLE_DATA);
-                        System.arraycopy(rawData, ioff, mAveragedData, ioff,
-                                MotionEvent.NUM_SAMPLE_DATA);
-                        continue;
-                    } else {
-                        // The pointer is going up.  Just fall through to
-                        // recompute the last averaged point (and don't add
-                        // it as a new point to include in the average).
-                        if (DEBUG_HACKS) Slog.v("InputDevice", "Pointer up @ index "
-                                + upOrDownPointer + " id " + mPointerIds[i]);
-                    }
-                } else {
-                    int end = mHistoryDataEnd[i];
-                    int eoff = poff + (end*MotionEvent.NUM_SAMPLE_DATA);
-                    int oldX = mHistoryData[eoff + MotionEvent.SAMPLE_X];
-                    int oldY = mHistoryData[eoff + MotionEvent.SAMPLE_Y];
-                    int newX = rawData[ioff + MotionEvent.SAMPLE_X];
-                    int newY = rawData[ioff + MotionEvent.SAMPLE_Y];
-                    int dx = newX-oldX;
-                    int dy = newY-oldY;
-                    int delta = dx*dx + dy*dy;
-                    if (DEBUG_HACKS) Slog.v("InputDevice", "Delta from last: " + delta);
-                    if (delta >= (75*75)) {
-                        // Magic number, if moving farther than this, turn
-                        // off filtering to avoid lag in response.
-                        mHistoryDataStart[i] = 0;
-                        mHistoryDataEnd[i] = 0;
-                        System.arraycopy(rawData, ioff, mHistoryData, poff,
-                                MotionEvent.NUM_SAMPLE_DATA);
-                        System.arraycopy(rawData, ioff, mAveragedData, ioff,
-                                MotionEvent.NUM_SAMPLE_DATA);
-                        continue;
-                    } else {
-                        end++;
-                        if (end >= HISTORY_SIZE) {
-                            end -= HISTORY_SIZE;
-                        }
-                        mHistoryDataEnd[i] = end;
-                        int noff = poff + (end*MotionEvent.NUM_SAMPLE_DATA);
-                        mHistoryData[noff + MotionEvent.SAMPLE_X] = newX;
-                        mHistoryData[noff + MotionEvent.SAMPLE_Y] = newY;
-                        mHistoryData[noff + MotionEvent.SAMPLE_PRESSURE]
-                                = rawData[ioff + MotionEvent.SAMPLE_PRESSURE];
-                        int start = mHistoryDataStart[i];
-                        if (end == start) {
-                            start++;
-                            if (start >= HISTORY_SIZE) {
-                                start -= HISTORY_SIZE;
-                            }
-                            mHistoryDataStart[i] = start;
-                        }
-                    }
-                }
-                
-                // Now compute the average.
-                int start = mHistoryDataStart[i];
-                int end = mHistoryDataEnd[i];
-                int x=0, y=0;
-                int totalPressure = 0;
-                while (start != end) {
-                    int soff = poff + (start*MotionEvent.NUM_SAMPLE_DATA);
-                    int pressure = mHistoryData[soff + MotionEvent.SAMPLE_PRESSURE];
-                    if (pressure <= 0) pressure = 1;
-                    x += mHistoryData[soff + MotionEvent.SAMPLE_X] * pressure;
-                    y += mHistoryData[soff + MotionEvent.SAMPLE_Y] * pressure;
-                    totalPressure += pressure;
-                    start++;
-                    if (start >= HISTORY_SIZE) start = 0;
-                }
-                int eoff = poff + (end*MotionEvent.NUM_SAMPLE_DATA);
-                int pressure = mHistoryData[eoff + MotionEvent.SAMPLE_PRESSURE];
-                if (pressure <= 0) pressure = 1;
-                x += mHistoryData[eoff + MotionEvent.SAMPLE_X] * pressure;
-                y += mHistoryData[eoff + MotionEvent.SAMPLE_Y] * pressure;
-                totalPressure += pressure;
-                x /= totalPressure;
-                y /= totalPressure;
-                if (DEBUG_HACKS) Slog.v("InputDevice", "Averaging " + totalPressure
-                        + " weight: (" + x + "," + y + ")");
-                mAveragedData[ioff + MotionEvent.SAMPLE_X] = x;
-                mAveragedData[ioff + MotionEvent.SAMPLE_Y] = y;
-                mAveragedData[ioff + MotionEvent.SAMPLE_PRESSURE] =
-                        rawData[ioff + MotionEvent.SAMPLE_PRESSURE];
-                mAveragedData[ioff + MotionEvent.SAMPLE_SIZE] =
-                        rawData[ioff + MotionEvent.SAMPLE_SIZE];
-            }
-            return mAveragedData;
-        }
-        
-        private boolean assignPointer(int nextIndex, boolean allowOverlap) {
-            final int lastNumPointers = mLastNumPointers;
-            final int[] next2Last = mNext2Last;
-            final long[] next2LastDistance = mNext2LastDistance;
-            final int[] last2Next = mLast2Next;
-            final int[] lastData = mLastData;
-            final int[] nextData = mNextData;
-            final int id = nextIndex * MotionEvent.NUM_SAMPLE_DATA;
-            
-            if (DEBUG_POINTERS) Slog.v("InputDevice", "assignPointer: nextIndex="
-                    + nextIndex + " dataOff=" + id);
-            final int x1 = nextData[id + MotionEvent.SAMPLE_X];
-            final int y1 = nextData[id + MotionEvent.SAMPLE_Y];
-            
-            long bestDistance = -1;
-            int bestIndex = -1;
-            for (int j=0; j<lastNumPointers; j++) {
-                // If we are not allowing multiple new points to be assigned
-                // to the same old pointer, then skip this one if it is already
-                // detected as a conflict (-2).
-                if (!allowOverlap && last2Next[j] < -1) {
-                    continue;
-                }
-                final int jd = j * MotionEvent.NUM_SAMPLE_DATA;
-                final int xd = lastData[jd + MotionEvent.SAMPLE_X] - x1;
-                final int yd = lastData[jd + MotionEvent.SAMPLE_Y] - y1;
-                final long distance = xd*(long)xd + yd*(long)yd;
-                if (bestDistance == -1 || distance < bestDistance) {
-                    bestDistance = distance;
-                    bestIndex = j;
-                }
-            }
-            
-            if (DEBUG_POINTERS) Slog.v("InputDevice", "New index " + nextIndex
-                    + " best old index=" + bestIndex + " (distance="
-                    + bestDistance + ")");
-            next2Last[nextIndex] = bestIndex;
-            next2LastDistance[nextIndex] = bestDistance;
-            
-            if (bestIndex < 0) {
-                return true;
-            }
-            
-            if (last2Next[bestIndex] == -1) {
-                last2Next[bestIndex] = nextIndex;
-                return false;
-            }
-            
-            if (DEBUG_POINTERS) Slog.v("InputDevice", "Old index " + bestIndex
-                    + " has multiple best new pointers!");
-            
-            last2Next[bestIndex] = -2;
-            return true;
-        }
-        
-        private int updatePointerIdentifiers() {
-            final int[] lastData = mLastData;
-            final int[] nextData = mNextData;
-            final int nextNumPointers = mNextNumPointers;
-            final int lastNumPointers = mLastNumPointers;
-            
-            if (nextNumPointers == 1 && lastNumPointers == 1) {
-                System.arraycopy(nextData, 0, lastData, 0,
-                        MotionEvent.NUM_SAMPLE_DATA);
-                return -1;
-            }
-            
-            // Clear our old state.
-            final int[] last2Next = mLast2Next;
-            for (int i=0; i<lastNumPointers; i++) {
-                last2Next[i] = -1;
-            }
-            
-            if (DEBUG_POINTERS) Slog.v("InputDevice",
-                    "Update pointers: lastNumPointers=" + lastNumPointers
-                    + " nextNumPointers=" + nextNumPointers);
-            
-            // Figure out the closes new points to the previous points.
-            final int[] next2Last = mNext2Last;
-            final long[] next2LastDistance = mNext2LastDistance;
-            boolean conflicts = false;
-            for (int i=0; i<nextNumPointers; i++) {
-                conflicts |= assignPointer(i, true);
-            }
-            
-            // Resolve ambiguities in pointer mappings, when two or more
-            // new pointer locations find their best previous location is
-            // the same.
-            if (conflicts) {
-                if (DEBUG_POINTERS) Slog.v("InputDevice", "Resolving conflicts");
-                
-                for (int i=0; i<lastNumPointers; i++) {
-                    if (last2Next[i] != -2) {
-                        continue;
-                    }
-                    
-                    // Note that this algorithm is far from perfect.  Ideally
-                    // we should do something like the one described at
-                    // http://portal.acm.org/citation.cfm?id=997856
-                    
-                    if (DEBUG_POINTERS) Slog.v("InputDevice",
-                            "Resolving last index #" + i);
-                    
-                    int numFound;
-                    do {
-                        numFound = 0;
-                        long worstDistance = 0;
-                        int worstJ = -1;
-                        for (int j=0; j<nextNumPointers; j++) {
-                            if (next2Last[j] != i) {
-                                continue;
-                            }
-                            numFound++;
-                            if (worstDistance < next2LastDistance[j]) {
-                                worstDistance = next2LastDistance[j];
-                                worstJ = j;
-                            }
-                        }
-                        
-                        if (worstJ >= 0) {
-                            if (DEBUG_POINTERS) Slog.v("InputDevice",
-                                    "Worst new pointer: " + worstJ
-                                    + " (distance=" + worstDistance + ")");
-                            if (assignPointer(worstJ, false)) {
-                                // In this case there is no last pointer
-                                // remaining for this new one!
-                                next2Last[worstJ] = -1;
-                            }
-                        }
-                    } while (numFound > 2);
-                }
-            }
-            
-            int retIndex = -1;
-            
-            if (lastNumPointers < nextNumPointers) {
-                // We have one or more new pointers that are down.  Create a
-                // new pointer identifier for one of them.
-                if (DEBUG_POINTERS) Slog.v("InputDevice", "Adding new pointer");
-                int nextId = 0;
-                int i=0;
-                while (i < lastNumPointers) {
-                    if (mPointerIds[i] > nextId) {
-                        // Found a hole, insert the pointer here.
-                        if (DEBUG_POINTERS) Slog.v("InputDevice",
-                                "Inserting new pointer at hole " + i);
-                        System.arraycopy(mPointerIds, i, mPointerIds,
-                                i+1, lastNumPointers-i);
-                        System.arraycopy(lastData, i*MotionEvent.NUM_SAMPLE_DATA,
-                                lastData, (i+1)*MotionEvent.NUM_SAMPLE_DATA,
-                                (lastNumPointers-i)*MotionEvent.NUM_SAMPLE_DATA);
-                        System.arraycopy(next2Last, i, next2Last,
-                                i+1, lastNumPointers-i);
-                        break;
-                    }
-                    i++;
-                    nextId++;
-                }
-                
-                if (DEBUG_POINTERS) Slog.v("InputDevice",
-                        "New pointer id " + nextId + " at index " + i);
-                
-                mLastNumPointers++;
-                retIndex = i;
-                mPointerIds[i] = nextId;
-                
-                // And assign this identifier to the first new pointer.
-                for (int j=0; j<nextNumPointers; j++) {
-                    if (next2Last[j] < 0) {
-                        if (DEBUG_POINTERS) Slog.v("InputDevice",
-                                "Assigning new id to new pointer index " + j);
-                        next2Last[j] = i;
-                        break;
-                    }
-                }
-            }
-            
-            // Propagate all of the current data into the appropriate
-            // location in the old data to match the pointer ID that was
-            // assigned to it.
-            for (int i=0; i<nextNumPointers; i++) {
-                int lastIndex = next2Last[i];
-                if (lastIndex >= 0) {
-                    if (DEBUG_POINTERS) Slog.v("InputDevice",
-                            "Copying next pointer index " + i
-                            + " to last index " + lastIndex);
-                    System.arraycopy(nextData, i*MotionEvent.NUM_SAMPLE_DATA,
-                            lastData, lastIndex*MotionEvent.NUM_SAMPLE_DATA,
-                            MotionEvent.NUM_SAMPLE_DATA);
-                }
-            }
-            
-            if (lastNumPointers > nextNumPointers) {
-                // One or more pointers has gone up.  Find the first one,
-                // and adjust accordingly.
-                if (DEBUG_POINTERS) Slog.v("InputDevice", "Removing old pointer");
-                for (int i=0; i<lastNumPointers; i++) {
-                    if (last2Next[i] == -1) {
-                        if (DEBUG_POINTERS) Slog.v("InputDevice",
-                                "Removing old pointer at index " + i);
-                        retIndex = i;
-                        break;
-                    }
-                }
-            }
-            
-            return retIndex;
-        }
-        
-        void removeOldPointer(int index) {
-            final int lastNumPointers = mLastNumPointers;
-            if (index >= 0 && index < lastNumPointers) {
-                System.arraycopy(mPointerIds, index+1, mPointerIds,
-                        index, lastNumPointers-index-1);
-                System.arraycopy(mLastData, (index+1)*MotionEvent.NUM_SAMPLE_DATA,
-                        mLastData, (index)*MotionEvent.NUM_SAMPLE_DATA,
-                        (lastNumPointers-index-1)*MotionEvent.NUM_SAMPLE_DATA);
-                mLastNumPointers--;
-            }
-        }
-        
-        MotionEvent generateAbsMotion(InputDevice device, long curTime,
-                long curTimeNano, Display display, int orientation,
-                int metaState) {
-            
-            if (mSkipLastPointers) {
-                mSkipLastPointers = false;
-                mLastNumPointers = 0;
-            }
-            
-            if (mNextNumPointers <= 0 && mLastNumPointers <= 0) {
-                return null;
-            }
-            
-            final int lastNumPointers = mLastNumPointers;
-            final int nextNumPointers = mNextNumPointers;
-            if (mNextNumPointers > MAX_POINTERS) {
-                Slog.w("InputDevice", "Number of pointers " + mNextNumPointers
-                        + " exceeded maximum of " + MAX_POINTERS);
-                mNextNumPointers = MAX_POINTERS;
-            }
-            
-            int upOrDownPointer = updatePointerIdentifiers();
-            
-            final float[] reportData = mReportData;
-            final int[] rawData;
-            if (KeyInputQueue.BAD_TOUCH_HACK) {
-                rawData = generateAveragedData(upOrDownPointer, lastNumPointers,
-                        nextNumPointers);
-            } else {
-                rawData = mLastData;
-            }
-            
-            final int numPointers = mLastNumPointers;
-            
-            if (DEBUG_POINTERS) Slog.v("InputDevice", "Processing "
-                    + numPointers + " pointers (going from " + lastNumPointers
-                    + " to " + nextNumPointers + ")");
-            
-            for (int i=0; i<numPointers; i++) {
-                final int pos = i * MotionEvent.NUM_SAMPLE_DATA;
-                reportData[pos + MotionEvent.SAMPLE_X] = rawData[pos + MotionEvent.SAMPLE_X];
-                reportData[pos + MotionEvent.SAMPLE_Y] = rawData[pos + MotionEvent.SAMPLE_Y];
-                reportData[pos + MotionEvent.SAMPLE_PRESSURE] = rawData[pos + MotionEvent.SAMPLE_PRESSURE];
-                reportData[pos + MotionEvent.SAMPLE_SIZE] = rawData[pos + MotionEvent.SAMPLE_SIZE];
-            }
-            
-            int action;
-            int edgeFlags = 0;
-            if (nextNumPointers != lastNumPointers) {
-                if (nextNumPointers > lastNumPointers) {
-                    if (lastNumPointers == 0) {
-                        action = MotionEvent.ACTION_DOWN;
-                        mDownTime = curTime;
-                    } else {
-                        action = MotionEvent.ACTION_POINTER_DOWN
-                                | (upOrDownPointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
-                    }
-                } else {
-                    if (numPointers == 1) {
-                        action = MotionEvent.ACTION_UP;
-                    } else {
-                        action = MotionEvent.ACTION_POINTER_UP
-                                | (upOrDownPointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
-                    }
-                }
-                currentMove = null;
-            } else {
-                action = MotionEvent.ACTION_MOVE;
-            }
-            
-            final int dispW = display.getWidth()-1;
-            final int dispH = display.getHeight()-1;
-            int w = dispW;
-            int h = dispH;
-            if (orientation == Surface.ROTATION_90
-                    || orientation == Surface.ROTATION_270) {
-                int tmp = w;
-                w = h;
-                h = tmp;
-            }
-            
-            final AbsoluteInfo absX = device.absX;
-            final AbsoluteInfo absY = device.absY;
-            final AbsoluteInfo absPressure = device.absPressure;
-            final AbsoluteInfo absSize = device.absSize;
-            for (int i=0; i<numPointers; i++) {
-                final int j = i * MotionEvent.NUM_SAMPLE_DATA;
-            
-                if (absX != null) {
-                    reportData[j + MotionEvent.SAMPLE_X] =
-                            ((reportData[j + MotionEvent.SAMPLE_X]-absX.minValue)
-                                / absX.range) * w;
-                }
-                if (absY != null) {
-                    reportData[j + MotionEvent.SAMPLE_Y] =
-                            ((reportData[j + MotionEvent.SAMPLE_Y]-absY.minValue)
-                                / absY.range) * h;
-                }
-                if (absPressure != null) {
-                    reportData[j + MotionEvent.SAMPLE_PRESSURE] = 
-                            ((reportData[j + MotionEvent.SAMPLE_PRESSURE]-absPressure.minValue)
-                                / (float)absPressure.range);
-                }
-                if (absSize != null) {
-                    reportData[j + MotionEvent.SAMPLE_SIZE] = 
-                            ((reportData[j + MotionEvent.SAMPLE_SIZE]-absSize.minValue)
-                                / (float)absSize.range);
-                }
-                
-                switch (orientation) {
-                    case Surface.ROTATION_90: {
-                        final float temp = reportData[j + MotionEvent.SAMPLE_X];
-                        reportData[j + MotionEvent.SAMPLE_X] = reportData[j + MotionEvent.SAMPLE_Y];
-                        reportData[j + MotionEvent.SAMPLE_Y] = w-temp;
-                        break;
-                    }
-                    case Surface.ROTATION_180: {
-                        reportData[j + MotionEvent.SAMPLE_X] = w-reportData[j + MotionEvent.SAMPLE_X];
-                        reportData[j + MotionEvent.SAMPLE_Y] = h-reportData[j + MotionEvent.SAMPLE_Y];
-                        break;
-                    }
-                    case Surface.ROTATION_270: {
-                        final float temp = reportData[j + MotionEvent.SAMPLE_X];
-                        reportData[j + MotionEvent.SAMPLE_X] = h-reportData[j + MotionEvent.SAMPLE_Y];
-                        reportData[j + MotionEvent.SAMPLE_Y] = temp;
-                        break;
-                    }
-                }
-            }
-            
-            // We only consider the first pointer when computing the edge
-            // flags, since they are global to the event.
-            if (action == MotionEvent.ACTION_DOWN) {
-                if (reportData[MotionEvent.SAMPLE_X] <= 0) {
-                    edgeFlags |= MotionEvent.EDGE_LEFT;
-                } else if (reportData[MotionEvent.SAMPLE_X] >= dispW) {
-                    edgeFlags |= MotionEvent.EDGE_RIGHT;
-                }
-                if (reportData[MotionEvent.SAMPLE_Y] <= 0) {
-                    edgeFlags |= MotionEvent.EDGE_TOP;
-                } else if (reportData[MotionEvent.SAMPLE_Y] >= dispH) {
-                    edgeFlags |= MotionEvent.EDGE_BOTTOM;
-                }
-            }
-            
-            if (currentMove != null) {
-                if (false) Slog.i("InputDevice", "Adding batch x="
-                        + reportData[MotionEvent.SAMPLE_X]
-                        + " y=" + reportData[MotionEvent.SAMPLE_Y]
-                        + " to " + currentMove);
-                currentMove.addBatch(curTime, reportData, metaState);
-                if (WindowManagerPolicy.WATCH_POINTER) {
-                    Slog.i("KeyInputQueue", "Updating: " + currentMove);
-                }
-                return null;
-            }
-            
-            MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime,
-                    curTimeNano, action, numPointers, mPointerIds, reportData,
-                    metaState, xPrecision, yPrecision, device.id, edgeFlags);
-            if (action == MotionEvent.ACTION_MOVE) {
-                currentMove = me;
-            }
-            
-            if (nextNumPointers < lastNumPointers) {
-                removeOldPointer(upOrDownPointer);
-            }
-            
-            return me;
-        }
-        
-        boolean hasMore() {
-            return mLastNumPointers != mNextNumPointers;
-        }
-        
-        void finish() {
-            mNextNumPointers = mAddingPointerOffset = 0;
-            mNextData[MotionEvent.SAMPLE_PRESSURE] = 0;
-        }
-        
-        MotionEvent generateRelMotion(InputDevice device, long curTime,
-                long curTimeNano, int orientation, int metaState) {
-            
-            final float[] scaled = mReportData;
-            
-            // For now we only support 1 pointer with relative motions.
-            scaled[MotionEvent.SAMPLE_X] = mNextData[MotionEvent.SAMPLE_X];
-            scaled[MotionEvent.SAMPLE_Y] = mNextData[MotionEvent.SAMPLE_Y];
-            scaled[MotionEvent.SAMPLE_PRESSURE] = 1.0f;
-            scaled[MotionEvent.SAMPLE_SIZE] = 0;
-            int edgeFlags = 0;
-            
-            int action;
-            if (mNextNumPointers != mLastNumPointers) {
-                mNextData[MotionEvent.SAMPLE_X] =
-                        mNextData[MotionEvent.SAMPLE_Y] = 0;
-                if (mNextNumPointers > 0 && mLastNumPointers == 0) {
-                    action = MotionEvent.ACTION_DOWN;
-                    mDownTime = curTime;
-                } else if (mNextNumPointers == 0) {
-                    action = MotionEvent.ACTION_UP;
-                } else {
-                    action = MotionEvent.ACTION_MOVE;
-                }
-                mLastNumPointers = mNextNumPointers;
-                currentMove = null;
-            } else {
-                action = MotionEvent.ACTION_MOVE;
-            }
-            
-            scaled[MotionEvent.SAMPLE_X] *= xMoveScale;
-            scaled[MotionEvent.SAMPLE_Y] *= yMoveScale;
-            switch (orientation) {
-                case Surface.ROTATION_90: {
-                    final float temp = scaled[MotionEvent.SAMPLE_X];
-                    scaled[MotionEvent.SAMPLE_X] = scaled[MotionEvent.SAMPLE_Y];
-                    scaled[MotionEvent.SAMPLE_Y] = -temp;
-                    break;
-                }
-                case Surface.ROTATION_180: {
-                    scaled[MotionEvent.SAMPLE_X] = -scaled[MotionEvent.SAMPLE_X];
-                    scaled[MotionEvent.SAMPLE_Y] = -scaled[MotionEvent.SAMPLE_Y];
-                    break;
-                }
-                case Surface.ROTATION_270: {
-                    final float temp = scaled[MotionEvent.SAMPLE_X];
-                    scaled[MotionEvent.SAMPLE_X] = -scaled[MotionEvent.SAMPLE_Y];
-                    scaled[MotionEvent.SAMPLE_Y] = temp;
-                    break;
-                }
-            }
-            
-            if (currentMove != null) {
-                if (false) Slog.i("InputDevice", "Adding batch x="
-                        + scaled[MotionEvent.SAMPLE_X]
-                        + " y=" + scaled[MotionEvent.SAMPLE_Y]
-                        + " to " + currentMove);
-                currentMove.addBatch(curTime, scaled, metaState);
-                if (WindowManagerPolicy.WATCH_POINTER) {
-                    Slog.i("KeyInputQueue", "Updating: " + currentMove);
-                }
-                return null;
-            }
-            
-            MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime,
-                    curTimeNano, action, 1, mPointerIds, scaled, metaState,
-                    xPrecision, yPrecision, device.id, edgeFlags);
-            if (action == MotionEvent.ACTION_MOVE) {
-                currentMove = me;
-            }
-            return me;
-        }
-    }
-    
-    static class AbsoluteInfo {
-        int minValue;
-        int maxValue;
-        int range;
-        int flat;
-        int fuzz;
-        
-        final void dump(PrintWriter pw) {
-            pw.print("minValue="); pw.print(minValue);
-            pw.print(" maxValue="); pw.print(maxValue);
-            pw.print(" range="); pw.print(range);
-            pw.print(" flat="); pw.print(flat);
-            pw.print(" fuzz="); pw.print(fuzz);
-        }
-    };
-    
-    InputDevice(int _id, int _classes, String _name,
-            AbsoluteInfo _absX, AbsoluteInfo _absY,
-            AbsoluteInfo _absPressure, AbsoluteInfo _absSize) {
-        id = _id;
-        classes = _classes;
-        name = _name;
-        absX = _absX;
-        absY = _absY;
-        absPressure = _absPressure;
-        absSize = _absSize;
-    }
-};
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index 2ba2914..cdae27c 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -56,7 +56,6 @@
     private final Callbacks mCallbacks;
     private final Context mContext;
     private final WindowManagerService mWindowManagerService;
-    private final WindowManagerPolicy mWindowManagerPolicy;
     private final PowerManager mPowerManager;
     private final PowerManagerService mPowerManagerService;
     
@@ -103,12 +102,10 @@
     
     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;
         
@@ -325,23 +322,8 @@
         private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
         
         @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);
+        public void virtualKeyDownFeedback() {
+            mWindowManagerService.mInputMonitor.virtualKeyDownFeedback();
         }
         
         @SuppressWarnings("unused")
@@ -356,7 +338,7 @@
         
         @SuppressWarnings("unused")
         public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
-            mWindowManagerPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
+            mWindowManagerService.mInputMonitor.notifyLidSwitchChanged(whenNanos, lidOpen);
         }
         
         @SuppressWarnings("unused")
@@ -380,17 +362,17 @@
         }
         
         @SuppressWarnings("unused")
-        public int interceptKeyBeforeQueueing(int deviceId, int type, int scanCode,
-                int keyCode, int policyFlags, int value, long whenNanos, boolean isScreenOn) {
-            return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(deviceId, type,
-                    scanCode, keyCode, policyFlags, value, whenNanos, isScreenOn);
+        public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
+                int policyFlags, boolean isScreenOn) {
+            return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
+                    whenNanos, keyCode, down, policyFlags, isScreenOn);
         }
         
         @SuppressWarnings("unused")
-        public boolean interceptKeyBeforeDispatching(InputChannel focus, int keyCode,
-                int metaState, boolean down, int repeatCount, int policyFlags) {
+        public boolean interceptKeyBeforeDispatching(InputChannel focus, int action,
+                int flags, int keyCode, int metaState, int repeatCount, int policyFlags) {
             return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(focus,
-                    keyCode, metaState, down, repeatCount, policyFlags);
+                    action, flags, keyCode, metaState, repeatCount, policyFlags);
         }
         
         @SuppressWarnings("unused")
@@ -401,18 +383,6 @@
         }
         
         @SuppressWarnings("unused")
-        public void goToSleep(long whenNanos) {
-            long when = whenNanos / 1000000;
-            mPowerManager.goToSleep(when);
-        }
-        
-        @SuppressWarnings("unused")
-        public void pokeUserActivity(long eventTimeNanos, int eventType) {
-            long eventTime = eventTimeNanos / 1000000;
-            mPowerManagerService.userActivity(eventTime, false, eventType, false);
-        }
-        
-        @SuppressWarnings("unused")
         public void notifyAppSwitchComing() {
             mWindowManagerService.mInputMonitor.notifyAppSwitchComing();
         }
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
deleted file mode 100644
index f62c7ee..0000000
--- a/services/java/com/android/server/KeyInputQueue.java
+++ /dev/null
@@ -1,1388 +0,0 @@
-/*
- * Copyright (C) 2007 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.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.os.Environment;
-import android.os.LatencyTimer;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.Xml;
-import android.view.Display;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.RawInputEvent;
-import android.view.Surface;
-import android.view.WindowManagerPolicy;
-
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-
-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;
-
-public abstract class KeyInputQueue {
-    static final String TAG = "KeyInputQueue";
-
-    static final boolean DEBUG = false;
-    static final boolean DEBUG_VIRTUAL_KEYS = false;
-    static final boolean DEBUG_POINTERS = false;
-    
-    /**
-     * Turn on some hacks we have to improve the touch interaction with a
-     * certain device whose screen currently is not all that good.
-     */
-    static boolean BAD_TOUCH_HACK = false;
-    
-    /**
-     * Turn on some hacks to improve touch interaction with another device
-     * where touch coordinate data can get corrupted.
-     */
-    static boolean JUMPY_TOUCH_HACK = false;
-    
-    private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
-
-    final SparseArray<InputDevice> mDevices = new SparseArray<InputDevice>();
-    final SparseArray<InputDevice> mIgnoredDevices = new SparseArray<InputDevice>();
-    final ArrayList<VirtualKey> mVirtualKeys = new ArrayList<VirtualKey>();
-    final HapticFeedbackCallback mHapticFeedbackCallback;
-    
-    int mGlobalMetaState = 0;
-    boolean mHaveGlobalMetaState = false;
-    
-    final QueuedEvent mFirst;
-    final QueuedEvent mLast;
-    QueuedEvent mCache;
-    int mCacheCount;
-
-    Display mDisplay = null;
-    int mDisplayWidth;
-    int mDisplayHeight;
-    
-    int mOrientation = Surface.ROTATION_0;
-    int[] mKeyRotationMap = null;
-    
-    VirtualKey mPressedVirtualKey = null;
-    
-    PowerManager.WakeLock mWakeLock;
-
-    static final int[] KEY_90_MAP = new int[] {
-        KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT,
-        KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_UP,
-        KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_LEFT,
-        KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_DOWN,
-    };
-    
-    static final int[] KEY_180_MAP = new int[] {
-        KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_UP,
-        KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_LEFT,
-        KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
-        KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT,
-    };
-    
-    static final int[] KEY_270_MAP = new int[] {
-        KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_LEFT,
-        KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_UP,
-        KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_RIGHT,
-        KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_DOWN,
-    };
-    
-    public static final int FILTER_REMOVE = 0;
-    public static final int FILTER_KEEP = 1;
-    public static final int FILTER_ABORT = -1;
-
-    private static final boolean MEASURE_LATENCY = false;
-    private LatencyTimer lt;
-
-    public interface FilterCallback {
-        int filterEvent(QueuedEvent ev);
-    }
-    
-    public interface HapticFeedbackCallback {
-        void virtualKeyFeedback(KeyEvent event);
-    }
-    
-    static class QueuedEvent {
-        InputDevice inputDevice;
-        long whenNano;
-        int flags; // From the raw event
-        int classType; // One of the class constants in InputEvent
-        Object event;
-        boolean inQueue;
-
-        void copyFrom(QueuedEvent that) {
-            this.inputDevice = that.inputDevice;
-            this.whenNano = that.whenNano;
-            this.flags = that.flags;
-            this.classType = that.classType;
-            this.event = that.event;
-        }
-
-        @Override
-        public String toString() {
-            return "QueuedEvent{"
-                + Integer.toHexString(System.identityHashCode(this))
-                + " " + event + "}";
-        }
-        
-        // not copied
-        QueuedEvent prev;
-        QueuedEvent next;
-    }
-
-    /**
-     * A key that exists as a part of the touch-screen, outside of the normal
-     * display area of the screen.
-     */
-    static class VirtualKey {
-        int scancode;
-        int centerx;
-        int centery;
-        int width;
-        int height;
-        
-        int hitLeft;
-        int hitTop;
-        int hitRight;
-        int hitBottom;
-        
-        InputDevice lastDevice;
-        int lastKeycode;
-        
-        boolean checkHit(int x, int y) {
-            return (x >= hitLeft && x <= hitRight
-                    && y >= hitTop && y <= hitBottom);
-        }
-        
-        void computeHitRect(InputDevice dev, int dw, int dh) {
-            if (dev == lastDevice) {
-                return;
-            }
-            
-            if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "computeHitRect for " + scancode
-                    + ": dev=" + dev + " absX=" + dev.absX + " absY=" + dev.absY);
-            
-            lastDevice = dev;
-            
-            int minx = dev.absX.minValue;
-            int maxx = dev.absX.maxValue;
-            
-            int halfw = width/2;
-            int left = centerx - halfw;
-            int right = centerx + halfw;
-            hitLeft = minx + ((left*maxx-minx)/dw);
-            hitRight = minx + ((right*maxx-minx)/dw);
-            
-            int miny = dev.absY.minValue;
-            int maxy = dev.absY.maxValue;
-            
-            int halfh = height/2;
-            int top = centery - halfh;
-            int bottom = centery + halfh;
-            hitTop = miny + ((top*maxy-miny)/dh);
-            hitBottom = miny + ((bottom*maxy-miny)/dh);
-        }
-    }
-
-    private void readVirtualKeys(String deviceName) {
-        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 {
-                        VirtualKey sb = new VirtualKey();
-                        sb.scancode = Integer.parseInt(it[i+1]);
-                        sb.centerx = Integer.parseInt(it[i+2]);
-                        sb.centery = Integer.parseInt(it[i+3]);
-                        sb.width = Integer.parseInt(it[i+4]);
-                        sb.height = Integer.parseInt(it[i+5]);
-                        if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Virtual key "
-                                + sb.scancode + ": center=" + sb.centerx + ","
-                                + sb.centery + " size=" + sb.width + "x"
-                                + sb.height);
-                        mVirtualKeys.add(sb);
-                    } 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);
-        }
-    }
-
-    private void readExcludedDevices() {
-        // 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) {
-                    if (DEBUG) Slog.v(TAG, "addExcludedDevice " + name);
-                    addExcludedDevice(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) { }
-        }
-    }
-
-    KeyInputQueue(Context context, HapticFeedbackCallback  hapticFeedbackCallback) {
-        if (MEASURE_LATENCY) {
-            lt = new LatencyTimer(100, 1000);
-        }
-
-        Resources r = context.getResources();
-        BAD_TOUCH_HACK = r.getBoolean(com.android.internal.R.bool.config_filterTouchEvents);
-        
-        JUMPY_TOUCH_HACK = r.getBoolean(com.android.internal.R.bool.config_filterJumpyTouchEvents);
-        
-        mHapticFeedbackCallback = hapticFeedbackCallback;
-        
-        if (! WindowManagerService.ENABLE_NATIVE_INPUT_DISPATCH) {
-            readExcludedDevices();
-        }
-        
-        PowerManager pm = (PowerManager)context.getSystemService(
-                                                        Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                                                        "KeyInputQueue");
-        mWakeLock.setReferenceCounted(false);
-
-        mFirst = new QueuedEvent();
-        mLast = new QueuedEvent();
-        mFirst.next = mLast;
-        mLast.prev = mFirst;
-
-        if (! WindowManagerService.ENABLE_NATIVE_INPUT_DISPATCH) {
-            mThread.start();
-        }
-    }
-
-    public void setDisplay(Display display) {
-        mDisplay = display;
-        
-        // We assume at this point that the display dimensions reflect the
-        // natural, unrotated display.  We will perform hit tests for soft
-        // buttons based on that display.
-        mDisplayWidth = display.getWidth();
-        mDisplayHeight = display.getHeight();
-    }
-    
-    public void getInputConfiguration(Configuration config) {
-        synchronized (mFirst) {
-            config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
-            config.keyboard = Configuration.KEYBOARD_NOKEYS;
-            config.navigation = Configuration.NAVIGATION_NONAV;
-            
-            final int N = mDevices.size();
-            for (int i=0; i<N; i++) {
-                InputDevice d = mDevices.valueAt(i);
-                if (d != null) {
-                    if ((d.classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
-                        config.touchscreen
-                                = Configuration.TOUCHSCREEN_FINGER;
-                        //Slog.i("foo", "***** HAVE TOUCHSCREEN!");
-                    }
-                    if ((d.classes&RawInputEvent.CLASS_ALPHAKEY) != 0) {
-                        config.keyboard
-                                = Configuration.KEYBOARD_QWERTY;
-                        //Slog.i("foo", "***** HAVE QWERTY!");
-                    }
-                    if ((d.classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
-                        config.navigation
-                                = Configuration.NAVIGATION_TRACKBALL;
-                        //Slog.i("foo", "***** HAVE TRACKBALL!");
-                    } else if ((d.classes&RawInputEvent.CLASS_DPAD) != 0) {
-                        config.navigation
-                                = Configuration.NAVIGATION_DPAD;
-                        //Slog.i("foo", "***** HAVE DPAD!");
-                    }
-                }
-            }
-        }
-    }
-    
-    public int getScancodeState(int code) {
-        synchronized (mFirst) {
-            VirtualKey vk = mPressedVirtualKey;
-            if (vk != null) {
-                if (vk.scancode == code) {
-                    return 2;
-                }
-            }
-            return nativeGetScancodeState(code);
-        }
-    }
-    
-    public int getScancodeState(int deviceId, int code) {
-        synchronized (mFirst) {
-            VirtualKey vk = mPressedVirtualKey;
-            if (vk != null) {
-                if (vk.scancode == code) {
-                    return 2;
-                }
-            }
-            return nativeGetScancodeState(deviceId, code);
-        }
-    }
-    
-    public int getTrackballScancodeState(int code) {
-        synchronized (mFirst) {
-            final int N = mDevices.size();
-            for (int i=0; i<N; i++) {
-                InputDevice dev = mDevices.valueAt(i);
-                if ((dev.classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
-                    int res = nativeGetScancodeState(dev.id, code);
-                    if (res > 0) {
-                        return res;
-                    }
-                }
-            }
-        }
-        
-        return 0;
-    }
-    
-    public int getDPadScancodeState(int code) {
-        synchronized (mFirst) {
-            final int N = mDevices.size();
-            for (int i=0; i<N; i++) {
-                InputDevice dev = mDevices.valueAt(i);
-                if ((dev.classes&RawInputEvent.CLASS_DPAD) != 0) {
-                    int res = nativeGetScancodeState(dev.id, code);
-                    if (res > 0) {
-                        return res;
-                    }
-                }
-            }
-        }
-        
-        return 0;
-    }
-    
-    public int getKeycodeState(int code) {
-        synchronized (mFirst) {
-            VirtualKey vk = mPressedVirtualKey;
-            if (vk != null) {
-                if (vk.lastKeycode == code) {
-                    return 2;
-                }
-            }
-            return nativeGetKeycodeState(code);
-        }
-    }
-    
-    public int getKeycodeState(int deviceId, int code) {
-        synchronized (mFirst) {
-            VirtualKey vk = mPressedVirtualKey;
-            if (vk != null) {
-                if (vk.lastKeycode == code) {
-                    return 2;
-                }
-            }
-            return nativeGetKeycodeState(deviceId, code);
-        }
-    }
-    
-    public int getTrackballKeycodeState(int code) {
-        synchronized (mFirst) {
-            final int N = mDevices.size();
-            for (int i=0; i<N; i++) {
-                InputDevice dev = mDevices.valueAt(i);
-                if ((dev.classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
-                    int res = nativeGetKeycodeState(dev.id, code);
-                    if (res > 0) {
-                        return res;
-                    }
-                }
-            }
-        }
-        
-        return 0;
-    }
-    
-    public int getDPadKeycodeState(int code) {
-        synchronized (mFirst) {
-            final int N = mDevices.size();
-            for (int i=0; i<N; i++) {
-                InputDevice dev = mDevices.valueAt(i);
-                if ((dev.classes&RawInputEvent.CLASS_DPAD) != 0) {
-                    int res = nativeGetKeycodeState(dev.id, code);
-                    if (res > 0) {
-                        return res;
-                    }
-                }
-            }
-        }
-        
-        return 0;
-    }
-    
-    public static native String getDeviceName(int deviceId);
-    public static native int getDeviceClasses(int deviceId);
-    public static native void addExcludedDevice(String deviceName);
-    public static native boolean getAbsoluteInfo(int deviceId, int axis,
-            InputDevice.AbsoluteInfo outInfo);
-    public static native int getSwitchState(int sw);
-    public static native int getSwitchState(int deviceId, int sw);
-    public static native int nativeGetScancodeState(int code);
-    public static native int nativeGetScancodeState(int deviceId, int code);
-    public static native int nativeGetKeycodeState(int code);
-    public static native int nativeGetKeycodeState(int deviceId, int code);
-    public static native int scancodeToKeycode(int deviceId, int scancode);
-    public static native boolean hasKeys(int[] keycodes, boolean[] keyExists);
-    
-    public static KeyEvent newKeyEvent(InputDevice device, long downTime,
-            long eventTime, boolean down, int keycode, int repeatCount,
-            int scancode, int flags) {
-        return new KeyEvent(
-                downTime, eventTime,
-                down ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP,
-                keycode, repeatCount,
-                device != null ? device.mMetaKeysState : 0,
-                device != null ? device.id : -1, scancode,
-                flags | KeyEvent.FLAG_FROM_SYSTEM);
-    }
-    
-    Thread mThread = new Thread("InputDeviceReader") {
-        public void run() {
-            if (DEBUG) Slog.v(TAG, "InputDeviceReader.run()");
-            android.os.Process.setThreadPriority(
-                    android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
-            
-            RawInputEvent ev = new RawInputEvent();
-            while (true) {
-                try {
-                    InputDevice di;
-
-                    // block, doesn't release the monitor
-                    readEvent(ev);
-
-                    boolean send = false;
-                    boolean configChanged = false;
-                    
-                    if (false) {
-                        Slog.i(TAG, "Input event: dev=0x"
-                                + Integer.toHexString(ev.deviceId)
-                                + " type=0x" + Integer.toHexString(ev.type)
-                                + " scancode=" + ev.scancode
-                                + " keycode=" + ev.keycode
-                                + " value=" + ev.value);
-                    }
-                    
-                    if (ev.type == RawInputEvent.EV_DEVICE_ADDED) {
-                        synchronized (mFirst) {
-                            di = newInputDevice(ev.deviceId);
-                            if (di.classes != 0) {
-                                // If this device is some kind of input class,
-                                // we care about it.
-                                mDevices.put(ev.deviceId, di);
-                                if ((di.classes & RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
-                                    readVirtualKeys(di.name);
-                                }
-                                // The configuration may have changed because
-                                // of this device.
-                                configChanged = true;
-                            } else {
-                                // We won't do anything with this device.
-                                mIgnoredDevices.put(ev.deviceId, di);
-                                Slog.i(TAG, "Ignoring non-input device: id=0x"
-                                        + Integer.toHexString(di.id)
-                                        + ", name=" + di.name);
-                            }
-                        }
-                    } else if (ev.type == RawInputEvent.EV_DEVICE_REMOVED) {
-                        synchronized (mFirst) {
-                            if (false) {
-                                Slog.i(TAG, "Device removed: id=0x"
-                                        + Integer.toHexString(ev.deviceId));
-                            }
-                            di = mDevices.get(ev.deviceId);
-                            if (di != null) {
-                                mDevices.delete(ev.deviceId);
-                                // The configuration may have changed because
-                                // of this device.
-                                configChanged = true;
-                            } else if ((di=mIgnoredDevices.get(ev.deviceId)) != null) {
-                                mIgnoredDevices.remove(ev.deviceId);
-                            } else {
-                                Slog.w(TAG, "Removing bad device id: "
-                                        + Integer.toHexString(ev.deviceId));
-                                continue;
-                            }
-                        }
-                    } else {
-                        di = getInputDevice(ev.deviceId);
-                        if (di == null) {
-                            // This may be some junk from an ignored device.
-                            continue;
-                        }
-                        
-                        // first crack at it
-                        send = preprocessEvent(di, ev);
-
-                        if (ev.type == RawInputEvent.EV_KEY) {
-                            di.mMetaKeysState = makeMetaState(ev.keycode,
-                                    ev.value != 0, di.mMetaKeysState);
-                            mHaveGlobalMetaState = false;
-                        }
-                    }
-
-                    if (configChanged) {
-                        synchronized (mFirst) {
-                            addLocked(di, System.nanoTime(), 0,
-                                    RawInputEvent.CLASS_CONFIGURATION_CHANGED,
-                                    null);
-                        }
-                    }
-                    
-                    if (!send) {
-                        continue;
-                    }
-                    
-                    synchronized (mFirst) {
-                        // NOTE: The event timebase absolutely must be the same
-                        // timebase as SystemClock.uptimeMillis().
-                        //curTime = gotOne ? ev.when : SystemClock.uptimeMillis();
-                        final long curTime = SystemClock.uptimeMillis();
-                        final long curTimeNano = System.nanoTime();
-                        //Slog.i(TAG, "curTime=" + curTime + ", systemClock=" + SystemClock.uptimeMillis());
-                        
-                        final int classes = di.classes;
-                        final int type = ev.type;
-                        final int scancode = ev.scancode;
-                        send = false;
-                        
-                        // Is it a key event?
-                        if (type == RawInputEvent.EV_KEY &&
-                                (classes&RawInputEvent.CLASS_KEYBOARD) != 0 &&
-                                (scancode < RawInputEvent.BTN_FIRST ||
-                                        scancode > RawInputEvent.BTN_LAST)) {
-                            boolean down;
-                            if (ev.value != 0) {
-                                down = true;
-                                di.mKeyDownTime = curTime;
-                            } else {
-                                down = false;
-                            }
-                            int keycode = rotateKeyCodeLocked(ev.keycode);
-                            addLocked(di, curTimeNano, ev.flags,
-                                    RawInputEvent.CLASS_KEYBOARD,
-                                    newKeyEvent(di, di.mKeyDownTime, curTime, down,
-                                            keycode, 0, scancode,
-                                            ((ev.flags & WindowManagerPolicy.FLAG_WOKE_HERE) != 0)
-                                             ? KeyEvent.FLAG_WOKE_HERE : 0));
-                            
-                        } else if (ev.type == RawInputEvent.EV_KEY) {
-                            // Single touch protocol: touch going down or up.
-                            if (ev.scancode == RawInputEvent.BTN_TOUCH &&
-                                    (classes&(RawInputEvent.CLASS_TOUCHSCREEN
-                                            |RawInputEvent.CLASS_TOUCHSCREEN_MT))
-                                            == RawInputEvent.CLASS_TOUCHSCREEN) {
-                                di.mAbs.changed = true;
-                                di.mAbs.mDown[0] = ev.value != 0;
-                            
-                            // Trackball (mouse) protocol: press down or up.
-                            } else if (ev.scancode == RawInputEvent.BTN_MOUSE &&
-                                    (classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
-                                di.mRel.changed = true;
-                                di.mRel.mNextNumPointers = ev.value != 0 ? 1 : 0;
-                                send = true;
-                            }
-    
-                        // Process position events from multitouch protocol.
-                        } else if (ev.type == RawInputEvent.EV_ABS &&
-                                (classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) {
-                            if (ev.scancode == RawInputEvent.ABS_MT_TOUCH_MAJOR) {
-                                di.mAbs.changed = true;
-                                di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
-                                        + MotionEvent.SAMPLE_PRESSURE] = ev.value;
-                            } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_X) {
-                                di.mAbs.changed = true;
-                                di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
-                                    + MotionEvent.SAMPLE_X] = ev.value;
-                                if (DEBUG_POINTERS) Slog.v(TAG, "MT @"
-                                        + di.mAbs.mAddingPointerOffset
-                                        + " X:" + ev.value);
-                            } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_Y) {
-                                di.mAbs.changed = true;
-                                di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
-                                    + MotionEvent.SAMPLE_Y] = ev.value;
-                                if (DEBUG_POINTERS) Slog.v(TAG, "MT @"
-                                        + di.mAbs.mAddingPointerOffset
-                                        + " Y:" + ev.value);
-                            } else if (ev.scancode == RawInputEvent.ABS_MT_WIDTH_MAJOR) {
-                                di.mAbs.changed = true;
-                                di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
-                                    + MotionEvent.SAMPLE_SIZE] = ev.value;
-                            }
-                        
-                        // Process position events from single touch protocol.
-                        } else if (ev.type == RawInputEvent.EV_ABS &&
-                                (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
-                            if (ev.scancode == RawInputEvent.ABS_X) {
-                                di.mAbs.changed = true;
-                                di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value;
-                            } else if (ev.scancode == RawInputEvent.ABS_Y) {
-                                di.mAbs.changed = true;
-                                di.curTouchVals[MotionEvent.SAMPLE_Y] = ev.value;
-                            } else if (ev.scancode == RawInputEvent.ABS_PRESSURE) {
-                                di.mAbs.changed = true;
-                                di.curTouchVals[MotionEvent.SAMPLE_PRESSURE] = ev.value;
-                                di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA
-                                                 + MotionEvent.SAMPLE_PRESSURE] = ev.value;
-                            } else if (ev.scancode == RawInputEvent.ABS_TOOL_WIDTH) {
-                                di.mAbs.changed = true;
-                                di.curTouchVals[MotionEvent.SAMPLE_SIZE] = ev.value;
-                                di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA
-                                                 + MotionEvent.SAMPLE_SIZE] = ev.value;
-                            }
-    
-                        // Process movement events from trackball (mouse) protocol.
-                        } else if (ev.type == RawInputEvent.EV_REL &&
-                                (classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
-                            // Add this relative movement into our totals.
-                            if (ev.scancode == RawInputEvent.REL_X) {
-                                di.mRel.changed = true;
-                                di.mRel.mNextData[MotionEvent.SAMPLE_X] += ev.value;
-                            } else if (ev.scancode == RawInputEvent.REL_Y) {
-                                di.mRel.changed = true;
-                                di.mRel.mNextData[MotionEvent.SAMPLE_Y] += ev.value;
-                            }
-                        }
-                        
-                        // Handle multitouch protocol sync: tells us that the
-                        // driver has returned all data for -one- of the pointers
-                        // that is currently down.
-                        if (ev.type == RawInputEvent.EV_SYN
-                                && ev.scancode == RawInputEvent.SYN_MT_REPORT
-                                && di.mAbs != null) {
-                            di.mAbs.changed = true;
-                            if (di.mAbs.mNextData[MotionEvent.SAMPLE_PRESSURE] > 0) {
-                                // If the value is <= 0, the pointer is not
-                                // down, so keep it in the count.
-                                
-                                if (di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
-                                                      + MotionEvent.SAMPLE_PRESSURE] != 0) {
-                                    final int num = di.mAbs.mNextNumPointers+1;
-                                    di.mAbs.mNextNumPointers = num;
-                                    if (DEBUG_POINTERS) Slog.v(TAG,
-                                            "MT_REPORT: now have " + num + " pointers");
-                                    final int newOffset = (num <= InputDevice.MAX_POINTERS)
-                                            ? (num * MotionEvent.NUM_SAMPLE_DATA)
-                                            : (InputDevice.MAX_POINTERS *
-                                                    MotionEvent.NUM_SAMPLE_DATA);
-                                    di.mAbs.mAddingPointerOffset = newOffset;
-                                    di.mAbs.mNextData[newOffset
-                                            + MotionEvent.SAMPLE_PRESSURE] = 0;
-                                } else {
-                                    if (DEBUG_POINTERS) Slog.v(TAG, "MT_REPORT: no pointer");
-                                }
-                            }
-                        
-                        // Handle general event sync: all data for the current
-                        // event update has been delivered.
-                        } else if (send || (ev.type == RawInputEvent.EV_SYN
-                                && ev.scancode == RawInputEvent.SYN_REPORT)) {
-                            if (mDisplay != null) {
-                                if (!mHaveGlobalMetaState) {
-                                    computeGlobalMetaStateLocked();
-                                }
-                                
-                                MotionEvent me;
-                                
-                                InputDevice.MotionState ms = di.mAbs;
-                                if (ms.changed) {
-                                    ms.everChanged = true;
-                                    ms.changed = false;
-                                    
-                                    if ((classes&(RawInputEvent.CLASS_TOUCHSCREEN
-                                            |RawInputEvent.CLASS_TOUCHSCREEN_MT))
-                                            == RawInputEvent.CLASS_TOUCHSCREEN) {
-                                        ms.mNextNumPointers = 0;
-                                        if (ms.mDown[0]) {
-                                            System.arraycopy(di.curTouchVals, 0,
-                                                    ms.mNextData, 0,
-                                                    MotionEvent.NUM_SAMPLE_DATA);
-                                            ms.mNextNumPointers++;
-                                        }
-                                    }
-                                    
-                                    if (BAD_TOUCH_HACK) {
-                                        ms.dropBadPoint(di);
-                                    }
-                                    if (JUMPY_TOUCH_HACK) {
-                                        ms.dropJumpyPoint(di);
-                                    }
-                                    
-                                    boolean doMotion = !monitorVirtualKey(di,
-                                            ev, curTime, curTimeNano);
-                                    
-                                    if (doMotion && ms.mNextNumPointers > 0
-                                            && (ms.mLastNumPointers == 0
-                                                    || ms.mSkipLastPointers)) {
-                                        doMotion = !generateVirtualKeyDown(di,
-                                                ev, curTime, curTimeNano);
-                                    }
-                                    
-                                    if (doMotion) {
-                                        // XXX Need to be able to generate
-                                        // multiple events here, for example
-                                        // if two fingers change up/down state
-                                        // at the same time.
-                                        do {
-                                            me = ms.generateAbsMotion(di, curTime,
-                                                    curTimeNano, mDisplay,
-                                                    mOrientation, mGlobalMetaState);
-                                            if (DEBUG_POINTERS) Slog.v(TAG, "Absolute: x="
-                                                    + di.mAbs.mNextData[MotionEvent.SAMPLE_X]
-                                                    + " y="
-                                                    + di.mAbs.mNextData[MotionEvent.SAMPLE_Y]
-                                                    + " ev=" + me);
-                                            if (me != null) {
-                                                if (WindowManagerPolicy.WATCH_POINTER) {
-                                                    Slog.i(TAG, "Enqueueing: " + me);
-                                                }
-                                                addLocked(di, curTimeNano, ev.flags,
-                                                        RawInputEvent.CLASS_TOUCHSCREEN, me);
-                                            }
-                                        } while (ms.hasMore());
-                                    } else {
-                                        // We are consuming movement in the
-                                        // virtual key area...  but still
-                                        // propagate this to the previous
-                                        // data for comparisons.
-                                        int num = ms.mNextNumPointers;
-                                        if (num > InputDevice.MAX_POINTERS) {
-                                            num = InputDevice.MAX_POINTERS;
-                                        }
-                                        System.arraycopy(ms.mNextData, 0,
-                                                ms.mLastData, 0,
-                                                num * MotionEvent.NUM_SAMPLE_DATA);
-                                        ms.mLastNumPointers = num;
-                                        ms.mSkipLastPointers = true;
-                                    }
-                                    
-                                    ms.finish();
-                                }
-                                
-                                ms = di.mRel;
-                                if (ms.changed) {
-                                    ms.everChanged = true;
-                                    ms.changed = false;
-                                    
-                                    me = ms.generateRelMotion(di, curTime,
-                                            curTimeNano,
-                                            mOrientation, mGlobalMetaState);
-                                    if (false) Slog.v(TAG, "Relative: x="
-                                            + di.mRel.mNextData[MotionEvent.SAMPLE_X]
-                                            + " y="
-                                            + di.mRel.mNextData[MotionEvent.SAMPLE_Y]
-                                            + " ev=" + me);
-                                    if (me != null) {
-                                        addLocked(di, curTimeNano, ev.flags,
-                                                RawInputEvent.CLASS_TRACKBALL, me);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                
-                } catch (RuntimeException exc) {
-                    Slog.e(TAG, "InputReaderThread uncaught exception", exc);
-                }
-            }
-        }
-    };
-
-    private boolean isInsideDisplay(InputDevice dev) {
-        final InputDevice.AbsoluteInfo absx = dev.absX;
-        final InputDevice.AbsoluteInfo absy = dev.absY;
-        final InputDevice.MotionState absm = dev.mAbs;
-        if (absx == null || absy == null || absm == null) {
-            return true;
-        }
-        
-        if (absm.mNextData[MotionEvent.SAMPLE_X] >= absx.minValue
-                && absm.mNextData[MotionEvent.SAMPLE_X] <= absx.maxValue
-                && absm.mNextData[MotionEvent.SAMPLE_Y] >= absy.minValue
-                && absm.mNextData[MotionEvent.SAMPLE_Y] <= absy.maxValue) {
-            if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Input ("
-                    + absm.mNextData[MotionEvent.SAMPLE_X]
-                    + "," + absm.mNextData[MotionEvent.SAMPLE_Y]
-                    + ") inside of display");
-            return true;
-        }
-        
-        return false;
-    }
-    
-    private VirtualKey findVirtualKey(InputDevice dev) {
-        final int N = mVirtualKeys.size();
-        if (N <= 0) {
-            return null;
-        }
-        
-        final InputDevice.MotionState absm = dev.mAbs;
-        for (int i=0; i<N; i++) {
-            VirtualKey sb = mVirtualKeys.get(i);
-            sb.computeHitRect(dev, mDisplayWidth, mDisplayHeight);
-            if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Hit test ("
-                    + absm.mNextData[MotionEvent.SAMPLE_X] + ","
-                    + absm.mNextData[MotionEvent.SAMPLE_Y] + ") in code "
-                    + sb.scancode + " - (" + sb.hitLeft
-                    + "," + sb.hitTop + ")-(" + sb.hitRight + ","
-                    + sb.hitBottom + ")");
-            if (sb.checkHit(absm.mNextData[MotionEvent.SAMPLE_X],
-                    absm.mNextData[MotionEvent.SAMPLE_Y])) {
-                if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Hit!");
-                return sb;
-            }
-        }
-        
-        return null;
-    }
-    
-    private boolean generateVirtualKeyDown(InputDevice di, RawInputEvent ev,
-            long curTime, long curTimeNano) {
-        if (isInsideDisplay(di)) {
-            // Didn't consume event.
-            return false;
-        }
-        
-        
-        VirtualKey vk = findVirtualKey(di);
-        if (vk != null) {
-            final InputDevice.MotionState ms = di.mAbs;
-            mPressedVirtualKey = vk;
-            vk.lastKeycode = scancodeToKeycode(di.id, vk.scancode);
-            ms.mLastNumPointers = ms.mNextNumPointers;
-            di.mKeyDownTime = curTime;
-            if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG,
-                    "Generate key down for: " + vk.scancode
-                    + " (keycode=" + vk.lastKeycode + ")");
-            KeyEvent event = newKeyEvent(di, di.mKeyDownTime, curTime, true,
-                    vk.lastKeycode, 0, vk.scancode,
-                    KeyEvent.FLAG_VIRTUAL_HARD_KEY);
-            mHapticFeedbackCallback.virtualKeyFeedback(event);
-            addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD,
-                    event);
-        }
-        
-        // We always consume the event, even if we didn't
-        // generate a key event.  There are two reasons for
-        // this: to avoid spurious touches when holding
-        // the edges of the device near the touchscreen,
-        // and to avoid reporting events if there are virtual
-        // keys on the touchscreen outside of the display
-        // area.
-        // Note that for all of this we are only looking at the
-        // first pointer, since what we are handling here is the
-        // first pointer going down, and this is the coordinate
-        // that will be used to dispatch the event.
-        if (false) {
-            final InputDevice.AbsoluteInfo absx = di.absX;
-            final InputDevice.AbsoluteInfo absy = di.absY;
-            final InputDevice.MotionState absm = di.mAbs;
-            Slog.v(TAG, "Rejecting ("
-                + absm.mNextData[MotionEvent.SAMPLE_X] + ","
-                + absm.mNextData[MotionEvent.SAMPLE_Y] + "): outside of ("
-                + absx.minValue + "," + absy.minValue
-                + ")-(" + absx.maxValue + ","
-                + absx.maxValue + ")");
-        }
-        return true;
-    }
-    
-    private boolean monitorVirtualKey(InputDevice di, RawInputEvent ev,
-            long curTime, long curTimeNano) {
-        VirtualKey vk = mPressedVirtualKey;
-        if (vk == null) {
-            return false;
-        }
-        
-        final InputDevice.MotionState ms = di.mAbs;
-        if (ms.mNextNumPointers <= 0) {
-            mPressedVirtualKey = null;
-            ms.mLastNumPointers = 0;
-            if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Generate key up for: " + vk.scancode);
-            KeyEvent event = newKeyEvent(di, di.mKeyDownTime, curTime, false,
-                    vk.lastKeycode, 0, vk.scancode,
-                    KeyEvent.FLAG_VIRTUAL_HARD_KEY);
-            mHapticFeedbackCallback.virtualKeyFeedback(event);
-            addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD,
-                    event);
-            return true;
-            
-        } else if (isInsideDisplay(di)) {
-            // Whoops the pointer has moved into
-            // the display area!  Cancel the
-            // virtual key and start a pointer
-            // motion.
-            mPressedVirtualKey = null;
-            if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Cancel key up for: " + vk.scancode);
-            KeyEvent event = newKeyEvent(di, di.mKeyDownTime, curTime, false,
-                    vk.lastKeycode, 0, vk.scancode,
-                    KeyEvent.FLAG_CANCELED | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
-            mHapticFeedbackCallback.virtualKeyFeedback(event);
-            addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD,
-                    event);
-            ms.mLastNumPointers = 0;
-            return false;
-        }
-        
-        return true;
-    }
-    
-    /**
-     * Returns a new meta state for the given keys and old state.
-     */
-    private static final int makeMetaState(int keycode, boolean down, int old) {
-        int mask;
-        switch (keycode) {
-        case KeyEvent.KEYCODE_ALT_LEFT:
-            mask = KeyEvent.META_ALT_LEFT_ON;
-            break;
-        case KeyEvent.KEYCODE_ALT_RIGHT:
-            mask = KeyEvent.META_ALT_RIGHT_ON;
-            break;
-        case KeyEvent.KEYCODE_SHIFT_LEFT:
-            mask = KeyEvent.META_SHIFT_LEFT_ON;
-            break;
-        case KeyEvent.KEYCODE_SHIFT_RIGHT:
-            mask = KeyEvent.META_SHIFT_RIGHT_ON;
-            break;
-        case KeyEvent.KEYCODE_SYM:
-            mask = KeyEvent.META_SYM_ON;
-            break;
-        default:
-            return old;
-        }
-        int result = ~(KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)
-                    & (down ? (old | mask) : (old & ~mask));
-        if (0 != (result & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON))) {
-            result |= KeyEvent.META_ALT_ON;
-        }
-        if (0 != (result & (KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON))) {
-            result |= KeyEvent.META_SHIFT_ON;
-        }
-        return result;
-    }
-
-    private void computeGlobalMetaStateLocked() {
-        int i = mDevices.size();
-        mGlobalMetaState = 0;
-        while ((--i) >= 0) {
-            mGlobalMetaState |= mDevices.valueAt(i).mMetaKeysState;
-        }
-        mHaveGlobalMetaState = true;
-    }
-    
-    /*
-     * Return true if you want the event to get passed on to the 
-     * rest of the system, and false if you've handled it and want
-     * it dropped.
-     */
-    abstract boolean preprocessEvent(InputDevice device, RawInputEvent event);
-
-    InputDevice getInputDevice(int deviceId) {
-        synchronized (mFirst) {
-            return getInputDeviceLocked(deviceId);
-        }
-    }
-    
-    private InputDevice getInputDeviceLocked(int deviceId) {
-        return mDevices.get(deviceId);
-    }
-
-    public void setOrientation(int orientation) {
-        synchronized(mFirst) {
-            mOrientation = orientation;
-            switch (orientation) {
-                case Surface.ROTATION_90:
-                    mKeyRotationMap = KEY_90_MAP;
-                    break;
-                case Surface.ROTATION_180:
-                    mKeyRotationMap = KEY_180_MAP;
-                    break;
-                case Surface.ROTATION_270:
-                    mKeyRotationMap = KEY_270_MAP;
-                    break;
-                default:
-                    mKeyRotationMap = null;
-                    break;
-            }
-        }
-    }
-    
-    public int rotateKeyCode(int keyCode) {
-        synchronized(mFirst) {
-            return rotateKeyCodeLocked(keyCode);
-        }
-    }
-    
-    private int rotateKeyCodeLocked(int keyCode) {
-        int[] map = mKeyRotationMap;
-        if (map != null) {
-            final int N = map.length;
-            for (int i=0; i<N; i+=2) {
-                if (map[i] == keyCode) {
-                    return map[i+1];
-                }
-            }
-        }
-        return keyCode;
-    }
-    
-    boolean hasEvents() {
-        synchronized (mFirst) {
-            return mFirst.next != mLast;
-        }
-    }
-    
-    /*
-     * returns true if we returned an event, and false if we timed out
-     */
-    QueuedEvent getEvent(long timeoutMS) {
-        long begin = SystemClock.uptimeMillis();
-        final long end = begin+timeoutMS;
-        long now = begin;
-        synchronized (mFirst) {
-            while (mFirst.next == mLast && end > now) {
-                try {
-                    mWakeLock.release();
-                    mFirst.wait(end-now);
-                }
-                catch (InterruptedException e) {
-                }
-                now = SystemClock.uptimeMillis();
-                if (begin > now) {
-                    begin = now;
-                }
-            }
-            if (mFirst.next == mLast) {
-                return null;
-            }
-            QueuedEvent p = mFirst.next;
-            mFirst.next = p.next;
-            mFirst.next.prev = mFirst;
-            p.inQueue = false;
-            return p;
-        }
-    }
-
-    /**
-     * Return true if the queue has an up event pending that corresponds
-     * to the same key as the given key event.
-     */
-    boolean hasKeyUpEvent(KeyEvent origEvent) {
-        synchronized (mFirst) {
-            final int keyCode = origEvent.getKeyCode();
-            QueuedEvent cur = mLast.prev;
-            while (cur.prev != null) {
-                if (cur.classType == RawInputEvent.CLASS_KEYBOARD) {
-                    KeyEvent ke = (KeyEvent)cur.event;
-                    if (ke.getAction() == KeyEvent.ACTION_UP
-                            && ke.getKeyCode() == keyCode) {
-                        return true;
-                    }
-                }
-                cur = cur.prev;
-            }
-        }
-        
-        return false;
-    }
-    
-    void recycleEvent(QueuedEvent ev) {
-        synchronized (mFirst) {
-            //Slog.i(TAG, "Recycle event: " + ev);
-            if (ev.event == ev.inputDevice.mAbs.currentMove) {
-                ev.inputDevice.mAbs.currentMove = null;
-            }
-            if (ev.event == ev.inputDevice.mRel.currentMove) {
-                if (false) Slog.i(TAG, "Detach rel " + ev.event);
-                ev.inputDevice.mRel.currentMove = null;
-                ev.inputDevice.mRel.mNextData[MotionEvent.SAMPLE_X] = 0;
-                ev.inputDevice.mRel.mNextData[MotionEvent.SAMPLE_Y] = 0;
-            }
-            recycleLocked(ev);
-        }
-    }
-    
-    void filterQueue(FilterCallback cb) {
-        synchronized (mFirst) {
-            QueuedEvent cur = mLast.prev;
-            while (cur.prev != null) {
-                switch (cb.filterEvent(cur)) {
-                    case FILTER_REMOVE:
-                        cur.prev.next = cur.next;
-                        cur.next.prev = cur.prev;
-                        break;
-                    case FILTER_ABORT:
-                        return;
-                }
-                cur = cur.prev;
-            }
-        }
-    }
-    
-    private QueuedEvent obtainLocked(InputDevice device, long whenNano,
-            int flags, int classType, Object event) {
-        QueuedEvent ev;
-        if (mCacheCount == 0) {
-            ev = new QueuedEvent();
-        } else {
-            ev = mCache;
-            ev.inQueue = false;
-            mCache = ev.next;
-            mCacheCount--;
-        }
-        ev.inputDevice = device;
-        ev.whenNano = whenNano;
-        ev.flags = flags;
-        ev.classType = classType;
-        ev.event = event;
-        return ev;
-    }
-
-    private void recycleLocked(QueuedEvent ev) {
-        if (ev.inQueue) {
-            throw new RuntimeException("Event already in queue!");
-        }
-        if (mCacheCount < 10) {
-            mCacheCount++;
-            ev.next = mCache;
-            mCache = ev;
-            ev.inQueue = true;
-        }
-    }
-
-    private void addLocked(InputDevice device, long whenNano, int flags,
-            int classType, Object event) {
-        boolean poke = mFirst.next == mLast;
-
-        QueuedEvent ev = obtainLocked(device, whenNano, flags, classType, event);
-        QueuedEvent p = mLast.prev;
-        while (p != mFirst && ev.whenNano < p.whenNano) {
-            p = p.prev;
-        }
-
-        ev.next = p.next;
-        ev.prev = p;
-        p.next = ev;
-        ev.next.prev = ev;
-        ev.inQueue = true;
-
-        if (poke) {
-            long time;
-            if (MEASURE_LATENCY) {
-                time = System.nanoTime();
-            }
-            mFirst.notify();
-            mWakeLock.acquire();
-            if (MEASURE_LATENCY) {
-                lt.sample("1 addLocked-queued event ", System.nanoTime() - time);
-            }
-        }
-    }
-
-    private InputDevice newInputDevice(int deviceId) {
-        int classes = getDeviceClasses(deviceId);
-        String name = getDeviceName(deviceId);
-        InputDevice.AbsoluteInfo absX = null;
-        InputDevice.AbsoluteInfo absY = null;
-        InputDevice.AbsoluteInfo absPressure = null;
-        InputDevice.AbsoluteInfo absSize = null;
-        if (classes != 0) {
-            Slog.i(TAG, "Device added: id=0x" + Integer.toHexString(deviceId)
-                    + ", name=" + name
-                    + ", classes=" + Integer.toHexString(classes));
-            if ((classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) {
-                absX = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_MT_POSITION_X, "X");
-                absY = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_MT_POSITION_Y, "Y");
-                absPressure = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_MT_TOUCH_MAJOR, "Pressure");
-                absSize = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_MT_WIDTH_MAJOR, "Size");
-            } else if ((classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
-                absX = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_X, "X");
-                absY = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_Y, "Y");
-                absPressure = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_PRESSURE, "Pressure");
-                absSize = loadAbsoluteInfo(deviceId,
-                        RawInputEvent.ABS_TOOL_WIDTH, "Size");
-            }
-        }
-        
-        return new InputDevice(deviceId, classes, name, absX, absY, absPressure, absSize);
-    }
-    
-    private InputDevice.AbsoluteInfo loadAbsoluteInfo(int id, int channel,
-            String name) {
-        InputDevice.AbsoluteInfo info = new InputDevice.AbsoluteInfo();
-        if (getAbsoluteInfo(id, channel, info)
-                && info.minValue != info.maxValue) {
-            Slog.i(TAG, "  " + name + ": min=" + info.minValue
-                    + " max=" + info.maxValue
-                    + " flat=" + info.flat
-                    + " fuzz=" + info.fuzz);
-            info.range = info.maxValue-info.minValue;
-            return info;
-        }
-        Slog.i(TAG, "  " + name + ": unknown values");
-        return null;
-    }
-    private static native boolean readEvent(RawInputEvent outEvent);
-    
-    void dump(PrintWriter pw, String prefix) {
-        synchronized (mFirst) {
-            for (int i=0; i<mDevices.size(); i++) {
-                InputDevice dev = mDevices.valueAt(i);
-                pw.print(prefix); pw.print("Device #");
-                        pw.print(mDevices.keyAt(i)); pw.print(" ");
-                        pw.print(dev.name); pw.print(" (classes=0x");
-                        pw.print(Integer.toHexString(dev.classes));
-                        pw.println("):");
-                pw.print(prefix); pw.print("  mKeyDownTime=");
-                        pw.print(dev.mKeyDownTime); pw.print(" mMetaKeysState=");
-                        pw.println(dev.mMetaKeysState);
-                if (dev.absX != null) {
-                    pw.print(prefix); pw.print("  absX: "); dev.absX.dump(pw);
-                            pw.println("");
-                }
-                if (dev.absY != null) {
-                    pw.print(prefix); pw.print("  absY: "); dev.absY.dump(pw);
-                            pw.println("");
-                }
-                if (dev.absPressure != null) {
-                    pw.print(prefix); pw.print("  absPressure: ");
-                            dev.absPressure.dump(pw); pw.println("");
-                }
-                if (dev.absSize != null) {
-                    pw.print(prefix); pw.print("  absSize: ");
-                            dev.absSize.dump(pw); pw.println("");
-                }
-                if (dev.mAbs.everChanged) {
-                    pw.print(prefix); pw.println("  mAbs:");
-                    dev.mAbs.dump(pw, prefix + "    ");
-                }
-                if (dev.mRel.everChanged) {
-                    pw.print(prefix); pw.println("  mRel:");
-                    dev.mRel.dump(pw, prefix + "    ");
-                }
-            }
-            pw.println(" ");
-            for (int i=0; i<mIgnoredDevices.size(); i++) {
-                InputDevice dev = mIgnoredDevices.valueAt(i);
-                pw.print(prefix); pw.print("Ignored Device #");
-                        pw.print(mIgnoredDevices.keyAt(i)); pw.print(" ");
-                        pw.print(dev.name); pw.print(" (classes=0x");
-                        pw.print(Integer.toHexString(dev.classes));
-                        pw.println(")");
-            }
-            pw.println(" ");
-            for (int i=0; i<mVirtualKeys.size(); i++) {
-                VirtualKey vk = mVirtualKeys.get(i);
-                pw.print(prefix); pw.print("Virtual Key #");
-                        pw.print(i); pw.println(":");
-                pw.print(prefix); pw.print("  scancode="); pw.println(vk.scancode);
-                pw.print(prefix); pw.print("  centerx="); pw.print(vk.centerx);
-                        pw.print(" centery="); pw.print(vk.centery);
-                        pw.print(" width="); pw.print(vk.width);
-                        pw.print(" height="); pw.println(vk.height);
-                pw.print(prefix); pw.print("  hitLeft="); pw.print(vk.hitLeft);
-                        pw.print(" hitTop="); pw.print(vk.hitTop);
-                        pw.print(" hitRight="); pw.print(vk.hitRight);
-                        pw.print(" hitBottom="); pw.println(vk.hitBottom);
-                if (vk.lastDevice != null) {
-                    pw.print(prefix); pw.print("  lastDevice=#");
-                            pw.println(vk.lastDevice.id);
-                }
-                if (vk.lastKeycode != 0) {
-                    pw.print(prefix); pw.print("  lastKeycode=");
-                            pw.println(vk.lastKeycode);
-                }
-            }
-            pw.println(" ");
-            pw.print(prefix); pw.print("  Default keyboard: ");
-                    pw.println(SystemProperties.get("hw.keyboards.0.devname"));
-            pw.print(prefix); pw.print("  mGlobalMetaState=");
-                    pw.print(mGlobalMetaState); pw.print(" mHaveGlobalMetaState=");
-                    pw.println(mHaveGlobalMetaState);
-            pw.print(prefix); pw.print("  mDisplayWidth=");
-                    pw.print(mDisplayWidth); pw.print(" mDisplayHeight=");
-                    pw.println(mDisplayHeight);
-            pw.print(prefix); pw.print("  mOrientation=");
-                    pw.println(mOrientation);
-            if (mPressedVirtualKey != null) {
-                pw.print(prefix); pw.print("  mPressedVirtualKey.scancode=");
-                        pw.println(mPressedVirtualKey.scancode);
-            }
-        }
-    }
-}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 493a348..e9d5efc 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -247,6 +247,9 @@
     private static final boolean mSpew = false;
     private static final boolean mDebugProximitySensor = (true || mSpew);
     private static final boolean mDebugLightSensor = (false || mSpew);
+    
+    private native void nativeInit();
+    private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
 
     /*
     static PrintStream mLog;
@@ -481,6 +484,11 @@
                 }
             }
         }
+        
+        nativeInit();
+        synchronized (mLocks) {
+            updateNativePowerStateLocked();
+        }
     }
 
     void initInThread() {
@@ -1557,8 +1565,16 @@
                     }
                 }
             }
+            
+            updateNativePowerStateLocked();
         }
     }
+    
+    private void updateNativePowerStateLocked() {
+        nativeSetPowerState(
+                (mPowerState & SCREEN_ON_BIT) != 0,
+                (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
+    }
 
     private int screenOffFinishedAnimatingLocked(int reason) {
         // I don't think we need to check the current state here because all of these
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 483f9eb..38f1e1f 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -48,7 +48,6 @@
 import com.android.internal.view.IInputMethodClient;
 import com.android.internal.view.IInputMethodManager;
 import com.android.internal.view.WindowManagerPolicyThread;
-import com.android.server.KeyInputQueue.QueuedEvent;
 import com.android.server.am.BatteryStatsService;
 
 import android.Manifest;
@@ -95,6 +94,7 @@
 import android.util.SparseIntArray;
 import android.view.Display;
 import android.view.Gravity;
+import android.view.HapticFeedbackConstants;
 import android.view.IApplicationToken;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
@@ -105,7 +105,6 @@
 import android.view.InputQueue;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
-import android.view.RawInputEvent;
 import android.view.Surface;
 import android.view.SurfaceSession;
 import android.view.View;
@@ -137,7 +136,7 @@
 
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
-        implements Watchdog.Monitor, KeyInputQueue.HapticFeedbackCallback {
+        implements Watchdog.Monitor {
     static final String TAG = "WindowManager";
     static final boolean DEBUG = false;
     static final boolean DEBUG_FOCUS = false;
@@ -159,17 +158,12 @@
     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;
     static final boolean BLUR = true;
     static final boolean localLOGV = DEBUG;
 
-    /** How long to wait for subsequent key repeats, in milliseconds */
-    static final int KEY_REPEAT_DELAY = 50;
-
     /** How much to multiply the policy's type layer, to reserve room
      * for multiple windows of the same type and Z-ordering adjustment
      * with TYPE_LAYER_OFFSET. */
@@ -210,34 +204,11 @@
     // Default input dispatching timeout in nanoseconds.
     private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
 
-    static final int INJECT_FAILED = 0;
-    static final int INJECT_SUCCEEDED = 1;
-    static final int INJECT_NO_PERMISSION = -1;
-
     static final int UPDATE_FOCUS_NORMAL = 0;
     static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
     static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
     static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
 
-    /** The minimum time between dispatching touch events. */
-    int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
-
-    // Last touch event time
-    long mLastTouchEventTime = 0;
-
-    // Last touch event type
-    int mLastTouchEventType = OTHER_EVENT;
-
-    // Time to wait before calling useractivity again. This saves CPU usage
-    // when we get a flood of touch events.
-    static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
-
-    // Last time we call user activity
-    long mLastUserActivityCallTime = 0;
-
-    // Last time we updated battery stats
-    long mLastBatteryStatsCallTime = 0;
-
     private static final String SYSTEM_SECURE = "ro.secure";
     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
@@ -486,7 +457,6 @@
     float mLastWallpaperY = -1;
     float mLastWallpaperXStep = -1;
     float mLastWallpaperYStep = -1;
-    boolean mSendingPointersToWallpaper = false;
     // This is set when we are waiting for a wallpaper to tell us it is done
     // changing its scroll position.
     WindowState mWaitingOnWallpaper;
@@ -504,10 +474,7 @@
     float mWindowAnimationScale = 1.0f;
     float mTransitionAnimationScale = 1.0f;
 
-    final KeyWaiter mKeyWaiter = new KeyWaiter();
-    final KeyQ mQueue;
     final InputManager mInputManager;
-    final InputDispatcherThread mInputThread;
 
     // Who is holding the screen on.
     Session mHoldingScreenOn;
@@ -523,8 +490,6 @@
 
     private ViewServer mViewServer;
 
-    final Rect mTempRect = new Rect();
-
     final Configuration mTempConfiguration = new Configuration();
     int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
 
@@ -652,28 +617,11 @@
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         mContext.registerReceiver(mBroadcastReceiver, filter);
 
-        int max_events_per_sec = 35;
-        try {
-            max_events_per_sec = Integer.parseInt(SystemProperties
-                    .get("windowsmgr.max_events_per_sec"));
-            if (max_events_per_sec < 1) {
-                max_events_per_sec = 35;
-            }
-        } catch (NumberFormatException e) {
-        }
-        mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
-
         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();
+        mInputManager = new InputManager(context, this, pmc, mPowerManager);
 
         PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
         thr.start();
@@ -687,11 +635,7 @@
             }
         }
 
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            mInputManager.start();
-        } else {
-            mInputThread.start();
-        }
+        mInputManager.start();
 
         // Add ourself to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
@@ -1817,70 +1761,6 @@
             }
         }
     }
-
-    void sendPointerToWallpaperLocked(WindowState srcWin,
-            MotionEvent pointer, long eventTime) {
-        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;
-                }
-                try {
-                    MotionEvent ev = MotionEvent.obtainNoHistory(pointer);
-                    if (srcWin != null) {
-                        ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left,
-                                srcWin.mFrame.top-wallpaper.mFrame.top);
-                    } else {
-                        ev.offsetLocation(-wallpaper.mFrame.left, -wallpaper.mFrame.top);
-                    }
-                    switch (pointer.getAction()) {
-                        case MotionEvent.ACTION_DOWN:
-                            mSendingPointersToWallpaper = true;
-                            break;
-                        case MotionEvent.ACTION_UP:
-                            mSendingPointersToWallpaper = false;
-                            break;
-                    }
-                    wallpaper.mClient.dispatchPointer(ev, eventTime, false);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Failure sending pointer to wallpaper", e);
-                }
-            }
-        }
-    }
-
-    void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
-            MotionEvent pointer, long eventTime, boolean skipped) {
-        if (relWin != null) {
-            mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
-        } else {
-            mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
-        }
-        
-        // If we sent an initial down to the wallpaper, then continue
-        // sending events until the final up.
-        if (mSendingPointersToWallpaper) {
-            if (skipped) {
-                Slog.i(TAG, "Sending skipped pointer to wallpaper!");
-            }
-            sendPointerToWallpaperLocked(relWin, pointer, eventTime);
-            
-        // If we are on top of the wallpaper, then the wallpaper also
-        // gets to see this movement.
-        } else if (srcWin != null
-                && pointer.getAction() == MotionEvent.ACTION_DOWN
-                && mWallpaperTarget == srcWin
-                && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
-            sendPointerToWallpaperLocked(relWin, pointer, eventTime);
-        }
-    }
     
     public int addWindow(Session session, IWindow client,
             WindowManager.LayoutParams attrs, int viewVisibility,
@@ -1903,12 +1783,7 @@
                 mDisplay = wm.getDefaultDisplay();
                 mInitialDisplayWidth = mDisplay.getWidth();
                 mInitialDisplayHeight = mDisplay.getHeight();
-                if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                    mInputManager.setDisplaySize(0,
-                            mInitialDisplayWidth, mInitialDisplayHeight);
-                } else {
-                    mQueue.setDisplay(mDisplay);
-                }
+                mInputManager.setDisplaySize(0, mInitialDisplayWidth, mInitialDisplayHeight);
                 reportNewConfig = true;
             }
 
@@ -2002,15 +1877,13 @@
                 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);
-                }
+            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!
@@ -2186,14 +2059,7 @@
     }
 
     private void removeWindowInnerLocked(Session session, WindowState win) {
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            mInputMonitor.windowIsBeingRemovedLw(win);
-        } else {
-            mKeyWaiter.finishedKey(session, win.mClient, true,
-                    KeyWaiter.RETURN_NOTHING);
-            mKeyWaiter.releasePendingPointerLocked(win.mSession);
-            mKeyWaiter.releasePendingTrackballLocked(win.mSession);
-        }
+        mInputMonitor.windowIsBeingRemovedLw(win);
 
         win.mRemoved = true;
 
@@ -2561,12 +2427,7 @@
                               applyAnimationLocked(win, transit, false)) {
                             focusMayChange = true;
                             win.mExiting = true;
-                            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                                mInputMonitor.windowIsBecomingInvisibleLw(win);
-                            } else {
-                                mKeyWaiter.finishedKey(session, client, true,
-                                        KeyWaiter.RETURN_NOTHING);
-                            }
+                            mInputMonitor.windowIsBecomingInvisibleLw(win);
                         } else if (win.isAnimating()) {
                             // Currently in a hide animation... turn this into
                             // an exit.
@@ -3027,12 +2888,7 @@
                         if (win.isVisibleNow()) {
                             applyAnimationLocked(win,
                                     WindowManagerPolicy.TRANSIT_EXIT, false);
-                            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                                mInputMonitor.windowIsBeingRemovedLw(win);
-                            } else {
-                                mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
-                                        KeyWaiter.RETURN_NOTHING);
-                            }
+                            mInputMonitor.windowIsBeingRemovedLw(win);
                             changed = true;
                         }
                     }
@@ -3349,12 +3205,8 @@
                 if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
                 changed = mFocusedApp != null;
                 mFocusedApp = null;
-                if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                    if (changed) {
-                        mInputMonitor.setFocusedAppLw(null);
-                    }
-                } else {
-                    mKeyWaiter.tickle();
+                if (changed) {
+                    mInputMonitor.setFocusedAppLw(null);
                 }
             } else {
                 AppWindowToken newFocus = findAppWindowToken(token);
@@ -3365,12 +3217,8 @@
                 changed = mFocusedApp != newFocus;
                 mFocusedApp = newFocus;
                 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp);
-                if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                    if (changed) {
-                        mInputMonitor.setFocusedAppLw(newFocus);
-                    }
-                } else {
-                    mKeyWaiter.tickle();
+                if (changed) {
+                    mInputMonitor.setFocusedAppLw(newFocus);
                 }
             }
 
@@ -3682,12 +3530,7 @@
                         applyAnimationLocked(win,
                                 WindowManagerPolicy.TRANSIT_EXIT, false);
                     }
-                    if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                        mInputMonitor.windowIsBecomingInvisibleLw(win);
-                    } else {
-                        mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
-                                KeyWaiter.RETURN_NOTHING);
-                    }
+                    mInputMonitor.windowIsBecomingInvisibleLw(win);
                     changed = true;
                 }
             }
@@ -3972,11 +3815,7 @@
                     if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
                     mFocusedApp = null;
                     updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
-                    if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                        mInputMonitor.setFocusedAppLw(null);
-                    } else {
-                        mKeyWaiter.tickle();
-                    }
+                    mInputMonitor.setFocusedAppLw(null);
                 }
             } else {
                 Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
@@ -4441,11 +4280,7 @@
                 "getSwitchState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getSwitchState(sw);
-        } else {
-            return KeyInputQueue.getSwitchState(sw);
-        }
+        return mInputManager.getSwitchState(sw);
     }
 
     public int getSwitchStateForDevice(int devid, int sw) {
@@ -4453,11 +4288,7 @@
                 "getSwitchStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getSwitchState(devid, sw);
-        } else {
-            return KeyInputQueue.getSwitchState(devid, sw);
-        }
+        return mInputManager.getSwitchState(devid, sw);
     }
 
     public int getScancodeState(int sw) {
@@ -4465,11 +4296,7 @@
                 "getScancodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getScancodeState(sw);
-        } else {
-            return mQueue.getScancodeState(sw);
-        }
+        return mInputManager.getScancodeState(sw);
     }
 
     public int getScancodeStateForDevice(int devid, int sw) {
@@ -4477,11 +4304,7 @@
                 "getScancodeStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getScancodeState(devid, sw);
-        } else {
-            return mQueue.getScancodeState(devid, sw);
-        }
+        return mInputManager.getScancodeState(devid, sw);
     }
 
     public int getTrackballScancodeState(int sw) {
@@ -4489,11 +4312,7 @@
                 "getTrackballScancodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getTrackballScancodeState(sw);
-        } else {
-            return mQueue.getTrackballScancodeState(sw);
-        }
+        return mInputManager.getTrackballScancodeState(sw);
     }
 
     public int getDPadScancodeState(int sw) {
@@ -4501,11 +4320,7 @@
                 "getDPadScancodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getDPadScancodeState(sw);
-        } else {
-            return mQueue.getDPadScancodeState(sw);
-        }
+        return mInputManager.getDPadScancodeState(sw);
     }
 
     public int getKeycodeState(int sw) {
@@ -4513,11 +4328,7 @@
                 "getKeycodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getKeycodeState(sw);
-        } else {
-            return mQueue.getKeycodeState(sw);
-        }
+        return mInputManager.getKeycodeState(sw);
     }
 
     public int getKeycodeStateForDevice(int devid, int sw) {
@@ -4525,11 +4336,7 @@
                 "getKeycodeStateForDevice()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getKeycodeState(devid, sw);
-        } else {
-            return mQueue.getKeycodeState(devid, sw);
-        }
+        return mInputManager.getKeycodeState(devid, sw);
     }
 
     public int getTrackballKeycodeState(int sw) {
@@ -4537,11 +4344,7 @@
                 "getTrackballKeycodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getTrackballKeycodeState(sw);
-        } else {
-            return mQueue.getTrackballKeycodeState(sw);
-        }
+        return mInputManager.getTrackballKeycodeState(sw);
     }
 
     public int getDPadKeycodeState(int sw) {
@@ -4549,19 +4352,11 @@
                 "getDPadKeycodeState()")) {
             throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.getDPadKeycodeState(sw);
-        } else {
-            return mQueue.getDPadKeycodeState(sw);
-        }
+        return mInputManager.getDPadKeycodeState(sw);
     }
 
     public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            return mInputManager.hasKeys(keycodes, keyExists);
-        } else {
-            return KeyInputQueue.hasKeys(keycodes, keyExists);
-        }
+        return mInputManager.hasKeys(keycodes, keyExists);
     }
 
     public void enableScreenAfterBoot() {
@@ -4706,11 +4501,7 @@
             mLayoutNeeded = true;
             startFreezingDisplayLocked();
             Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
-            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                mInputManager.setDisplayOrientation(0, rotation);
-            } else {
-                mQueue.setOrientation(rotation);
-            }
+            mInputManager.setDisplayOrientation(0, rotation);
             if (mDisplayEnabled) {
                 Surface.setOrientation(0, rotation, animFlags);
             }
@@ -5041,11 +4832,8 @@
         if (mDisplay == null) {
             return false;
         }
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            mInputManager.getInputConfiguration(config);
-        } else {
-            mQueue.getInputConfiguration(config);
-        }
+        
+        mInputManager.getInputConfiguration(config);
 
         // Use the effective "visual" dimensions based on current rotation
         final boolean rotated = (mRotation == Surface.ROTATION_90
@@ -5326,6 +5114,13 @@
             mTempInputWindows.clear();
         }
         
+        /* Provides feedback for a virtual key down. */
+        public void virtualKeyDownFeedback() {
+            synchronized (mWindowMap) {
+                mPolicy.performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
+            }
+        }
+        
         /* Notifies that an app switch key (BACK / HOME) has just been pressed.
          * This essentially starts a .5 second timeout for the application to process
          * subsequent input events while waiting for the app switch to occur.  If it takes longer
@@ -5334,30 +5129,28 @@
         public void notifyAppSwitchComing() {
             // TODO Not implemented yet.  Should go in the native side.
         }
-
+        
+        /* Notifies that the lid switch changed state. */
+        public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+            mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
+        }
+        
         /* Provides an opportunity for the window manager policy to intercept early key
          * processing as soon as the key has been read from the device. */
-        public int interceptKeyBeforeQueueing(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 mPolicy.interceptKeyTq(event, isScreenOn);
+        public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
+                int policyFlags, boolean isScreenOn) {
+            return mPolicy.interceptKeyBeforeQueueing(whenNanos,
+                    keyCode, down, policyFlags, isScreenOn);
         }
         
         /* Provides an opportunity for the window manager policy to process a key before
          * ordinary dispatch. */
-        public boolean interceptKeyBeforeDispatching(InputChannel focus, int keyCode,
-                int metaState, boolean down, int repeatCount, int policyFlags) {
+        public boolean interceptKeyBeforeDispatching(InputChannel focus,
+                int action, int flags, int keyCode, int metaState, int repeatCount,
+                int policyFlags) {
             WindowState windowState = getWindowStateForInputChannel(focus);
-            return mPolicy.interceptKeyTi(windowState, keyCode, metaState, down, repeatCount,
-                    policyFlags);
+            return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
+                    keyCode, metaState, repeatCount, policyFlags);
         }
         
         /* Called when the current input focus changes.
@@ -5496,450 +5289,6 @@
         }
     }
 
-    private final void wakeupIfNeeded(WindowState targetWin, int eventType) {
-        long curTime = SystemClock.uptimeMillis();
-
-        if (eventType == TOUCH_EVENT || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT) {
-            if (mLastTouchEventType == eventType &&
-                    (curTime - mLastUserActivityCallTime) < MIN_TIME_BETWEEN_USERACTIVITIES) {
-                return;
-            }
-            mLastUserActivityCallTime = curTime;
-            mLastTouchEventType = eventType;
-        }
-
-        if (targetWin == null
-                || targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
-            mPowerManager.userActivity(curTime, false, eventType, false);
-        }
-    }
-
-    // tells if it's a cheek event or not -- this function is stateful
-    private static final int EVENT_NONE = 0;
-    private static final int EVENT_UNKNOWN = 0;
-    private static final int EVENT_CHEEK = 0;
-    private static final int EVENT_IGNORE_DURATION = 300; // ms
-    private static final float CHEEK_THRESHOLD = 0.6f;
-    private int mEventState = EVENT_NONE;
-    private float mEventSize;
-
-    private int eventType(MotionEvent ev) {
-        float size = ev.getSize();
-        switch (ev.getAction()) {
-        case MotionEvent.ACTION_DOWN:
-            mEventSize = size;
-            return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT;
-        case MotionEvent.ACTION_UP:
-            if (size > mEventSize) mEventSize = size;
-            return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT;
-        case MotionEvent.ACTION_MOVE:
-            final int N = ev.getHistorySize();
-            if (size > mEventSize) mEventSize = size;
-            if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
-            for (int i=0; i<N; i++) {
-                size = ev.getHistoricalSize(i);
-                if (size > mEventSize) mEventSize = size;
-                if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
-            }
-            if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) {
-                return TOUCH_EVENT;
-            } else {
-                return LONG_TOUCH_EVENT;
-            }
-        default:
-            // not good
-            return OTHER_EVENT;
-        }
-    }
-    
-    private boolean mFatTouch; // remove me together with dispatchPointer
-
-    /**
-     * @return Returns true if event was dispatched, false if it was dropped for any reason
-     */
-    private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
-        if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Slog.v(TAG,
-                "dispatchPointer " + ev);
-
-        if (MEASURE_LATENCY) {
-            lt.sample("3 Wait for last dispatch ", System.nanoTime() - qev.whenNano);
-        }
-
-        Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
-                ev, true, false, pid, uid);
-
-        if (MEASURE_LATENCY) {
-            lt.sample("3 Last dispatch finished ", System.nanoTime() - qev.whenNano);
-        }
-
-        int action = ev.getAction();
-
-        if (action == MotionEvent.ACTION_UP) {
-            // let go of our target
-            mKeyWaiter.mMotionTarget = null;
-            mPowerManager.logPointerUpEvent();
-        } else if (action == MotionEvent.ACTION_DOWN) {
-            mPowerManager.logPointerDownEvent();
-        }
-
-        if (targetObj == 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 " + ev.getAction());
-            }
-            synchronized (mWindowMap) {
-                dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
-            }
-            if (qev != null) {
-                mQueue.recycleEvent(qev);
-            }
-            ev.recycle();
-            return INJECT_FAILED;
-        }
-        if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
-            synchronized (mWindowMap) {
-                dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
-            }
-            if (qev != null) {
-                mQueue.recycleEvent(qev);
-            }
-            ev.recycle();
-            return INJECT_SUCCEEDED;
-        }
-
-        WindowState target = (WindowState)targetObj;
-
-        final long eventTime = ev.getEventTime();
-        final long eventTimeNano = ev.getEventTimeNano();
-
-        //Slog.i(TAG, "Sending " + ev + " to " + target);
-
-        if (uid != 0 && uid != target.mSession.mUid) {
-            if (mContext.checkPermission(
-                    android.Manifest.permission.INJECT_EVENTS, pid, uid)
-                    != PackageManager.PERMISSION_GRANTED) {
-                Slog.w(TAG, "Permission denied: injecting pointer event from pid "
-                        + pid + " uid " + uid + " to window " + target
-                        + " owned by uid " + target.mSession.mUid);
-                if (qev != null) {
-                    mQueue.recycleEvent(qev);
-                }
-                ev.recycle();
-                return INJECT_NO_PERMISSION;
-            }
-        }
-
-        if (MEASURE_LATENCY) {
-            lt.sample("4 in dispatchPointer     ", System.nanoTime() - eventTimeNano);
-        }
-
-        if ((target.mAttrs.flags &
-                        WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
-            //target wants to ignore fat touch events
-            boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
-            //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
-                        ev.setAction(MotionEvent.ACTION_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
-                        ev.setAction(MotionEvent.ACTION_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) {
-                //recycle que, ev
-                if (qev != null) {
-                    mQueue.recycleEvent(qev);
-                }
-                ev.recycle();
-                return INJECT_FAILED;
-            }
-        } //end if target
-
-        // Enable this for testing the "right" value
-        if (false && action == MotionEvent.ACTION_DOWN) {
-            int max_events_per_sec = 35;
-            try {
-                max_events_per_sec = Integer.parseInt(SystemProperties
-                        .get("windowsmgr.max_events_per_sec"));
-                if (max_events_per_sec < 1) {
-                    max_events_per_sec = 35;
-                }
-            } catch (NumberFormatException e) {
-            }
-            mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
-        }
-
-        /*
-         * Throttle events to minimize CPU usage when there's a flood of events
-         * e.g. constant contact with the screen
-         */
-        if (action == MotionEvent.ACTION_MOVE) {
-            long nextEventTime = mLastTouchEventTime + mMinWaitTimeBetweenTouchEvents;
-            long now = SystemClock.uptimeMillis();
-            if (now < nextEventTime) {
-                try {
-                    Thread.sleep(nextEventTime - now);
-                } catch (InterruptedException e) {
-                }
-                mLastTouchEventTime = nextEventTime;
-            } else {
-                mLastTouchEventTime = now;
-            }
-        }
-
-        if (MEASURE_LATENCY) {
-            lt.sample("5 in dispatchPointer     ", System.nanoTime() - eventTimeNano);
-        }
-
-        synchronized(mWindowMap) {
-            if (!target.isVisibleLw()) {
-                // During this motion dispatch, the target window has become
-                // invisible.
-                dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
-                if (qev != null) {
-                    mQueue.recycleEvent(qev);
-                }
-                ev.recycle();
-                return INJECT_SUCCEEDED;
-            }
-
-            if (qev != null && action == MotionEvent.ACTION_MOVE) {
-                mKeyWaiter.bindTargetWindowLocked(target,
-                        KeyWaiter.RETURN_PENDING_POINTER, qev);
-                ev = null;
-            } else {
-                if (action == MotionEvent.ACTION_DOWN) {
-                    WindowState out = mKeyWaiter.mOutsideTouchTargets;
-                    if (out != null) {
-                        MotionEvent oev = MotionEvent.obtain(ev);
-                        oev.setAction(MotionEvent.ACTION_OUTSIDE);
-                        do {
-                            final Rect frame = out.mFrame;
-                            oev.offsetLocation(-(float)frame.left, -(float)frame.top);
-                            try {
-                                out.mClient.dispatchPointer(oev, eventTime, false);
-                            } catch (android.os.RemoteException e) {
-                                Slog.i(TAG, "WINDOW DIED during outside motion dispatch: " + out);
-                            }
-                            oev.offsetLocation((float)frame.left, (float)frame.top);
-                            out = out.mNextOutsideTouch;
-                        } while (out != null);
-                        mKeyWaiter.mOutsideTouchTargets = null;
-                    }
-                }
-
-                dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
-
-                final Rect frame = target.mFrame;
-                ev.offsetLocation(-(float)frame.left, -(float)frame.top);
-                mKeyWaiter.bindTargetWindowLocked(target);
-            }
-        }
-
-        // finally offset the event to the target's coordinate system and
-        // dispatch the event.
-        try {
-            if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
-                Slog.v(TAG, "Delivering pointer " + qev + " to " + target);
-            }
-
-            if (MEASURE_LATENCY) {
-                lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano);
-            }
-
-            target.mClient.dispatchPointer(ev, eventTime, true);
-
-            if (MEASURE_LATENCY) {
-                lt.sample("7 after  svr->client ipc ", System.nanoTime() - eventTimeNano);
-            }
-            return INJECT_SUCCEEDED;
-        } catch (android.os.RemoteException e) {
-            Slog.i(TAG, "WINDOW DIED during motion dispatch: " + target);
-            mKeyWaiter.mMotionTarget = null;
-            try {
-                removeWindow(target.mSession, target.mClient);
-            } catch (java.util.NoSuchElementException ex) {
-                // This will happen if the window has already been
-                // removed.
-            }
-        }
-        return INJECT_FAILED;
-    }
-
-    /**
-     * @return Returns true if event was dispatched, false if it was dropped for any reason
-     */
-    private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
-        if (DEBUG_INPUT) Slog.v(
-                TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
-
-        Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
-                ev, false, false, pid, uid);
-        if (focusObj == null) {
-            Slog.w(TAG, "No focus window, dropping trackball: " + ev);
-            if (qev != null) {
-                mQueue.recycleEvent(qev);
-            }
-            ev.recycle();
-            return INJECT_FAILED;
-        }
-        if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
-            if (qev != null) {
-                mQueue.recycleEvent(qev);
-            }
-            ev.recycle();
-            return INJECT_SUCCEEDED;
-        }
-
-        WindowState focus = (WindowState)focusObj;
-
-        if (uid != 0 && uid != focus.mSession.mUid) {
-            if (mContext.checkPermission(
-                    android.Manifest.permission.INJECT_EVENTS, pid, uid)
-                    != PackageManager.PERMISSION_GRANTED) {
-                Slog.w(TAG, "Permission denied: injecting key event from pid "
-                        + pid + " uid " + uid + " to window " + focus
-                        + " owned by uid " + focus.mSession.mUid);
-                if (qev != null) {
-                    mQueue.recycleEvent(qev);
-                }
-                ev.recycle();
-                return INJECT_NO_PERMISSION;
-            }
-        }
-
-        final long eventTime = ev.getEventTime();
-
-        synchronized(mWindowMap) {
-            if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
-                mKeyWaiter.bindTargetWindowLocked(focus,
-                        KeyWaiter.RETURN_PENDING_TRACKBALL, qev);
-                // We don't deliver movement events to the client, we hold
-                // them and wait for them to call back.
-                ev = null;
-            } else {
-                mKeyWaiter.bindTargetWindowLocked(focus);
-            }
-        }
-
-        try {
-            focus.mClient.dispatchTrackball(ev, eventTime, true);
-            return INJECT_SUCCEEDED;
-        } catch (android.os.RemoteException e) {
-            Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
-            try {
-                removeWindow(focus.mSession, focus.mClient);
-            } catch (java.util.NoSuchElementException ex) {
-                // This will happen if the window has already been
-                // removed.
-            }
-        }
-
-        return INJECT_FAILED;
-    }
-
-    /**
-     * @return Returns true if event was dispatched, false if it was dropped for any reason
-     */
-    private int dispatchKey(KeyEvent event, int pid, int uid) {
-        if (DEBUG_INPUT) Slog.v(TAG, "Dispatch key: " + event);
-
-        Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
-                null, false, false, pid, uid);
-        if (focusObj == null) {
-            Slog.w(TAG, "No focus window, dropping: " + event);
-            return INJECT_FAILED;
-        }
-        if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
-            return INJECT_SUCCEEDED;
-        }
-
-        // Okay we have finished waiting for the last event to be processed.
-        // First off, if this is a repeat event, check to see if there is
-        // a corresponding up event in the queue.  If there is, we will
-        // just drop the repeat, because it makes no sense to repeat after
-        // the user has released a key.  (This is especially important for
-        // long presses.)
-        if (event.getRepeatCount() > 0 && mQueue.hasKeyUpEvent(event)) {
-            return INJECT_SUCCEEDED;
-        }
-
-        WindowState focus = (WindowState)focusObj;
-
-        if (DEBUG_INPUT) Slog.v(
-            TAG, "Dispatching to " + focus + ": " + event);
-
-        if (uid != 0 && uid != focus.mSession.mUid) {
-            if (mContext.checkPermission(
-                    android.Manifest.permission.INJECT_EVENTS, pid, uid)
-                    != PackageManager.PERMISSION_GRANTED) {
-                Slog.w(TAG, "Permission denied: injecting key event from pid "
-                        + pid + " uid " + uid + " to window " + focus
-                        + " owned by uid " + focus.mSession.mUid);
-                return INJECT_NO_PERMISSION;
-            }
-        }
-
-        synchronized(mWindowMap) {
-            mKeyWaiter.bindTargetWindowLocked(focus);
-        }
-
-        // NOSHIP extra state logging
-        mKeyWaiter.recordDispatchState(event, focus);
-        // END NOSHIP
-
-        try {
-            if (DEBUG_INPUT || DEBUG_FOCUS) {
-                Slog.v(TAG, "Delivering key " + event.getKeyCode()
-                        + " to " + focus);
-            }
-            focus.mClient.dispatchKey(event);
-            return INJECT_SUCCEEDED;
-        } catch (android.os.RemoteException e) {
-            Slog.i(TAG, "WINDOW DIED during key dispatch: " + focus);
-            try {
-                removeWindow(focus.mSession, focus.mClient);
-            } catch (java.util.NoSuchElementException ex) {
-                // This will happen if the window has already been
-                // removed.
-            }
-        }
-
-        return INJECT_FAILED;
-    }
-
     public void pauseKeyDispatching(IBinder _token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "pauseKeyDispatching()")) {
@@ -5949,11 +5298,7 @@
         synchronized (mWindowMap) {
             WindowToken token = mTokenMap.get(_token);
             if (token != null) {
-                if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                    mInputMonitor.pauseDispatchingLw(token);
-                } else {
-                    mKeyWaiter.pauseDispatchingLocked(token);
-                }
+                mInputMonitor.pauseDispatchingLw(token);
             }
         }
     }
@@ -5967,11 +5312,7 @@
         synchronized (mWindowMap) {
             WindowToken token = mTokenMap.get(_token);
             if (token != null) {
-                if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                    mInputMonitor.resumeDispatchingLw(token);
-                } else {
-                    mKeyWaiter.resumeDispatchingLocked(token);
-                }
+                mInputMonitor.resumeDispatchingLw(token);
             }
         }
     }
@@ -5983,11 +5324,7 @@
         }
 
         synchronized (mWindowMap) {
-            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                mInputMonitor.setEventDispatchingLw(enabled);
-            } else {
-                mKeyWaiter.setEventDispatchingLocked(enabled);
-            }
+            mInputMonitor.setEventDispatchingLw(enabled);
         }
     }
 
@@ -6020,16 +5357,8 @@
         final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
         
-        final int result;
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            result = mInputManager.injectKeyEvent(newEvent, InputQueue.INPUT_EVENT_NATURE_KEY,
-                    pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
-        } else {
-            result = dispatchKey(newEvent, pid, uid);
-            if (sync) {
-                mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
-            }
-        }
+        final int result = mInputManager.injectKeyEvent(newEvent,
+                InputQueue.INPUT_EVENT_NATURE_KEY, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
         
         Binder.restoreCallingIdentity(ident);
         return reportInjectionResult(result);
@@ -6049,16 +5378,8 @@
         final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
         
-        final int result;
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TOUCH,
-                    pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
-        } else {
-            result = dispatchPointer(null, ev, pid, uid);
-            if (sync) {
-                mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
-            }
-        }
+        final int result = mInputManager.injectMotionEvent(ev,
+                InputQueue.INPUT_EVENT_NATURE_TOUCH, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
         
         Binder.restoreCallingIdentity(ident);
         return reportInjectionResult(result);
@@ -6078,48 +5399,29 @@
         final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
         
-        final int result;
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            result = mInputManager.injectMotionEvent(ev, InputQueue.INPUT_EVENT_NATURE_TRACKBALL,
-                    pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
-        } else {
-            result = dispatchTrackball(null, ev, pid, uid);
-            if (sync) {
-                mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
-            }
-        }
+        final int result = mInputManager.injectMotionEvent(ev,
+                InputQueue.INPUT_EVENT_NATURE_TRACKBALL, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
         
         Binder.restoreCallingIdentity(ident);
         return reportInjectionResult(result);
     }
     
     private boolean reportInjectionResult(int result) {
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            switch (result) {
-                case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
-                    Slog.w(TAG, "Input event injection permission denied.");
-                    throw new SecurityException(
-                            "Injecting to another application requires INJECT_EVENTS permission");
-                case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
-                    Slog.v(TAG, "Input event injection succeeded.");
-                    return true;
-                case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
-                    Slog.w(TAG, "Input event injection timed out.");
-                    return false;
-                case InputManager.INPUT_EVENT_INJECTION_FAILED:
-                default:
-                    Slog.w(TAG, "Input event injection failed.");
-                    return false;
-            }
-        } else {
-            switch (result) {
-                case INJECT_NO_PERMISSION:
-                    throw new SecurityException(
-                            "Injecting to another application requires INJECT_EVENTS permission");
-                case INJECT_SUCCEEDED:
-                    return true;
-            }
-            return false;
+        switch (result) {
+            case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+                Slog.w(TAG, "Input event injection permission denied.");
+                throw new SecurityException(
+                        "Injecting to another application requires INJECT_EVENTS permission");
+            case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
+                Slog.v(TAG, "Input event injection succeeded.");
+                return true;
+            case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
+                Slog.w(TAG, "Input event injection timed out.");
+                return false;
+            case InputManager.INPUT_EVENT_INJECTION_FAILED:
+            default:
+                Slog.w(TAG, "Input event injection failed.");
+                return false;
         }
     }
 
@@ -6133,867 +5435,6 @@
         return mCurrentFocus;
     }
 
-    /**
-     * This class holds the state for dispatching key events.  This state
-     * is protected by the KeyWaiter instance, NOT by the window lock.  You
-     * can be holding the main window lock while acquire the KeyWaiter lock,
-     * but not the other way around.
-     */
-    final class KeyWaiter {
-        // NOSHIP debugging
-        public class DispatchState {
-            private KeyEvent event;
-            private WindowState focus;
-            private long time;
-            private WindowState lastWin;
-            private IBinder lastBinder;
-            private boolean finished;
-            private boolean gotFirstWindow;
-            private boolean eventDispatching;
-            private long timeToSwitch;
-            private boolean wasFrozen;
-            private boolean focusPaused;
-            private WindowState curFocus;
-
-            DispatchState(KeyEvent theEvent, WindowState theFocus) {
-                focus = theFocus;
-                event = theEvent;
-                time = System.currentTimeMillis();
-                // snapshot KeyWaiter state
-                lastWin = mLastWin;
-                lastBinder = mLastBinder;
-                finished = mFinished;
-                gotFirstWindow = mGotFirstWindow;
-                eventDispatching = mEventDispatching;
-                timeToSwitch = mTimeToSwitch;
-                wasFrozen = mWasFrozen;
-                curFocus = mCurrentFocus;
-                // cache the paused state at ctor time as well
-                if (theFocus == null || theFocus.mToken == null) {
-                    focusPaused = false;
-                } else {
-                    focusPaused = theFocus.mToken.paused;
-                }
-            }
-
-            public String toString() {
-                return "{{" + event + " to " + focus + " @ " + time
-                        + " lw=" + lastWin + " lb=" + lastBinder
-                        + " fin=" + finished + " gfw=" + gotFirstWindow
-                        + " ed=" + eventDispatching + " tts=" + timeToSwitch
-                        + " wf=" + wasFrozen + " fp=" + focusPaused
-                        + " mcf=" + curFocus + "}}";
-            }
-        };
-        private DispatchState mDispatchState = null;
-        public void recordDispatchState(KeyEvent theEvent, WindowState theFocus) {
-            mDispatchState = new DispatchState(theEvent, theFocus);
-        }
-        // END NOSHIP
-
-        public static final int RETURN_NOTHING = 0;
-        public static final int RETURN_PENDING_POINTER = 1;
-        public static final int RETURN_PENDING_TRACKBALL = 2;
-
-        final Object SKIP_TARGET_TOKEN = new Object();
-        final Object CONSUMED_EVENT_TOKEN = new Object();
-
-        private WindowState mLastWin = null;
-        private IBinder mLastBinder = null;
-        private boolean mFinished = true;
-        private boolean mGotFirstWindow = false;
-        private boolean mEventDispatching = true;
-        private long mTimeToSwitch = 0;
-        /* package */ boolean mWasFrozen = false;
-
-        // Target of Motion events
-        WindowState mMotionTarget;
-
-        // Windows above the target who would like to receive an "outside"
-        // touch event for any down events outside of them.
-        WindowState mOutsideTouchTargets;
-
-        /**
-         * Wait for the last event dispatch to complete, then find the next
-         * target that should receive the given event and wait for that one
-         * to be ready to receive it.
-         */
-        Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
-                MotionEvent nextMotion, boolean isPointerEvent,
-                boolean failIfTimeout, int callingPid, int callingUid) {
-            long startTime = SystemClock.uptimeMillis();
-            long keyDispatchingTimeout = 5 * 1000;
-            long waitedFor = 0;
-
-            while (true) {
-                // Figure out which window we care about.  It is either the
-                // last window we are waiting to have process the event or,
-                // if none, then the next window we think the event should go
-                // to.  Note: we retrieve mLastWin outside of the lock, so
-                // it may change before we lock.  Thus we must check it again.
-                WindowState targetWin = mLastWin;
-                boolean targetIsNew = targetWin == null;
-                if (DEBUG_INPUT) Slog.v(
-                        TAG, "waitForLastKey: mFinished=" + mFinished +
-                        ", mLastWin=" + mLastWin);
-                if (targetIsNew) {
-                    Object target = findTargetWindow(nextKey, qev, nextMotion,
-                            isPointerEvent, callingPid, callingUid);
-                    if (target == SKIP_TARGET_TOKEN) {
-                        // The user has pressed a special key, and we are
-                        // dropping all pending events before it.
-                        if (DEBUG_INPUT) Slog.v(TAG, "Skipping: " + nextKey
-                                + " " + nextMotion);
-                        return null;
-                    }
-                    if (target == CONSUMED_EVENT_TOKEN) {
-                        if (DEBUG_INPUT) Slog.v(TAG, "Consumed: " + nextKey
-                                + " " + nextMotion);
-                        return target;
-                    }
-                    targetWin = (WindowState)target;
-                }
-
-                AppWindowToken targetApp = null;
-
-                // Now: is it okay to send the next event to this window?
-                synchronized (this) {
-                    // First: did we come here based on the last window not
-                    // being null, but it changed by the time we got here?
-                    // If so, try again.
-                    if (!targetIsNew && mLastWin == null) {
-                        continue;
-                    }
-
-                    // We never dispatch events if not finished with the
-                    // last one, or the display is frozen.
-                    if (mFinished && !mDisplayFrozen) {
-                        // If event dispatching is disabled, then we
-                        // just consume the events.
-                        if (!mEventDispatching) {
-                            if (DEBUG_INPUT) Slog.v(TAG,
-                                    "Skipping event; dispatching disabled: "
-                                    + nextKey + " " + nextMotion);
-                            return null;
-                        }
-                        if (targetWin != null) {
-                            // If this is a new target, and that target is not
-                            // paused or unresponsive, then all looks good to
-                            // handle the event.
-                            if (targetIsNew && !targetWin.mToken.paused) {
-                                return targetWin;
-                            }
-
-                        // If we didn't find a target window, and there is no
-                        // focused app window, then just eat the events.
-                        } else if (mFocusedApp == null) {
-                            if (DEBUG_INPUT) Slog.v(TAG,
-                                    "Skipping event; no focused app: "
-                                    + nextKey + " " + nextMotion);
-                            return null;
-                        }
-                    }
-
-                    if (DEBUG_INPUT) Slog.v(
-                            TAG, "Waiting for last key in " + mLastBinder
-                            + " target=" + targetWin
-                            + " mFinished=" + mFinished
-                            + " mDisplayFrozen=" + mDisplayFrozen
-                            + " targetIsNew=" + targetIsNew
-                            + " paused="
-                            + (targetWin != null ? targetWin.mToken.paused : false)
-                            + " mFocusedApp=" + mFocusedApp
-                            + " mCurrentFocus=" + mCurrentFocus);
-
-                    targetApp = targetWin != null
-                            ? targetWin.mAppToken : mFocusedApp;
-
-                    long curTimeout = keyDispatchingTimeout;
-                    if (mTimeToSwitch != 0) {
-                        long now = SystemClock.uptimeMillis();
-                        if (mTimeToSwitch <= now) {
-                            // If an app switch key has been pressed, and we have
-                            // waited too long for the current app to finish
-                            // processing keys, then wait no more!
-                            doFinishedKeyLocked(false);
-                            continue;
-                        }
-                        long switchTimeout = mTimeToSwitch - now;
-                        if (curTimeout > switchTimeout) {
-                            curTimeout = switchTimeout;
-                        }
-                    }
-
-                    try {
-                        // after that continue
-                        // processing keys, so we don't get stuck.
-                        if (DEBUG_INPUT) Slog.v(
-                                TAG, "Waiting for key dispatch: " + curTimeout);
-                        wait(curTimeout);
-                        if (DEBUG_INPUT) Slog.v(TAG, "Finished waiting @"
-                                + SystemClock.uptimeMillis() + " startTime="
-                                + startTime + " switchTime=" + mTimeToSwitch
-                                + " target=" + targetWin + " mLW=" + mLastWin
-                                + " mLB=" + mLastBinder + " fin=" + mFinished
-                                + " mCurrentFocus=" + mCurrentFocus);
-                    } catch (InterruptedException e) {
-                    }
-                }
-
-                // If we were frozen during configuration change, restart the
-                // timeout checks from now; otherwise look at whether we timed
-                // out before awakening.
-                if (mWasFrozen) {
-                    waitedFor = 0;
-                    mWasFrozen = false;
-                } else {
-                    waitedFor = SystemClock.uptimeMillis() - startTime;
-                }
-
-                if (waitedFor >= keyDispatchingTimeout && mTimeToSwitch == 0) {
-                    IApplicationToken at = null;
-                    synchronized (this) {
-                        Slog.w(TAG, "Key dispatching timed out sending to " +
-                              (targetWin != null ? targetWin.mAttrs.getTitle()
-                              : "<null>: no window ready for key dispatch"));
-                        // NOSHIP debugging
-                        Slog.w(TAG, "Previous dispatch state: " + mDispatchState);
-                        Slog.w(TAG, "Current dispatch state: " +
-                                new DispatchState(nextKey, targetWin));
-                        // END NOSHIP
-                        //dump();
-                        if (targetWin != null) {
-                            at = targetWin.getAppToken();
-                        } else if (targetApp != null) {
-                            at = targetApp.appToken;
-                        }
-                    }
-
-                    boolean abort = true;
-                    if (at != null) {
-                        try {
-                            long timeout = at.getKeyDispatchingTimeout();
-                            if (timeout > waitedFor) {
-                                // we did not wait the proper amount of time for this application.
-                                // set the timeout to be the real timeout and wait again.
-                                keyDispatchingTimeout = timeout - waitedFor;
-                                continue;
-                            } else {
-                                abort = at.keyDispatchingTimedOut();
-                            }
-                        } catch (RemoteException ex) {
-                        }
-                    }
-
-                    synchronized (this) {
-                        if (abort && (mLastWin == targetWin || targetWin == null)) {
-                            mFinished = true;
-                            if (mLastWin != null) {
-                                if (DEBUG_INPUT) Slog.v(TAG,
-                                        "Window " + mLastWin +
-                                        " timed out on key input");
-                                if (mLastWin.mToken.paused) {
-                                    Slog.w(TAG, "Un-pausing dispatching to this window");
-                                    mLastWin.mToken.paused = false;
-                                }
-                            }
-                            if (mMotionTarget == targetWin) {
-                                mMotionTarget = null;
-                            }
-                            mLastWin = null;
-                            mLastBinder = null;
-                            if (failIfTimeout || targetWin == null) {
-                                return null;
-                            }
-                        } else {
-                            Slog.w(TAG, "Continuing to wait for key to be dispatched");
-                            startTime = SystemClock.uptimeMillis();
-                        }
-                    }
-                }
-            }
-        }
-
-        Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
-                MotionEvent nextMotion, boolean isPointerEvent,
-                int callingPid, int callingUid) {
-            mOutsideTouchTargets = null;
-
-            if (nextKey != null) {
-                // Find the target window for a normal key event.
-                final int keycode = nextKey.getKeyCode();
-                final int repeatCount = nextKey.getRepeatCount();
-                final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
-                boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
-
-                if (!dispatch) {
-                    if (callingUid == 0 ||
-                            mContext.checkPermission(
-                                    android.Manifest.permission.INJECT_EVENTS,
-                                    callingPid, callingUid)
-                                    == PackageManager.PERMISSION_GRANTED) {
-                        mPolicy.interceptKeyTi(null, keycode,
-                                nextKey.getMetaState(), down, repeatCount,
-                                nextKey.getFlags());
-                    }
-                    Slog.w(TAG, "Event timeout during app switch: dropping "
-                            + nextKey);
-                    return SKIP_TARGET_TOKEN;
-                }
-
-                // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
-
-                WindowState focus = null;
-                synchronized(mWindowMap) {
-                    focus = getFocusedWindowLocked();
-                }
-
-                wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
-
-                if (callingUid == 0 ||
-                        (focus != null && callingUid == focus.mSession.mUid) ||
-                        mContext.checkPermission(
-                                android.Manifest.permission.INJECT_EVENTS,
-                                callingPid, callingUid)
-                                == PackageManager.PERMISSION_GRANTED) {
-                    if (mPolicy.interceptKeyTi(focus,
-                            keycode, nextKey.getMetaState(), down, repeatCount,
-                            nextKey.getFlags())) {
-                        return CONSUMED_EVENT_TOKEN;
-                    }
-                }
-
-                return focus;
-
-            } else if (!isPointerEvent) {
-                boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
-                if (!dispatch) {
-                    Slog.w(TAG, "Event timeout during app switch: dropping trackball "
-                            + nextMotion);
-                    return SKIP_TARGET_TOKEN;
-                }
-
-                WindowState focus = null;
-                synchronized(mWindowMap) {
-                    focus = getFocusedWindowLocked();
-                }
-
-                wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
-                return focus;
-            }
-
-            if (nextMotion == null) {
-                return SKIP_TARGET_TOKEN;
-            }
-
-            boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
-                    KeyEvent.KEYCODE_UNKNOWN);
-            if (!dispatch) {
-                Slog.w(TAG, "Event timeout during app switch: dropping pointer "
-                        + nextMotion);
-                return SKIP_TARGET_TOKEN;
-            }
-
-            // Find the target window for a pointer event.
-            int action = nextMotion.getAction();
-            final float xf = nextMotion.getX();
-            final float yf = nextMotion.getY();
-            final long eventTime = nextMotion.getEventTime();
-
-            final boolean screenWasOff = qev != null
-                    && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
-
-            WindowState target = null;
-
-            synchronized(mWindowMap) {
-                synchronized (this) {
-                    if (action == MotionEvent.ACTION_DOWN) {
-                        if (mMotionTarget != 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: "
-                                    + mMotionTarget);
-                            mMotionTarget = null;
-                        }
-
-                        // ACTION_DOWN is special, because we need to lock next events to
-                        // the window we'll land onto.
-                        final int x = (int)xf;
-                        final int y = (int)yf;
-
-                        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) {
-                                    mMotionTarget = child;
-                                } else {
-                                    //Slog.i(TAG, "Waking, skip!");
-                                    mMotionTarget = 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 && mMotionTarget != topErrWindow) {
-                            mMotionTarget = null;
-                        }
-                    }
-
-                    target = mMotionTarget;
-                }
-            }
-
-            wakeupIfNeeded(target, eventType(nextMotion));
-
-            // Pointer events are a little different -- if there isn't a
-            // target found for any event, then just drop it.
-            return target != null ? target : SKIP_TARGET_TOKEN;
-        }
-
-        boolean checkShouldDispatchKey(int keycode) {
-            synchronized (this) {
-                if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
-                    mTimeToSwitch = 0;
-                    return true;
-                }
-                if (mTimeToSwitch != 0
-                        && mTimeToSwitch < SystemClock.uptimeMillis()) {
-                    return false;
-                }
-                return true;
-            }
-        }
-
-        void bindTargetWindowLocked(WindowState win,
-                int pendingWhat, QueuedEvent pendingMotion) {
-            synchronized (this) {
-                bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
-            }
-        }
-
-        void bindTargetWindowLocked(WindowState win) {
-            synchronized (this) {
-                bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
-            }
-        }
-
-        void bindTargetWindowLockedLocked(WindowState win,
-                int pendingWhat, QueuedEvent pendingMotion) {
-            mLastWin = win;
-            mLastBinder = win.mClient.asBinder();
-            mFinished = false;
-            if (pendingMotion != null) {
-                final Session s = win.mSession;
-                if (pendingWhat == RETURN_PENDING_POINTER) {
-                    releasePendingPointerLocked(s);
-                    s.mPendingPointerMove = pendingMotion;
-                    s.mPendingPointerWindow = win;
-                    if (DEBUG_INPUT) Slog.v(TAG,
-                            "bindTargetToWindow " + s.mPendingPointerMove);
-                } else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
-                    releasePendingTrackballLocked(s);
-                    s.mPendingTrackballMove = pendingMotion;
-                    s.mPendingTrackballWindow = win;
-                }
-            }
-        }
-
-        void releasePendingPointerLocked(Session s) {
-            if (DEBUG_INPUT) Slog.v(TAG,
-                    "releasePendingPointer " + s.mPendingPointerMove);
-            if (s.mPendingPointerMove != null) {
-                mQueue.recycleEvent(s.mPendingPointerMove);
-                s.mPendingPointerMove = null;
-            }
-        }
-
-        void releasePendingTrackballLocked(Session s) {
-            if (s.mPendingTrackballMove != null) {
-                mQueue.recycleEvent(s.mPendingTrackballMove);
-                s.mPendingTrackballMove = null;
-            }
-        }
-
-        MotionEvent finishedKey(Session session, IWindow client, boolean force,
-                int returnWhat) {
-            if (DEBUG_INPUT) Slog.v(
-                TAG, "finishedKey: client=" + client + ", force=" + force);
-
-            if (client == null) {
-                return null;
-            }
-
-            MotionEvent res = null;
-            QueuedEvent qev = null;
-            WindowState win = null;
-
-            synchronized (this) {
-                if (DEBUG_INPUT) Slog.v(
-                    TAG, "finishedKey: client=" + client.asBinder()
-                    + ", force=" + force + ", last=" + mLastBinder
-                    + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")");
-
-                if (returnWhat == RETURN_PENDING_POINTER) {
-                    qev = session.mPendingPointerMove;
-                    win = session.mPendingPointerWindow;
-                    session.mPendingPointerMove = null;
-                    session.mPendingPointerWindow = null;
-                } else if (returnWhat == RETURN_PENDING_TRACKBALL) {
-                    qev = session.mPendingTrackballMove;
-                    win = session.mPendingTrackballWindow;
-                    session.mPendingTrackballMove = null;
-                    session.mPendingTrackballWindow = null;
-                }
-
-                if (mLastBinder == client.asBinder()) {
-                    if (DEBUG_INPUT) Slog.v(
-                        TAG, "finishedKey: last paused="
-                        + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
-                    if (mLastWin != null && (!mLastWin.mToken.paused || force
-                            || !mEventDispatching)) {
-                        doFinishedKeyLocked(true);
-                    } else {
-                        // Make sure to wake up anyone currently waiting to
-                        // dispatch a key, so they can re-evaluate their
-                        // current situation.
-                        mFinished = true;
-                        notifyAll();
-                    }
-                }
-
-                if (qev != null) {
-                    res = (MotionEvent)qev.event;
-                    if (DEBUG_INPUT) Slog.v(TAG,
-                            "Returning pending motion: " + res);
-                    mQueue.recycleEvent(qev);
-                    if (win != null && returnWhat == RETURN_PENDING_POINTER) {
-                        res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
-                    }
-                }
-            }
-
-            if (res != null && returnWhat == RETURN_PENDING_POINTER) {
-                synchronized (mWindowMap) {
-                    dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
-                }
-            }
-
-            return res;
-        }
-
-        void tickle() {
-            synchronized (this) {
-                notifyAll();
-            }
-        }
-
-        void handleNewWindowLocked(WindowState newWindow) {
-            if (!newWindow.canReceiveKeys()) {
-                return;
-            }
-            synchronized (this) {
-                if (DEBUG_INPUT) Slog.v(
-                    TAG, "New key dispatch window: win="
-                    + newWindow.mClient.asBinder()
-                    + ", last=" + mLastBinder
-                    + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
-                    + "), finished=" + mFinished + ", paused="
-                    + newWindow.mToken.paused);
-
-                // Displaying a window implicitly causes dispatching to
-                // be unpaused.  (This is to protect against bugs if someone
-                // pauses dispatching but forgets to resume.)
-                newWindow.mToken.paused = false;
-
-                mGotFirstWindow = true;
-
-                if ((newWindow.mAttrs.flags & FLAG_SYSTEM_ERROR) != 0) {
-                    if (DEBUG_INPUT) Slog.v(TAG,
-                            "New SYSTEM_ERROR window; resetting state");
-                    mLastWin = null;
-                    mLastBinder = null;
-                    mMotionTarget = null;
-                    mFinished = true;
-                } else if (mLastWin != null) {
-                    // If the new window is above the window we are
-                    // waiting on, then stop waiting and let key dispatching
-                    // start on the new guy.
-                    if (DEBUG_INPUT) Slog.v(
-                        TAG, "Last win layer=" + mLastWin.mLayer
-                        + ", new win layer=" + newWindow.mLayer);
-                    if (newWindow.mLayer >= mLastWin.mLayer) {
-                        // The new window is above the old; finish pending input to the last
-                        // window and start directing it to the new one.
-                        mLastWin.mToken.paused = false;
-                        doFinishedKeyLocked(false);  // does a notifyAll()
-                        return;
-                    }
-                }
-
-                // Now that we've put a new window state in place, make the event waiter
-                // take notice and retarget its attentions.
-                notifyAll();
-            }
-        }
-
-        void pauseDispatchingLocked(WindowToken token) {
-            synchronized (this)
-            {
-                if (DEBUG_INPUT) Slog.v(TAG, "Pausing WindowToken " + token);
-                token.paused = true;
-
-                /*
-                if (mLastWin != null && !mFinished && mLastWin.mBaseLayer <= layer) {
-                    mPaused = true;
-                } else {
-                    if (mLastWin == null) {
-                        Slog.i(TAG, "Key dispatching not paused: no last window.");
-                    } else if (mFinished) {
-                        Slog.i(TAG, "Key dispatching not paused: finished last key.");
-                    } else {
-                        Slog.i(TAG, "Key dispatching not paused: window in higher layer.");
-                    }
-                }
-                */
-            }
-        }
-
-        void resumeDispatchingLocked(WindowToken token) {
-            synchronized (this) {
-                if (token.paused) {
-                    if (DEBUG_INPUT) Slog.v(
-                        TAG, "Resuming WindowToken " + token
-                        + ", last=" + mLastBinder
-                        + " (token=" + (mLastWin != null ? mLastWin.mToken : null)
-                        + "), finished=" + mFinished + ", paused="
-                        + token.paused);
-                    token.paused = false;
-                    if (mLastWin != null && mLastWin.mToken == token && mFinished) {
-                        doFinishedKeyLocked(false);
-                    } else {
-                        notifyAll();
-                    }
-                }
-            }
-        }
-
-        void setEventDispatchingLocked(boolean enabled) {
-            synchronized (this) {
-                mEventDispatching = enabled;
-                notifyAll();
-            }
-        }
-
-        void appSwitchComing() {
-            synchronized (this) {
-                // Don't wait for more than .5 seconds for app to finish
-                // processing the pending events.
-                long now = SystemClock.uptimeMillis() + 500;
-                if (DEBUG_INPUT) Slog.v(TAG, "appSwitchComing: " + now);
-                if (mTimeToSwitch == 0 || now < mTimeToSwitch) {
-                    mTimeToSwitch = now;
-                }
-                notifyAll();
-            }
-        }
-
-        private final void doFinishedKeyLocked(boolean force) {
-            if (mLastWin != null) {
-                releasePendingPointerLocked(mLastWin.mSession);
-                releasePendingTrackballLocked(mLastWin.mSession);
-            }
-
-            if (force || mLastWin == null || !mLastWin.mToken.paused
-                    || !mLastWin.isVisibleLw()) {
-                // If the current window has been paused, we aren't -really-
-                // finished...  so let the waiters still wait.
-                mLastWin = null;
-                mLastBinder = null;
-            }
-            mFinished = true;
-            notifyAll();
-        }
-    }
-
-    private class KeyQ extends KeyInputQueue
-            implements KeyInputQueue.FilterCallback {
-        KeyQ() {
-            super(mContext, WindowManagerService.this);
-        }
-
-        @Override
-        boolean preprocessEvent(InputDevice device, RawInputEvent event) {
-            if (mPolicy.preprocessInputEventTq(event)) {
-                return true;
-            }
-
-            switch (event.type) {
-                case RawInputEvent.EV_KEY: {
-                    // XXX begin hack
-                    if (DEBUG) {
-                        if (event.keycode == KeyEvent.KEYCODE_G) {
-                            if (event.value != 0) {
-                                // G down
-                                mPolicy.screenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
-                            }
-                            return false;
-                        }
-                        if (event.keycode == KeyEvent.KEYCODE_D) {
-                            if (event.value != 0) {
-                                //dump();
-                            }
-                            return false;
-                        }
-                    }
-                    // XXX end hack
-
-                    boolean screenIsOff = !mPowerManager.isScreenOn();
-                    boolean screenIsDim = !mPowerManager.isScreenBright();
-                    int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
-
-                    if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
-                        mPowerManager.goToSleep(event.when);
-                    }
-
-                    if (screenIsOff) {
-                        event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
-                    }
-                    if (screenIsDim) {
-                        event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
-                    }
-                    if ((actions & WindowManagerPolicy.ACTION_POKE_USER_ACTIVITY) != 0) {
-                        mPowerManager.userActivity(event.when, false,
-                                LocalPowerManager.BUTTON_EVENT, false);
-                    }
-
-                    if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
-                        if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
-                            filterQueue(this);
-                            mKeyWaiter.appSwitchComing();
-                        }
-                        return true;
-                    } else {
-                        return false;
-                    }
-                }
-
-                case RawInputEvent.EV_REL: {
-                    boolean screenIsOff = !mPowerManager.isScreenOn();
-                    boolean screenIsDim = !mPowerManager.isScreenBright();
-                    if (screenIsOff) {
-                        if (!mPolicy.isWakeRelMovementTq(event.deviceId,
-                                device.classes, event)) {
-                            //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
-                            return false;
-                        }
-                        event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
-                    }
-                    if (screenIsDim) {
-                        event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
-                    }
-                    return true;
-                }
-
-                case RawInputEvent.EV_ABS: {
-                    boolean screenIsOff = !mPowerManager.isScreenOn();
-                    boolean screenIsDim = !mPowerManager.isScreenBright();
-                    if (screenIsOff) {
-                        if (!mPolicy.isWakeAbsMovementTq(event.deviceId,
-                                device.classes, event)) {
-                            //Slog.i(TAG, "dropping because screenIsOff and !isWakeKey");
-                            return false;
-                        }
-                        event.flags |= WindowManagerPolicy.FLAG_WOKE_HERE;
-                    }
-                    if (screenIsDim) {
-                        event.flags |= WindowManagerPolicy.FLAG_BRIGHT_HERE;
-                    }
-                    return true;
-                }
-
-                default:
-                    return true;
-            }
-        }
-
-        public int filterEvent(QueuedEvent ev) {
-            switch (ev.classType) {
-                case RawInputEvent.CLASS_KEYBOARD:
-                    KeyEvent ke = (KeyEvent)ev.event;
-                    if (mPolicy.isMovementKeyTi(ke.getKeyCode())) {
-                        Slog.w(TAG, "Dropping movement key during app switch: "
-                                + ke.getKeyCode() + ", action=" + ke.getAction());
-                        return FILTER_REMOVE;
-                    }
-                    return FILTER_ABORT;
-                default:
-                    return FILTER_KEEP;
-            }
-        }
-    }
-
     public boolean detectSafeMode() {
         mSafeMode = mPolicy.detectSafeMode();
         return mSafeMode;
@@ -7003,219 +5444,6 @@
         mPolicy.systemReady();
     }
 
-    private final class InputDispatcherThread extends Thread {
-        // Time to wait when there is nothing to do: 9999 seconds.
-        static final int LONG_WAIT=9999*1000;
-
-        public InputDispatcherThread() {
-            super("InputDispatcher");
-        }
-
-        @Override
-        public void run() {
-            while (true) {
-                try {
-                    process();
-                } catch (Exception e) {
-                    Slog.e(TAG, "Exception in input dispatcher", e);
-                }
-            }
-        }
-
-        private void process() {
-            android.os.Process.setThreadPriority(
-                    android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
-
-            // The last key event we saw
-            KeyEvent lastKey = null;
-
-            // Last keydown time for auto-repeating keys
-            long lastKeyTime = SystemClock.uptimeMillis();
-            long nextKeyTime = lastKeyTime+LONG_WAIT;
-            long downTime = 0;
-
-            // How many successive repeats we generated
-            int keyRepeatCount = 0;
-
-            // Need to report that configuration has changed?
-            boolean configChanged = false;
-
-            while (true) {
-                long curTime = SystemClock.uptimeMillis();
-
-                if (DEBUG_INPUT) Slog.v(
-                    TAG, "Waiting for next key: now=" + curTime
-                    + ", repeat @ " + nextKeyTime);
-
-                // Retrieve next event, waiting only as long as the next
-                // repeat timeout.  If the configuration has changed, then
-                // don't wait at all -- we'll report the change as soon as
-                // we have processed all events.
-                QueuedEvent ev = mQueue.getEvent(
-                    (int)((!configChanged && curTime < nextKeyTime)
-                            ? (nextKeyTime-curTime) : 0));
-
-                if (DEBUG_INPUT && ev != null) Slog.v(
-                        TAG, "Event: type=" + ev.classType + " data=" + ev.event);
-
-                if (MEASURE_LATENCY) {
-                    lt.sample("2 got event              ", System.nanoTime() - ev.whenNano);
-                }
-
-                if (lastKey != null && !mPolicy.allowKeyRepeat()) {
-                    // cancel key repeat at the request of the policy.
-                    lastKey = null;
-                    downTime = 0;
-                    lastKeyTime = curTime;
-                    nextKeyTime = curTime + LONG_WAIT;
-                }
-                try {
-                    if (ev != null) {
-                        curTime = SystemClock.uptimeMillis();
-                        int eventType;
-                        if (ev.classType == RawInputEvent.CLASS_TOUCHSCREEN) {
-                            eventType = eventType((MotionEvent)ev.event);
-                        } else if (ev.classType == RawInputEvent.CLASS_KEYBOARD ||
-                                    ev.classType == RawInputEvent.CLASS_TRACKBALL) {
-                            eventType = LocalPowerManager.BUTTON_EVENT;
-                        } else {
-                            eventType = LocalPowerManager.OTHER_EVENT;
-                        }
-                        try {
-                            if ((curTime - mLastBatteryStatsCallTime)
-                                    >= MIN_TIME_BETWEEN_USERACTIVITIES) {
-                                mLastBatteryStatsCallTime = curTime;
-                                mBatteryStats.noteInputEvent();
-                            }
-                        } catch (RemoteException e) {
-                            // Ignore
-                        }
-
-                        if (ev.classType == RawInputEvent.CLASS_CONFIGURATION_CHANGED) {
-                            // do not wake screen in this case
-                        } else if (eventType != TOUCH_EVENT
-                                && eventType != LONG_TOUCH_EVENT
-                                && eventType != CHEEK_EVENT) {
-                            mPowerManager.userActivity(curTime, false,
-                                    eventType, false);
-                        } else if (mLastTouchEventType != eventType
-                                || (curTime - mLastUserActivityCallTime)
-                                >= MIN_TIME_BETWEEN_USERACTIVITIES) {
-                            mLastUserActivityCallTime = curTime;
-                            mLastTouchEventType = eventType;
-                            mPowerManager.userActivity(curTime, false,
-                                    eventType, false);
-                        }
-
-                        switch (ev.classType) {
-                            case RawInputEvent.CLASS_KEYBOARD:
-                                KeyEvent ke = (KeyEvent)ev.event;
-                                if (ke.isDown()) {
-                                    lastKeyTime = curTime;
-                                    if (lastKey != null &&
-                                            ke.getKeyCode() == lastKey.getKeyCode()) {
-                                        keyRepeatCount++;
-                                        // Arbitrary long timeout to block
-                                        // repeating here since we know that
-                                        // the device driver takes care of it.
-                                        nextKeyTime = lastKeyTime + LONG_WAIT;
-                                        if (DEBUG_INPUT) Slog.v(
-                                                TAG, "Received repeated key down");
-                                    } else {
-                                        downTime = curTime;
-                                        keyRepeatCount = 0;
-                                        nextKeyTime = lastKeyTime
-                                                + ViewConfiguration.getLongPressTimeout();
-                                        if (DEBUG_INPUT) Slog.v(
-                                            TAG, "Received key down: first repeat @ "
-                                            + nextKeyTime);
-                                    }
-                                    lastKey = ke;
-                                } else {
-                                    lastKey = null;
-                                    downTime = 0;
-                                    keyRepeatCount = 0;
-                                    // Arbitrary long timeout.
-                                    lastKeyTime = curTime;
-                                    nextKeyTime = curTime + LONG_WAIT;
-                                    if (DEBUG_INPUT) Slog.v(
-                                        TAG, "Received key up: ignore repeat @ "
-                                        + nextKeyTime);
-                                }
-                                if (keyRepeatCount > 0) {
-                                    dispatchKey(KeyEvent.changeTimeRepeat(ke,
-                                            ke.getEventTime(), keyRepeatCount), 0, 0);
-                                } else {
-                                    dispatchKey(ke, 0, 0);
-                                }
-                                mQueue.recycleEvent(ev);
-                                break;
-                            case RawInputEvent.CLASS_TOUCHSCREEN:
-                                //Slog.i(TAG, "Read next event " + ev);
-                                dispatchPointer(ev, (MotionEvent)ev.event, 0, 0);
-                                break;
-                            case RawInputEvent.CLASS_TRACKBALL:
-                                dispatchTrackball(ev, (MotionEvent)ev.event, 0, 0);
-                                break;
-                            case RawInputEvent.CLASS_CONFIGURATION_CHANGED:
-                                configChanged = true;
-                                break;
-                            default:
-                                mQueue.recycleEvent(ev);
-                            break;
-                        }
-
-                    } else if (configChanged) {
-                        configChanged = false;
-                        sendNewConfiguration();
-
-                    } else if (lastKey != null) {
-                        curTime = SystemClock.uptimeMillis();
-
-                        // Timeout occurred while key was down.  If it is at or
-                        // past the key repeat time, dispatch the repeat.
-                        if (DEBUG_INPUT) Slog.v(
-                            TAG, "Key timeout: repeat=" + nextKeyTime
-                            + ", now=" + curTime);
-                        if (curTime < nextKeyTime) {
-                            continue;
-                        }
-
-                        lastKeyTime = nextKeyTime;
-                        nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
-                        keyRepeatCount++;
-                        if (DEBUG_INPUT) Slog.v(
-                            TAG, "Key repeat: count=" + keyRepeatCount
-                            + ", next @ " + nextKeyTime);
-                        KeyEvent newEvent;
-                        if (downTime != 0 && (downTime
-                                + ViewConfiguration.getLongPressTimeout())
-                                <= curTime) {
-                            newEvent = KeyEvent.changeTimeRepeat(lastKey,
-                                    curTime, keyRepeatCount,
-                                    lastKey.getFlags() | KeyEvent.FLAG_LONG_PRESS);
-                            downTime = 0;
-                        } else {
-                            newEvent = KeyEvent.changeTimeRepeat(lastKey,
-                                    curTime, keyRepeatCount);
-                        }
-                        dispatchKey(newEvent, 0, 0);
-
-                    } else {
-                        curTime = SystemClock.uptimeMillis();
-
-                        lastKeyTime = curTime;
-                        nextKeyTime = curTime + LONG_WAIT;
-                    }
-
-                } catch (Exception e) {
-                    Slog.e(TAG,
-                        "Input thread received uncaught exception: " + e, e);
-                }
-            }
-        }
-    }
-
     // -------------------------------------------------------------
     // Client Session State
     // -------------------------------------------------------------
@@ -7231,20 +5459,6 @@
         int mNumWindow = 0;
         boolean mClientDead = false;
 
-        /**
-         * Current pointer move event being dispatched to client window...  must
-         * hold key lock to access.
-         */
-        QueuedEvent mPendingPointerMove;
-        WindowState mPendingPointerWindow;
-
-        /**
-         * Current trackball move event being dispatched to client window...  must
-         * hold key lock to access.
-         */
-        QueuedEvent mPendingTrackballMove;
-        WindowState mPendingTrackballWindow;
-
         public Session(IInputMethodClient client, IInputContext inputContext) {
             mClient = client;
             mInputContext = inputContext;
@@ -7363,36 +5577,6 @@
             finishDrawingWindow(this, window);
         }
 
-        public void finishKey(IWindow window) {
-            if (localLOGV) Slog.v(
-                TAG, "IWindow finishKey called for " + window);
-            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                throw new IllegalStateException("Should not be called anymore.");
-            }
-            mKeyWaiter.finishedKey(this, window, false,
-                    KeyWaiter.RETURN_NOTHING);
-        }
-
-        public MotionEvent getPendingPointerMove(IWindow window) {
-            if (localLOGV) Slog.v(
-                    TAG, "IWindow getPendingMotionEvent called for " + window);
-            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                throw new IllegalStateException("Should not be called anymore.");
-            }
-            return mKeyWaiter.finishedKey(this, window, false,
-                    KeyWaiter.RETURN_PENDING_POINTER);
-        }
-
-        public MotionEvent getPendingTrackballMove(IWindow window) {
-            if (localLOGV) Slog.v(
-                    TAG, "IWindow getPendingMotionEvent called for " + window);
-            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                throw new IllegalStateException("Should not be called anymore.");
-            }
-            return mKeyWaiter.finishedKey(this, window, false,
-                    KeyWaiter.RETURN_PENDING_TRACKBALL);
-        }
-
         public void setInTouchMode(boolean mode) {
             synchronized(mWindowMap) {
                 mInTouchMode = mode;
@@ -7496,16 +5680,6 @@
             pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
                     pw.print(" mClientDead="); pw.print(mClientDead);
                     pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
-            if (mPendingPointerWindow != null || mPendingPointerMove != null) {
-                pw.print(prefix);
-                        pw.print("mPendingPointerWindow="); pw.print(mPendingPointerWindow);
-                        pw.print(" mPendingPointerMove="); pw.println(mPendingPointerMove);
-            }
-            if (mPendingTrackballWindow != null || mPendingTrackballMove != null) {
-                pw.print(prefix);
-                        pw.print("mPendingTrackballWindow="); pw.print(mPendingTrackballWindow);
-                        pw.print(" mPendingTrackballMove="); pw.println(mPendingTrackballMove);
-            }
         }
 
         @Override
@@ -7556,8 +5730,6 @@
         boolean mObscured;
         boolean mTurnOnScreen;
 
-        WindowState mNextOutsideTouch;
-
         int mLayoutSeq = -1;
         
         Configuration mConfiguration = null;
@@ -8074,16 +6246,6 @@
         }
 
         void destroySurfaceLocked() {
-            // Window is no longer on-screen, so can no longer receive
-            // key events...  if we were waiting for it to finish
-            // handling a key event, the wait is over!
-            if (! ENABLE_NATIVE_INPUT_DISPATCH) {
-                mKeyWaiter.finishedKey(mSession, mClient, true,
-                        KeyWaiter.RETURN_NOTHING);
-                mKeyWaiter.releasePendingPointerLocked(mSession);
-                mKeyWaiter.releasePendingTrackballLocked(mSession);
-            }
-
             if (mAppToken != null && this == mAppToken.startingWindow) {
                 mAppToken.startingDisplayed = false;
             }
@@ -8099,9 +6261,7 @@
                     WindowState c = (WindowState)mChildWindows.get(i);
                     c.mAttachedHidden = true;
                     
-                    if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                        mInputMonitor.windowIsBecomingInvisibleLw(c);
-                    }
+                    mInputMonitor.windowIsBecomingInvisibleLw(c);
                 }
 
                 if (mReportDestroySurface) {
@@ -8410,12 +6570,8 @@
                 }
                 mLastHidden = true;
                 
-                if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                    for (int i=0; i<N; i++) {
-                        mInputMonitor.windowIsBecomingInvisibleLw((WindowState)mChildWindows.get(i));
-                    }
-                } else {
-                    mKeyWaiter.releasePendingPointerLocked(mSession);
+                for (int i=0; i<N; i++) {
+                    mInputMonitor.windowIsBecomingInvisibleLw((WindowState)mChildWindows.get(i));
                 }
             }
             mExiting = false;
@@ -8752,13 +6908,11 @@
                 // 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;
-                }
+            if (mInputChannel != null) {
+                mInputManager.unregisterInputChannel(mInputChannel);
+                
+                mInputChannel.dispose();
+                mInputChannel = null;
             }
         }
 
@@ -10174,9 +8328,7 @@
         }
         
         // Window frames may have changed.  Tell the input dispatcher about it.
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            mInputMonitor.updateInputWindowsLw();
-        }
+        mInputMonitor.updateInputWindowsLw();
 
         return mPolicy.finishLayoutLw();
     }
@@ -10977,11 +9129,7 @@
                                     Slog.w(TAG, "Exception hiding surface in " + w);
                                 }
                             }
-                            if (ENABLE_NATIVE_INPUT_DISPATCH) {
-                                mInputMonitor.windowIsBecomingInvisibleLw(w);
-                            } else {
-                                mKeyWaiter.releasePendingPointerLocked(w.mSession);
-                            }
+                            mInputMonitor.windowIsBecomingInvisibleLw(w);
                         }
                         // If we are waiting for this window to handle an
                         // orientation change, well, it is hidden, so
@@ -11583,13 +9731,7 @@
     }
     
     private void finishUpdateFocusedWindowAfterAssignLayersLocked() {
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            mInputMonitor.setInputFocusLw(mCurrentFocus);
-        } else {
-            if (mCurrentFocus != null) {
-                mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
-            }
-        }
+        mInputMonitor.setInputFocusLw(mCurrentFocus);
     }
 
     private WindowState computeFocusedWindowLocked() {
@@ -11663,17 +9805,6 @@
 
     private void startFreezingDisplayLocked() {
         if (mDisplayFrozen) {
-            // Freezing the display also suspends key event delivery, to
-            // keep events from going astray while the display is reconfigured.
-            // If someone has changed orientation again while the screen is
-            // still frozen, the events will continue to be blocked while the
-            // successive orientation change is processed.  To prevent spurious
-            // ANRs, we reset the event dispatch timeout in this case.
-            if (! ENABLE_NATIVE_INPUT_DISPATCH) {
-                synchronized (mKeyWaiter) {
-                    mKeyWaiter.mWasFrozen = true;
-                }
-            }
             return;
         }
 
@@ -11696,9 +9827,7 @@
         
         mDisplayFrozen = true;
         
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            mInputMonitor.freezeInputDispatchingLw();
-        }
+        mInputMonitor.freezeInputDispatchingLw();
         
         if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
             mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
@@ -11731,16 +9860,7 @@
         }
         Surface.unfreezeDisplay(0);
 
-        // Reset the key delivery timeout on unfreeze, too.  We force a wakeup here
-        // too because regular key delivery processing should resume immediately.
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            mInputMonitor.thawInputDispatchingLw();
-        } else {
-            synchronized (mKeyWaiter) {
-                mKeyWaiter.mWasFrozen = true;
-                mKeyWaiter.notifyAll();
-            }
-        }
+        mInputMonitor.thawInputDispatchingLw();
 
         // While the display is frozen we don't re-compute the orientation
         // to avoid inconsistent states.  However, something interesting
@@ -11772,13 +9892,8 @@
             return;
         }
 
-        if (ENABLE_NATIVE_INPUT_DISPATCH) {
-            pw.println("Input Dispatcher State:");
-            mInputManager.dump(pw);
-        } else {
-            pw.println("Input State:");
-            mQueue.dump(pw, "  ");
-        }
+        pw.println("Input Dispatcher State:");
+        mInputManager.dump(pw);
         pw.println(" ");
         
         synchronized(mWindowMap) {
@@ -11995,16 +10110,6 @@
             }
             pw.print("  DisplayWidth="); pw.print(mDisplay.getWidth());
                     pw.print(" DisplayHeight="); pw.println(mDisplay.getHeight());
-
-            if (! ENABLE_NATIVE_INPUT_DISPATCH) {
-                pw.println("  KeyWaiter state:");
-                pw.print("    mLastWin="); pw.print(mKeyWaiter.mLastWin);
-                        pw.print(" mLastBinder="); pw.println(mKeyWaiter.mLastBinder);
-                pw.print("    mFinished="); pw.print(mKeyWaiter.mFinished);
-                        pw.print(" mGotFirstWindow="); pw.print(mKeyWaiter.mGotFirstWindow);
-                        pw.print(" mEventDispatching="); pw.print(mKeyWaiter.mEventDispatching);
-                        pw.print(" mTimeToSwitch="); pw.println(mKeyWaiter.mTimeToSwitch);
-            }
         }
     }
 
@@ -12012,12 +10117,6 @@
     public void monitor() {
         synchronized (mWindowMap) { }
         synchronized (mKeyguardTokenWatcher) { }
-        synchronized (mKeyWaiter) { }
-        synchronized (mInputMonitor) { }
-    }
-
-    public void virtualKeyFeedback(KeyEvent event) {
-        mPolicy.keyFeedbackFromInput(event);
     }
 
     /**
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index 499ca86..0cf36b3 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -4,9 +4,9 @@
 LOCAL_SRC_FILES:= \
     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_PowerManagerService.cpp \
     com_android_server_SensorService.cpp \
     com_android_server_SystemServer.cpp \
     com_android_server_VibratorService.cpp \
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index d0f856b..fc901f4 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -40,6 +40,7 @@
 #include "../../core/jni/android_view_KeyEvent.h"
 #include "../../core/jni/android_view_MotionEvent.h"
 #include "../../core/jni/android_view_InputChannel.h"
+#include "com_android_server_PowerManagerService.h"
 
 namespace android {
 
@@ -107,16 +108,6 @@
     LAST_SYSTEM_WINDOW      = 2999,
 };
 
-enum {
-    POWER_MANAGER_OTHER_EVENT = 0,
-    POWER_MANAGER_CHEEK_EVENT = 1,
-    POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either
-                                   // up events or LONG_TOUCH events.
-    POWER_MANAGER_LONG_TOUCH_EVENT = 3,
-    POWER_MANAGER_TOUCH_UP_EVENT = 4,
-    POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events.
-};
-
 // Delay between reporting long touch events to the power manager.
 const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms
 
@@ -133,20 +124,16 @@
 static struct {
     jclass clazz;
 
-    jmethodID isScreenOn;
-    jmethodID isScreenBright;
     jmethodID notifyConfigurationChanged;
     jmethodID notifyLidSwitchChanged;
     jmethodID notifyInputChannelBroken;
     jmethodID notifyInputChannelANR;
     jmethodID notifyInputChannelRecoveredFromANR;
     jmethodID notifyANR;
-    jmethodID virtualKeyFeedback;
+    jmethodID virtualKeyDownFeedback;
     jmethodID interceptKeyBeforeQueueing;
     jmethodID interceptKeyBeforeDispatching;
     jmethodID checkInjectEventsPermission;
-    jmethodID goToSleep;
-    jmethodID pokeUserActivity;
     jmethodID notifyAppSwitchComing;
     jmethodID filterTouchEvents;
     jmethodID filterJumpyTouchEvents;
@@ -228,9 +215,7 @@
 
     virtual bool getDisplayInfo(int32_t displayId,
             int32_t* width, int32_t* height, int32_t* orientation);
-    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 void virtualKeyDownFeedback();
     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,
@@ -321,7 +306,7 @@
     int32_t mDisplayWidth, mDisplayHeight;
     int32_t mDisplayOrientation;
 
-    // Callbacks.
+    // Power manager interactions.
     bool isScreenOn();
     bool isScreenBright();
 
@@ -369,9 +354,9 @@
 
     void releaseTouchedWindowLd();
 
-    int32_t identifyTrackballEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
+    int32_t waitForTrackballEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
             int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
-    int32_t identifyTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
+    int32_t waitForTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
             int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
 
     bool interceptKeyBeforeDispatching(const InputTarget& target,
@@ -391,6 +376,7 @@
     }
 
     static bool isAppSwitchKey(int32_t keyCode);
+    static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
     static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
 };
 
@@ -422,6 +408,36 @@
     return keyCode == KEYCODE_HOME || keyCode == KEYCODE_ENDCALL;
 }
 
+bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
+    // Special keys that the WindowManagerPolicy might care about.
+    switch (keyCode) {
+    case KEYCODE_VOLUME_UP:
+    case KEYCODE_VOLUME_DOWN:
+    case KEYCODE_ENDCALL:
+    case KEYCODE_POWER:
+    case KEYCODE_CALL:
+    case KEYCODE_HOME:
+    case KEYCODE_MENU:
+    case KEYCODE_SEARCH:
+        // media keys
+    case KEYCODE_HEADSETHOOK:
+    case KEYCODE_MEDIA_PLAY_PAUSE:
+    case KEYCODE_MEDIA_STOP:
+    case KEYCODE_MEDIA_NEXT:
+    case KEYCODE_MEDIA_PREVIOUS:
+    case KEYCODE_MEDIA_REWIND:
+    case KEYCODE_MEDIA_FAST_FORWARD:
+        return true;
+    default:
+        // We need to pass all keys to the policy in the following cases:
+        // - screen is off
+        // - keyguard is visible
+        // - policy is performing key chording
+        //return ! isScreenOn || keyguardVisible || chording;
+        return true; // XXX stubbed out for now
+    }
+}
+
 bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
     if (env->ExceptionCheck()) {
         LOGE("An exception was thrown by callback '%s'.", methodName);
@@ -546,39 +562,22 @@
 }
 
 bool NativeInputManager::isScreenOn() {
-    JNIEnv* env = jniEnv();
-
-    jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenOn);
-    if (checkAndClearExceptionFromCallback(env, "isScreenOn")) {
-        return true;
-    }
-    return result;
+    return android_server_PowerManagerService_isScreenOn();
 }
 
 bool NativeInputManager::isScreenBright() {
-    JNIEnv* env = jniEnv();
-
-    jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenBright);
-    if (checkAndClearExceptionFromCallback(env, "isScreenBright")) {
-        return true;
-    }
-    return result;
+    return android_server_PowerManagerService_isScreenBright();
 }
 
-void NativeInputManager::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) {
+void NativeInputManager::virtualKeyDownFeedback() {
 #if DEBUG_INPUT_READER_POLICY
-    LOGD("virtualKeyFeedback - when=%lld, deviceId=%d, action=%d, flags=%d, keyCode=%d, "
-            "scanCode=%d, metaState=%d, downTime=%lld",
-            when, deviceId, action, flags, keyCode, scanCode, metaState, downTime);
+    LOGD("virtualKeyDownFeedback");
 #endif
 
     JNIEnv* env = jniEnv();
 
-    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyFeedback,
-            when, deviceId, action, flags, keyCode, scanCode, metaState, downTime);
-    checkAndClearExceptionFromCallback(env, "virtualKeyFeedback");
+    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
+    checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
 }
 
 int32_t NativeInputManager::interceptKey(nsecs_t when,
@@ -593,16 +592,21 @@
     const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
     const int32_t WM_ACTION_GO_TO_SLEEP = 4;
 
-    JNIEnv* env = jniEnv();
-
     bool isScreenOn = this->isScreenOn();
     bool isScreenBright = this->isScreenBright();
 
-    jint wmActions = env->CallIntMethod(mCallbacksObj,
-            gCallbacksClassInfo.interceptKeyBeforeQueueing,
-            deviceId, EV_KEY, scanCode, keyCode, policyFlags, down ? 1 : 0, when, isScreenOn);
-    if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
-        wmActions = 0;
+    jint wmActions = 0;
+    if (isPolicyKey(keyCode, isScreenOn)) {
+        JNIEnv* env = jniEnv();
+
+        wmActions = env->CallIntMethod(mCallbacksObj,
+                gCallbacksClassInfo.interceptKeyBeforeQueueing,
+                when, keyCode, down, policyFlags, isScreenOn);
+        if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
+            wmActions = 0;
+        }
+    } else {
+        wmActions = WM_ACTION_PASS_TO_USER;
     }
 
     int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
@@ -617,8 +621,7 @@
     }
 
     if (wmActions & WM_ACTION_GO_TO_SLEEP) {
-        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.goToSleep, when);
-        checkAndClearExceptionFromCallback(env, "goToSleep");
+        android_server_PowerManagerService_goToSleep(when);
     }
 
     if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
@@ -629,6 +632,8 @@
         actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
 
         if (down && isAppSwitchKey(keyCode)) {
+            JNIEnv* env = jniEnv();
+
             env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyAppSwitchComing);
             checkAndClearExceptionFromCallback(env, "notifyAppSwitchComing");
 
@@ -1531,11 +1536,13 @@
         windowType = focusedWindow->layoutParamsType;
     } // release lock
 
-    const InputTarget& target = outTargets.top();
-    bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags);
-    if (consumed) {
-        outTargets.clear();
-        return INPUT_EVENT_INJECTION_SUCCEEDED;
+    if (isPolicyKey(keyEvent->getKeyCode(), isScreenOn())) {
+        const InputTarget& target = outTargets.top();
+        bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags);
+        if (consumed) {
+            outTargets.clear();
+            return INPUT_EVENT_INJECTION_SUCCEEDED;
+        }
     }
 
     pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT);
@@ -1552,11 +1559,11 @@
 
     switch (motionEvent->getNature()) {
     case INPUT_EVENT_NATURE_TRACKBALL:
-        return identifyTrackballEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
+        return waitForTrackballEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
                 outTargets);
 
     case INPUT_EVENT_NATURE_TOUCH:
-        return identifyTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
+        return waitForTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
                 outTargets);
 
     default:
@@ -1565,11 +1572,11 @@
     }
 }
 
-int32_t NativeInputManager::identifyTrackballEventTargets(MotionEvent* motionEvent,
+int32_t NativeInputManager::waitForTrackballEventTargets(MotionEvent* motionEvent,
         uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
         Vector<InputTarget>& outTargets) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
-    LOGD("identifyTrackballEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
+    LOGD("waitForTrackballEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
             policyFlags, injectorPid, injectorUid);
 #endif
 
@@ -1591,11 +1598,11 @@
     return INPUT_EVENT_INJECTION_SUCCEEDED;
 }
 
-int32_t NativeInputManager::identifyTouchEventTargets(MotionEvent* motionEvent,
+int32_t NativeInputManager::waitForTouchEventTargets(MotionEvent* motionEvent,
         uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
         Vector<InputTarget>& outTargets) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
-    LOGD("identifyTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
+    LOGD("waitForTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
             policyFlags, injectorPid, injectorUid);
 #endif
 
@@ -1642,8 +1649,8 @@
     if (inputChannelObj) {
         jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
                 gCallbacksClassInfo.interceptKeyBeforeDispatching,
-                inputChannelObj, keyEvent->getKeyCode(), keyEvent->getMetaState(),
-                keyEvent->getAction() == KEY_EVENT_ACTION_DOWN,
+                inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
+                keyEvent->getKeyCode(), keyEvent->getMetaState(),
                 keyEvent->getRepeatCount(), policyFlags);
         bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
 
@@ -1665,10 +1672,7 @@
 }
 
 void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
-    JNIEnv* env = jniEnv();
-    env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.pokeUserActivity,
-            eventTime, eventType);
-    checkAndClearExceptionFromCallback(env, "pokeUserActivity");
+    android_server_PowerManagerService_userActivity(eventTime, eventType);
 }
 
 void NativeInputManager::dumpDispatchStateLd() {
@@ -2082,12 +2086,6 @@
 
     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");
 
@@ -2106,24 +2104,18 @@
     GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
             "notifyANR", "(Ljava/lang/Object;)J");
 
-    GET_METHOD_ID(gCallbacksClassInfo.virtualKeyFeedback, gCallbacksClassInfo.clazz,
-            "virtualKeyFeedback", "(JIIIIIIJ)V");
+    GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
+            "virtualKeyDownFeedback", "()V");
 
     GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
-            "interceptKeyBeforeQueueing", "(IIIIIIJZ)I");
+            "interceptKeyBeforeQueueing", "(JIZIZ)I");
 
     GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
-            "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIZII)Z");
+            "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIII)Z");
 
     GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
             "checkInjectEventsPermission", "(II)Z");
 
-    GET_METHOD_ID(gCallbacksClassInfo.goToSleep, gCallbacksClassInfo.clazz,
-            "goToSleep", "(J)V");
-
-    GET_METHOD_ID(gCallbacksClassInfo.pokeUserActivity, gCallbacksClassInfo.clazz,
-            "pokeUserActivity", "(JI)V");
-
     GET_METHOD_ID(gCallbacksClassInfo.notifyAppSwitchComing, gCallbacksClassInfo.clazz,
             "notifyAppSwitchComing", "()V");
 
diff --git a/services/jni/com_android_server_KeyInputQueue.cpp b/services/jni/com_android_server_KeyInputQueue.cpp
deleted file mode 100644
index f9e3585..0000000
--- a/services/jni/com_android_server_KeyInputQueue.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Input"
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include <utils/misc.h>
-#include <utils/Log.h>
-
-#include <ui/EventHub.h>
-#include <utils/threads.h>
-
-#include <stdio.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-static struct input_offsets_t
-{
-    jfieldID mMinValue;
-    jfieldID mMaxValue;
-    jfieldID mFlat;
-    jfieldID mFuzz;
-    
-    jfieldID mDeviceId;
-    jfieldID mType;
-    jfieldID mScancode;
-    jfieldID mKeycode;
-    jfieldID mFlags;
-    jfieldID mValue;
-    jfieldID mWhen;
-} gInputOffsets;
-
-// ----------------------------------------------------------------------------
-
-static Mutex gLock;
-static sp<EventHub> gHub;
-
-static jboolean
-android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
-                                          jobject event)
-{
-    gLock.lock();
-    sp<EventHub> hub = gHub;
-    if (hub == NULL) {
-        hub = new EventHub;
-        gHub = hub;
-    }
-    gLock.unlock();
-
-    int32_t deviceId;
-    int32_t type;
-    int32_t scancode, keycode;
-    uint32_t flags;
-    int32_t value;
-    nsecs_t when;
-    bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode,
-            &flags, &value, &when);
-
-    env->SetIntField(event, gInputOffsets.mDeviceId, (jint)deviceId);
-    env->SetIntField(event, gInputOffsets.mType, (jint)type);
-    env->SetIntField(event, gInputOffsets.mScancode, (jint)scancode);
-    env->SetIntField(event, gInputOffsets.mKeycode, (jint)keycode);
-    env->SetIntField(event, gInputOffsets.mFlags, (jint)flags);
-    env->SetIntField(event, gInputOffsets.mValue, value);
-    env->SetLongField(event, gInputOffsets.mWhen,
-                        (jlong)(nanoseconds_to_milliseconds(when)));
-
-    return res;
-}
-
-static jint
-android_server_KeyInputQueue_getDeviceClasses(JNIEnv* env, jobject clazz,
-                                              jint deviceId)
-{
-    jint classes = 0;
-    gLock.lock();
-    if (gHub != NULL) classes = gHub->getDeviceClasses(deviceId);
-    gLock.unlock();
-    return classes;
-}
-
-static jstring
-android_server_KeyInputQueue_getDeviceName(JNIEnv* env, jobject clazz,
-                                              jint deviceId)
-{
-    String8 name;
-    gLock.lock();
-    if (gHub != NULL) name = gHub->getDeviceName(deviceId);
-    gLock.unlock();
-    
-    if (name.size() > 0) {
-        return env->NewStringUTF(name.string());
-    }
-    return NULL;
-}
-
-static void
-android_server_KeyInputQueue_addExcludedDevice(JNIEnv* env, jobject clazz,
-                                              jstring deviceName)
-{
-    gLock.lock();
-    sp<EventHub> hub = gHub;
-    if (hub == NULL) {
-        hub = new EventHub;
-        gHub = hub;
-    }
-    gLock.unlock();
-
-    const char* nameStr = env->GetStringUTFChars(deviceName, NULL);
-    gHub->addExcludedDevice(nameStr);
-    env->ReleaseStringUTFChars(deviceName, nameStr);
-}
-
-static jboolean
-android_server_KeyInputQueue_getAbsoluteInfo(JNIEnv* env, jobject clazz,
-                                             jint deviceId, jint axis,
-                                             jobject info)
-{
-    int32_t minValue, maxValue, flat, fuzz;
-    int res = -1;
-    gLock.lock();
-    if (gHub != NULL) {
-        res = gHub->getAbsoluteInfo(deviceId, axis,
-                &minValue, &maxValue, &flat, &fuzz);
-    }
-    gLock.unlock();
-    
-    if (res < 0) return JNI_FALSE;
-    
-    env->SetIntField(info, gInputOffsets.mMinValue, (jint)minValue);
-    env->SetIntField(info, gInputOffsets.mMaxValue, (jint)maxValue);
-    env->SetIntField(info, gInputOffsets.mFlat, (jint)flat);
-    env->SetIntField(info, gInputOffsets.mFuzz, (jint)fuzz);
-    return JNI_TRUE;
-}
-
-static jint
-android_server_KeyInputQueue_getSwitchState(JNIEnv* env, jobject clazz,
-                                           jint sw)
-{
-    jint st = -1;
-    gLock.lock();
-    if (gHub != NULL) st = gHub->getSwitchState(-1, -1, sw);
-    gLock.unlock();
-    
-    return st;
-}
-
-static jint
-android_server_KeyInputQueue_getSwitchStateDevice(JNIEnv* env, jobject clazz,
-                                            jint deviceId, jint sw)
-{
-    jint st = -1;
-    gLock.lock();
-    if (gHub != NULL) st = gHub->getSwitchState(deviceId, -1, sw);
-    gLock.unlock();
-    
-    return st;
-}
-
-static jint
-android_server_KeyInputQueue_getScancodeState(JNIEnv* env, jobject clazz,
-                                           jint sw)
-{
-    jint st = -1;
-    gLock.lock();
-    if (gHub != NULL) st = gHub->getScanCodeState(0, -1, sw);
-    gLock.unlock();
-    
-    return st;
-}
-
-static jint
-android_server_KeyInputQueue_getScancodeStateDevice(JNIEnv* env, jobject clazz,
-                                            jint deviceId, jint sw)
-{
-    jint st = -1;
-    gLock.lock();
-    if (gHub != NULL) st = gHub->getScanCodeState(deviceId, -1, sw);
-    gLock.unlock();
-    
-    return st;
-}
-
-static jint
-android_server_KeyInputQueue_getKeycodeState(JNIEnv* env, jobject clazz,
-                                           jint sw)
-{
-    jint st = -1;
-    gLock.lock();
-    if (gHub != NULL) st = gHub->getKeyCodeState(0, -1, sw);
-    gLock.unlock();
-    
-    return st;
-}
-
-static jint
-android_server_KeyInputQueue_getKeycodeStateDevice(JNIEnv* env, jobject clazz,
-                                            jint deviceId, jint sw)
-{
-    jint st = -1;
-    gLock.lock();
-    if (gHub != NULL) st = gHub->getKeyCodeState(deviceId,-1, sw);
-    gLock.unlock();
-    
-    return st;
-}
-
-static jint
-android_server_KeyInputQueue_scancodeToKeycode(JNIEnv* env, jobject clazz,
-                                            jint deviceId, jint scancode)
-{
-    jint res = 0;
-    gLock.lock();
-    if (gHub != NULL) {
-        int32_t keycode;
-        uint32_t flags;
-        gHub->scancodeToKeycode(deviceId, scancode, &keycode, &flags);
-        res = keycode;
-    }
-    gLock.unlock();
-    
-    return res;
-}
-
-static jboolean
-android_server_KeyInputQueue_hasKeys(JNIEnv* env, jobject clazz,
-                                     jintArray keyCodes, jbooleanArray outFlags)
-{
-    jboolean ret = JNI_FALSE;
-
-    int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
-    uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
-    jsize numCodes = env->GetArrayLength(keyCodes);
-    if (numCodes == env->GetArrayLength(outFlags)) {
-        gLock.lock();
-        if (gHub != NULL) ret = gHub->hasKeys(numCodes, codes, flags);
-        gLock.unlock();
-    }
-
-    env->ReleaseBooleanArrayElements(outFlags, flags, 0);
-    env->ReleaseIntArrayElements(keyCodes, codes, 0);
-    return ret;
-}
-
-// ----------------------------------------------------------------------------
-
-/*
- * JNI registration.
- */
-static JNINativeMethod gInputMethods[] = {
-    /* name, signature, funcPtr */
-    { "readEvent",       "(Landroid/view/RawInputEvent;)Z",
-            (void*) android_server_KeyInputQueue_readEvent },
-    { "getDeviceClasses", "(I)I",
-        (void*) android_server_KeyInputQueue_getDeviceClasses },
-    { "getDeviceName", "(I)Ljava/lang/String;",
-        (void*) android_server_KeyInputQueue_getDeviceName },
-    { "addExcludedDevice", "(Ljava/lang/String;)V",
-        (void*) android_server_KeyInputQueue_addExcludedDevice },
-    { "getAbsoluteInfo", "(IILcom/android/server/InputDevice$AbsoluteInfo;)Z",
-        (void*) android_server_KeyInputQueue_getAbsoluteInfo },
-    { "getSwitchState", "(I)I",
-        (void*) android_server_KeyInputQueue_getSwitchState },
-    { "getSwitchState", "(II)I",
-        (void*) android_server_KeyInputQueue_getSwitchStateDevice },
-    { "nativeGetScancodeState", "(I)I",
-        (void*) android_server_KeyInputQueue_getScancodeState },
-    { "nativeGetScancodeState", "(II)I",
-        (void*) android_server_KeyInputQueue_getScancodeStateDevice },
-    { "nativeGetKeycodeState", "(I)I",
-        (void*) android_server_KeyInputQueue_getKeycodeState },
-    { "nativeGetKeycodeState", "(II)I",
-        (void*) android_server_KeyInputQueue_getKeycodeStateDevice },
-    { "hasKeys", "([I[Z)Z",
-        (void*) android_server_KeyInputQueue_hasKeys },
-    { "scancodeToKeycode", "(II)I",
-        (void*) android_server_KeyInputQueue_scancodeToKeycode },
-};
-
-int register_android_server_KeyInputQueue(JNIEnv* env)
-{
-    jclass input = env->FindClass("com/android/server/KeyInputQueue");
-    LOG_FATAL_IF(input == NULL, "Unable to find class com/android/server/KeyInputQueue");
-    int res = jniRegisterNativeMethods(env, "com/android/server/KeyInputQueue",
-                                        gInputMethods, NELEM(gInputMethods));
-
-    jclass absoluteInfo = env->FindClass("com/android/server/InputDevice$AbsoluteInfo");
-    LOG_FATAL_IF(absoluteInfo == NULL, "Unable to find class com/android/server/InputDevice$AbsoluteInfo");
-    
-    gInputOffsets.mMinValue
-        = env->GetFieldID(absoluteInfo, "minValue", "I");
-    LOG_FATAL_IF(gInputOffsets.mMinValue == NULL, "Unable to find InputDevice.AbsoluteInfo.minValue");
-    
-    gInputOffsets.mMaxValue
-        = env->GetFieldID(absoluteInfo, "maxValue", "I");
-    LOG_FATAL_IF(gInputOffsets.mMaxValue == NULL, "Unable to find InputDevice.AbsoluteInfo.maxValue");
-    
-    gInputOffsets.mFlat
-        = env->GetFieldID(absoluteInfo, "flat", "I");
-    LOG_FATAL_IF(gInputOffsets.mFlat == NULL, "Unable to find InputDevice.AbsoluteInfo.flat");
-    
-    gInputOffsets.mFuzz
-        = env->GetFieldID(absoluteInfo, "fuzz", "I");
-    LOG_FATAL_IF(gInputOffsets.mFuzz == NULL, "Unable to find InputDevice.AbsoluteInfo.fuzz");
-    
-    jclass inputEvent = env->FindClass("android/view/RawInputEvent");
-    LOG_FATAL_IF(inputEvent == NULL, "Unable to find class android/view/RawInputEvent");
-
-    gInputOffsets.mDeviceId
-        = env->GetFieldID(inputEvent, "deviceId", "I");
-    LOG_FATAL_IF(gInputOffsets.mDeviceId == NULL, "Unable to find RawInputEvent.deviceId");
-    
-    gInputOffsets.mType
-        = env->GetFieldID(inputEvent, "type", "I");
-    LOG_FATAL_IF(gInputOffsets.mType == NULL, "Unable to find RawInputEvent.type");
-    
-    gInputOffsets.mScancode
-        = env->GetFieldID(inputEvent, "scancode", "I");
-    LOG_FATAL_IF(gInputOffsets.mScancode == NULL, "Unable to find RawInputEvent.scancode");
-
-    gInputOffsets.mKeycode
-        = env->GetFieldID(inputEvent, "keycode", "I");
-    LOG_FATAL_IF(gInputOffsets.mKeycode == NULL, "Unable to find RawInputEvent.keycode");
-
-    gInputOffsets.mFlags
-        = env->GetFieldID(inputEvent, "flags", "I");
-    LOG_FATAL_IF(gInputOffsets.mFlags == NULL, "Unable to find RawInputEvent.flags");
-
-    gInputOffsets.mValue
-        = env->GetFieldID(inputEvent, "value", "I");
-    LOG_FATAL_IF(gInputOffsets.mValue == NULL, "Unable to find RawInputEvent.value");
-    
-    gInputOffsets.mWhen
-        = env->GetFieldID(inputEvent, "when", "J");
-    LOG_FATAL_IF(gInputOffsets.mWhen == NULL, "Unable to find RawInputEvent.when");
-
-    return res;
-}
-
-}; // namespace android
-
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp
new file mode 100644
index 0000000..b80dbc5
--- /dev/null
+++ b/services/jni/com_android_server_PowerManagerService.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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 "PowerManagerService-JNI"
+
+//#define LOG_NDEBUG 0
+
+#include "JNIHelp.h"
+#include "jni.h"
+#include <limits.h>
+#include <android_runtime/AndroidRuntime.h>
+#include "com_android_server_PowerManagerService.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+    jclass clazz;
+
+    jmethodID goToSleep;
+    jmethodID userActivity;
+} gPowerManagerServiceClassInfo;
+
+// ----------------------------------------------------------------------------
+
+static jobject gPowerManagerServiceObj;
+
+static Mutex gPowerManagerLock;
+static bool gScreenOn;
+static bool gScreenBright;
+
+// ----------------------------------------------------------------------------
+
+static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
+    if (env->ExceptionCheck()) {
+        LOGE("An exception was thrown by callback '%s'.", methodName);
+        LOGE_EX(env);
+        env->ExceptionClear();
+        return true;
+    }
+    return false;
+}
+
+bool android_server_PowerManagerService_isScreenOn() {
+    AutoMutex _l(gPowerManagerLock);
+    return gScreenOn;
+}
+
+bool android_server_PowerManagerService_isScreenBright() {
+    AutoMutex _l(gPowerManagerLock);
+    return gScreenBright;
+}
+
+void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
+    if (gPowerManagerServiceObj) {
+        JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+        env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.userActivity,
+                nanoseconds_to_milliseconds(eventTime), false, eventType, false);
+        checkAndClearExceptionFromCallback(env, "userActivity");
+    }
+}
+
+void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) {
+    if (gPowerManagerServiceObj) {
+        JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+        env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.goToSleep,
+                nanoseconds_to_milliseconds(eventTime));
+        checkAndClearExceptionFromCallback(env, "goToSleep");
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+static void android_server_PowerManagerService_nativeInit(JNIEnv* env, jobject obj) {
+    gPowerManagerServiceObj = env->NewGlobalRef(obj);
+}
+
+static void android_server_PowerManagerService_nativeSetPowerState(JNIEnv* env,
+        jobject serviceObj, jboolean screenOn, jboolean screenBright) {
+    AutoMutex _l(gPowerManagerLock);
+    gScreenOn = screenOn;
+    gScreenBright = screenBright;
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gPowerManagerServiceMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeInit", "()V",
+            (void*) android_server_PowerManagerService_nativeInit },
+    { "nativeSetPowerState", "(ZZ)V",
+            (void*) android_server_PowerManagerService_nativeSetPowerState },
+};
+
+#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_PowerManagerService(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "com/android/server/PowerManagerService",
+            gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    // Callbacks
+
+    FIND_CLASS(gPowerManagerServiceClassInfo.clazz, "com/android/server/PowerManagerService");
+
+    GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, gPowerManagerServiceClassInfo.clazz,
+            "goToSleep", "(J)V");
+
+    GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, gPowerManagerServiceClassInfo.clazz,
+            "userActivity", "(JZIZ)V");
+
+    return 0;
+}
+
+} /* namespace android */
diff --git a/services/jni/com_android_server_PowerManagerService.h b/services/jni/com_android_server_PowerManagerService.h
new file mode 100644
index 0000000..9b05f38
--- /dev/null
+++ b/services/jni/com_android_server_PowerManagerService.h
@@ -0,0 +1,42 @@
+/*
+ * 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_SERVER_POWER_MANAGER_SERVICE_H
+#define _ANDROID_SERVER_POWER_MANAGER_SERVICE_H
+
+#include "JNIHelp.h"
+#include "jni.h"
+
+namespace android {
+
+enum {
+    POWER_MANAGER_OTHER_EVENT = 0,
+    POWER_MANAGER_CHEEK_EVENT = 1,
+    POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either
+                                   // up events or LONG_TOUCH events.
+    POWER_MANAGER_LONG_TOUCH_EVENT = 3,
+    POWER_MANAGER_TOUCH_UP_EVENT = 4,
+    POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events.
+};
+
+extern bool android_server_PowerManagerService_isScreenOn();
+extern bool android_server_PowerManagerService_isScreenBright();
+extern void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType);
+extern void android_server_PowerManagerService_goToSleep(nsecs_t eventTime);
+
+} // namespace android
+
+#endif // _ANDROID_SERVER_POWER_MANAGER_SERVICE_H
diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp
index a1a6838..1a2d8b6 100644
--- a/services/jni/onload.cpp
+++ b/services/jni/onload.cpp
@@ -6,9 +6,9 @@
 namespace android {
 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_PowerManagerService(JNIEnv* env);
 int register_android_server_SensorService(JNIEnv* env);
 int register_android_server_VibratorService(JNIEnv* env);
 int register_android_server_SystemServer(JNIEnv* env);
@@ -28,7 +28,7 @@
     }
     LOG_ASSERT(env, "Could not retrieve the env!");
 
-    register_android_server_KeyInputQueue(env);
+    register_android_server_PowerManagerService(env);
     register_android_server_InputManager(env);
     register_android_server_LightsService(env);
     register_android_server_AlarmManagerService(env);
