Merge "Add FLAG_CANCELED for all ACTION_CANCEL events"
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index dc9f02a..5d9ee5f 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3165,6 +3165,9 @@
}
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;
}
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index 563868d..93419a1 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -289,13 +289,16 @@
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,
@@ -388,11 +391,15 @@
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,
@@ -400,7 +407,7 @@
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
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 3abe43a..dfe3d16 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -58,6 +58,7 @@
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 =
@@ -139,12 +140,20 @@
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();
@@ -944,6 +953,28 @@
}
}
+ 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()
@@ -1196,14 +1227,14 @@
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,
@@ -2546,8 +2577,8 @@
// 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) {
@@ -3544,8 +3575,10 @@
}
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) {
@@ -5109,8 +5142,8 @@
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());
}
@@ -5277,8 +5310,8 @@
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());
}
@@ -5400,8 +5433,8 @@
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());
@@ -7768,7 +7801,7 @@
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();