Merge "More native input dispatch work." into gingerbread

This commit is contained in:
Chris Tate
2010-07-07 17:43:12 -07:00
committed by Android (Google) Code Review
23 changed files with 892 additions and 6092 deletions

View File

@ -216,20 +216,7 @@ public abstract class WallpaperService extends Service {
@Override @Override
public void handleTouch(MotionEvent event, Runnable finishedCallback) { public void handleTouch(MotionEvent event, Runnable finishedCallback) {
try { try {
synchronized (mLock) { dispatchPointer(event);
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (mPendingMove != null) {
mCaller.removeMessages(MSG_TOUCH_EVENT, mPendingMove);
mPendingMove.recycle();
}
mPendingMove = event;
} else {
mPendingMove = null;
}
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT,
event);
mCaller.sendMessage(msg);
}
} finally { } finally {
finishedCallback.run(); finishedCallback.run();
} }
@ -237,26 +224,6 @@ public abstract class WallpaperService extends Service {
}; };
final BaseIWindow mWindow = new BaseIWindow() { 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 @Override
public void resized(int w, int h, Rect coveredInsets, public void resized(int w, int h, Rect coveredInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) { Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
@ -466,6 +433,22 @@ public abstract class WallpaperService extends Service {
*/ */
public void onSurfaceDestroyed(SurfaceHolder holder) { 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) { void updateSurface(boolean forceRelayout, boolean forceReport) {
if (mDestroyed) { if (mDestroyed) {
@ -523,10 +506,8 @@ public abstract class WallpaperService extends Service {
mInputChannel); mInputChannel);
mCreated = true; mCreated = true;
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) { InputQueue.registerInputChannel(mInputChannel, mInputHandler,
InputQueue.registerInputChannel(mInputChannel, mInputHandler, Looper.myQueue());
Looper.myQueue());
}
} }
mSurfaceHolder.mSurfaceLock.lock(); mSurfaceHolder.mSurfaceLock.lock();
@ -770,10 +751,8 @@ public abstract class WallpaperService extends Service {
if (DEBUG) Log.v(TAG, "Removing window and destroying surface " if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
+ mSurfaceHolder.getSurface() + " of: " + this); + mSurfaceHolder.getSurface() + " of: " + this);
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) { if (mInputChannel != null) {
if (mInputChannel != null) { InputQueue.unregisterInputChannel(mInputChannel);
InputQueue.unregisterInputChannel(mInputChannel);
}
} }
mSession.remove(mWindow); mSession.remove(mWindow);
@ -782,13 +761,11 @@ public abstract class WallpaperService extends Service {
mSurfaceHolder.mSurface.release(); mSurfaceHolder.mSurface.release();
mCreated = false; mCreated = false;
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) { // Dispose the input channel after removing the window so the Window Manager
// Dispose the input channel after removing the window so the Window Manager // doesn't interpret the input channel being closed as an abnormal termination.
// doesn't interpret the input channel being closed as an abnormal termination. if (mInputChannel != null) {
if (mInputChannel != null) { mInputChannel.dispose();
mInputChannel.dispose(); mInputChannel = null;
mInputChannel = null;
}
} }
} }
} }
@ -841,7 +818,7 @@ public abstract class WallpaperService extends Service {
public void dispatchPointer(MotionEvent event) { public void dispatchPointer(MotionEvent event) {
if (mEngine != null) { if (mEngine != null) {
mEngine.mWindow.onDispatchPointer(event, event.getEventTime(), false); mEngine.dispatchPointer(event);
} }
} }

View File

@ -46,9 +46,6 @@ oneway interface IWindow {
void resized(int w, int h, in Rect coveredInsets, in Rect visibleInsets, void resized(int w, int h, in Rect coveredInsets, in Rect visibleInsets,
boolean reportDraw, in Configuration newConfig); 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 dispatchAppVisibility(boolean visible);
void dispatchGetNewSurface(); void dispatchGetNewSurface();

View File

@ -109,10 +109,6 @@ interface IWindowSession {
void getDisplayFrame(IWindow window, out Rect outDisplayFrame); void getDisplayFrame(IWindow window, out Rect outDisplayFrame);
void finishDrawing(IWindow window); void finishDrawing(IWindow window);
void finishKey(IWindow window);
MotionEvent getPendingPointerMove(IWindow window);
MotionEvent getPendingTrackballMove(IWindow window);
void setInTouchMode(boolean showFocus); void setInTouchMode(boolean showFocus);
boolean getInTouchMode(); boolean getInTouchMode();

View File

@ -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;
}

View File

@ -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) { public void dispatchAppVisibility(boolean visible) {
// The point of SurfaceView is to let the app control the surface. // 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 SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
private static final String LOG_TAG = "SurfaceHolder"; private static final String LOG_TAG = "SurfaceHolder";
private int mSaveCount;
public boolean isCreating() { public boolean isCreating() {
return mIsCreating; return mIsCreating;

View File

@ -556,18 +556,16 @@ public final class ViewRoot extends Handler implements ViewParent,
"Unable to add window -- unknown error code " + res); "Unable to add window -- unknown error code " + res);
} }
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) { if (view instanceof RootViewSurfaceTaker) {
if (view instanceof RootViewSurfaceTaker) { mInputQueueCallback =
mInputQueueCallback = ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
((RootViewSurfaceTaker)view).willYouTakeTheInputQueue(); }
} if (mInputQueueCallback != null) {
if (mInputQueueCallback != null) { mInputQueue = new InputQueue(mInputChannel);
mInputQueue = new InputQueue(mInputChannel); mInputQueueCallback.onInputQueueCreated(mInputQueue);
mInputQueueCallback.onInputQueueCreated(mInputQueue); } else {
} else { InputQueue.registerInputChannel(mInputChannel, mInputHandler,
InputQueue.registerInputChannel(mInputChannel, mInputHandler, Looper.myQueue());
Looper.myQueue());
}
} }
view.assignParent(this); view.assignParent(this);
@ -1745,16 +1743,12 @@ public final class ViewRoot extends Handler implements ViewParent,
} }
mSurface.release(); mSurface.release();
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) { if (mInputChannel != null) {
if (mInputChannel != null) { if (mInputQueueCallback != null) {
if (mInputQueueCallback != null) { mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
mInputQueueCallback.onInputQueueDestroyed(mInputQueue); mInputQueueCallback = null;
mInputQueueCallback = null; } else {
} else { InputQueue.unregisterInputChannel(mInputChannel);
InputQueue.unregisterInputChannel(mInputChannel);
}
mInputChannel.dispose();
mInputChannel = null;
} }
} }
@ -1763,13 +1757,11 @@ public final class ViewRoot extends Handler implements ViewParent,
} catch (RemoteException e) { } catch (RemoteException e) {
} }
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) { // Dispose the input channel after removing the window so the Window Manager
// Dispose the input channel after removing the window so the Window Manager // doesn't interpret the input channel being closed as an abnormal termination.
// doesn't interpret the input channel being closed as an abnormal termination. if (mInputChannel != null) {
if (mInputChannel != null) { mInputChannel.dispose();
mInputChannel.dispose(); mInputChannel = null;
mInputChannel = null;
}
} }
} }
@ -1869,105 +1861,22 @@ public final class ViewRoot extends Handler implements ViewParent,
deliverKeyEvent((KeyEvent)msg.obj, true); deliverKeyEvent((KeyEvent)msg.obj, true);
break; break;
case DISPATCH_POINTER: { case DISPATCH_POINTER: {
MotionEvent event = (MotionEvent)msg.obj; 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);
}
try { try {
boolean handled; deliverPointerEvent(event);
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);
}
}
}
}
} finally { } finally {
if (callWhenDone) { event.recycle();
finishMotionEvent();
}
recycleMotionEvent(event);
if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!"); 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; } break;
case DISPATCH_TRACKBALL: case DISPATCH_TRACKBALL: {
deliverTrackballEvent((MotionEvent)msg.obj, msg.arg1 != 0); MotionEvent event = (MotionEvent) msg.obj;
break; try {
deliverTrackballEvent(event);
} finally {
event.recycle();
}
} break;
case DISPATCH_APP_VISIBILITY: case DISPATCH_APP_VISIBILITY:
handleAppVisibility(msg.arg1 != 0); handleAppVisibility(msg.arg1 != 0);
break; break;
@ -2101,61 +2010,12 @@ public final class ViewRoot extends Handler implements ViewParent,
} }
private void finishKeyEvent(KeyEvent event) { private void finishKeyEvent(KeyEvent event) {
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) { if (mFinishedCallback != null) {
if (mFinishedCallback != null) { mFinishedCallback.run();
mFinishedCallback.run(); mFinishedCallback = null;
mFinishedCallback = null;
}
} else {
try {
sWindowSession.finishKey(mWindow);
} catch (RemoteException e) {
}
} }
} }
private void finishMotionEvent() {
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
throw new IllegalStateException("Should not be reachable with native input dispatch.");
}
try {
sWindowSession.finishKey(mWindow);
} catch (RemoteException e) {
}
}
private void recycleMotionEvent(MotionEvent event) {
if (event != null) {
event.recycle();
}
}
private MotionEvent getPendingPointerMotionEvent() {
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
throw new IllegalStateException("Should not be reachable with native input dispatch.");
}
try {
return sWindowSession.getPendingPointerMove(mWindow);
} catch (RemoteException e) {
return null;
}
}
private MotionEvent getPendingTrackballMotionEvent() {
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
throw new IllegalStateException("Should not be reachable with native input dispatch.");
}
try {
return sWindowSession.getPendingTrackballMove(mWindow);
} catch (RemoteException e) {
return null;
}
}
/** /**
* Something in the current window tells us we need to change the touch mode. For * 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. * 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; return false;
} }
private void deliverPointerEvent(MotionEvent event) {
private void deliverTrackballEvent(MotionEvent event, boolean callWhenDone) { if (mTranslator != null) {
if (event == null) { mTranslator.translateEventInScreenToAppWindow(event);
event = getPendingTrackballMotionEvent();
callWhenDone = false;
} }
boolean handled;
if (mView != null && mAdded) {
// enter touch mode on the down
boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN;
if (isDown) {
ensureTouchMode(true);
}
if(Config.LOGV) {
captureMotionLog("captureDispatchPointer", event);
}
if (mCurScrollY != 0) {
event.offsetLocation(0, mCurScrollY);
}
if (MEASURE_LATENCY) {
lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());
}
handled = mView.dispatchTouchEvent(event);
if (MEASURE_LATENCY) {
lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());
}
if (!handled && isDown) {
int edgeSlop = mViewConfiguration.getScaledEdgeSlop();
final int edgeFlags = event.getEdgeFlags();
int direction = View.FOCUS_UP;
int x = (int)event.getX();
int y = (int)event.getY();
final int[] deltas = new int[2];
if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) {
direction = View.FOCUS_DOWN;
if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
deltas[0] = edgeSlop;
x += edgeSlop;
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
deltas[0] = -edgeSlop;
x -= edgeSlop;
}
} else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) {
direction = View.FOCUS_UP;
if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
deltas[0] = edgeSlop;
x += edgeSlop;
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
deltas[0] = -edgeSlop;
x -= edgeSlop;
}
} else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
direction = View.FOCUS_RIGHT;
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
direction = View.FOCUS_LEFT;
}
if (edgeFlags != 0 && mView instanceof ViewGroup) {
View nearest = FocusFinder.getInstance().findNearestTouchable(
((ViewGroup) mView), x, y, direction, deltas);
if (nearest != null) {
event.offsetLocation(deltas[0], deltas[1]);
event.setEdgeFlags(0);
mView.dispatchTouchEvent(event);
}
}
}
}
}
private void deliverTrackballEvent(MotionEvent event) {
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event); if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
boolean handled = false; boolean handled = false;
try { if (mView != null && mAdded) {
if (event == null) { handled = mView.dispatchTrackballEvent(event);
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 (handled) { if (handled) {
if (callWhenDone) {
finishMotionEvent();
}
recycleMotionEvent(event);
// If we reach this, we delivered a trackball event to mView and // If we reach this, we delivered a trackball event to mView and
// mView consumed it. Because we will not translate the trackball // mView consumed it. Because we will not translate the trackball
// event into a key event, touch mode will not exit, so we exit // event into a key event, touch mode will not exit, so we exit
// touch mode here. // touch mode here.
ensureTouchMode(false); ensureTouchMode(false);
//noinspection ReturnInsideFinallyBlock
return; 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; final TrackballAxis x = mTrackballAxisX;
@ -2327,95 +2240,86 @@ public final class ViewRoot extends Handler implements ViewParent,
mLastTrackballTime = curTime; mLastTrackballTime = curTime;
} }
try { final int action = event.getAction();
final int action = event.getAction(); final int metastate = event.getMetaState();
final int metastate = event.getMetaState(); switch (action) {
switch (action) { case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_DOWN: x.reset(2);
x.reset(2); y.reset(2);
y.reset(2); deliverKeyEvent(new KeyEvent(curTime, curTime,
deliverKeyEvent(new KeyEvent(curTime, curTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER,
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0, metastate), false);
0, metastate), false); break;
break; case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_UP: x.reset(2);
x.reset(2); y.reset(2);
y.reset(2); deliverKeyEvent(new KeyEvent(curTime, curTime,
deliverKeyEvent(new KeyEvent(curTime, curTime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER,
KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0, metastate), false);
0, metastate), false); break;
break; }
}
if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step=" if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step="
+ x.step + " dir=" + x.dir + " acc=" + x.acceleration + x.step + " dir=" + x.dir + " acc=" + x.acceleration
+ " move=" + event.getX() + " move=" + event.getX()
+ " / Y=" + y.position + " step=" + " / Y=" + y.position + " step="
+ y.step + " dir=" + y.dir + " acc=" + y.acceleration + y.step + " dir=" + y.dir + " acc=" + y.acceleration
+ " move=" + event.getY()); + " move=" + event.getY());
final float xOff = x.collect(event.getX(), event.getEventTime(), "X"); final float xOff = x.collect(event.getX(), event.getEventTime(), "X");
final float yOff = y.collect(event.getY(), event.getEventTime(), "Y"); final float yOff = y.collect(event.getY(), event.getEventTime(), "Y");
// Generate DPAD events based on the trackball movement. // Generate DPAD events based on the trackball movement.
// We pick the axis that has moved the most as the direction of // 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 // 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 // other axis is reset -- we don't want to perform DPAD jumps due
// to slight movements in the trackball when making major movements // to slight movements in the trackball when making major movements
// along the other axis. // along the other axis.
int keycode = 0; int keycode = 0;
int movement = 0; int movement = 0;
float accel = 1; float accel = 1;
if (xOff > yOff) { if (xOff > yOff) {
movement = x.generate((2/event.getXPrecision())); movement = x.generate((2/event.getXPrecision()));
if (movement != 0) { if (movement != 0) {
keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT
: KeyEvent.KEYCODE_DPAD_LEFT; : KeyEvent.KEYCODE_DPAD_LEFT;
accel = x.acceleration; accel = x.acceleration;
y.reset(2); 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);
}
} }
} 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 (keycode != 0) {
if (movement < 0) movement = -movement; if (movement < 0) movement = -movement;
int accelMovement = (int)(movement * accel); int accelMovement = (int)(movement * accel);
if (DEBUG_TRACKBALL) Log.v(TAG, "Move: movement=" + movement if (DEBUG_TRACKBALL) Log.v(TAG, "Move: movement=" + movement
+ " accelMovement=" + accelMovement + " accelMovement=" + accelMovement
+ " accel=" + accel); + " accel=" + accel);
if (accelMovement > movement) { if (accelMovement > movement) {
if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: " if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
+ keycode); + keycode);
movement--; movement--;
deliverKeyEvent(new KeyEvent(curTime, curTime, deliverKeyEvent(new KeyEvent(curTime, curTime,
KeyEvent.ACTION_MULTIPLE, keycode, KeyEvent.ACTION_MULTIPLE, keycode,
accelMovement-movement, metastate), false); 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 { while (movement > 0) {
if (callWhenDone) { if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
finishMotionEvent(); + keycode);
recycleMotionEvent(event); 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 mLastTrackballTime = curTime;
// it and take care of the bad app for us.
} }
} }
@ -2862,45 +2766,20 @@ public final class ViewRoot extends Handler implements ViewParent,
private final InputHandler mInputHandler = new InputHandler() { private final InputHandler mInputHandler = new InputHandler() {
public void handleKey(KeyEvent event, Runnable finishedCallback) { public void handleKey(KeyEvent event, Runnable finishedCallback) {
mFinishedCallback = 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", dispatchKey(event);
"===================================================");
}
}
Message msg = obtainMessage(DISPATCH_KEY);
msg.obj = event;
if (LOCAL_LOGV) Log.v(
"ViewRoot", "sending key " + event + " to " + mView);
sendMessageAtTime(msg, event.getEventTime());
} }
public void handleTouch(MotionEvent event, Runnable finishedCallback) { public void handleTouch(MotionEvent event, Runnable finishedCallback) {
finishedCallback.run(); finishedCallback.run();
Message msg = obtainMessage(DISPATCH_POINTER); dispatchPointer(event);
msg.obj = event;
msg.arg1 = 0;
sendMessageAtTime(msg, event.getEventTime());
} }
public void handleTrackball(MotionEvent event, Runnable finishedCallback) { public void handleTrackball(MotionEvent event, Runnable finishedCallback) {
finishedCallback.run(); finishedCallback.run();
Message msg = obtainMessage(DISPATCH_TRACKBALL); dispatchTrackball(event);
msg.obj = event;
msg.arg1 = 0;
sendMessageAtTime(msg, event.getEventTime());
} }
}; };
@ -2927,22 +2806,18 @@ public final class ViewRoot extends Handler implements ViewParent,
sendMessageAtTime(msg, event.getEventTime()); sendMessageAtTime(msg, event.getEventTime());
} }
public void dispatchPointer(MotionEvent event, long eventTime, public void dispatchPointer(MotionEvent event) {
boolean callWhenDone) {
Message msg = obtainMessage(DISPATCH_POINTER); Message msg = obtainMessage(DISPATCH_POINTER);
msg.obj = event; msg.obj = event;
msg.arg1 = callWhenDone ? 1 : 0; sendMessageAtTime(msg, event.getEventTime());
sendMessageAtTime(msg, eventTime);
} }
public void dispatchTrackball(MotionEvent event, long eventTime, public void dispatchTrackball(MotionEvent event) {
boolean callWhenDone) {
Message msg = obtainMessage(DISPATCH_TRACKBALL); Message msg = obtainMessage(DISPATCH_TRACKBALL);
msg.obj = event; msg.obj = event;
msg.arg1 = callWhenDone ? 1 : 0; sendMessageAtTime(msg, event.getEventTime());
sendMessageAtTime(msg, eventTime);
} }
public void dispatchAppVisibility(boolean visible) { public void dispatchAppVisibility(boolean visible) {
Message msg = obtainMessage(DISPATCH_APP_VISIBILITY); Message msg = obtainMessage(DISPATCH_APP_VISIBILITY);
msg.arg1 = visible ? 1 : 0; 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 { static class W extends IWindow.Stub {
private final WeakReference<ViewRoot> mViewRoot; private final WeakReference<ViewRoot> mViewRoot;
private final Looper mMainLooper;
public W(ViewRoot viewRoot, Context context) { public W(ViewRoot viewRoot, Context context) {
mViewRoot = new WeakReference<ViewRoot>(viewRoot); mViewRoot = new WeakReference<ViewRoot>(viewRoot);
mMainLooper = context.getMainLooper();
} }
public void resized(int w, int h, Rect coveredInsets, 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) { public void dispatchAppVisibility(boolean visible) {
final ViewRoot viewRoot = mViewRoot.get(); final ViewRoot viewRoot = mViewRoot.get();
if (viewRoot != null) { if (viewRoot != null) {

View File

@ -78,12 +78,6 @@ public interface WindowManagerPolicy {
public final static int FLAG_BRIGHT_HERE = 0x20000000; public final static int FLAG_BRIGHT_HERE = 0x20000000;
public final static boolean WATCH_POINTER = false; 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 // flags for interceptKeyTq
/** /**
@ -555,23 +549,26 @@ public interface WindowManagerPolicy {
public Animation createForceHideEnterAnimation(); public Animation createForceHideEnterAnimation();
/** /**
* Called from the key queue thread before a key is dispatched to the * Called from the input reader thread before a key is enqueued.
* input thread.
* *
* <p>There are some actions that need to be handled here because they * <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. * 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 * Generally, it's best to keep as little as possible in the queue thread
* because it's the most fragile. * 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}, * @return The bitwise or of the {@link #ACTION_PASS_TO_USER},
* {@link #ACTION_POKE_USER_ACTIVITY} and {@link #ACTION_GO_TO_SLEEP} flags. * {@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 * <p>Allows you to define
* behavior for keys that can not be overridden by applications or redirect * 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 * @param win The window that currently has focus. This is where the key
* event will normally go. * event will normally go.
* @param code Key code. * @param action The key event action.
* @param metaKeys bit mask of meta keys that are held. * @param flags The key event flags.
* @param down Is this a key press (true) or release (false)? * @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 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 * @return Returns true if the policy consumed the event and it should
* not be further dispatched. * not be further dispatched.
*/ */
public boolean interceptKeyTi(WindowState win, int code, public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
int metaKeys, boolean down, int repeatCount, int flags); int keyCode, int metaState, int repeatCount, int policyFlags);
/** /**
* Called when layout of the windows is about to start. * Called when layout of the windows is about to start.
@ -701,84 +699,14 @@ public interface WindowManagerPolicy {
* Return whether the screen is currently on. * Return whether the screen is currently on.
*/ */
public boolean isScreenOn(); public boolean isScreenOn();
/** /**
* Perform any initial processing of a low-level input event before the * Tell the policy that the lid switch has changed state.
* window manager handles special keys and generates a high-level event * @param whenNanos The time when the change occurred in uptime nanoseconds.
* that is dispatched to the application. * @param lidOpen True if the lid is now open.
*
* @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.
*/ */
public boolean preprocessInputEventTq(RawInputEvent event);
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen); 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. * Tell the policy if anyone is requesting that keyguard not come on.
* *
@ -851,18 +779,6 @@ public interface WindowManagerPolicy {
*/ */
public void enableScreenAfterBoot(); 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. * Called every time the window manager is dispatching a pointer event.
*/ */
@ -875,13 +791,6 @@ public interface WindowManagerPolicy {
*/ */
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always); 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 * Called when we have stopped keeping the screen on because a window
* requesting this is no longer visible. * requesting this is no longer visible.

View File

@ -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) { public void dispatchAppVisibility(boolean visible) {
} }

View File

@ -250,7 +250,13 @@ struct InputDevice {
nsecs_t downTime; nsecs_t downTime;
struct CurrentVirtualKeyState { struct CurrentVirtualKeyState {
bool down; enum Status {
STATUS_UP,
STATUS_DOWN,
STATUS_CANCELED
};
Status status;
nsecs_t downTime; nsecs_t downTime;
int32_t keyCode; int32_t keyCode;
int32_t scanCode; int32_t scanCode;
@ -295,6 +301,7 @@ struct InputDevice {
void calculatePointerIds(); void calculatePointerIds();
bool isPointInsideDisplay(int32_t x, int32_t y) const; bool isPointInsideDisplay(int32_t x, int32_t y) const;
const InputDevice::VirtualKey* findVirtualKeyHit() const;
}; };
InputDevice(int32_t id, uint32_t classes, String8 name); InputDevice(int32_t id, uint32_t classes, String8 name);
@ -390,11 +397,9 @@ public:
virtual bool getDisplayInfo(int32_t displayId, virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation) = 0; 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, virtual void virtualKeyDownFeedback() = 0;
int32_t action, int32_t flags, int32_t keyCode,
int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
/* Intercepts a key event. /* Intercepts a key event.
* The policy can use this method as an opportunity to perform power management functions * The policy can use this method as an opportunity to perform power management functions

View File

@ -299,14 +299,13 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK; uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
if (entry->refCount == 1) { if (entry->refCount == 1) {
entry->eventTime = currentTime; entry->eventTime = currentTime;
entry->downTime = currentTime;
entry->policyFlags = policyFlags; entry->policyFlags = policyFlags;
entry->repeatCount += 1; entry->repeatCount += 1;
} else { } else {
KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime, KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
entry->deviceId, entry->nature, policyFlags, entry->deviceId, entry->nature, policyFlags,
entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->action, entry->flags, entry->keyCode, entry->scanCode,
entry->metaState, entry->repeatCount + 1, currentTime); entry->metaState, entry->repeatCount + 1, entry->downTime);
mKeyRepeatState.lastKeyEntry = newEntry; mKeyRepeatState.lastKeyEntry = newEntry;
mAllocator.releaseKeyEntry(entry); mAllocator.releaseKeyEntry(entry);
@ -314,6 +313,10 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
entry = newEntry; entry = newEntry;
} }
if (entry->repeatCount == 1) {
entry->flags |= KEY_EVENT_FLAG_LONG_PRESS;
}
mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout; mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout;
#if DEBUG_OUTBOUND_EVENT_DETAILS #if DEBUG_OUTBOUND_EVENT_DETAILS

View File

@ -189,7 +189,7 @@ void InputDevice::TrackballState::reset() {
void InputDevice::TouchScreenState::reset() { void InputDevice::TouchScreenState::reset() {
lastTouch.clear(); lastTouch.clear();
downTime = 0; downTime = 0;
currentVirtualKey.down = false; currentVirtualKey.status = CurrentVirtualKeyState::STATUS_UP;
for (uint32_t i = 0; i < MAX_POINTERS; i++) { for (uint32_t i = 0; i < MAX_POINTERS; i++) {
averagingTouchFilter.historyStart[i] = 0; averagingTouchFilter.historyStart[i] = 0;
@ -746,6 +746,29 @@ bool InputDevice::TouchScreenState::isPointInsideDisplay(int32_t x, int32_t y) c
&& y <= parameters.yAxis.maxValue; && 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 --- // --- InputDevice::SingleTouchScreenState ---
@ -1269,81 +1292,76 @@ void InputReader::onTouchScreenChanged(nsecs_t when,
bool InputReader::consumeVirtualKeyTouches(nsecs_t when, bool InputReader::consumeVirtualKeyTouches(nsecs_t when,
InputDevice* device, uint32_t policyFlags) { 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) { if (device->touchScreen.currentTouch.pointerCount == 0) {
// Pointer went up while virtual key was down. Send key up event. // Pointer went up after virtual key canceled.
device->touchScreen.currentVirtualKey.down = false; 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 #if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d", LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode, device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode); device->touchScreen.currentVirtualKey.scanCode);
#endif #endif
dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP, dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY); KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
return true; // consumed return true; // consumed
} }
int32_t x = device->touchScreen.currentTouch.pointers[0].x; if (device->touchScreen.currentTouch.pointerCount == 1) {
int32_t y = device->touchScreen.currentTouch.pointers[0].y; const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
if (device->touchScreen.isPointInsideDisplay(x, y) if (virtualKey
|| device->touchScreen.currentTouch.pointerCount != 1) { && virtualKey->keyCode == device->touchScreen.currentVirtualKey.keyCode) {
// Pointer moved inside the display area or another pointer also went down. // Pointer is still within the space of the virtual key.
// Send key cancellation. return true; // consumed
device->touchScreen.currentVirtualKey.down = false; }
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode);
#endif
dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY
| KEY_EVENT_FLAG_CANCELED);
// Clear the last touch data so we will consider the pointer as having just been
// pressed down when generating subsequent motion events.
device->touchScreen.lastTouch.clear();
return false; // not consumed
} }
} else if (device->touchScreen.currentTouch.pointerCount == 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 #if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, " LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
"left=%d, top=%d, right=%d, bottom=%d", device->touchScreen.currentVirtualKey.keyCode,
x, y, device->touchScreen.currentVirtualKey.scanCode);
virtualKey.keyCode, virtualKey.scanCode,
virtualKey.hitLeft, virtualKey.hitTop,
virtualKey.hitRight, virtualKey.hitBottom);
#endif #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)) { default:
device->touchScreen.currentVirtualKey.down = true; 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.downTime = when;
device->touchScreen.currentVirtualKey.keyCode = virtualKey.keyCode; device->touchScreen.currentVirtualKey.keyCode = virtualKey->keyCode;
device->touchScreen.currentVirtualKey.scanCode = virtualKey.scanCode; device->touchScreen.currentVirtualKey.scanCode = virtualKey->scanCode;
#if DEBUG_VIRTUAL_KEYS #if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d", LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode, device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode); device->touchScreen.currentVirtualKey.scanCode);
#endif #endif
dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_DOWN, dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_DOWN,
KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY); KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
return true; // consumed return true; // consumed
} }
} }
return false; // not consumed
} }
return false; // not consumed
} }
void InputReader::dispatchVirtualKey(nsecs_t when, void InputReader::dispatchVirtualKey(nsecs_t when,
@ -1356,8 +1374,9 @@ void InputReader::dispatchVirtualKey(nsecs_t when,
nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime; nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime;
int32_t metaState = globalMetaState(); int32_t metaState = globalMetaState();
mPolicy->virtualKeyFeedback(when, device->id, keyEventAction, keyEventFlags, if (keyEventAction == KEY_EVENT_ACTION_DOWN) {
keyCode, scanCode, metaState, downTime); mPolicy->virtualKeyDownFeedback();
}
int32_t policyActions = mPolicy->interceptKey(when, device->id, int32_t policyActions = mPolicy->interceptKey(when, device->id,
keyEventAction == KEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags); keyEventAction == KEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
@ -1852,7 +1871,7 @@ void InputReader::configureVirtualKeys(InputDevice* device) {
uint32_t flags; uint32_t flags;
if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode, if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode,
& keyCode, & flags)) { & 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 device->touchScreen.virtualKeys.pop(); // drop the key
continue; continue;
} }
@ -1933,7 +1952,8 @@ void InputReader::updateExportedVirtualKeyState() {
for (size_t i = 0; i < mDevices.size(); i++) { for (size_t i = 0; i < mDevices.size(); i++) {
InputDevice* device = mDevices.valueAt(i); InputDevice* device = mDevices.valueAt(i);
if (device->isTouchScreen()) { if (device->isTouchScreen()) {
if (device->touchScreen.currentVirtualKey.down) { if (device->touchScreen.currentVirtualKey.status
== InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN) {
keyCode = device->touchScreen.currentVirtualKey.keyCode; keyCode = device->touchScreen.currentVirtualKey.keyCode;
scanCode = device->touchScreen.currentVirtualKey.scanCode; scanCode = device->touchScreen.currentVirtualKey.scanCode;
} }

View File

@ -60,7 +60,6 @@ import android.view.IWindowManager;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.WindowOrientationListener; import android.view.WindowOrientationListener;
import android.view.RawInputEvent;
import android.view.Surface; import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration; 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_MEDIA_OVERLAY_SUBLAYER = -1;
static final int APPLICATION_PANEL_SUBLAYER = 1; static final int APPLICATION_PANEL_SUBLAYER = 1;
static final int APPLICATION_SUB_PANEL_SUBLAYER = 2; 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. // Debugging: set this to have the system act like there is no hard keyboard.
static final boolean KEYBOARD_ALWAYS_HIDDEN = false; 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_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; 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(); final Object mLock = new Object();
Context mContext; Context mContext;
@ -690,7 +691,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
void readLidState() { void readLidState() {
try { try {
int sw = mWindowManager.getSwitchState(RawInputEvent.SW_LID); int sw = mWindowManager.getSwitchState(SW_LID);
if (sw >= 0) { if (sw >= 0) {
mLidOpen = sw == 0; mLidOpen = sw == 0;
} }
@ -727,19 +728,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
: Configuration.KEYBOARDHIDDEN_YES; : 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) { public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY) {
if (mPointerLocationView == null) { if (mPointerLocationView == null) {
return; return;
@ -1034,19 +1022,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}; };
/** {@inheritDoc} */ /** {@inheritDoc} */
public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, @Override
int repeatCount, int flags) { public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
boolean keyguardOn = keyguardOn(); 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) { 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); + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
} }
// Clear a pending HOME longpress if the user releases Home // Clear a pending HOME longpress if the user releases Home
// TODO: This could probably be inside the next bit of logic, but that code // 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. // 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); 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 // If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home! // while it was pressed, then it is time to go home!
if (code == KeyEvent.KEYCODE_HOME) { if (keyCode == KeyEvent.KEYCODE_HOME) {
if (!down) { if (!down) {
mHomePressed = false; mHomePressed = false;
if ((flags&KeyEvent.FLAG_CANCELED) == 0) { if (! canceled) {
// If an incoming call is ringing, HOME is totally disabled. // If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallScreen at this point, // (The user is already on the InCallScreen at this point,
// and his ONLY options are to answer or reject the call.) // 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 // can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second // it handle it, because that gives us the correct 5 second
// timeout. // timeout.
if (code == KeyEvent.KEYCODE_HOME) { if (keyCode == KeyEvent.KEYCODE_HOME) {
// If a system window has focus, then it doesn't make sense // If a system window has focus, then it doesn't make sense
// right now to interact with applications. // right now to interact with applications.
@ -1122,17 +1113,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHomePressed = true; mHomePressed = true;
} }
return true; return true;
} else if (code == KeyEvent.KEYCODE_MENU) { } else if (keyCode == KeyEvent.KEYCODE_MENU) {
// Hijack modified menu keys for debugging features // Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON; final int chordBug = KeyEvent.META_SHIFT_ON;
if (down && repeatCount == 0) { if (down && repeatCount == 0) {
if (mEnableShiftMenuBugReports && (metaKeys & chordBug) == chordBug) { if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
Intent intent = new Intent(Intent.ACTION_BUG_REPORT); Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
mContext.sendOrderedBroadcast(intent, null); mContext.sendOrderedBroadcast(intent, null);
return true; return true;
} else if (SHOW_PROCESSES_ON_ALT_MENU && } 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(); Intent service = new Intent();
service.setClassName(mContext, "com.android.server.LoadAverageService"); service.setClassName(mContext, "com.android.server.LoadAverageService");
ContentResolver res = mContext.getContentResolver(); ContentResolver res = mContext.getContentResolver();
@ -1148,7 +1139,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return true; return true;
} }
} }
} else if (code == KeyEvent.KEYCODE_SEARCH) { } else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
if (down) { if (down) {
if (repeatCount == 0) { if (repeatCount == 0) {
mSearchKeyPressed = true; mSearchKeyPressed = true;
@ -1167,7 +1158,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Shortcuts are invoked through Search+key, so intercept those here // Shortcuts are invoked through Search+key, so intercept those here
if (mSearchKeyPressed) { if (mSearchKeyPressed) {
if (down && repeatCount == 0 && !keyguardOn) { if (down && repeatCount == 0 && !keyguardOn) {
Intent shortcutIntent = mShortcutManager.getIntent(code, metaKeys); Intent shortcutIntent = mShortcutManager.getIntent(keyCode, metaState);
if (shortcutIntent != null) { if (shortcutIntent != null) {
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(shortcutIntent); mContext.startActivity(shortcutIntent);
@ -1606,42 +1597,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} }
/** {@inheritDoc} */ /** {@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) { public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
// lid changed state // lid changed state
mLidOpen = lidOpen; 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. * @return Whether a telephone call is in progress right now.
*/ */
@ -1762,60 +1697,63 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} }
/** {@inheritDoc} */ /** {@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; 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 // 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. // the same as if it were open and in front.
// This will prevent any keys other than the power button from waking the screen // This will prevent any keys other than the power button from waking the screen
// when the keyguard is hidden by another activity. // when the keyguard is hidden by another activity.
final boolean keyguardActive = (screenIsOn ? final boolean keyguardActive = (isScreenOn ?
mKeyguardMediator.isShowingAndNotHidden() : mKeyguardMediator.isShowingAndNotHidden() :
mKeyguardMediator.isShowing()); mKeyguardMediator.isShowing());
if (false) { if (false) {
Log.d(TAG, "interceptKeyTq event=" + event + " keycode=" + event.keycode Log.d(TAG, "interceptKeyTq keycode=" + keyCode
+ " screenIsOn=" + screenIsOn + " keyguardActive=" + keyguardActive); + " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
} }
if (keyguardActive) { if (keyguardActive) {
if (screenIsOn) { if (isScreenOn) {
// when the screen is on, always give the event to the keyguard // when the screen is on, always give the event to the keyguard
result |= ACTION_PASS_TO_USER; result |= ACTION_PASS_TO_USER;
} else { } else {
// otherwise, don't pass it to the user // otherwise, don't pass it to the user
result &= ~ACTION_PASS_TO_USER; result &= ~ACTION_PASS_TO_USER;
final boolean isKeyDown = if (isWakeKey && down) {
(event.type == RawInputEvent.EV_KEY) && (event.value != 0);
if (isWakeKey && isKeyDown) {
// tell the mediator about a wake key, it may decide to // tell the mediator about a wake key, it may decide to
// turn on the screen depending on whether the key is // turn on the screen depending on whether the key is
// appropriate. // appropriate.
if (!mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(event.keycode) if (!mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode)
&& (event.keycode == KeyEvent.KEYCODE_VOLUME_DOWN && (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| event.keycode == KeyEvent.KEYCODE_VOLUME_UP)) { || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
// when keyguard is showing and screen off, we need // when keyguard is showing and screen off, we need
// to handle the volume key for calls and music here // to handle the volume key for calls and music here
if (isInCall()) { if (isInCall()) {
handleVolumeKey(AudioManager.STREAM_VOICE_CALL, event.keycode); handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
} else if (isMusicActive()) { } 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, // If we are in-call with screen off and keyguard is not showing,
// then handle the volume key ourselves. // then handle the volume key ourselves.
// This is necessary because the phone app will disable the keyguard // This is necessary because the phone app will disable the keyguard
// when the proximity sensor is in use. // when the proximity sensor is in use.
if (isInCall() && event.type == RawInputEvent.EV_KEY && if (isInCall() &&
(event.keycode == KeyEvent.KEYCODE_VOLUME_DOWN (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| event.keycode == KeyEvent.KEYCODE_VOLUME_UP)) { || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
result &= ~ACTION_PASS_TO_USER; result &= ~ACTION_PASS_TO_USER;
handleVolumeKey(AudioManager.STREAM_VOICE_CALL, event.keycode); handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
} }
if (isWakeKey) { if (isWakeKey) {
// a wake key has a sole purpose of waking the device; don't pass // 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; if (keyCode == KeyEvent.KEYCODE_ENDCALL
int code = event.keycode; || keyCode == KeyEvent.KEYCODE_POWER) {
boolean down = event.value != 0; if (down) {
boolean handled = false;
if (type == RawInputEvent.EV_KEY) { boolean hungUp = false;
if (code == KeyEvent.KEYCODE_ENDCALL // key repeats are generated by the window manager, and we don't see them
|| code == KeyEvent.KEYCODE_POWER) { // here, so unless the driver is doing something it shouldn't be, we know
if (down) { // this is the real press event.
boolean handled = false; ITelephony phoneServ = getPhoneInterface();
boolean hungUp = false; if (phoneServ != null) {
// key repeats are generated by the window manager, and we don't see them try {
// here, so unless the driver is doing something it shouldn't be, we know if (keyCode == KeyEvent.KEYCODE_ENDCALL) {
// this is the real press event. handled = hungUp = phoneServ.endCall();
ITelephony phoneServ = getPhoneInterface(); } else if (keyCode == KeyEvent.KEYCODE_POWER) {
if (phoneServ != null) { if (phoneServ.isRinging()) {
try { // Pressing Power while there's a ringing incoming
if (code == KeyEvent.KEYCODE_ENDCALL) { // 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(); 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 { } catch (RemoteException ex) {
Log.w(TAG, "!!! Unable to find ITelephony interface !!!"); Log.w(TAG, "ITelephony threw RemoteException" + ex);
}
if (!screenIsOn
|| (handled && code != KeyEvent.KEYCODE_POWER)
|| (handled && hungUp && code == KeyEvent.KEYCODE_POWER)) {
mShouldTurnOffOnKeyUp = false;
} else {
// only try to turn off the screen if we didn't already hang up
mShouldTurnOffOnKeyUp = true;
mHandler.postDelayed(mPowerLongPress,
ViewConfiguration.getGlobalActionKeyTimeout());
result &= ~ACTION_PASS_TO_USER;
} }
} else { } else {
mHandler.removeCallbacks(mPowerLongPress); Log.w(TAG, "!!! Unable to find ITelephony interface !!!");
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;
}
} }
} else if (isMediaKey(code)) {
// This key needs to be handled even if the screen is off. if (!isScreenOn
// If others need to be handled while it's off, this is a reasonable || (handled && keyCode != KeyEvent.KEYCODE_POWER)
// pattern to follow. || (handled && hungUp && keyCode == KeyEvent.KEYCODE_POWER)) {
if ((result & ACTION_PASS_TO_USER) == 0) { mShouldTurnOffOnKeyUp = false;
// Only do this if we would otherwise not pass it to the user. In that } else {
// case, the PhoneWindow class will do the same thing, except it will // only try to turn off the screen if we didn't already hang up
// only do it if the showing app doesn't process the key on its own. mShouldTurnOffOnKeyUp = true;
KeyEvent keyEvent = new KeyEvent(event.when, event.when, mHandler.postDelayed(mPowerLongPress,
down ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP, ViewConfiguration.getGlobalActionKeyTimeout());
code, 0); result &= ~ACTION_PASS_TO_USER;
mBroadcastWakeLock.acquire();
mHandler.post(new PassHeadsetKey(keyEvent));
} }
} else if (code == KeyEvent.KEYCODE_CALL) { } else {
// If an incoming call is ringing, answer it! mHandler.removeCallbacks(mPowerLongPress);
// (We handle this key here, rather than in the InCallScreen, to make if (mShouldTurnOffOnKeyUp) {
// sure we'll respond to the key even if the InCallScreen hasn't come to mShouldTurnOffOnKeyUp = false;
// the foreground yet.) boolean gohome, sleeps;
if (keyCode == KeyEvent.KEYCODE_ENDCALL) {
// We answer the call on the DOWN event, to agree with gohome = (mEndcallBehavior
// the "fallback" behavior in the InCallScreen. & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0;
if (down) { sleeps = (mEndcallBehavior
try { & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0;
ITelephony phoneServ = getPhoneInterface(); } else {
if (phoneServ != null) { gohome = false;
if (phoneServ.isRinging()) { sleeps = true;
Log.i(TAG, "interceptKeyTq:"
+ " CALL key-down while ringing: Answer the call!");
phoneServ.answerRingingCall();
// And *don't* pass this key thru to the current activity
// (which is presumably the InCallScreen.)
result &= ~ACTION_PASS_TO_USER;
}
} else {
Log.w(TAG, "CALL button: Unable to find ITelephony interface");
}
} catch (RemoteException ex) {
Log.w(TAG, "CALL button: RemoteException from getPhoneInterface()", ex);
} }
if (keyguardActive
|| (sleeps && !gohome)
|| (gohome && !goHome() && sleeps)) {
// they must already be on the keyguad or home screen,
// go to sleep instead
Log.d(TAG, "I'm tired mEndcallBehavior=0x"
+ Integer.toHexString(mEndcallBehavior));
result &= ~ACTION_POKE_USER_ACTIVITY;
result |= ACTION_GO_TO_SLEEP;
}
result &= ~ACTION_PASS_TO_USER;
} }
} else if ((code == KeyEvent.KEYCODE_VOLUME_UP) }
|| (code == KeyEvent.KEYCODE_VOLUME_DOWN)) { } else if (isMediaKey(keyCode)) {
// If an incoming call is ringing, either VOLUME key means // This key needs to be handled even if the screen is off.
// "silence ringer". We handle these keys here, rather than // If others need to be handled while it's off, this is a reasonable
// in the InCallScreen, to make sure we'll respond to them // pattern to follow.
// even if the InCallScreen hasn't come to the foreground yet. if ((result & ACTION_PASS_TO_USER) == 0) {
// Only do this if we would otherwise not pass it to the user. In that
// case, the PhoneWindow class will do the same thing, except it will
// only do it if the showing app doesn't process the key on its own.
long when = whenNanos / 1000000;
KeyEvent keyEvent = new KeyEvent(when, when,
down ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP,
keyCode, 0);
mBroadcastWakeLock.acquire();
mHandler.post(new PassHeadsetKey(keyEvent));
}
} else if (keyCode == KeyEvent.KEYCODE_CALL) {
// If an incoming call is ringing, answer it!
// (We handle this key here, rather than in the InCallScreen, to make
// sure we'll respond to the key even if the InCallScreen hasn't come to
// the foreground yet.)
// Look for the DOWN event here, to agree with the "fallback" // We answer the call on the DOWN event, to agree with
// behavior in the InCallScreen. // the "fallback" behavior in the InCallScreen.
if (down) { if (down) {
try { try {
ITelephony phoneServ = getPhoneInterface(); ITelephony phoneServ = getPhoneInterface();
if (phoneServ != null) { if (phoneServ != null) {
if (phoneServ.isRinging()) { if (phoneServ.isRinging()) {
Log.i(TAG, "interceptKeyTq:" Log.i(TAG, "interceptKeyTq:"
+ " VOLUME key-down while ringing: Silence ringer!"); + " CALL key-down while ringing: Answer the call!");
// Silence the ringer. (It's safe to call this phoneServ.answerRingingCall();
// even if the ringer has already been silenced.)
phoneServ.silenceRinger();
// And *don't* pass this key thru to the current activity // And *don't* pass this key thru to the current activity
// (which is probably the InCallScreen.) // (which is presumably the InCallScreen.)
result &= ~ACTION_PASS_TO_USER; result &= ~ACTION_PASS_TO_USER;
}
} else {
Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
} }
} catch (RemoteException ex) { } else {
Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex); Log.w(TAG, "CALL button: Unable to find ITelephony interface");
} }
} catch (RemoteException ex) {
Log.w(TAG, "CALL button: RemoteException from getPhoneInterface()", ex);
}
}
} else if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP)
|| (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
// If an incoming call is ringing, either VOLUME key means
// "silence ringer". We handle these keys here, rather than
// in the InCallScreen, to make sure we'll respond to them
// even if the InCallScreen hasn't come to the foreground yet.
// Look for the DOWN event here, to agree with the "fallback"
// behavior in the InCallScreen.
if (down) {
try {
ITelephony phoneServ = getPhoneInterface();
if (phoneServ != null) {
if (phoneServ.isRinging()) {
Log.i(TAG, "interceptKeyTq:"
+ " VOLUME key-down while ringing: Silence ringer!");
// Silence the ringer. (It's safe to call this
// even if the ringer has already been silenced.)
phoneServ.silenceRinger();
// And *don't* pass this key thru to the current activity
// (which is probably the InCallScreen.)
result &= ~ACTION_PASS_TO_USER;
}
} else {
Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
}
} catch (RemoteException ex) {
Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
} }
} }
} }
@ -2023,35 +1956,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} */ /** {@inheritDoc} */
public void screenTurnedOff(int why) { public void screenTurnedOff(int why) {
EventLog.writeEvent(70000, 0); EventLog.writeEvent(70000, 0);
@ -2165,7 +2069,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU); int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S); int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER); 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; mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0;
performHapticFeedbackLw(null, mSafeMode performHapticFeedbackLw(null, mSafeMode
? HapticFeedbackConstants.SAFE_MODE_ENABLED ? HapticFeedbackConstants.SAFE_MODE_ENABLED
@ -2413,13 +2317,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return true; 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() { public void screenOnStoppedLw() {
if (!mKeyguardMediator.isShowingAndNotHidden() && mPowerManager.isScreenOn()) { if (!mKeyguardMediator.isShowingAndNotHidden() && mPowerManager.isScreenOn()) {
long curTime = SystemClock.uptimeMillis(); long curTime = SystemClock.uptimeMillis();

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,6 @@ public class InputManager {
private final Callbacks mCallbacks; private final Callbacks mCallbacks;
private final Context mContext; private final Context mContext;
private final WindowManagerService mWindowManagerService; private final WindowManagerService mWindowManagerService;
private final WindowManagerPolicy mWindowManagerPolicy;
private final PowerManager mPowerManager; private final PowerManager mPowerManager;
private final PowerManagerService mPowerManagerService; private final PowerManagerService mPowerManagerService;
@ -103,12 +102,10 @@ public class InputManager {
public InputManager(Context context, public InputManager(Context context,
WindowManagerService windowManagerService, WindowManagerService windowManagerService,
WindowManagerPolicy windowManagerPolicy,
PowerManager powerManager, PowerManager powerManager,
PowerManagerService powerManagerService) { PowerManagerService powerManagerService) {
this.mContext = context; this.mContext = context;
this.mWindowManagerService = windowManagerService; this.mWindowManagerService = windowManagerService;
this.mWindowManagerPolicy = windowManagerPolicy;
this.mPowerManager = powerManager; this.mPowerManager = powerManager;
this.mPowerManagerService = powerManagerService; this.mPowerManagerService = powerManagerService;
@ -325,23 +322,8 @@ public class InputManager {
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
@SuppressWarnings("unused") @SuppressWarnings("unused")
public boolean isScreenOn() { public void virtualKeyDownFeedback() {
return mPowerManagerService.isScreenOn(); mWindowManagerService.mInputMonitor.virtualKeyDownFeedback();
}
@SuppressWarnings("unused")
public boolean isScreenBright() {
return mPowerManagerService.isScreenBright();
}
@SuppressWarnings("unused")
public void virtualKeyFeedback(long whenNanos, int deviceId, int action, int flags,
int keyCode, int scanCode, int metaState, long downTimeNanos) {
KeyEvent keyEvent = new KeyEvent(downTimeNanos / 1000000,
whenNanos / 1000000, action, keyCode, 0, metaState, scanCode, deviceId,
flags);
mWindowManagerService.virtualKeyFeedback(keyEvent);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -356,7 +338,7 @@ public class InputManager {
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
mWindowManagerPolicy.notifyLidSwitchChanged(whenNanos, lidOpen); mWindowManagerService.mInputMonitor.notifyLidSwitchChanged(whenNanos, lidOpen);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -380,17 +362,17 @@ public class InputManager {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public int interceptKeyBeforeQueueing(int deviceId, int type, int scanCode, public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
int keyCode, int policyFlags, int value, long whenNanos, boolean isScreenOn) { int policyFlags, boolean isScreenOn) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(deviceId, type, return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
scanCode, keyCode, policyFlags, value, whenNanos, isScreenOn); whenNanos, keyCode, down, policyFlags, isScreenOn);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public boolean interceptKeyBeforeDispatching(InputChannel focus, int keyCode, public boolean interceptKeyBeforeDispatching(InputChannel focus, int action,
int metaState, boolean down, int repeatCount, int policyFlags) { int flags, int keyCode, int metaState, int repeatCount, int policyFlags) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(focus, return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(focus,
keyCode, metaState, down, repeatCount, policyFlags); action, flags, keyCode, metaState, repeatCount, policyFlags);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -400,18 +382,6 @@ public class InputManager {
== PackageManager.PERMISSION_GRANTED; == PackageManager.PERMISSION_GRANTED;
} }
@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") @SuppressWarnings("unused")
public void notifyAppSwitchComing() { public void notifyAppSwitchComing() {
mWindowManagerService.mInputMonitor.notifyAppSwitchComing(); mWindowManagerService.mInputMonitor.notifyAppSwitchComing();

File diff suppressed because it is too large Load Diff

View File

@ -247,6 +247,9 @@ class PowerManagerService extends IPowerManager.Stub
private static final boolean mSpew = false; private static final boolean mSpew = false;
private static final boolean mDebugProximitySensor = (true || mSpew); private static final boolean mDebugProximitySensor = (true || mSpew);
private static final boolean mDebugLightSensor = (false || mSpew); private static final boolean mDebugLightSensor = (false || mSpew);
private native void nativeInit();
private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
/* /*
static PrintStream mLog; static PrintStream mLog;
@ -481,6 +484,11 @@ class PowerManagerService extends IPowerManager.Stub
} }
} }
} }
nativeInit();
synchronized (mLocks) {
updateNativePowerStateLocked();
}
} }
void initInThread() { 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) { private int screenOffFinishedAnimatingLocked(int reason) {
// I don't think we need to check the current state here because all of these // I don't think we need to check the current state here because all of these

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,9 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \ LOCAL_SRC_FILES:= \
com_android_server_AlarmManagerService.cpp \ com_android_server_AlarmManagerService.cpp \
com_android_server_BatteryService.cpp \ com_android_server_BatteryService.cpp \
com_android_server_KeyInputQueue.cpp \
com_android_server_InputManager.cpp \ com_android_server_InputManager.cpp \
com_android_server_LightsService.cpp \ com_android_server_LightsService.cpp \
com_android_server_PowerManagerService.cpp \
com_android_server_SensorService.cpp \ com_android_server_SensorService.cpp \
com_android_server_SystemServer.cpp \ com_android_server_SystemServer.cpp \
com_android_server_VibratorService.cpp \ com_android_server_VibratorService.cpp \

View File

@ -40,6 +40,7 @@
#include "../../core/jni/android_view_KeyEvent.h" #include "../../core/jni/android_view_KeyEvent.h"
#include "../../core/jni/android_view_MotionEvent.h" #include "../../core/jni/android_view_MotionEvent.h"
#include "../../core/jni/android_view_InputChannel.h" #include "../../core/jni/android_view_InputChannel.h"
#include "com_android_server_PowerManagerService.h"
namespace android { namespace android {
@ -107,16 +108,6 @@ enum {
LAST_SYSTEM_WINDOW = 2999, 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. // Delay between reporting long touch events to the power manager.
const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms 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 { static struct {
jclass clazz; jclass clazz;
jmethodID isScreenOn;
jmethodID isScreenBright;
jmethodID notifyConfigurationChanged; jmethodID notifyConfigurationChanged;
jmethodID notifyLidSwitchChanged; jmethodID notifyLidSwitchChanged;
jmethodID notifyInputChannelBroken; jmethodID notifyInputChannelBroken;
jmethodID notifyInputChannelANR; jmethodID notifyInputChannelANR;
jmethodID notifyInputChannelRecoveredFromANR; jmethodID notifyInputChannelRecoveredFromANR;
jmethodID notifyANR; jmethodID notifyANR;
jmethodID virtualKeyFeedback; jmethodID virtualKeyDownFeedback;
jmethodID interceptKeyBeforeQueueing; jmethodID interceptKeyBeforeQueueing;
jmethodID interceptKeyBeforeDispatching; jmethodID interceptKeyBeforeDispatching;
jmethodID checkInjectEventsPermission; jmethodID checkInjectEventsPermission;
jmethodID goToSleep;
jmethodID pokeUserActivity;
jmethodID notifyAppSwitchComing; jmethodID notifyAppSwitchComing;
jmethodID filterTouchEvents; jmethodID filterTouchEvents;
jmethodID filterJumpyTouchEvents; jmethodID filterJumpyTouchEvents;
@ -228,9 +215,7 @@ public:
virtual bool getDisplayInfo(int32_t displayId, virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation); int32_t* width, int32_t* height, int32_t* orientation);
virtual void virtualKeyFeedback(nsecs_t when, int32_t deviceId, virtual void virtualKeyDownFeedback();
int32_t action, int32_t flags, int32_t keyCode,
int32_t scanCode, int32_t metaState, nsecs_t downTime);
virtual int32_t interceptKey(nsecs_t when, int32_t deviceId, virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags); bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags);
virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown, virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown,
@ -321,7 +306,7 @@ private:
int32_t mDisplayWidth, mDisplayHeight; int32_t mDisplayWidth, mDisplayHeight;
int32_t mDisplayOrientation; int32_t mDisplayOrientation;
// Callbacks. // Power manager interactions.
bool isScreenOn(); bool isScreenOn();
bool isScreenBright(); bool isScreenBright();
@ -369,9 +354,9 @@ private:
void releaseTouchedWindowLd(); 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 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); int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
bool interceptKeyBeforeDispatching(const InputTarget& target, bool interceptKeyBeforeDispatching(const InputTarget& target,
@ -391,6 +376,7 @@ private:
} }
static bool isAppSwitchKey(int32_t keyCode); static bool isAppSwitchKey(int32_t keyCode);
static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName); 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; 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) { bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
if (env->ExceptionCheck()) { if (env->ExceptionCheck()) {
LOGE("An exception was thrown by callback '%s'.", methodName); LOGE("An exception was thrown by callback '%s'.", methodName);
@ -546,39 +562,22 @@ bool NativeInputManager::getDisplayInfo(int32_t displayId,
} }
bool NativeInputManager::isScreenOn() { bool NativeInputManager::isScreenOn() {
JNIEnv* env = jniEnv(); return android_server_PowerManagerService_isScreenOn();
jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenOn);
if (checkAndClearExceptionFromCallback(env, "isScreenOn")) {
return true;
}
return result;
} }
bool NativeInputManager::isScreenBright() { bool NativeInputManager::isScreenBright() {
JNIEnv* env = jniEnv(); return android_server_PowerManagerService_isScreenBright();
jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenBright);
if (checkAndClearExceptionFromCallback(env, "isScreenBright")) {
return true;
}
return result;
} }
void NativeInputManager::virtualKeyFeedback(nsecs_t when, int32_t deviceId, void NativeInputManager::virtualKeyDownFeedback() {
int32_t action, int32_t flags, int32_t keyCode,
int32_t scanCode, int32_t metaState, nsecs_t downTime) {
#if DEBUG_INPUT_READER_POLICY #if DEBUG_INPUT_READER_POLICY
LOGD("virtualKeyFeedback - when=%lld, deviceId=%d, action=%d, flags=%d, keyCode=%d, " LOGD("virtualKeyDownFeedback");
"scanCode=%d, metaState=%d, downTime=%lld",
when, deviceId, action, flags, keyCode, scanCode, metaState, downTime);
#endif #endif
JNIEnv* env = jniEnv(); JNIEnv* env = jniEnv();
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyFeedback, env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
when, deviceId, action, flags, keyCode, scanCode, metaState, downTime); checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
checkAndClearExceptionFromCallback(env, "virtualKeyFeedback");
} }
int32_t NativeInputManager::interceptKey(nsecs_t when, 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_POKE_USER_ACTIVITY = 2;
const int32_t WM_ACTION_GO_TO_SLEEP = 4; const int32_t WM_ACTION_GO_TO_SLEEP = 4;
JNIEnv* env = jniEnv();
bool isScreenOn = this->isScreenOn(); bool isScreenOn = this->isScreenOn();
bool isScreenBright = this->isScreenBright(); bool isScreenBright = this->isScreenBright();
jint wmActions = env->CallIntMethod(mCallbacksObj, jint wmActions = 0;
gCallbacksClassInfo.interceptKeyBeforeQueueing, if (isPolicyKey(keyCode, isScreenOn)) {
deviceId, EV_KEY, scanCode, keyCode, policyFlags, down ? 1 : 0, when, isScreenOn); JNIEnv* env = jniEnv();
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0; 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; int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
@ -617,8 +621,7 @@ int32_t NativeInputManager::interceptKey(nsecs_t when,
} }
if (wmActions & WM_ACTION_GO_TO_SLEEP) { if (wmActions & WM_ACTION_GO_TO_SLEEP) {
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.goToSleep, when); android_server_PowerManagerService_goToSleep(when);
checkAndClearExceptionFromCallback(env, "goToSleep");
} }
if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) { if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
@ -629,6 +632,8 @@ int32_t NativeInputManager::interceptKey(nsecs_t when,
actions |= InputReaderPolicyInterface::ACTION_DISPATCH; actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
if (down && isAppSwitchKey(keyCode)) { if (down && isAppSwitchKey(keyCode)) {
JNIEnv* env = jniEnv();
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyAppSwitchComing); env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyAppSwitchComing);
checkAndClearExceptionFromCallback(env, "notifyAppSwitchComing"); checkAndClearExceptionFromCallback(env, "notifyAppSwitchComing");
@ -1531,11 +1536,13 @@ int32_t NativeInputManager::waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t
windowType = focusedWindow->layoutParamsType; windowType = focusedWindow->layoutParamsType;
} // release lock } // release lock
const InputTarget& target = outTargets.top(); if (isPolicyKey(keyEvent->getKeyCode(), isScreenOn())) {
bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags); const InputTarget& target = outTargets.top();
if (consumed) { bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags);
outTargets.clear(); if (consumed) {
return INPUT_EVENT_INJECTION_SUCCEEDED; outTargets.clear();
return INPUT_EVENT_INJECTION_SUCCEEDED;
}
} }
pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT); pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT);
@ -1552,11 +1559,11 @@ int32_t NativeInputManager::waitForMotionEventTargets(MotionEvent* motionEvent,
switch (motionEvent->getNature()) { switch (motionEvent->getNature()) {
case INPUT_EVENT_NATURE_TRACKBALL: case INPUT_EVENT_NATURE_TRACKBALL:
return identifyTrackballEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, return waitForTrackballEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
outTargets); outTargets);
case INPUT_EVENT_NATURE_TOUCH: case INPUT_EVENT_NATURE_TOUCH:
return identifyTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, return waitForTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid,
outTargets); outTargets);
default: 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, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
Vector<InputTarget>& outTargets) { Vector<InputTarget>& outTargets) {
#if DEBUG_INPUT_DISPATCHER_POLICY #if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("identifyTrackballEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", LOGD("waitForTrackballEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
policyFlags, injectorPid, injectorUid); policyFlags, injectorPid, injectorUid);
#endif #endif
@ -1591,11 +1598,11 @@ int32_t NativeInputManager::identifyTrackballEventTargets(MotionEvent* motionEve
return INPUT_EVENT_INJECTION_SUCCEEDED; 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, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid,
Vector<InputTarget>& outTargets) { Vector<InputTarget>& outTargets) {
#if DEBUG_INPUT_DISPATCHER_POLICY #if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("identifyTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", LOGD("waitForTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
policyFlags, injectorPid, injectorUid); policyFlags, injectorPid, injectorUid);
#endif #endif
@ -1642,8 +1649,8 @@ bool NativeInputManager::interceptKeyBeforeDispatching(const InputTarget& target
if (inputChannelObj) { if (inputChannelObj) {
jboolean consumed = env->CallBooleanMethod(mCallbacksObj, jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.interceptKeyBeforeDispatching,
inputChannelObj, keyEvent->getKeyCode(), keyEvent->getMetaState(), inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
keyEvent->getAction() == KEY_EVENT_ACTION_DOWN, keyEvent->getKeyCode(), keyEvent->getMetaState(),
keyEvent->getRepeatCount(), policyFlags); keyEvent->getRepeatCount(), policyFlags);
bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching"); 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) { void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
JNIEnv* env = jniEnv(); android_server_PowerManagerService_userActivity(eventTime, eventType);
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.pokeUserActivity,
eventTime, eventType);
checkAndClearExceptionFromCallback(env, "pokeUserActivity");
} }
void NativeInputManager::dumpDispatchStateLd() { void NativeInputManager::dumpDispatchStateLd() {
@ -2082,12 +2086,6 @@ int register_android_server_InputManager(JNIEnv* env) {
FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks"); 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, GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
"notifyConfigurationChanged", "(JIII)V"); "notifyConfigurationChanged", "(JIII)V");
@ -2106,24 +2104,18 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz, GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
"notifyANR", "(Ljava/lang/Object;)J"); "notifyANR", "(Ljava/lang/Object;)J");
GET_METHOD_ID(gCallbacksClassInfo.virtualKeyFeedback, gCallbacksClassInfo.clazz, GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
"virtualKeyFeedback", "(JIIIIIIJ)V"); "virtualKeyDownFeedback", "()V");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz, GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
"interceptKeyBeforeQueueing", "(IIIIIIJZ)I"); "interceptKeyBeforeQueueing", "(JIZIZ)I");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz, 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, GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
"checkInjectEventsPermission", "(II)Z"); "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, GET_METHOD_ID(gCallbacksClassInfo.notifyAppSwitchComing, gCallbacksClassInfo.clazz,
"notifyAppSwitchComing", "()V"); "notifyAppSwitchComing", "()V");

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -6,9 +6,9 @@
namespace android { namespace android {
int register_android_server_AlarmManagerService(JNIEnv* env); int register_android_server_AlarmManagerService(JNIEnv* env);
int register_android_server_BatteryService(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_InputManager(JNIEnv* env);
int register_android_server_LightsService(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_SensorService(JNIEnv* env);
int register_android_server_VibratorService(JNIEnv* env); int register_android_server_VibratorService(JNIEnv* env);
int register_android_server_SystemServer(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!"); 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_InputManager(env);
register_android_server_LightsService(env); register_android_server_LightsService(env);
register_android_server_AlarmManagerService(env); register_android_server_AlarmManagerService(env);