summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Tate <ctate@android.com>2010-07-07 17:43:12 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-07-07 17:43:12 -0700
commitb17f4dcfb3edba25bd8c30e60449b9bbcd600a57 (patch)
tree0820fc428a7c001e5eb8796ff806ee78f1b1638f
parentf3f25bf80b7d21f12442da8f82d17c79dd371692 (diff)
parent00fa7bdd69f0868fd17ea7c881c771d785b2fbbd (diff)
downloadframeworks_base-b17f4dcfb3edba25bd8c30e60449b9bbcd600a57.zip
frameworks_base-b17f4dcfb3edba25bd8c30e60449b9bbcd600a57.tar.gz
frameworks_base-b17f4dcfb3edba25bd8c30e60449b9bbcd600a57.tar.bz2
Merge "More native input dispatch work." into gingerbread
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java77
-rw-r--r--core/java/android/view/IWindow.aidl3
-rw-r--r--core/java/android/view/IWindowSession.aidl4
-rw-r--r--core/java/android/view/RawInputEvent.java201
-rw-r--r--core/java/android/view/SurfaceView.java36
-rw-r--r--core/java/android/view/ViewRoot.java598
-rw-r--r--core/java/android/view/WindowManagerPolicy.java131
-rw-r--r--core/java/com/android/internal/view/BaseIWindow.java53
-rw-r--r--include/ui/InputReader.h15
-rw-r--r--libs/ui/InputDispatcher.cpp7
-rw-r--r--libs/ui/InputReader.cpp128
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java453
-rw-r--r--services/java/com/android/server/InputDevice.java1025
-rw-r--r--services/java/com/android/server/InputManager.java50
-rw-r--r--services/java/com/android/server/KeyInputQueue.java1388
-rw-r--r--services/java/com/android/server/PowerManagerService.java16
-rw-r--r--services/java/com/android/server/WindowManagerService.java2093
-rw-r--r--services/jni/Android.mk2
-rw-r--r--services/jni/com_android_server_InputManager.cpp164
-rw-r--r--services/jni/com_android_server_KeyInputQueue.cpp358
-rw-r--r--services/jni/com_android_server_PowerManagerService.cpp142
-rw-r--r--services/jni/com_android_server_PowerManagerService.h42
-rw-r--r--services/jni/onload.cpp4
23 files changed, 895 insertions, 6095 deletions
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 @@ public abstract class WallpaperService extends Service {
@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 @@ public abstract class WallpaperService extends Service {
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 abstract class WallpaperService extends Service {
*/
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 @@ public abstract class WallpaperService extends Service {
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 @@ public abstract class WallpaperService extends Service {
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 @@ public abstract class WallpaperService extends Service {
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 abstract class WallpaperService extends Service {
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 @@ oneway interface IWindow {
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 @@ interface IWindowSession {
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 class SurfaceView extends View {
}
}
- 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 @@ public class SurfaceView extends View {
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 @@ public final class ViewRoot extends Handler implements ViewParent,
"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 @@ public final class ViewRoot extends Handler implements ViewParent,
}
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 @@ public final class ViewRoot extends Handler implements ViewParent,
} 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 @@ public final class ViewRoot extends Handler implements ViewParent,
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 @@ public final class ViewRoot extends Handler implements ViewParent,
}
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 @@ public final class ViewRoot extends Handler implements ViewParent,
return false;
}
+ private void deliverPointerEvent(MotionEvent event) {
+ if (mTranslator != null) {
+ mTranslator.translateEventInScreenToAppWindow(event);
+ }
+
+ boolean handled;
+ if (mView != null && mAdded) {
- private void deliverTrackballEvent(MotionEvent event, boolean callWhenDone) {
- if (event == null) {
- event = getPendingTrackballMotionEvent();
- callWhenDone = false;
+ // 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 @@ public final class ViewRoot extends Handler implements ViewParent,
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;
- }
-
- 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);
- }
- }
-
- 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;
- }
- } finally {
- if (callWhenDone) {
- finishMotionEvent();
- recycleMotionEvent(event);
+ 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");
+
+ // 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);
}
- // 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 @@ public final class ViewRoot extends Handler implements ViewParent,
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 @@ public final class ViewRoot extends Handler implements ViewParent,
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 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
- 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 final class ViewRoot extends Handler implements ViewParent,
}
}
- 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 interface WindowManagerPolicy {
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 interface WindowManagerPolicy {
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 @@ public interface WindowManagerPolicy {
*
* @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 @@ public interface WindowManagerPolicy {
* 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 interface WindowManagerPolicy {
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 interface WindowManagerPolicy {
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 class BaseIWindow extends IWindow.Stub {
}
}
- 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 @@ struct InputDevice {
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 @@ struct InputDevice {
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 @@ public:
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 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
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 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
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::TrackballState::reset() {
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 @@ bool InputDevice::TouchScreenState::isPointInsideDisplay(int32_t x, int32_t y) c
&& 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 @@ void InputReader::onTouchScreenChanged(nsecs_t when,
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 @@ void InputReader::dispatchVirtualKey(nsecs_t when,
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 @@ void InputReader::configureVirtualKeys(InputDevice* device) {
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 @@ void InputReader::updateExportedVirtualKeyState() {
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.IWindowManager;
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
: 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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
};
/** {@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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// 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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// 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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// 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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
/** {@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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
-
- /** {@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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
/** {@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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- 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 !!!");
+ } 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;
+ 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 {
+ 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 {
- // 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;
+ gohome = false;
+ sleeps = true;
}
- } 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;
+ 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 (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));
- }
- } 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");
+ }
+ } 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.)
+
+ // 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;
}
- } catch (RemoteException ex) {
- Log.w(TAG, "CALL 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 ((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.
-
- // 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");
+ }
+ } 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;
}
- } catch (RemoteException ex) {
- Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
+ } 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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
};
/** {@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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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 @@ public class InputManager {
private final Callbacks mCallbacks;
private final Context mContext;
private final WindowManagerService mWindowManagerService;
- private final WindowManagerPolicy mWindowManagerPolicy;
private final PowerManager mPowerManager;
private final PowerManagerService mPowerManagerService;
@@ -103,12 +102,10 @@ public class InputManager {
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 @@ public class InputManager {
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 @@ public class InputManager {
@SuppressWarnings("unused")
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
- mWindowManagerPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
+ mWindowManagerService.mInputMonitor.notifyLidSwitchChanged(whenNanos, lidOpen);
}
@SuppressWarnings("unused")
@@ -380,17 +362,17 @@ public class InputManager {
}
@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 @@ public class InputManager {
}
@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 @@ class PowerManagerService extends IPowerManager.Stub
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 @@ class PowerManagerService extends IPowerManager.Stub
}
}
}
+
+ nativeInit();
+ synchronized (mLocks) {
+ updateNativePowerStateLocked();
+ }
}
void initInThread() {
@@ -1557,8 +1565,16 @@ class PowerManagerService extends IPowerManager.Stub
}
}
}
+
+ 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.IInputContext;
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.Slog;
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.InputChannel;
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 @@ import java.util.List;
/** {@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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
// 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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
private ViewServer mViewServer;
- final Rect mTempRect = new Rect();
-
final Configuration mTempConfiguration = new Configuration();
int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED;
@@ -652,28 +617,11 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- 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 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
-
- 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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
"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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- 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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
synchronized (mWindowMap) {
- if (ENABLE_NATIVE_INPUT_DISPATCH) {
- mInputMonitor.setEventDispatchingLw(enabled);
- } else {
- mKeyWaiter.setEventDispatchingLocked(enabled);
- }
+ mInputMonitor.setEventDispatchingLw(enabled);
}
}
@@ -6020,16 +5357,8 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mObscured;
boolean mTurnOnScreen;
- WindowState mNextOutsideTouch;
-
int mLayoutSeq = -1;
Configuration mConfiguration = null;
@@ -8074,16 +6246,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
// 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 @@ public class WindowManagerService extends IWindowManager.Stub
}
// 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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplayFrozen = true;
- if (ENABLE_NATIVE_INPUT_DISPATCH) {
- mInputMonitor.freezeInputDispatchingLw();
- }
+ mInputMonitor.freezeInputDispatchingLw();
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
@@ -11731,16 +9860,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 class WindowManagerService extends IWindowManager.Stub
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 @@ include $(CLEAR_VARS)
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 @@ enum {
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 @@ const nsecs_t MIN_INPUT_DISPATCHING_TIMEOUT = 1000 * 1000000LL; // 1 sec
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 @@ public:
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 @@ private:
int32_t mDisplayWidth, mDisplayHeight;
int32_t mDisplayOrientation;
- // Callbacks.
+ // Power manager interactions.
bool isScreenOn();
bool isScreenBright();
@@ -369,9 +354,9 @@ private:
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 @@ private:
}
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 @@ bool NativeInputManager::isAppSwitchKey(int32_t keyCode) {
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::getDisplayInfo(int32_t displayId,
}
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 @@ int32_t NativeInputManager::interceptKey(nsecs_t when,
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 @@ int32_t NativeInputManager::interceptKey(nsecs_t when,
}
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 @@ int32_t NativeInputManager::interceptKey(nsecs_t when,
actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
if (down && isAppSwitchKey(keyCode)) {
+ JNIEnv* env = jniEnv();
+
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyAppSwitchComing);
checkAndClearExceptionFromCallback(env, "notifyAppSwitchComing");
@@ -1531,11 +1536,13 @@ int32_t NativeInputManager::waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t
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 @@ int32_t NativeInputManager::waitForMotionEventTargets(MotionEvent* motionEvent,
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::waitForMotionEventTargets(MotionEvent* motionEvent,
}
}
-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 @@ int32_t NativeInputManager::identifyTrackballEventTargets(MotionEvent* motionEve
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 @@ bool NativeInputManager::interceptKeyBeforeDispatching(const InputTarget& target
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::pokeUserActivityIfNeeded(int32_t windowType, int32_t ev
}
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 @@ int register_android_server_InputManager(JNIEnv* env) {
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 @@ int register_android_server_InputManager(JNIEnv* env) {
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 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
}
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);