Loading core/java/android/view/InputEventAssigner.java +17 −26 Original line number Original line Diff line number Diff line Loading @@ -45,13 +45,13 @@ import static android.view.InputDevice.SOURCE_TOUCHSCREEN; public class InputEventAssigner { public class InputEventAssigner { private static final String TAG = "InputEventAssigner"; private static final String TAG = "InputEventAssigner"; private boolean mHasUnprocessedDown = false; private boolean mHasUnprocessedDown = false; private int mEventId = INVALID_INPUT_EVENT_ID; private int mDownEventId = INVALID_INPUT_EVENT_ID; /** /** * Notify InputEventAssigner that the Choreographer callback has been processed. This will reset * Notify InputEventAssigner that a frame has been processed. We no longer need to keep track of * the 'down' state to assign the latest input event to the current frame. * the DOWN event because a frame has already been produced for it. */ */ public void onChoreographerCallback() { public void notifyFrameProcessed() { // Mark completion of this frame. Use newest input event from now on. // Mark completion of this frame. Use newest input event from now on. mHasUnprocessedDown = false; mHasUnprocessedDown = false; } } Loading @@ -62,31 +62,22 @@ public class InputEventAssigner { * @return the id of the input event to use for the current frame * @return the id of the input event to use for the current frame */ */ public int processEvent(InputEvent event) { public int processEvent(InputEvent event) { if (event instanceof KeyEvent) { // We will not do any special handling for key events return event.getId(); } if (event instanceof MotionEvent) { if (event instanceof MotionEvent) { MotionEvent motionEvent = (MotionEvent) event; MotionEvent motionEvent = (MotionEvent) event; if (motionEvent.isFromSource(SOURCE_TOUCHSCREEN)) { final int action = motionEvent.getActionMasked(); final int action = motionEvent.getActionMasked(); if (action == MotionEvent.ACTION_DOWN) { mHasUnprocessedDown = true; mDownEventId = event.getId(); } if (mHasUnprocessedDown && action == MotionEvent.ACTION_MOVE) { return mDownEventId; } if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { mHasUnprocessedDown = false; mHasUnprocessedDown = false; } } if (motionEvent.isFromSource(SOURCE_TOUCHSCREEN) && action == MotionEvent.ACTION_DOWN) { mHasUnprocessedDown = true; mEventId = event.getId(); // This will remain 'true' even if we receive a MOVE event, as long as choreographer // hasn't invoked the 'CALLBACK_INPUT' callback. } // Don't update the event id if we haven't processed DOWN yet. if (!mHasUnprocessedDown) { mEventId = event.getId(); } } return mEventId; } } return event.getId(); throw new IllegalArgumentException("Received unexpected " + event); } } } } core/java/android/view/ViewRootImpl.java +1 −5 Original line number Original line Diff line number Diff line Loading @@ -474,6 +474,7 @@ public final class ViewRootImpl implements ViewParent, FrameInfo frameInfo = mChoreographer.mFrameInfo; FrameInfo frameInfo = mChoreographer.mFrameInfo; mViewFrameInfo.populateFrameInfo(frameInfo); mViewFrameInfo.populateFrameInfo(frameInfo); mViewFrameInfo.reset(); mViewFrameInfo.reset(); mInputEventAssigner.notifyFrameProcessed(); return frameInfo; return frameInfo; } } Loading Loading @@ -8502,11 +8503,6 @@ public final class ViewRootImpl implements ViewParent, consumedBatches = false; consumedBatches = false; } } doProcessInputEvents(); doProcessInputEvents(); if (consumedBatches) { // Must be done after we processed the input events, to mark the completion of the frame // from the input point of view mInputEventAssigner.onChoreographerCallback(); } return consumedBatches; return consumedBatches; } } Loading tests/Input/src/com/android/test/input/InputEventAssignerTest.kt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -87,7 +87,7 @@ class InputEventAssignerTest { assertEquals(down.id, eventId) assertEquals(down.id, eventId) // Now send CALLBACK_INPUT to the assigner. It should provide the latest motion event // Now send CALLBACK_INPUT to the assigner. It should provide the latest motion event assigner.onChoreographerCallback() assigner.notifyFrameProcessed() eventId = assigner.processEvent(move3) eventId = assigner.processEvent(move3) assertEquals(move3.id, eventId) assertEquals(move3.id, eventId) eventId = assigner.processEvent(move4) eventId = assigner.processEvent(move4) Loading Loading @@ -122,7 +122,7 @@ class InputEventAssignerTest { eventId = assigner.processEvent(up) eventId = assigner.processEvent(up) // DOWN is only sticky for Motions, not for keys // DOWN is only sticky for Motions, not for keys assertEquals(up.id, eventId) assertEquals(up.id, eventId) assigner.onChoreographerCallback() assigner.notifyFrameProcessed() val down2 = createKeyEvent(KeyEvent.ACTION_DOWN, 22) val down2 = createKeyEvent(KeyEvent.ACTION_DOWN, 22) eventId = assigner.processEvent(down2) eventId = assigner.processEvent(down2) assertEquals(down2.id, eventId) assertEquals(down2.id, eventId) Loading Loading
core/java/android/view/InputEventAssigner.java +17 −26 Original line number Original line Diff line number Diff line Loading @@ -45,13 +45,13 @@ import static android.view.InputDevice.SOURCE_TOUCHSCREEN; public class InputEventAssigner { public class InputEventAssigner { private static final String TAG = "InputEventAssigner"; private static final String TAG = "InputEventAssigner"; private boolean mHasUnprocessedDown = false; private boolean mHasUnprocessedDown = false; private int mEventId = INVALID_INPUT_EVENT_ID; private int mDownEventId = INVALID_INPUT_EVENT_ID; /** /** * Notify InputEventAssigner that the Choreographer callback has been processed. This will reset * Notify InputEventAssigner that a frame has been processed. We no longer need to keep track of * the 'down' state to assign the latest input event to the current frame. * the DOWN event because a frame has already been produced for it. */ */ public void onChoreographerCallback() { public void notifyFrameProcessed() { // Mark completion of this frame. Use newest input event from now on. // Mark completion of this frame. Use newest input event from now on. mHasUnprocessedDown = false; mHasUnprocessedDown = false; } } Loading @@ -62,31 +62,22 @@ public class InputEventAssigner { * @return the id of the input event to use for the current frame * @return the id of the input event to use for the current frame */ */ public int processEvent(InputEvent event) { public int processEvent(InputEvent event) { if (event instanceof KeyEvent) { // We will not do any special handling for key events return event.getId(); } if (event instanceof MotionEvent) { if (event instanceof MotionEvent) { MotionEvent motionEvent = (MotionEvent) event; MotionEvent motionEvent = (MotionEvent) event; if (motionEvent.isFromSource(SOURCE_TOUCHSCREEN)) { final int action = motionEvent.getActionMasked(); final int action = motionEvent.getActionMasked(); if (action == MotionEvent.ACTION_DOWN) { mHasUnprocessedDown = true; mDownEventId = event.getId(); } if (mHasUnprocessedDown && action == MotionEvent.ACTION_MOVE) { return mDownEventId; } if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { mHasUnprocessedDown = false; mHasUnprocessedDown = false; } } if (motionEvent.isFromSource(SOURCE_TOUCHSCREEN) && action == MotionEvent.ACTION_DOWN) { mHasUnprocessedDown = true; mEventId = event.getId(); // This will remain 'true' even if we receive a MOVE event, as long as choreographer // hasn't invoked the 'CALLBACK_INPUT' callback. } // Don't update the event id if we haven't processed DOWN yet. if (!mHasUnprocessedDown) { mEventId = event.getId(); } } return mEventId; } } return event.getId(); throw new IllegalArgumentException("Received unexpected " + event); } } } }
core/java/android/view/ViewRootImpl.java +1 −5 Original line number Original line Diff line number Diff line Loading @@ -474,6 +474,7 @@ public final class ViewRootImpl implements ViewParent, FrameInfo frameInfo = mChoreographer.mFrameInfo; FrameInfo frameInfo = mChoreographer.mFrameInfo; mViewFrameInfo.populateFrameInfo(frameInfo); mViewFrameInfo.populateFrameInfo(frameInfo); mViewFrameInfo.reset(); mViewFrameInfo.reset(); mInputEventAssigner.notifyFrameProcessed(); return frameInfo; return frameInfo; } } Loading Loading @@ -8502,11 +8503,6 @@ public final class ViewRootImpl implements ViewParent, consumedBatches = false; consumedBatches = false; } } doProcessInputEvents(); doProcessInputEvents(); if (consumedBatches) { // Must be done after we processed the input events, to mark the completion of the frame // from the input point of view mInputEventAssigner.onChoreographerCallback(); } return consumedBatches; return consumedBatches; } } Loading
tests/Input/src/com/android/test/input/InputEventAssignerTest.kt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -87,7 +87,7 @@ class InputEventAssignerTest { assertEquals(down.id, eventId) assertEquals(down.id, eventId) // Now send CALLBACK_INPUT to the assigner. It should provide the latest motion event // Now send CALLBACK_INPUT to the assigner. It should provide the latest motion event assigner.onChoreographerCallback() assigner.notifyFrameProcessed() eventId = assigner.processEvent(move3) eventId = assigner.processEvent(move3) assertEquals(move3.id, eventId) assertEquals(move3.id, eventId) eventId = assigner.processEvent(move4) eventId = assigner.processEvent(move4) Loading Loading @@ -122,7 +122,7 @@ class InputEventAssignerTest { eventId = assigner.processEvent(up) eventId = assigner.processEvent(up) // DOWN is only sticky for Motions, not for keys // DOWN is only sticky for Motions, not for keys assertEquals(up.id, eventId) assertEquals(up.id, eventId) assigner.onChoreographerCallback() assigner.notifyFrameProcessed() val down2 = createKeyEvent(KeyEvent.ACTION_DOWN, 22) val down2 = createKeyEvent(KeyEvent.ACTION_DOWN, 22) eventId = assigner.processEvent(down2) eventId = assigner.processEvent(down2) assertEquals(down2.id, eventId) assertEquals(down2.id, eventId) Loading