Generate key events for stylus button presses
Ensure all devices that report stylus buttons are categorized as a
keyboard. This means that KeyboardInputMapper will get a chance to
handle the events from these devices.
Then, we allow KeyboardInputMapper to process stylus button events.
Since stylus button (e.g. BTN_STYLUS) are mapped to Android key codes in
the Generic.kl file, KeyEvents with the appropriate key codes will be
generated for these button presses.
Bug: 246394583
Test: atest inputflinger_tests
Change-Id: I92d4a60f23f98f9d239edf1f4dd400e6e528e350
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 18d03f8..eaa6f5c 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -2171,13 +2171,15 @@
device->readDeviceBitMask(EVIOCGBIT(EV_MSC, 0), device->mscBitmask);
device->readDeviceBitMask(EVIOCGPROP(0), device->propBitmask);
- // See if this is a keyboard. Ignore everything in the button range except for
- // joystick and gamepad buttons which are handled like keyboards for the most part.
+ // See if this is a device with keys. This could be full keyboard, or other devices like
+ // gamepads, joysticks, and styluses with buttons that should generate key presses.
bool haveKeyboardKeys =
device->keyBitmask.any(0, BTN_MISC) || device->keyBitmask.any(BTN_WHEEL, KEY_MAX + 1);
bool haveGamepadButtons = device->keyBitmask.any(BTN_MISC, BTN_MOUSE) ||
device->keyBitmask.any(BTN_JOYSTICK, BTN_DIGI);
- if (haveKeyboardKeys || haveGamepadButtons) {
+ bool haveStylusButtons = device->keyBitmask.test(BTN_STYLUS) ||
+ device->keyBitmask.test(BTN_STYLUS2) || device->keyBitmask.test(BTN_STYLUS3);
+ if (haveKeyboardKeys || haveGamepadButtons || haveStylusButtons) {
device->classes |= InputDeviceClass::KEYBOARD;
}
@@ -2208,14 +2210,10 @@
} else if (device->keyBitmask.test(BTN_TOUCH) && device->absBitmask.test(ABS_X) &&
device->absBitmask.test(ABS_Y)) {
device->classes |= InputDeviceClass::TOUCH;
- // Is this a BT stylus?
+ // Is this a stylus that reports contact/pressure independently of touch coordinates?
} else if ((device->absBitmask.test(ABS_PRESSURE) || device->keyBitmask.test(BTN_TOUCH)) &&
!device->absBitmask.test(ABS_X) && !device->absBitmask.test(ABS_Y)) {
device->classes |= InputDeviceClass::EXTERNAL_STYLUS;
- // Keyboard will try to claim some of the buttons but we really want to reserve those so we
- // can fuse it with the touch screen data, so just take them back. Note this means an
- // external stylus cannot also be a keyboard device.
- device->classes &= ~InputDeviceClass::KEYBOARD;
}
// See if this device is a joystick.