PointerChoreographer: Reset stylus icon on HOVER_EXIT
Unlike mouse and touchpad, a stylus pointer doesn't always move
"continuously" across the screen. It can jump from one place to another
by exiting hover at one location and entering hover in a different
place. When it first hovers in a new location, the same icon would have
been used in the new place as in the previous location until the app in
the new location specifies a new icon. If the app wants to show a
different icon, this can result in the old icon "flashing" for a short
period before it is updated.
To eliminate the flashing of the old icon, we will reset the icon on
HOVER_EXIT to the unspecified type.
Bug: 298074290
Test: manual
Test: atest inputflinger_tests
Change-Id: Ifdc7d999d39f2620b5ff91025b2d24ee2e23e4b9
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index 0be4c32..4571ef4 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -222,6 +222,7 @@
pc.setPosition(x, y);
if (args.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
pc.fade(PointerControllerInterface::Transition::IMMEDIATE);
+ pc.updatePointerIcon(PointerIconStyle::TYPE_NOT_SPECIFIED);
} else {
pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
}
diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp
index 86853bc..1ac043c 100644
--- a/services/inputflinger/tests/PointerChoreographer_test.cpp
+++ b/services/inputflinger/tests/PointerChoreographer_test.cpp
@@ -1447,6 +1447,15 @@
ASSERT_FALSE(mChoreographer.setPointerIcon(PointerIconStyle::TYPE_TEXT, DISPLAY_ID,
SECOND_DEVICE_ID));
pc->assertPointerIconNotSet();
+
+ // The stylus stops hovering. This should cause the icon to be reset.
+ mChoreographer.notifyMotion(
+ MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT, AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertPointerIconSet(PointerIconStyle::TYPE_NOT_SPECIFIED);
}
TEST_F(PointerChoreographerTest, SetsCustomPointerIconForStylus) {