Merge "Enforce serial ordering of MotionEvents." into gingerbread

This commit is contained in:
Jeff Brown
2010-09-23 14:51:52 -07:00
committed by Android (Google) Code Review
2 changed files with 48 additions and 20 deletions

View File

@@ -1876,6 +1876,9 @@ public final class ViewRoot extends Handler implements ViewParent,
deliverPointerEvent(event); deliverPointerEvent(event);
} finally { } finally {
event.recycle(); event.recycle();
if (msg.arg1 != 0) {
finishInputEvent();
}
if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!"); if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!");
} }
} break; } break;
@@ -1885,6 +1888,9 @@ public final class ViewRoot extends Handler implements ViewParent,
deliverTrackballEvent(event); deliverTrackballEvent(event);
} finally { } finally {
event.recycle(); event.recycle();
if (msg.arg1 != 0) {
finishInputEvent();
}
} }
} break; } break;
case DISPATCH_APP_VISIBILITY: case DISPATCH_APP_VISIBILITY:
@@ -2019,15 +2025,24 @@ public final class ViewRoot extends Handler implements ViewParent,
} }
} }
private void finishKeyEvent(KeyEvent event) { private void startInputEvent(Runnable finishedCallback) {
if (LOCAL_LOGV) Log.v(TAG, "Telling window manager key is finished"); if (mFinishedCallback != null) {
Slog.w(TAG, "Received a new input event from the input queue but there is "
+ "already an unfinished input event in progress.");
}
mFinishedCallback = finishedCallback;
}
private void finishInputEvent() {
if (LOCAL_LOGV) Log.v(TAG, "Telling window manager input event is finished");
if (mFinishedCallback != null) { if (mFinishedCallback != null) {
mFinishedCallback.run(); mFinishedCallback.run();
mFinishedCallback = null; mFinishedCallback = null;
} else { } else {
Slog.w(TAG, "Attempted to tell the input queue that the current key event " Slog.w(TAG, "Attempted to tell the input queue that the current input event "
+ "is finished but there is no key event actually in progress."); + "is finished but there is no input event actually in progress.");
} }
} }
@@ -2487,7 +2502,7 @@ public final class ViewRoot extends Handler implements ViewParent,
? mView.dispatchKeyEventPreIme(event) : true; ? mView.dispatchKeyEventPreIme(event) : true;
if (handled) { if (handled) {
if (sendDone) { if (sendDone) {
finishKeyEvent(event); finishInputEvent();
} }
return; return;
} }
@@ -2518,7 +2533,7 @@ public final class ViewRoot extends Handler implements ViewParent,
deliverKeyEventToViewHierarchy(event, sendDone); deliverKeyEventToViewHierarchy(event, sendDone);
return; return;
} else if (sendDone) { } else if (sendDone) {
finishKeyEvent(event); finishInputEvent();
} else { } else {
Log.w(TAG, "handleFinishedEvent(seq=" + seq Log.w(TAG, "handleFinishedEvent(seq=" + seq
+ " handled=" + handled + " ev=" + event + " handled=" + handled + " ev=" + event
@@ -2591,7 +2606,7 @@ public final class ViewRoot extends Handler implements ViewParent,
} finally { } finally {
if (sendDone) { if (sendDone) {
finishKeyEvent(event); finishInputEvent();
} }
// Let the exception fall through -- the looper will catch // Let the exception fall through -- the looper will catch
// it and take care of the bad app for us. // it and take care of the bad app for us.
@@ -2774,20 +2789,13 @@ 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) {
if (mFinishedCallback != null) { startInputEvent(finishedCallback);
Slog.w(TAG, "Received a new key event from the input queue but there is "
+ "already an unfinished key event in progress.");
}
mFinishedCallback = finishedCallback;
dispatchKey(event, true); dispatchKey(event, true);
} }
public void handleMotion(MotionEvent event, Runnable finishedCallback) { public void handleMotion(MotionEvent event, Runnable finishedCallback) {
finishedCallback.run(); startInputEvent(finishedCallback);
dispatchMotion(event, true);
dispatchMotion(event);
} }
}; };
@@ -2820,26 +2828,43 @@ public final class ViewRoot extends Handler implements ViewParent,
} }
public void dispatchMotion(MotionEvent event) { public void dispatchMotion(MotionEvent event) {
dispatchMotion(event, false);
}
private void dispatchMotion(MotionEvent event, boolean sendDone) {
int source = event.getSource(); int source = event.getSource();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) { if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
dispatchPointer(event); dispatchPointer(event, sendDone);
} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) { } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
dispatchTrackball(event); dispatchTrackball(event, sendDone);
} else { } else {
// TODO // TODO
Log.v(TAG, "Dropping unsupported motion event (unimplemented): " + event); Log.v(TAG, "Dropping unsupported motion event (unimplemented): " + event);
if (sendDone) {
finishInputEvent();
}
} }
} }
public void dispatchPointer(MotionEvent event) { public void dispatchPointer(MotionEvent event) {
dispatchPointer(event, false);
}
private void dispatchPointer(MotionEvent event, boolean sendDone) {
Message msg = obtainMessage(DISPATCH_POINTER); Message msg = obtainMessage(DISPATCH_POINTER);
msg.obj = event; msg.obj = event;
msg.arg1 = sendDone ? 1 : 0;
sendMessageAtTime(msg, event.getEventTime()); sendMessageAtTime(msg, event.getEventTime());
} }
public void dispatchTrackball(MotionEvent event) { public void dispatchTrackball(MotionEvent event) {
dispatchTrackball(event, false);
}
private void dispatchTrackball(MotionEvent event, boolean sendDone) {
Message msg = obtainMessage(DISPATCH_TRACKBALL); Message msg = obtainMessage(DISPATCH_TRACKBALL);
msg.obj = event; msg.obj = event;
msg.arg1 = sendDone ? 1 : 0;
sendMessageAtTime(msg, event.getEventTime()); sendMessageAtTime(msg, event.getEventTime());
} }

View File

@@ -232,8 +232,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override @Override
public void handleMotion(MotionEvent event, Runnable finishedCallback) { public void handleMotion(MotionEvent event, Runnable finishedCallback) {
finishedCallback.run(); finishedCallback.run();
synchronized (mLock) { synchronized (mLock) {
mPointerLocationView.addTouchEvent(event); if (mPointerLocationView != null) {
mPointerLocationView.addTouchEvent(event);
}
} }
} }
}; };