Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93ed4e30 authored by Jeff Brown's avatar Jeff Brown
Browse files

Enforce serial ordering of MotionEvents.

This change modifies ViewRoot to wait until the MotionEvent has been
delivered before telling the input dispatcher that it is finished.
The serial ordering guarantee will be required by new features that
may need to transfer touch focus from one window to another.

Change-Id: I0a64d1f0c8bc3f08846f213d6e28ce48b1d48e58
parent 37cedce1
Loading
Loading
Loading
Loading
+44 −19
Original line number Diff line number Diff line
@@ -1876,6 +1876,9 @@ public final class ViewRoot extends Handler implements ViewParent,
                deliverPointerEvent(event);
            } finally {
                event.recycle();
                if (msg.arg1 != 0) {
                    finishInputEvent();
                }
                if (LOCAL_LOGV || WATCH_POINTER) Log.i(TAG, "Done dispatching!");
            }
        } break;
@@ -1885,6 +1888,9 @@ public final class ViewRoot extends Handler implements ViewParent,
                deliverTrackballEvent(event);
            } finally {
                event.recycle();
                if (msg.arg1 != 0) {
                    finishInputEvent();
                }
            }
        } break;
        case DISPATCH_APP_VISIBILITY:
@@ -2019,15 +2025,24 @@ public final class ViewRoot extends Handler implements ViewParent,
        }
    }
    
    private void finishKeyEvent(KeyEvent event) {
        if (LOCAL_LOGV) Log.v(TAG, "Telling window manager key is finished");
    private void startInputEvent(Runnable finishedCallback) {
        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) {
            mFinishedCallback.run();
            mFinishedCallback = null;
        } else {
            Slog.w(TAG, "Attempted to tell the input queue that the current key event "
                    + "is finished but there is no key event actually in progress.");
            Slog.w(TAG, "Attempted to tell the input queue that the current input event "
                    + "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;
        if (handled) {
            if (sendDone) {
                finishKeyEvent(event);
                finishInputEvent();
            }
            return;
        }
@@ -2518,7 +2533,7 @@ public final class ViewRoot extends Handler implements ViewParent,
                deliverKeyEventToViewHierarchy(event, sendDone);
                return;
            } else if (sendDone) {
                finishKeyEvent(event);
                finishInputEvent();
            } else {
                Log.w(TAG, "handleFinishedEvent(seq=" + seq
                        + " handled=" + handled + " ev=" + event
@@ -2591,7 +2606,7 @@ public final class ViewRoot extends Handler implements ViewParent,

        } finally {
            if (sendDone) {
                finishKeyEvent(event);
                finishInputEvent();
            }
            // Let the exception fall through -- the looper will catch
            // 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() {
        public void handleKey(KeyEvent event, Runnable finishedCallback) {
            if (mFinishedCallback != null) {
                Slog.w(TAG, "Received a new key event from the input queue but there is "
                        + "already an unfinished key event in progress.");
            }

            mFinishedCallback = finishedCallback;

            startInputEvent(finishedCallback);
            dispatchKey(event, true);
        }

        public void handleMotion(MotionEvent event, Runnable finishedCallback) {
            finishedCallback.run();
            
            dispatchMotion(event);
            startInputEvent(finishedCallback);
            dispatchMotion(event, true);
        }
    };

@@ -2820,26 +2828,43 @@ public final class ViewRoot extends Handler implements ViewParent,
    }
    
    public void dispatchMotion(MotionEvent event) {
        dispatchMotion(event, false);
    }

    private void dispatchMotion(MotionEvent event, boolean sendDone) {
        int source = event.getSource();
        if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
            dispatchPointer(event);
            dispatchPointer(event, sendDone);
        } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
            dispatchTrackball(event);
            dispatchTrackball(event, sendDone);
        } else {
            // TODO
            Log.v(TAG, "Dropping unsupported motion event (unimplemented): " + event);
            if (sendDone) {
                finishInputEvent();
            }
        }
    }

    public void dispatchPointer(MotionEvent event) {
        dispatchPointer(event, false);
    }

    private void dispatchPointer(MotionEvent event, boolean sendDone) {
        Message msg = obtainMessage(DISPATCH_POINTER);
        msg.obj = event;
        msg.arg1 = sendDone ? 1 : 0;
        sendMessageAtTime(msg, event.getEventTime());
    }

    public void dispatchTrackball(MotionEvent event) {
        dispatchTrackball(event, false);
    }

    private void dispatchTrackball(MotionEvent event, boolean sendDone) {
        Message msg = obtainMessage(DISPATCH_TRACKBALL);
        msg.obj = event;
        msg.arg1 = sendDone ? 1 : 0;
        sendMessageAtTime(msg, event.getEventTime());
    }
    
+4 −1
Original line number Diff line number Diff line
@@ -232,10 +232,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        @Override
        public void handleMotion(MotionEvent event, Runnable finishedCallback) {
            finishedCallback.run();
            
            synchronized (mLock) {
                if (mPointerLocationView != null) {
                    mPointerLocationView.addTouchEvent(event);
                }
            }
        }
    };
    
    // The current size of the screen.