Merge changes from topic "cherrypicker-L69100000963689907:N98600001416520494" into main
* changes:
Add test to ensure a keyboard with HID usage support is not a stylus
Prevent keyboards from being recognized as a stylus
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 0354164..c468d45 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -2409,7 +2409,8 @@
}
// See if this device has any stylus buttons that we would want to fuse with touch data.
- if (!device->classes.any(InputDeviceClass::TOUCH | InputDeviceClass::TOUCH_MT)) {
+ if (!device->classes.any(InputDeviceClass::TOUCH | InputDeviceClass::TOUCH_MT) &&
+ !device->classes.any(InputDeviceClass::ALPHAKEY)) {
for (int32_t keycode : STYLUS_BUTTON_KEYCODES) {
if (device->hasKeycodeLocked(keycode)) {
device->classes |= InputDeviceClass::EXTERNAL_STYLUS;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 5141acb..38b32b3 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1476,6 +1476,46 @@
AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
}
+TEST_F(InputReaderIntegrationTest, KeyboardWithStylusButtons) {
+ std::unique_ptr<UinputKeyboard> keyboard =
+ createUinputDevice<UinputKeyboard>("KeyboardWithStylusButtons", /*productId=*/99,
+ std::initializer_list<int>{KEY_Q, KEY_W, KEY_E,
+ KEY_R, KEY_T, KEY_Y,
+ BTN_STYLUS, BTN_STYLUS2,
+ BTN_STYLUS3});
+ ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
+
+ const auto device = findDeviceByName(keyboard->getName());
+ ASSERT_TRUE(device.has_value());
+
+ // An alphabetical keyboard that reports stylus buttons should not be recognized as a stylus.
+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
+ << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, device->getKeyboardType());
+}
+
+TEST_F(InputReaderIntegrationTest, HidUsageKeyboardIsNotAStylus) {
+ // Create a Uinput keyboard that simulates a keyboard that can report HID usage codes. The
+ // hid-input driver reports HID usage codes using the value for EV_MSC MSC_SCAN event.
+ std::unique_ptr<UinputKeyboardWithHidUsage> keyboard =
+ createUinputDevice<UinputKeyboardWithHidUsage>(
+ std::initializer_list<int>{KEY_VOLUMEUP, KEY_VOLUMEDOWN});
+ ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
+
+ const auto device = findDeviceByName(keyboard->getName());
+ ASSERT_TRUE(device.has_value());
+
+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
+ << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
+
+ // If a device supports reporting HID usage codes, it shouldn't automatically support
+ // stylus keys.
+ const std::vector<int> keycodes{AKEYCODE_STYLUS_BUTTON_PRIMARY};
+ uint8_t outFlags[] = {0};
+ ASSERT_TRUE(mReader->hasKeys(device->getId(), AINPUT_SOURCE_KEYBOARD, keycodes, outFlags));
+ ASSERT_EQ(0, outFlags[0]) << "Keyboard should not have stylus button";
+}
+
/**
* The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
* on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
diff --git a/services/inputflinger/tests/UinputDevice.cpp b/services/inputflinger/tests/UinputDevice.cpp
index 97a2614..5a654c9 100644
--- a/services/inputflinger/tests/UinputDevice.cpp
+++ b/services/inputflinger/tests/UinputDevice.cpp
@@ -157,6 +157,18 @@
injectEvent(EV_SYN, SYN_REPORT, 0);
}
+// --- UinputKeyboardWithHidUsage ---
+
+UinputKeyboardWithHidUsage::UinputKeyboardWithHidUsage(std::initializer_list<int> keys)
+ : UinputKeyboard(DEVICE_NAME, PRODUCT_ID, keys) {}
+
+void UinputKeyboardWithHidUsage::configureDevice(int fd, uinput_user_dev* device) {
+ UinputKeyboard::configureDevice(fd, device);
+
+ ioctl(fd, UI_SET_EVBIT, EV_MSC);
+ ioctl(fd, UI_SET_MSCBIT, MSC_SCAN);
+}
+
// --- UinputTouchScreen ---
UinputTouchScreen::UinputTouchScreen(const Rect& size)
diff --git a/services/inputflinger/tests/UinputDevice.h b/services/inputflinger/tests/UinputDevice.h
index 51e331d..55996b8 100644
--- a/services/inputflinger/tests/UinputDevice.h
+++ b/services/inputflinger/tests/UinputDevice.h
@@ -165,13 +165,30 @@
explicit UinputExternalStylusWithPressure();
};
+// --- UinputKeyboardWithUsage ---
+// A keyboard that supports EV_MSC MSC_SCAN through which it can report HID usage codes.
+
+class UinputKeyboardWithHidUsage : public UinputKeyboard {
+public:
+ static constexpr const char* DEVICE_NAME = "Test Uinput Keyboard With Usage";
+ static constexpr int16_t PRODUCT_ID = 47;
+
+ template <class D, class... Ts>
+ friend std::unique_ptr<D> createUinputDevice(Ts... args);
+
+protected:
+ explicit UinputKeyboardWithHidUsage(std::initializer_list<int> keys);
+
+ void configureDevice(int fd, uinput_user_dev* device) override;
+};
+
// --- UinputTouchScreen ---
// A multi-touch touchscreen device with specific size that also supports styluses.
class UinputTouchScreen : public UinputKeyboard {
public:
static constexpr const char* DEVICE_NAME = "Test Uinput Touch Screen";
- static constexpr int16_t PRODUCT_ID = 47;
+ static constexpr int16_t PRODUCT_ID = 48;
static const int32_t RAW_TOUCH_MIN = 0;
static const int32_t RAW_TOUCH_MAX = 31;