Merge "Fix spot not disappear when display id changed"
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 17bbff8..ffc1d8c 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -395,6 +395,10 @@
}
if (changes && resetNeeded) {
+ // If device was reset, cancel touch event and update touch spot state.
+ cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime);
+ mCurrentCookedState.clear();
+ updateTouchSpots();
// Send reset, unless this is the first time the device has been configured,
// in which case the reader will call reset itself after all mappers are ready.
NotifyDeviceResetArgs args(getContext()->getNextId(), when, getDeviceId());
@@ -679,6 +683,7 @@
bool skipViewportUpdate = false;
if (viewportChanged) {
bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation;
+ const bool viewportDisplayIdChanged = mViewport.displayId != newViewport->displayId;
mViewport = *newViewport;
if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) {
@@ -792,6 +797,8 @@
mSurfaceTop = 0;
mSurfaceOrientation = DISPLAY_ORIENTATION_0;
}
+ // If displayId changed, do not skip viewport update.
+ skipViewportUpdate &= !viewportDisplayIdChanged;
}
// If moving between pointer modes, need to reset some state.
@@ -1927,6 +1934,10 @@
}
void TouchInputMapper::abortTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) {
+ if (mCurrentMotionAborted) {
+ // Current motion event was already aborted.
+ return;
+ }
BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
if (!currentIdBits.isEmpty()) {
int32_t metaState = getContext()->getGlobalMetaState();
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 0d5d06a..38e328b 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -6251,6 +6251,36 @@
toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
}
+TEST_F(SingleTouchInputMapperTest,
+ Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
+ NotifyMotionArgs motionArgs;
+
+ // Down.
+ int32_t x = 100;
+ int32_t y = 200;
+ processDown(mapper, x, y);
+ processSync(mapper);
+
+ // We should receive a down event
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+
+ // Change display id
+ clearViewports();
+ prepareSecondaryDisplay(ViewportType::INTERNAL);
+
+ // We should receive a cancel event
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
+ // Then receive reset called
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
+}
+
// --- MultiTouchInputMapperTest ---
class MultiTouchInputMapperTest : public TouchInputMapperTest {
@@ -8072,6 +8102,10 @@
// window's coordinate space.
frames[0].rotate(getInverseRotation(orientation));
ASSERT_EQ(frames, motionArgs.videoFrames);
+
+ // Release finger.
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
}
}