Merge "More native input dispatch work." into gingerbread
This commit is contained in:
@ -216,20 +216,7 @@ public abstract class WallpaperService extends Service {
|
||||
@Override
|
||||
public void handleTouch(MotionEvent event, Runnable finishedCallback) {
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (mPendingMove != null) {
|
||||
mCaller.removeMessages(MSG_TOUCH_EVENT, mPendingMove);
|
||||
mPendingMove.recycle();
|
||||
}
|
||||
mPendingMove = event;
|
||||
} else {
|
||||
mPendingMove = null;
|
||||
}
|
||||
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT,
|
||||
event);
|
||||
mCaller.sendMessage(msg);
|
||||
}
|
||||
dispatchPointer(event);
|
||||
} finally {
|
||||
finishedCallback.run();
|
||||
}
|
||||
@ -237,26 +224,6 @@ public abstract class WallpaperService extends Service {
|
||||
};
|
||||
|
||||
final BaseIWindow mWindow = new BaseIWindow() {
|
||||
@Override
|
||||
public boolean onDispatchPointer(MotionEvent event, long eventTime,
|
||||
boolean callWhenDone) {
|
||||
synchronized (mLock) {
|
||||
if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (mPendingMove != null) {
|
||||
mCaller.removeMessages(MSG_TOUCH_EVENT, mPendingMove);
|
||||
mPendingMove.recycle();
|
||||
}
|
||||
mPendingMove = event;
|
||||
} else {
|
||||
mPendingMove = null;
|
||||
}
|
||||
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT,
|
||||
event);
|
||||
mCaller.sendMessage(msg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resized(int w, int h, Rect coveredInsets,
|
||||
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
|
||||
@ -466,6 +433,22 @@ public abstract class WallpaperService extends Service {
|
||||
*/
|
||||
public void onSurfaceDestroyed(SurfaceHolder holder) {
|
||||
}
|
||||
|
||||
private void dispatchPointer(MotionEvent event) {
|
||||
synchronized (mLock) {
|
||||
if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (mPendingMove != null) {
|
||||
mCaller.removeMessages(MSG_TOUCH_EVENT, mPendingMove);
|
||||
mPendingMove.recycle();
|
||||
}
|
||||
mPendingMove = event;
|
||||
} else {
|
||||
mPendingMove = null;
|
||||
}
|
||||
Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
|
||||
mCaller.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void updateSurface(boolean forceRelayout, boolean forceReport) {
|
||||
if (mDestroyed) {
|
||||
@ -523,10 +506,8 @@ public abstract class WallpaperService extends Service {
|
||||
mInputChannel);
|
||||
mCreated = true;
|
||||
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
InputQueue.registerInputChannel(mInputChannel, mInputHandler,
|
||||
Looper.myQueue());
|
||||
}
|
||||
InputQueue.registerInputChannel(mInputChannel, mInputHandler,
|
||||
Looper.myQueue());
|
||||
}
|
||||
|
||||
mSurfaceHolder.mSurfaceLock.lock();
|
||||
@ -770,10 +751,8 @@ public abstract class WallpaperService extends Service {
|
||||
if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
|
||||
+ mSurfaceHolder.getSurface() + " of: " + this);
|
||||
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
if (mInputChannel != null) {
|
||||
InputQueue.unregisterInputChannel(mInputChannel);
|
||||
}
|
||||
if (mInputChannel != null) {
|
||||
InputQueue.unregisterInputChannel(mInputChannel);
|
||||
}
|
||||
|
||||
mSession.remove(mWindow);
|
||||
@ -782,13 +761,11 @@ public abstract class WallpaperService extends Service {
|
||||
mSurfaceHolder.mSurface.release();
|
||||
mCreated = false;
|
||||
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
// Dispose the input channel after removing the window so the Window Manager
|
||||
// doesn't interpret the input channel being closed as an abnormal termination.
|
||||
if (mInputChannel != null) {
|
||||
mInputChannel.dispose();
|
||||
mInputChannel = null;
|
||||
}
|
||||
// Dispose the input channel after removing the window so the Window Manager
|
||||
// doesn't interpret the input channel being closed as an abnormal termination.
|
||||
if (mInputChannel != null) {
|
||||
mInputChannel.dispose();
|
||||
mInputChannel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -841,7 +818,7 @@ public abstract class WallpaperService extends Service {
|
||||
|
||||
public void dispatchPointer(MotionEvent event) {
|
||||
if (mEngine != null) {
|
||||
mEngine.mWindow.onDispatchPointer(event, event.getEventTime(), false);
|
||||
mEngine.dispatchPointer(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,6 @@ oneway interface IWindow {
|
||||
|
||||
void resized(int w, int h, in Rect coveredInsets, in Rect visibleInsets,
|
||||
boolean reportDraw, in Configuration newConfig);
|
||||
void dispatchKey(in KeyEvent event);
|
||||
void dispatchPointer(in MotionEvent event, long eventTime, boolean callWhenDone);
|
||||
void dispatchTrackball(in MotionEvent event, long eventTime, boolean callWhenDone);
|
||||
void dispatchAppVisibility(boolean visible);
|
||||
void dispatchGetNewSurface();
|
||||
|
||||
|
@ -109,10 +109,6 @@ interface IWindowSession {
|
||||
void getDisplayFrame(IWindow window, out Rect outDisplayFrame);
|
||||
|
||||
void finishDrawing(IWindow window);
|
||||
|
||||
void finishKey(IWindow window);
|
||||
MotionEvent getPendingPointerMove(IWindow window);
|
||||
MotionEvent getPendingTrackballMove(IWindow window);
|
||||
|
||||
void setInTouchMode(boolean showFocus);
|
||||
boolean getInTouchMode();
|
||||
|
@ -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;
|
||||
}
|
@ -625,41 +625,6 @@ public class SurfaceView extends View {
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchKey(KeyEvent event) {
|
||||
SurfaceView surfaceView = mSurfaceView.get();
|
||||
if (surfaceView != null) {
|
||||
//Log.w("SurfaceView", "Unexpected key event in surface: " + event);
|
||||
if (surfaceView.mSession != null && surfaceView.mSurface != null) {
|
||||
try {
|
||||
surfaceView.mSession.finishKey(surfaceView.mWindow);
|
||||
} catch (RemoteException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchPointer(MotionEvent event, long eventTime,
|
||||
boolean callWhenDone) {
|
||||
Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
|
||||
//if (mSession != null && mSurface != null) {
|
||||
// try {
|
||||
// //mSession.finishKey(mWindow);
|
||||
// } catch (RemoteException ex) {
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
public void dispatchTrackball(MotionEvent event, long eventTime,
|
||||
boolean callWhenDone) {
|
||||
Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
|
||||
//if (mSession != null && mSurface != null) {
|
||||
// try {
|
||||
// //mSession.finishKey(mWindow);
|
||||
// } catch (RemoteException ex) {
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
public void dispatchAppVisibility(boolean visible) {
|
||||
// The point of SurfaceView is to let the app control the surface.
|
||||
}
|
||||
@ -686,7 +651,6 @@ public class SurfaceView extends View {
|
||||
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
|
||||
|
||||
private static final String LOG_TAG = "SurfaceHolder";
|
||||
private int mSaveCount;
|
||||
|
||||
public boolean isCreating() {
|
||||
return mIsCreating;
|
||||
|
@ -556,18 +556,16 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
"Unable to add window -- unknown error code " + res);
|
||||
}
|
||||
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
if (view instanceof RootViewSurfaceTaker) {
|
||||
mInputQueueCallback =
|
||||
((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
|
||||
}
|
||||
if (mInputQueueCallback != null) {
|
||||
mInputQueue = new InputQueue(mInputChannel);
|
||||
mInputQueueCallback.onInputQueueCreated(mInputQueue);
|
||||
} else {
|
||||
InputQueue.registerInputChannel(mInputChannel, mInputHandler,
|
||||
Looper.myQueue());
|
||||
}
|
||||
if (view instanceof RootViewSurfaceTaker) {
|
||||
mInputQueueCallback =
|
||||
((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
|
||||
}
|
||||
if (mInputQueueCallback != null) {
|
||||
mInputQueue = new InputQueue(mInputChannel);
|
||||
mInputQueueCallback.onInputQueueCreated(mInputQueue);
|
||||
} else {
|
||||
InputQueue.registerInputChannel(mInputChannel, mInputHandler,
|
||||
Looper.myQueue());
|
||||
}
|
||||
|
||||
view.assignParent(this);
|
||||
@ -1745,16 +1743,12 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
mSurface.release();
|
||||
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
if (mInputChannel != null) {
|
||||
if (mInputQueueCallback != null) {
|
||||
mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
|
||||
mInputQueueCallback = null;
|
||||
} else {
|
||||
InputQueue.unregisterInputChannel(mInputChannel);
|
||||
}
|
||||
mInputChannel.dispose();
|
||||
mInputChannel = null;
|
||||
if (mInputChannel != null) {
|
||||
if (mInputQueueCallback != null) {
|
||||
mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
|
||||
mInputQueueCallback = null;
|
||||
} else {
|
||||
InputQueue.unregisterInputChannel(mInputChannel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1763,13 +1757,11 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
// Dispose the input channel after removing the window so the Window Manager
|
||||
// doesn't interpret the input channel being closed as an abnormal termination.
|
||||
if (mInputChannel != null) {
|
||||
mInputChannel.dispose();
|
||||
mInputChannel = null;
|
||||
}
|
||||
// Dispose the input channel after removing the window so the Window Manager
|
||||
// doesn't interpret the input channel being closed as an abnormal termination.
|
||||
if (mInputChannel != null) {
|
||||
mInputChannel.dispose();
|
||||
mInputChannel = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1869,105 +1861,22 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
deliverKeyEvent((KeyEvent)msg.obj, true);
|
||||
break;
|
||||
case DISPATCH_POINTER: {
|
||||
MotionEvent event = (MotionEvent)msg.obj;
|
||||
boolean callWhenDone = msg.arg1 != 0;
|
||||
|
||||
if (event == null) {
|
||||
long timeBeforeGettingEvents;
|
||||
if (MEASURE_LATENCY) {
|
||||
timeBeforeGettingEvents = System.nanoTime();
|
||||
}
|
||||
|
||||
event = getPendingPointerMotionEvent();
|
||||
|
||||
if (MEASURE_LATENCY && event != null) {
|
||||
lt.sample("9 Client got events ", System.nanoTime() - event.getEventTimeNano());
|
||||
lt.sample("8 Client getting events ", timeBeforeGettingEvents - event.getEventTimeNano());
|
||||
}
|
||||
callWhenDone = false;
|
||||
}
|
||||
if (event != null && mTranslator != null) {
|
||||
mTranslator.translateEventInScreenToAppWindow(event);
|
||||
}
|
||||
MotionEvent event = (MotionEvent) msg.obj;
|
||||
try {
|
||||
boolean handled;
|
||||
if (mView != null && mAdded && event != null) {
|
||||
|
||||
// enter touch mode on the down
|
||||
boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN;
|
||||
if (isDown) {
|
||||
ensureTouchMode(true);
|
||||
}
|
||||
if(Config.LOGV) {
|
||||
captureMotionLog("captureDispatchPointer", event);
|
||||
}
|
||||
if (mCurScrollY != 0) {
|
||||
event.offsetLocation(0, mCurScrollY);
|
||||
}
|
||||
if (MEASURE_LATENCY) {
|
||||
lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());
|
||||
}
|
||||
handled = mView.dispatchTouchEvent(event);
|
||||
if (MEASURE_LATENCY) {
|
||||
lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());
|
||||
}
|
||||
if (!handled && isDown) {
|
||||
int edgeSlop = mViewConfiguration.getScaledEdgeSlop();
|
||||
|
||||
final int edgeFlags = event.getEdgeFlags();
|
||||
int direction = View.FOCUS_UP;
|
||||
int x = (int)event.getX();
|
||||
int y = (int)event.getY();
|
||||
final int[] deltas = new int[2];
|
||||
|
||||
if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) {
|
||||
direction = View.FOCUS_DOWN;
|
||||
if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
|
||||
deltas[0] = edgeSlop;
|
||||
x += edgeSlop;
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
|
||||
deltas[0] = -edgeSlop;
|
||||
x -= edgeSlop;
|
||||
}
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) {
|
||||
direction = View.FOCUS_UP;
|
||||
if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
|
||||
deltas[0] = edgeSlop;
|
||||
x += edgeSlop;
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
|
||||
deltas[0] = -edgeSlop;
|
||||
x -= edgeSlop;
|
||||
}
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
|
||||
direction = View.FOCUS_RIGHT;
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
|
||||
direction = View.FOCUS_LEFT;
|
||||
}
|
||||
|
||||
if (edgeFlags != 0 && mView instanceof ViewGroup) {
|
||||
View nearest = FocusFinder.getInstance().findNearestTouchable(
|
||||
((ViewGroup) mView), x, y, direction, deltas);
|
||||
if (nearest != null) {
|
||||
event.offsetLocation(deltas[0], deltas[1]);
|
||||
event.setEdgeFlags(0);
|
||||
mView.dispatchTouchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
deliverPointerEvent(event);
|
||||
} finally {
|
||||
if (callWhenDone) {
|
||||
finishMotionEvent();
|
||||
}
|
||||
recycleMotionEvent(event);
|
||||
event.recycle();
|
||||
if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!");
|
||||
// Let the exception fall through -- the looper will catch
|
||||
// it and take care of the bad app for us.
|
||||
}
|
||||
} break;
|
||||
case DISPATCH_TRACKBALL:
|
||||
deliverTrackballEvent((MotionEvent)msg.obj, msg.arg1 != 0);
|
||||
break;
|
||||
case DISPATCH_TRACKBALL: {
|
||||
MotionEvent event = (MotionEvent) msg.obj;
|
||||
try {
|
||||
deliverTrackballEvent(event);
|
||||
} finally {
|
||||
event.recycle();
|
||||
}
|
||||
} break;
|
||||
case DISPATCH_APP_VISIBILITY:
|
||||
handleAppVisibility(msg.arg1 != 0);
|
||||
break;
|
||||
@ -2101,61 +2010,12 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
|
||||
private void finishKeyEvent(KeyEvent event) {
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
if (mFinishedCallback != null) {
|
||||
mFinishedCallback.run();
|
||||
mFinishedCallback = null;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
sWindowSession.finishKey(mWindow);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
if (mFinishedCallback != null) {
|
||||
mFinishedCallback.run();
|
||||
mFinishedCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void finishMotionEvent() {
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
throw new IllegalStateException("Should not be reachable with native input dispatch.");
|
||||
}
|
||||
|
||||
try {
|
||||
sWindowSession.finishKey(mWindow);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
private void recycleMotionEvent(MotionEvent event) {
|
||||
if (event != null) {
|
||||
event.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
private MotionEvent getPendingPointerMotionEvent() {
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
throw new IllegalStateException("Should not be reachable with native input dispatch.");
|
||||
}
|
||||
|
||||
try {
|
||||
return sWindowSession.getPendingPointerMove(mWindow);
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private MotionEvent getPendingTrackballMotionEvent() {
|
||||
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
|
||||
throw new IllegalStateException("Should not be reachable with native input dispatch.");
|
||||
}
|
||||
|
||||
try {
|
||||
return sWindowSession.getPendingTrackballMove(mWindow);
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Something in the current window tells us we need to change the touch mode. For
|
||||
* example, we are not in touch mode, and the user touches the screen.
|
||||
@ -2277,42 +2137,95 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void deliverTrackballEvent(MotionEvent event, boolean callWhenDone) {
|
||||
if (event == null) {
|
||||
event = getPendingTrackballMotionEvent();
|
||||
callWhenDone = false;
|
||||
private void deliverPointerEvent(MotionEvent event) {
|
||||
if (mTranslator != null) {
|
||||
mTranslator.translateEventInScreenToAppWindow(event);
|
||||
}
|
||||
|
||||
boolean handled;
|
||||
if (mView != null && mAdded) {
|
||||
|
||||
// enter touch mode on the down
|
||||
boolean isDown = event.getAction() == MotionEvent.ACTION_DOWN;
|
||||
if (isDown) {
|
||||
ensureTouchMode(true);
|
||||
}
|
||||
if(Config.LOGV) {
|
||||
captureMotionLog("captureDispatchPointer", event);
|
||||
}
|
||||
if (mCurScrollY != 0) {
|
||||
event.offsetLocation(0, mCurScrollY);
|
||||
}
|
||||
if (MEASURE_LATENCY) {
|
||||
lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());
|
||||
}
|
||||
handled = mView.dispatchTouchEvent(event);
|
||||
if (MEASURE_LATENCY) {
|
||||
lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());
|
||||
}
|
||||
if (!handled && isDown) {
|
||||
int edgeSlop = mViewConfiguration.getScaledEdgeSlop();
|
||||
|
||||
final int edgeFlags = event.getEdgeFlags();
|
||||
int direction = View.FOCUS_UP;
|
||||
int x = (int)event.getX();
|
||||
int y = (int)event.getY();
|
||||
final int[] deltas = new int[2];
|
||||
|
||||
if ((edgeFlags & MotionEvent.EDGE_TOP) != 0) {
|
||||
direction = View.FOCUS_DOWN;
|
||||
if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
|
||||
deltas[0] = edgeSlop;
|
||||
x += edgeSlop;
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
|
||||
deltas[0] = -edgeSlop;
|
||||
x -= edgeSlop;
|
||||
}
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_BOTTOM) != 0) {
|
||||
direction = View.FOCUS_UP;
|
||||
if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
|
||||
deltas[0] = edgeSlop;
|
||||
x += edgeSlop;
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
|
||||
deltas[0] = -edgeSlop;
|
||||
x -= edgeSlop;
|
||||
}
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_LEFT) != 0) {
|
||||
direction = View.FOCUS_RIGHT;
|
||||
} else if ((edgeFlags & MotionEvent.EDGE_RIGHT) != 0) {
|
||||
direction = View.FOCUS_LEFT;
|
||||
}
|
||||
|
||||
if (edgeFlags != 0 && mView instanceof ViewGroup) {
|
||||
View nearest = FocusFinder.getInstance().findNearestTouchable(
|
||||
((ViewGroup) mView), x, y, direction, deltas);
|
||||
if (nearest != null) {
|
||||
event.offsetLocation(deltas[0], deltas[1]);
|
||||
event.setEdgeFlags(0);
|
||||
mView.dispatchTouchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deliverTrackballEvent(MotionEvent event) {
|
||||
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
|
||||
|
||||
boolean handled = false;
|
||||
try {
|
||||
if (event == null) {
|
||||
handled = true;
|
||||
} else if (mView != null && mAdded) {
|
||||
handled = mView.dispatchTrackballEvent(event);
|
||||
if (!handled) {
|
||||
// we could do something here, like changing the focus
|
||||
// or something?
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (mView != null && mAdded) {
|
||||
handled = mView.dispatchTrackballEvent(event);
|
||||
if (handled) {
|
||||
if (callWhenDone) {
|
||||
finishMotionEvent();
|
||||
}
|
||||
recycleMotionEvent(event);
|
||||
// If we reach this, we delivered a trackball event to mView and
|
||||
// mView consumed it. Because we will not translate the trackball
|
||||
// event into a key event, touch mode will not exit, so we exit
|
||||
// touch mode here.
|
||||
ensureTouchMode(false);
|
||||
//noinspection ReturnInsideFinallyBlock
|
||||
return;
|
||||
}
|
||||
// Let the exception fall through -- the looper will catch
|
||||
// it and take care of the bad app for us.
|
||||
|
||||
// Otherwise we could do something here, like changing the focus
|
||||
// or something?
|
||||
}
|
||||
|
||||
final TrackballAxis x = mTrackballAxisX;
|
||||
@ -2327,95 +2240,86 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
mLastTrackballTime = curTime;
|
||||
}
|
||||
|
||||
try {
|
||||
final int action = event.getAction();
|
||||
final int metastate = event.getMetaState();
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
x.reset(2);
|
||||
y.reset(2);
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER,
|
||||
0, metastate), false);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
x.reset(2);
|
||||
y.reset(2);
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER,
|
||||
0, metastate), false);
|
||||
break;
|
||||
}
|
||||
final int action = event.getAction();
|
||||
final int metastate = event.getMetaState();
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
x.reset(2);
|
||||
y.reset(2);
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER,
|
||||
0, metastate), false);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
x.reset(2);
|
||||
y.reset(2);
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER,
|
||||
0, metastate), false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step="
|
||||
+ x.step + " dir=" + x.dir + " acc=" + x.acceleration
|
||||
+ " move=" + event.getX()
|
||||
+ " / Y=" + y.position + " step="
|
||||
+ y.step + " dir=" + y.dir + " acc=" + y.acceleration
|
||||
+ " move=" + event.getY());
|
||||
final float xOff = x.collect(event.getX(), event.getEventTime(), "X");
|
||||
final float yOff = y.collect(event.getY(), event.getEventTime(), "Y");
|
||||
if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step="
|
||||
+ x.step + " dir=" + x.dir + " acc=" + x.acceleration
|
||||
+ " move=" + event.getX()
|
||||
+ " / Y=" + y.position + " step="
|
||||
+ y.step + " dir=" + y.dir + " acc=" + y.acceleration
|
||||
+ " move=" + event.getY());
|
||||
final float xOff = x.collect(event.getX(), event.getEventTime(), "X");
|
||||
final float yOff = y.collect(event.getY(), event.getEventTime(), "Y");
|
||||
|
||||
// Generate DPAD events based on the trackball movement.
|
||||
// We pick the axis that has moved the most as the direction of
|
||||
// the DPAD. When we generate DPAD events for one axis, then the
|
||||
// other axis is reset -- we don't want to perform DPAD jumps due
|
||||
// to slight movements in the trackball when making major movements
|
||||
// along the other axis.
|
||||
int keycode = 0;
|
||||
int movement = 0;
|
||||
float accel = 1;
|
||||
if (xOff > yOff) {
|
||||
movement = x.generate((2/event.getXPrecision()));
|
||||
if (movement != 0) {
|
||||
keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT
|
||||
: KeyEvent.KEYCODE_DPAD_LEFT;
|
||||
accel = x.acceleration;
|
||||
y.reset(2);
|
||||
}
|
||||
} else if (yOff > 0) {
|
||||
movement = y.generate((2/event.getYPrecision()));
|
||||
if (movement != 0) {
|
||||
keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_DOWN
|
||||
: KeyEvent.KEYCODE_DPAD_UP;
|
||||
accel = y.acceleration;
|
||||
x.reset(2);
|
||||
}
|
||||
// Generate DPAD events based on the trackball movement.
|
||||
// We pick the axis that has moved the most as the direction of
|
||||
// the DPAD. When we generate DPAD events for one axis, then the
|
||||
// other axis is reset -- we don't want to perform DPAD jumps due
|
||||
// to slight movements in the trackball when making major movements
|
||||
// along the other axis.
|
||||
int keycode = 0;
|
||||
int movement = 0;
|
||||
float accel = 1;
|
||||
if (xOff > yOff) {
|
||||
movement = x.generate((2/event.getXPrecision()));
|
||||
if (movement != 0) {
|
||||
keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT
|
||||
: KeyEvent.KEYCODE_DPAD_LEFT;
|
||||
accel = x.acceleration;
|
||||
y.reset(2);
|
||||
}
|
||||
} else if (yOff > 0) {
|
||||
movement = y.generate((2/event.getYPrecision()));
|
||||
if (movement != 0) {
|
||||
keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_DOWN
|
||||
: KeyEvent.KEYCODE_DPAD_UP;
|
||||
accel = y.acceleration;
|
||||
x.reset(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode != 0) {
|
||||
if (movement < 0) movement = -movement;
|
||||
int accelMovement = (int)(movement * accel);
|
||||
if (DEBUG_TRACKBALL) Log.v(TAG, "Move: movement=" + movement
|
||||
+ " accelMovement=" + accelMovement
|
||||
+ " accel=" + accel);
|
||||
if (accelMovement > movement) {
|
||||
if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
|
||||
+ keycode);
|
||||
movement--;
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_MULTIPLE, keycode,
|
||||
accelMovement-movement, metastate), false);
|
||||
}
|
||||
while (movement > 0) {
|
||||
if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
|
||||
+ keycode);
|
||||
movement--;
|
||||
curTime = SystemClock.uptimeMillis();
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_DOWN, keycode, 0, event.getMetaState()), false);
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_UP, keycode, 0, metastate), false);
|
||||
}
|
||||
mLastTrackballTime = curTime;
|
||||
if (keycode != 0) {
|
||||
if (movement < 0) movement = -movement;
|
||||
int accelMovement = (int)(movement * accel);
|
||||
if (DEBUG_TRACKBALL) Log.v(TAG, "Move: movement=" + movement
|
||||
+ " accelMovement=" + accelMovement
|
||||
+ " accel=" + accel);
|
||||
if (accelMovement > movement) {
|
||||
if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
|
||||
+ keycode);
|
||||
movement--;
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_MULTIPLE, keycode,
|
||||
accelMovement-movement, metastate), false);
|
||||
}
|
||||
} finally {
|
||||
if (callWhenDone) {
|
||||
finishMotionEvent();
|
||||
recycleMotionEvent(event);
|
||||
while (movement > 0) {
|
||||
if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
|
||||
+ keycode);
|
||||
movement--;
|
||||
curTime = SystemClock.uptimeMillis();
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_DOWN, keycode, 0, event.getMetaState()), false);
|
||||
deliverKeyEvent(new KeyEvent(curTime, curTime,
|
||||
KeyEvent.ACTION_UP, keycode, 0, metastate), false);
|
||||
}
|
||||
// Let the exception fall through -- the looper will catch
|
||||
// it and take care of the bad app for us.
|
||||
mLastTrackballTime = curTime;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2862,45 +2766,20 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
private final InputHandler mInputHandler = new InputHandler() {
|
||||
public void handleKey(KeyEvent event, Runnable finishedCallback) {
|
||||
mFinishedCallback = finishedCallback;
|
||||
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
//noinspection ConstantConditions
|
||||
if (false && event.getKeyCode() == KeyEvent.KEYCODE_CAMERA) {
|
||||
if (Config.LOGD) Log.d("keydisp",
|
||||
"===================================================");
|
||||
if (Config.LOGD) Log.d("keydisp", "Focused view Hierarchy is:");
|
||||
debug();
|
||||
|
||||
if (Config.LOGD) Log.d("keydisp",
|
||||
"===================================================");
|
||||
}
|
||||
}
|
||||
|
||||
Message msg = obtainMessage(DISPATCH_KEY);
|
||||
msg.obj = event;
|
||||
|
||||
if (LOCAL_LOGV) Log.v(
|
||||
"ViewRoot", "sending key " + event + " to " + mView);
|
||||
|
||||
sendMessageAtTime(msg, event.getEventTime());
|
||||
dispatchKey(event);
|
||||
}
|
||||
|
||||
public void handleTouch(MotionEvent event, Runnable finishedCallback) {
|
||||
finishedCallback.run();
|
||||
|
||||
Message msg = obtainMessage(DISPATCH_POINTER);
|
||||
msg.obj = event;
|
||||
msg.arg1 = 0;
|
||||
sendMessageAtTime(msg, event.getEventTime());
|
||||
dispatchPointer(event);
|
||||
}
|
||||
|
||||
public void handleTrackball(MotionEvent event, Runnable finishedCallback) {
|
||||
finishedCallback.run();
|
||||
|
||||
Message msg = obtainMessage(DISPATCH_TRACKBALL);
|
||||
msg.obj = event;
|
||||
msg.arg1 = 0;
|
||||
sendMessageAtTime(msg, event.getEventTime());
|
||||
dispatchTrackball(event);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2927,22 +2806,18 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
sendMessageAtTime(msg, event.getEventTime());
|
||||
}
|
||||
|
||||
public void dispatchPointer(MotionEvent event, long eventTime,
|
||||
boolean callWhenDone) {
|
||||
public void dispatchPointer(MotionEvent event) {
|
||||
Message msg = obtainMessage(DISPATCH_POINTER);
|
||||
msg.obj = event;
|
||||
msg.arg1 = callWhenDone ? 1 : 0;
|
||||
sendMessageAtTime(msg, eventTime);
|
||||
sendMessageAtTime(msg, event.getEventTime());
|
||||
}
|
||||
|
||||
public void dispatchTrackball(MotionEvent event, long eventTime,
|
||||
boolean callWhenDone) {
|
||||
public void dispatchTrackball(MotionEvent event) {
|
||||
Message msg = obtainMessage(DISPATCH_TRACKBALL);
|
||||
msg.obj = event;
|
||||
msg.arg1 = callWhenDone ? 1 : 0;
|
||||
sendMessageAtTime(msg, eventTime);
|
||||
sendMessageAtTime(msg, event.getEventTime());
|
||||
}
|
||||
|
||||
|
||||
public void dispatchAppVisibility(boolean visible) {
|
||||
Message msg = obtainMessage(DISPATCH_APP_VISIBILITY);
|
||||
msg.arg1 = visible ? 1 : 0;
|
||||
@ -3073,56 +2948,11 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
class EventCompletion extends Handler {
|
||||
final IWindow mWindow;
|
||||
final KeyEvent mKeyEvent;
|
||||
final boolean mIsPointer;
|
||||
final MotionEvent mMotionEvent;
|
||||
|
||||
EventCompletion(Looper looper, IWindow window, KeyEvent key,
|
||||
boolean isPointer, MotionEvent motion) {
|
||||
super(looper);
|
||||
mWindow = window;
|
||||
mKeyEvent = key;
|
||||
mIsPointer = isPointer;
|
||||
mMotionEvent = motion;
|
||||
sendEmptyMessage(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (mKeyEvent != null) {
|
||||
finishKeyEvent(mKeyEvent);
|
||||
} else if (mIsPointer) {
|
||||
boolean didFinish;
|
||||
MotionEvent event = mMotionEvent;
|
||||
if (event == null) {
|
||||
event = getPendingPointerMotionEvent();
|
||||
didFinish = true;
|
||||
} else {
|
||||
didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
|
||||
}
|
||||
if (!didFinish) {
|
||||
finishMotionEvent();
|
||||
}
|
||||
} else {
|
||||
MotionEvent event = mMotionEvent;
|
||||
if (event == null) {
|
||||
event = getPendingTrackballMotionEvent();
|
||||
} else {
|
||||
finishMotionEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class W extends IWindow.Stub {
|
||||
private final WeakReference<ViewRoot> mViewRoot;
|
||||
private final Looper mMainLooper;
|
||||
|
||||
public W(ViewRoot viewRoot, Context context) {
|
||||
mViewRoot = new WeakReference<ViewRoot>(viewRoot);
|
||||
mMainLooper = context.getMainLooper();
|
||||
}
|
||||
|
||||
public void resized(int w, int h, Rect coveredInsets,
|
||||
@ -3134,40 +2964,6 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchKey(KeyEvent event) {
|
||||
final ViewRoot viewRoot = mViewRoot.get();
|
||||
if (viewRoot != null) {
|
||||
viewRoot.dispatchKey(event);
|
||||
} else {
|
||||
Log.w("ViewRoot.W", "Key event " + event + " but no ViewRoot available!");
|
||||
viewRoot.new EventCompletion(mMainLooper, this, event, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchPointer(MotionEvent event, long eventTime,
|
||||
boolean callWhenDone) {
|
||||
final ViewRoot viewRoot = mViewRoot.get();
|
||||
if (viewRoot != null) {
|
||||
if (MEASURE_LATENCY) {
|
||||
// Note: eventTime is in milliseconds
|
||||
ViewRoot.lt.sample("* ViewRoot b4 dispatchPtr", System.nanoTime() - eventTime * 1000000);
|
||||
}
|
||||
viewRoot.dispatchPointer(event, eventTime, callWhenDone);
|
||||
} else {
|
||||
viewRoot.new EventCompletion(mMainLooper, this, null, true, event);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchTrackball(MotionEvent event, long eventTime,
|
||||
boolean callWhenDone) {
|
||||
final ViewRoot viewRoot = mViewRoot.get();
|
||||
if (viewRoot != null) {
|
||||
viewRoot.dispatchTrackball(event, eventTime, callWhenDone);
|
||||
} else {
|
||||
viewRoot.new EventCompletion(mMainLooper, this, null, false, event);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchAppVisibility(boolean visible) {
|
||||
final ViewRoot viewRoot = mViewRoot.get();
|
||||
if (viewRoot != null) {
|
||||
|
@ -78,12 +78,6 @@ public interface WindowManagerPolicy {
|
||||
public final static int FLAG_BRIGHT_HERE = 0x20000000;
|
||||
|
||||
public final static boolean WATCH_POINTER = false;
|
||||
|
||||
/**
|
||||
* Temporary flag added during the transition to the new native input dispatcher.
|
||||
* This will be removed when the old input dispatch code is deleted.
|
||||
*/
|
||||
public final static boolean ENABLE_NATIVE_INPUT_DISPATCH = true;
|
||||
|
||||
// flags for interceptKeyTq
|
||||
/**
|
||||
@ -555,23 +549,26 @@ public interface WindowManagerPolicy {
|
||||
public Animation createForceHideEnterAnimation();
|
||||
|
||||
/**
|
||||
* Called from the key queue thread before a key is dispatched to the
|
||||
* input thread.
|
||||
* Called from the input reader thread before a key is enqueued.
|
||||
*
|
||||
* <p>There are some actions that need to be handled here because they
|
||||
* affect the power state of the device, for example, the power keys.
|
||||
* Generally, it's best to keep as little as possible in the queue thread
|
||||
* because it's the most fragile.
|
||||
* @param whenNanos The event time in uptime nanoseconds.
|
||||
* @param keyCode The key code.
|
||||
* @param down True if the key is down.
|
||||
* @param policyFlags The policy flags associated with the key.
|
||||
* @param isScreenOn True if the screen is already on
|
||||
*
|
||||
* @param event the raw input event as read from the driver
|
||||
* @param screenIsOn true if the screen is already on
|
||||
* @return The bitwise or of the {@link #ACTION_PASS_TO_USER},
|
||||
* {@link #ACTION_POKE_USER_ACTIVITY} and {@link #ACTION_GO_TO_SLEEP} flags.
|
||||
*/
|
||||
public int interceptKeyTq(RawInputEvent event, boolean screenIsOn);
|
||||
public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down, int policyFlags,
|
||||
boolean isScreenOn);
|
||||
|
||||
/**
|
||||
* Called from the input thread before a key is dispatched to a window.
|
||||
* Called from the input dispatcher thread before a key is dispatched to a window.
|
||||
*
|
||||
* <p>Allows you to define
|
||||
* behavior for keys that can not be overridden by applications or redirect
|
||||
@ -583,16 +580,17 @@ public interface WindowManagerPolicy {
|
||||
*
|
||||
* @param win The window that currently has focus. This is where the key
|
||||
* event will normally go.
|
||||
* @param code Key code.
|
||||
* @param metaKeys bit mask of meta keys that are held.
|
||||
* @param down Is this a key press (true) or release (false)?
|
||||
* @param action The key event action.
|
||||
* @param flags The key event flags.
|
||||
* @param keyCode The key code.
|
||||
* @param metaState bit mask of meta keys that are held.
|
||||
* @param repeatCount Number of times a key down has repeated.
|
||||
* @param flags event's flags.
|
||||
* @param policyFlags The policy flags associated with the key.
|
||||
* @return Returns true if the policy consumed the event and it should
|
||||
* not be further dispatched.
|
||||
*/
|
||||
public boolean interceptKeyTi(WindowState win, int code,
|
||||
int metaKeys, boolean down, int repeatCount, int flags);
|
||||
public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
|
||||
int keyCode, int metaState, int repeatCount, int policyFlags);
|
||||
|
||||
/**
|
||||
* Called when layout of the windows is about to start.
|
||||
@ -701,84 +699,14 @@ public interface WindowManagerPolicy {
|
||||
* Return whether the screen is currently on.
|
||||
*/
|
||||
public boolean isScreenOn();
|
||||
|
||||
|
||||
/**
|
||||
* Perform any initial processing of a low-level input event before the
|
||||
* window manager handles special keys and generates a high-level event
|
||||
* that is dispatched to the application.
|
||||
*
|
||||
* @param event The input event that has occurred.
|
||||
*
|
||||
* @return Return true if you have consumed the event and do not want
|
||||
* further processing to occur; return false for normal processing.
|
||||
* Tell the policy that the lid switch has changed state.
|
||||
* @param whenNanos The time when the change occurred in uptime nanoseconds.
|
||||
* @param lidOpen True if the lid is now open.
|
||||
*/
|
||||
public boolean preprocessInputEventTq(RawInputEvent event);
|
||||
|
||||
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
|
||||
|
||||
/**
|
||||
* Determine whether a given key code is used to cause an app switch
|
||||
* to occur (most often the HOME key, also often ENDCALL). If you return
|
||||
* true, then the system will go into a special key processing state
|
||||
* where it drops any pending events that it cans and adjusts timeouts to
|
||||
* try to get to this key as quickly as possible.
|
||||
*
|
||||
* <p>Note that this function is called from the low-level input queue
|
||||
* thread, with either/or the window or input lock held; be very careful
|
||||
* about what you do here. You absolutely should never acquire a lock
|
||||
* that you would ever hold elsewhere while calling out into the window
|
||||
* manager or view hierarchy.
|
||||
*
|
||||
* @param keycode The key that should be checked for performing an
|
||||
* app switch before delivering to the application.
|
||||
*
|
||||
* @return Return true if this is an app switch key and special processing
|
||||
* should happen; return false for normal processing.
|
||||
*/
|
||||
public boolean isAppSwitchKeyTqTiLwLi(int keycode);
|
||||
|
||||
/**
|
||||
* Determine whether a given key code is used for movement within a UI,
|
||||
* and does not generally cause actions to be performed (normally the DPAD
|
||||
* movement keys, NOT the DPAD center press key). This is called
|
||||
* when {@link #isAppSwitchKeyTiLi} returns true to remove any pending events
|
||||
* in the key queue that are not needed to switch applications.
|
||||
*
|
||||
* <p>Note that this function is called from the low-level input queue
|
||||
* thread; be very careful about what you do here.
|
||||
*
|
||||
* @param keycode The key that is waiting to be delivered to the
|
||||
* application.
|
||||
*
|
||||
* @return Return true if this is a purely navigation key and can be
|
||||
* dropped without negative consequences; return false to keep it.
|
||||
*/
|
||||
public boolean isMovementKeyTi(int keycode);
|
||||
|
||||
/**
|
||||
* Given the current state of the world, should this relative movement
|
||||
* wake up the device?
|
||||
*
|
||||
* @param device The device the movement came from.
|
||||
* @param classes The input classes associated with the device.
|
||||
* @param event The input event that occurred.
|
||||
* @return
|
||||
*/
|
||||
public boolean isWakeRelMovementTq(int device, int classes,
|
||||
RawInputEvent event);
|
||||
|
||||
/**
|
||||
* Given the current state of the world, should this absolute movement
|
||||
* wake up the device?
|
||||
*
|
||||
* @param device The device the movement came from.
|
||||
* @param classes The input classes associated with the device.
|
||||
* @param event The input event that occurred.
|
||||
* @return
|
||||
*/
|
||||
public boolean isWakeAbsMovementTq(int device, int classes,
|
||||
RawInputEvent event);
|
||||
|
||||
/**
|
||||
* Tell the policy if anyone is requesting that keyguard not come on.
|
||||
*
|
||||
@ -851,18 +779,6 @@ public interface WindowManagerPolicy {
|
||||
*/
|
||||
public void enableScreenAfterBoot();
|
||||
|
||||
/**
|
||||
* Returns true if the user's cheek has been pressed against the phone. This is
|
||||
* determined by comparing the event's size attribute with a threshold value.
|
||||
* For example for a motion event like down or up or move, if the size exceeds
|
||||
* the threshold, it is considered as cheek press.
|
||||
* @param ev the motion event generated when the cheek is pressed
|
||||
* against the phone
|
||||
* @return Returns true if the user's cheek has been pressed against the phone
|
||||
* screen resulting in an invalid motion event
|
||||
*/
|
||||
public boolean isCheekPressedAgainstScreen(MotionEvent ev);
|
||||
|
||||
/**
|
||||
* Called every time the window manager is dispatching a pointer event.
|
||||
*/
|
||||
@ -875,13 +791,6 @@ public interface WindowManagerPolicy {
|
||||
*/
|
||||
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always);
|
||||
|
||||
/**
|
||||
* A special function that is called from the very low-level input queue
|
||||
* to provide feedback to the user. Currently only called for virtual
|
||||
* keys.
|
||||
*/
|
||||
public void keyFeedbackFromInput(KeyEvent event);
|
||||
|
||||
/**
|
||||
* Called when we have stopped keeping the screen on because a window
|
||||
* requesting this is no longer visible.
|
||||
|
Reference in New Issue
Block a user