Reset touch state when device resets
At any point in time, an input device may be reset. We already generate
cancel events to handle this situation.
However, that's not sufficient.
In this CL, touch state is cleared of all pointers for the device that
is getting reset.
Bug: 273376858
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests --gtest_filter="*NotifyDeviceResetCancelsHoveringStream*"
Change-Id: I66da4f3eec125a6b260ed1478bca00164bb40c9e
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 0741be0..147b7d4 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -3678,6 +3678,30 @@
AllOf(WithMotionAction(ACTION_CANCEL), WithDisplayId(ADISPLAY_ID_DEFAULT)));
}
+TEST_F(InputDispatcherTest, NotifyDeviceResetCancelsHoveringStream) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,
+ "Fake Window", ADISPLAY_ID_DEFAULT);
+
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(10).y(10))
+ .build());
+
+ window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
+
+ // When device reset happens, that hover stream should be terminated with ACTION_HOVER_EXIT
+ mDispatcher->notifyDeviceReset({/*id=*/10, /*eventTime=*/20, DEVICE_ID});
+ window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
+
+ // After the device has been reset, a new hovering stream can be sent to the window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(15).y(15))
+ .build());
+ window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
+}
+
TEST_F(InputDispatcherTest, InterceptKeyByPolicy) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,