Loading services/inputflinger/dispatcher/InputDispatcher.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -3165,6 +3165,9 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio } dispatchEntry->resolvedFlags = motionEntry.flags; if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_CANCEL) { dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED; } if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) { dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; } Loading services/inputflinger/dispatcher/InputState.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -289,13 +289,16 @@ std::vector<std::unique_ptr<EventEntry>> InputState::synthesizeCancelationEvents if (options.pointerIds == std::nullopt) { const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL; int32_t flags = memento.flags; if (action == AMOTION_EVENT_ACTION_CANCEL) { flags |= AMOTION_EVENT_FLAG_CANCELED; } events.push_back( std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId, memento.source, memento.displayId, memento.policyFlags, action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, action, 0 /*actionButton*/, flags, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision, memento.yPrecision, memento.xCursorPosition, Loading Loading @@ -388,11 +391,15 @@ std::vector<std::unique_ptr<MotionEntry>> InputState::synthesizeCancelationEvent if (canceledPointerIndices.size() == memento.pointerCount) { const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL; int32_t flags = memento.flags; if (action == AMOTION_EVENT_ACTION_CANCEL) { flags |= AMOTION_EVENT_FLAG_CANCELED; } events.push_back( std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId, memento.source, memento.displayId, memento.policyFlags, action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/, flags, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision, memento.yPrecision, memento.xCursorPosition, Loading @@ -400,7 +407,7 @@ std::vector<std::unique_ptr<MotionEntry>> InputState::synthesizeCancelationEvent memento.pointerCount, memento.pointerProperties, memento.pointerCoords)); } else { // If we aren't canceling all pointers, we need to generated ACTION_POINTER_UP with // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with // FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the // previously canceled pointers from PointerProperties and PointerCoords, and update // pointerCount appropriately. For convenience, sort the canceled pointer indices so that we Loading services/inputflinger/tests/InputDispatcher_test.cpp +48 −15 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ static constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT; static constexpr int32_t SECOND_DISPLAY_ID = 1; static constexpr int32_t ACTION_OUTSIDE = AMOTION_EVENT_ACTION_OUTSIDE; static constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL; static constexpr int32_t POINTER_1_DOWN = AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); static constexpr int32_t POINTER_2_DOWN = Loading Loading @@ -139,12 +140,20 @@ MATCHER_P(WithDownTime, downTime, "InputEvent with specified downTime") { return arg.getDownTime() == downTime; } MATCHER_P(WithDisplayId, displayId, "InputEvent with specified displayId") { return arg.getDisplayId() == displayId; } MATCHER_P(WithSource, source, "InputEvent with specified source") { *result_listener << "expected source " << inputEventSourceToString(source) << ", but got " << inputEventSourceToString(arg.getSource()); return arg.getSource() == source; } MATCHER_P(WithFlags, flags, "InputEvent with specified flags") { return arg.getFlags() == flags; } MATCHER_P2(WithCoords, x, y, "MotionEvent with specified coordinates") { if (arg.getPointerCount() != 1) { *result_listener << "Expected 1 pointer, got " << arg.getPointerCount(); Loading Loading @@ -944,6 +953,28 @@ public: } } MotionEvent* consumeMotion() { InputEvent* event = consume(); if (event == nullptr) { ADD_FAILURE() << mName << ": expected a MotionEvent, but didn't get one."; return nullptr; } if (event->getType() != AINPUT_EVENT_TYPE_MOTION) { ADD_FAILURE() << mName << " expected a MotionEvent, got " << inputEventTypeToString(event->getType()) << " event"; return nullptr; } return static_cast<MotionEvent*>(event); } void consumeMotionEvent(const ::testing::Matcher<MotionEvent>& matcher) { MotionEvent* motionEvent = consumeMotion(); ASSERT_NE(nullptr, motionEvent) << "Did not get a motion event, but expected " << matcher; ASSERT_THAT(*motionEvent, matcher); } void consumeFocusEvent(bool hasFocus, bool inTouchMode) { InputEvent* event = consume(); ASSERT_NE(nullptr, event) << mName.c_str() Loading Loading @@ -1196,14 +1227,14 @@ public: void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) { consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId, expectedFlags); consumeMotionEvent(AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(expectedDisplayId), WithFlags(expectedFlags | AMOTION_EVENT_FLAG_CANCELED))); } void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) { consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId, expectedFlags); consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithDisplayId(expectedDisplayId), WithFlags(expectedFlags))); } void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, Loading Loading @@ -2546,8 +2577,8 @@ TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) { // on the app side. NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID); mDispatcher->notifyDeviceReset(&args); window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*expectedFlags*/); window->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); } TEST_F(InputDispatcherTest, InterceptKeyByPolicy) { Loading Loading @@ -3544,8 +3575,10 @@ public: } void consumeMotionCancel(int32_t expectedDisplayId, int32_t expectedFlags = 0) { mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId, expectedFlags); mInputReceiver->consumeMotionEvent( AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL), WithDisplayId(expectedDisplayId), WithFlags(expectedFlags | AMOTION_EVENT_FLAG_CANCELED))); } void consumeMotionPointerDown(int32_t pointerIdx) { Loading Loading @@ -5109,8 +5142,8 @@ TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) { mFakePolicy->assertNotifyWindowUnresponsiveWasCalled(timeout, mWindow); mWindow->finishEvent(*sequenceNum); mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*flags*/); mWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyWindowResponsiveWasCalled(mWindow->getToken(), mWindow->getPid()); } Loading Loading @@ -5277,8 +5310,8 @@ TEST_F(InputDispatcherSingleWindowAnr, SpyWindowAnr) { mFakePolicy->assertNotifyWindowUnresponsiveWasCalled(timeout, spy); spy->finishEvent(*sequenceNum); spy->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*flags*/); spy->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyWindowResponsiveWasCalled(spy->getToken(), mWindow->getPid()); } Loading Loading @@ -5400,8 +5433,8 @@ TEST_F(InputDispatcherSingleWindowAnr, Policy_DoesNotGetDuplicateAnr) { mFakePolicy->assertNotifyAnrWasNotCalled(); // When the ANR happened, dispatcher should abort the current event stream via ACTION_CANCEL mWindow->consumeMotionDown(); mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*flags*/); mWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); mWindow->assertNoEvents(); mDispatcher->waitForIdle(); mFakePolicy->assertNotifyWindowResponsiveWasCalled(mWindow->getToken(), mWindow->getPid()); Loading Loading @@ -7768,7 +7801,7 @@ TEST_F(InputDispatcherPilferPointersTest, ContinuesToReceiveGestureAfterPilfer) ASSERT_EQ(InputEventInjectionResult::FAILED, injectMotionEvent(mDispatcher, thirdFingerDownEvent, INJECT_EVENT_TIMEOUT, InputEventInjectionSync::WAIT_FOR_RESULT)) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; << "Inject motion event should return InputEventInjectionResult::FAILED"; spy->assertNoEvents(); window->assertNoEvents(); Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -3165,6 +3165,9 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio } dispatchEntry->resolvedFlags = motionEntry.flags; if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_CANCEL) { dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED; } if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) { dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; } Loading
services/inputflinger/dispatcher/InputState.cpp +12 −5 Original line number Diff line number Diff line Loading @@ -289,13 +289,16 @@ std::vector<std::unique_ptr<EventEntry>> InputState::synthesizeCancelationEvents if (options.pointerIds == std::nullopt) { const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL; int32_t flags = memento.flags; if (action == AMOTION_EVENT_ACTION_CANCEL) { flags |= AMOTION_EVENT_FLAG_CANCELED; } events.push_back( std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId, memento.source, memento.displayId, memento.policyFlags, action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, action, 0 /*actionButton*/, flags, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision, memento.yPrecision, memento.xCursorPosition, Loading Loading @@ -388,11 +391,15 @@ std::vector<std::unique_ptr<MotionEntry>> InputState::synthesizeCancelationEvent if (canceledPointerIndices.size() == memento.pointerCount) { const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL; int32_t flags = memento.flags; if (action == AMOTION_EVENT_ACTION_CANCEL) { flags |= AMOTION_EVENT_FLAG_CANCELED; } events.push_back( std::make_unique<MotionEntry>(mIdGenerator.nextId(), currentTime, memento.deviceId, memento.source, memento.displayId, memento.policyFlags, action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/, flags, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision, memento.yPrecision, memento.xCursorPosition, Loading @@ -400,7 +407,7 @@ std::vector<std::unique_ptr<MotionEntry>> InputState::synthesizeCancelationEvent memento.pointerCount, memento.pointerProperties, memento.pointerCoords)); } else { // If we aren't canceling all pointers, we need to generated ACTION_POINTER_UP with // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with // FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the // previously canceled pointers from PointerProperties and PointerCoords, and update // pointerCount appropriately. For convenience, sort the canceled pointer indices so that we Loading
services/inputflinger/tests/InputDispatcher_test.cpp +48 −15 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ static constexpr int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT; static constexpr int32_t SECOND_DISPLAY_ID = 1; static constexpr int32_t ACTION_OUTSIDE = AMOTION_EVENT_ACTION_OUTSIDE; static constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL; static constexpr int32_t POINTER_1_DOWN = AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); static constexpr int32_t POINTER_2_DOWN = Loading Loading @@ -139,12 +140,20 @@ MATCHER_P(WithDownTime, downTime, "InputEvent with specified downTime") { return arg.getDownTime() == downTime; } MATCHER_P(WithDisplayId, displayId, "InputEvent with specified displayId") { return arg.getDisplayId() == displayId; } MATCHER_P(WithSource, source, "InputEvent with specified source") { *result_listener << "expected source " << inputEventSourceToString(source) << ", but got " << inputEventSourceToString(arg.getSource()); return arg.getSource() == source; } MATCHER_P(WithFlags, flags, "InputEvent with specified flags") { return arg.getFlags() == flags; } MATCHER_P2(WithCoords, x, y, "MotionEvent with specified coordinates") { if (arg.getPointerCount() != 1) { *result_listener << "Expected 1 pointer, got " << arg.getPointerCount(); Loading Loading @@ -944,6 +953,28 @@ public: } } MotionEvent* consumeMotion() { InputEvent* event = consume(); if (event == nullptr) { ADD_FAILURE() << mName << ": expected a MotionEvent, but didn't get one."; return nullptr; } if (event->getType() != AINPUT_EVENT_TYPE_MOTION) { ADD_FAILURE() << mName << " expected a MotionEvent, got " << inputEventTypeToString(event->getType()) << " event"; return nullptr; } return static_cast<MotionEvent*>(event); } void consumeMotionEvent(const ::testing::Matcher<MotionEvent>& matcher) { MotionEvent* motionEvent = consumeMotion(); ASSERT_NE(nullptr, motionEvent) << "Did not get a motion event, but expected " << matcher; ASSERT_THAT(*motionEvent, matcher); } void consumeFocusEvent(bool hasFocus, bool inTouchMode) { InputEvent* event = consume(); ASSERT_NE(nullptr, event) << mName.c_str() Loading Loading @@ -1196,14 +1227,14 @@ public: void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) { consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId, expectedFlags); consumeMotionEvent(AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(expectedDisplayId), WithFlags(expectedFlags | AMOTION_EVENT_FLAG_CANCELED))); } void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) { consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId, expectedFlags); consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithDisplayId(expectedDisplayId), WithFlags(expectedFlags))); } void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, Loading Loading @@ -2546,8 +2577,8 @@ TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) { // on the app side. NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID); mDispatcher->notifyDeviceReset(&args); window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*expectedFlags*/); window->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); } TEST_F(InputDispatcherTest, InterceptKeyByPolicy) { Loading Loading @@ -3544,8 +3575,10 @@ public: } void consumeMotionCancel(int32_t expectedDisplayId, int32_t expectedFlags = 0) { mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId, expectedFlags); mInputReceiver->consumeMotionEvent( AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL), WithDisplayId(expectedDisplayId), WithFlags(expectedFlags | AMOTION_EVENT_FLAG_CANCELED))); } void consumeMotionPointerDown(int32_t pointerIdx) { Loading Loading @@ -5109,8 +5142,8 @@ TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) { mFakePolicy->assertNotifyWindowUnresponsiveWasCalled(timeout, mWindow); mWindow->finishEvent(*sequenceNum); mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*flags*/); mWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyWindowResponsiveWasCalled(mWindow->getToken(), mWindow->getPid()); } Loading Loading @@ -5277,8 +5310,8 @@ TEST_F(InputDispatcherSingleWindowAnr, SpyWindowAnr) { mFakePolicy->assertNotifyWindowUnresponsiveWasCalled(timeout, spy); spy->finishEvent(*sequenceNum); spy->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*flags*/); spy->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); ASSERT_TRUE(mDispatcher->waitForIdle()); mFakePolicy->assertNotifyWindowResponsiveWasCalled(spy->getToken(), mWindow->getPid()); } Loading Loading @@ -5400,8 +5433,8 @@ TEST_F(InputDispatcherSingleWindowAnr, Policy_DoesNotGetDuplicateAnr) { mFakePolicy->assertNotifyAnrWasNotCalled(); // When the ANR happened, dispatcher should abort the current event stream via ACTION_CANCEL mWindow->consumeMotionDown(); mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT, 0 /*flags*/); mWindow->consumeMotionEvent( AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT))); mWindow->assertNoEvents(); mDispatcher->waitForIdle(); mFakePolicy->assertNotifyWindowResponsiveWasCalled(mWindow->getToken(), mWindow->getPid()); Loading Loading @@ -7768,7 +7801,7 @@ TEST_F(InputDispatcherPilferPointersTest, ContinuesToReceiveGestureAfterPilfer) ASSERT_EQ(InputEventInjectionResult::FAILED, injectMotionEvent(mDispatcher, thirdFingerDownEvent, INJECT_EVENT_TIMEOUT, InputEventInjectionSync::WAIT_FOR_RESULT)) << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; << "Inject motion event should return InputEventInjectionResult::FAILED"; spy->assertNoEvents(); window->assertNoEvents(); Loading