Loading libs/input/rust/keyboard_classification_config.rs 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ use crate::input::KeyboardType; // TODO(b/263559234): Categorize some of these to KeyboardType::None based on ability to produce // key events at all. (Requires setup allowing InputDevice to dynamically add/remove // KeyboardInputMapper based on blocklist and KeyEvents in case a KeyboardType::None device ends // up producing a key event) pub static CLASSIFIED_DEVICES: &[( /* vendorId */ u16, /* productId */ u16, KeyboardType, /* is_finalized */ bool, )] = &[ // HP X4000 Wireless Mouse (0x03f0, 0xa407, KeyboardType::NonAlphabetic, true), // Microsoft Wireless Mobile Mouse 6000 (0x045e, 0x0745, KeyboardType::NonAlphabetic, true), // Microsoft Surface Precision Mouse (0x045e, 0x0821, KeyboardType::NonAlphabetic, true), // Microsoft Pro IntelliMouse (0x045e, 0x082a, KeyboardType::NonAlphabetic, true), // Microsoft Bluetooth Mouse (0x045e, 0x082f, KeyboardType::NonAlphabetic, true), // Xbox One Elite Series 2 gamepad (0x045e, 0x0b05, KeyboardType::NonAlphabetic, true), // Logitech T400 (0x046d, 0x4026, KeyboardType::NonAlphabetic, true), // Logitech M720 Triathlon (Unifying) (0x046d, 0x405e, KeyboardType::NonAlphabetic, true), // Logitech MX Master 2S (Unifying) (0x046d, 0x4069, KeyboardType::NonAlphabetic, true), // Logitech M585 (Unifying) (0x046d, 0x406b, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2 (Unifying) (0x046d, 0x4072, KeyboardType::NonAlphabetic, true), // Logitech Pebble M350 (0x046d, 0x4080, KeyboardType::NonAlphabetic, true), // Logitech T630 Ultrathin (0x046d, 0xb00d, KeyboardType::NonAlphabetic, true), // Logitech M558 (0x046d, 0xb011, KeyboardType::NonAlphabetic, true), // Logitech MX Master (Bluetooth) (0x046d, 0xb012, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2 (Bluetooth) (0x046d, 0xb013, KeyboardType::NonAlphabetic, true), // Logitech M720 Triathlon (Bluetooth) (0x046d, 0xb015, KeyboardType::NonAlphabetic, true), // Logitech M535 (0x046d, 0xb016, KeyboardType::NonAlphabetic, true), // Logitech MX Master / Anywhere 2 (Bluetooth) (0x046d, 0xb017, KeyboardType::NonAlphabetic, true), // Logitech MX Master 2S (Bluetooth) (0x046d, 0xb019, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2S (Bluetooth) (0x046d, 0xb01a, KeyboardType::NonAlphabetic, true), // Logitech M585/M590 (Bluetooth) (0x046d, 0xb01b, KeyboardType::NonAlphabetic, true), // Logitech G603 Lightspeed Gaming Mouse (Bluetooth) (0x046d, 0xb01c, KeyboardType::NonAlphabetic, true), // Logitech MX Master (Bluetooth) (0x046d, 0xb01e, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2 (Bluetooth) (0x046d, 0xb01f, KeyboardType::NonAlphabetic, true), // Logitech MX Master 3 (Bluetooth) (0x046d, 0xb023, KeyboardType::NonAlphabetic, true), // Logitech G604 Lightspeed Gaming Mouse (Bluetooth) (0x046d, 0xb024, KeyboardType::NonAlphabetic, true), // Logitech Spotlight Presentation Remote (Bluetooth) (0x046d, 0xb503, KeyboardType::NonAlphabetic, true), // Logitech R500 (Bluetooth) (0x046d, 0xb505, KeyboardType::NonAlphabetic, true), // Logitech M500s (0x046d, 0xc093, KeyboardType::NonAlphabetic, true), // Logitech Spotlight Presentation Remote (USB dongle) (0x046d, 0xc53e, KeyboardType::NonAlphabetic, true), // Elecom Enelo IR LED Mouse 350 (0x056e, 0x0134, KeyboardType::NonAlphabetic, true), // Elecom EPRIM Blue LED 5 button mouse 228 (0x056e, 0x0141, KeyboardType::NonAlphabetic, true), // Elecom Blue LED Mouse 203 (0x056e, 0x0159, KeyboardType::NonAlphabetic, true), // Zebra LS2208 barcode scanner (0x05e0, 0x1200, KeyboardType::NonAlphabetic, true), // RDing FootSwitch1F1 (0x0c45, 0x7403, KeyboardType::NonAlphabetic, true), // SteelSeries Sensei RAW Frost Blue (0x1038, 0x1369, KeyboardType::NonAlphabetic, true), // SteelSeries Rival 3 Wired (0x1038, 0x1824, KeyboardType::NonAlphabetic, true), // SteelSeries Rival 3 Wireless (USB dongle) (0x1038, 0x1830, KeyboardType::NonAlphabetic, true), // Yubico.com Yubikey (0x1050, 0x0010, KeyboardType::NonAlphabetic, true), // Yubico.com Yubikey 4 OTP+U2F+CCID (0x1050, 0x0407, KeyboardType::NonAlphabetic, true), // Lenovo USB-C Wired Compact Mouse (0x17ef, 0x6123, KeyboardType::NonAlphabetic, true), // Corsair Katar Pro Wireless (USB dongle) (0x1b1c, 0x1b94, KeyboardType::NonAlphabetic, true), // Corsair Katar Pro Wireless (Bluetooth) (0x1bae, 0x1b1c, KeyboardType::NonAlphabetic, true), // Kensington Pro Fit Full-size (0x1bcf, 0x08a0, KeyboardType::NonAlphabetic, true), // Huion HS64 (0x256c, 0x006d, KeyboardType::NonAlphabetic, true), // XP-Pen Star G640 (0x28bd, 0x0914, KeyboardType::NonAlphabetic, true), // XP-Pen Artist 12 Pro (0x28bd, 0x091f, KeyboardType::NonAlphabetic, true), // XP-Pen Deco mini7W (0x28bd, 0x0928, KeyboardType::NonAlphabetic, true), ]; libs/input/rust/keyboard_classifier.rs +38 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ //! TODO(b/263559234): Data store implementation to store information about past classification use crate::input::{DeviceId, InputDevice, KeyboardType}; use crate::keyboard_classification_config::CLASSIFIED_DEVICES; use crate::{DeviceClass, ModifierState}; use std::collections::HashMap; Loading Loading @@ -126,6 +127,14 @@ impl KeyboardClassifier { (KeyboardType::NonAlphabetic, true) }; } // Check in known device list for classification for data in CLASSIFIED_DEVICES.iter() { if device.identifier.vendor == data.0 && device.identifier.product == data.1 { return (data.2, data.3); } } // Any composite device with multiple device classes should be categorized as non-alphabetic // keyboard initially if device.classes.contains(DeviceClass::Touch) Loading Loading @@ -169,6 +178,7 @@ impl KeyboardClassifier { #[cfg(test)] mod tests { use crate::input::{DeviceId, InputDevice, KeyboardType}; use crate::keyboard_classification_config::CLASSIFIED_DEVICES; use crate::keyboard_classifier::KeyboardClassifier; use crate::{DeviceClass, ModifierState, RustInputDeviceIdentifier}; Loading Loading @@ -326,6 +336,17 @@ mod tests { assert!(!classifier.is_finalized(DEVICE_ID)); } #[test] fn classify_known_devices() { let mut classifier = KeyboardClassifier::new(); for device in CLASSIFIED_DEVICES.iter() { classifier .notify_keyboard_changed(create_device_with_vendor_product_ids(device.0, device.1)); assert_eq!(classifier.get_keyboard_type(DEVICE_ID), device.2); assert_eq!(classifier.is_finalized(DEVICE_ID), device.3); } } fn create_device(classes: DeviceClass) -> InputDevice { InputDevice { device_id: DEVICE_ID, Loading @@ -342,4 +363,21 @@ mod tests { classes, } } fn create_device_with_vendor_product_ids(vendor: u16, product: u16) -> InputDevice { InputDevice { device_id: DEVICE_ID, identifier: RustInputDeviceIdentifier { name: "test_device".to_string(), location: "location".to_string(), unique_id: "unique_id".to_string(), bus: 123, vendor, product, version: 567, descriptor: "descriptor".to_string(), }, classes: DeviceClass::Keyboard | DeviceClass::AlphabeticKey | DeviceClass::External, } } } libs/input/rust/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ mod input; mod input_verifier; mod keyboard_classification_config; mod keyboard_classifier; pub use input::{ Loading Loading
libs/input/rust/keyboard_classification_config.rs 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ use crate::input::KeyboardType; // TODO(b/263559234): Categorize some of these to KeyboardType::None based on ability to produce // key events at all. (Requires setup allowing InputDevice to dynamically add/remove // KeyboardInputMapper based on blocklist and KeyEvents in case a KeyboardType::None device ends // up producing a key event) pub static CLASSIFIED_DEVICES: &[( /* vendorId */ u16, /* productId */ u16, KeyboardType, /* is_finalized */ bool, )] = &[ // HP X4000 Wireless Mouse (0x03f0, 0xa407, KeyboardType::NonAlphabetic, true), // Microsoft Wireless Mobile Mouse 6000 (0x045e, 0x0745, KeyboardType::NonAlphabetic, true), // Microsoft Surface Precision Mouse (0x045e, 0x0821, KeyboardType::NonAlphabetic, true), // Microsoft Pro IntelliMouse (0x045e, 0x082a, KeyboardType::NonAlphabetic, true), // Microsoft Bluetooth Mouse (0x045e, 0x082f, KeyboardType::NonAlphabetic, true), // Xbox One Elite Series 2 gamepad (0x045e, 0x0b05, KeyboardType::NonAlphabetic, true), // Logitech T400 (0x046d, 0x4026, KeyboardType::NonAlphabetic, true), // Logitech M720 Triathlon (Unifying) (0x046d, 0x405e, KeyboardType::NonAlphabetic, true), // Logitech MX Master 2S (Unifying) (0x046d, 0x4069, KeyboardType::NonAlphabetic, true), // Logitech M585 (Unifying) (0x046d, 0x406b, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2 (Unifying) (0x046d, 0x4072, KeyboardType::NonAlphabetic, true), // Logitech Pebble M350 (0x046d, 0x4080, KeyboardType::NonAlphabetic, true), // Logitech T630 Ultrathin (0x046d, 0xb00d, KeyboardType::NonAlphabetic, true), // Logitech M558 (0x046d, 0xb011, KeyboardType::NonAlphabetic, true), // Logitech MX Master (Bluetooth) (0x046d, 0xb012, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2 (Bluetooth) (0x046d, 0xb013, KeyboardType::NonAlphabetic, true), // Logitech M720 Triathlon (Bluetooth) (0x046d, 0xb015, KeyboardType::NonAlphabetic, true), // Logitech M535 (0x046d, 0xb016, KeyboardType::NonAlphabetic, true), // Logitech MX Master / Anywhere 2 (Bluetooth) (0x046d, 0xb017, KeyboardType::NonAlphabetic, true), // Logitech MX Master 2S (Bluetooth) (0x046d, 0xb019, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2S (Bluetooth) (0x046d, 0xb01a, KeyboardType::NonAlphabetic, true), // Logitech M585/M590 (Bluetooth) (0x046d, 0xb01b, KeyboardType::NonAlphabetic, true), // Logitech G603 Lightspeed Gaming Mouse (Bluetooth) (0x046d, 0xb01c, KeyboardType::NonAlphabetic, true), // Logitech MX Master (Bluetooth) (0x046d, 0xb01e, KeyboardType::NonAlphabetic, true), // Logitech MX Anywhere 2 (Bluetooth) (0x046d, 0xb01f, KeyboardType::NonAlphabetic, true), // Logitech MX Master 3 (Bluetooth) (0x046d, 0xb023, KeyboardType::NonAlphabetic, true), // Logitech G604 Lightspeed Gaming Mouse (Bluetooth) (0x046d, 0xb024, KeyboardType::NonAlphabetic, true), // Logitech Spotlight Presentation Remote (Bluetooth) (0x046d, 0xb503, KeyboardType::NonAlphabetic, true), // Logitech R500 (Bluetooth) (0x046d, 0xb505, KeyboardType::NonAlphabetic, true), // Logitech M500s (0x046d, 0xc093, KeyboardType::NonAlphabetic, true), // Logitech Spotlight Presentation Remote (USB dongle) (0x046d, 0xc53e, KeyboardType::NonAlphabetic, true), // Elecom Enelo IR LED Mouse 350 (0x056e, 0x0134, KeyboardType::NonAlphabetic, true), // Elecom EPRIM Blue LED 5 button mouse 228 (0x056e, 0x0141, KeyboardType::NonAlphabetic, true), // Elecom Blue LED Mouse 203 (0x056e, 0x0159, KeyboardType::NonAlphabetic, true), // Zebra LS2208 barcode scanner (0x05e0, 0x1200, KeyboardType::NonAlphabetic, true), // RDing FootSwitch1F1 (0x0c45, 0x7403, KeyboardType::NonAlphabetic, true), // SteelSeries Sensei RAW Frost Blue (0x1038, 0x1369, KeyboardType::NonAlphabetic, true), // SteelSeries Rival 3 Wired (0x1038, 0x1824, KeyboardType::NonAlphabetic, true), // SteelSeries Rival 3 Wireless (USB dongle) (0x1038, 0x1830, KeyboardType::NonAlphabetic, true), // Yubico.com Yubikey (0x1050, 0x0010, KeyboardType::NonAlphabetic, true), // Yubico.com Yubikey 4 OTP+U2F+CCID (0x1050, 0x0407, KeyboardType::NonAlphabetic, true), // Lenovo USB-C Wired Compact Mouse (0x17ef, 0x6123, KeyboardType::NonAlphabetic, true), // Corsair Katar Pro Wireless (USB dongle) (0x1b1c, 0x1b94, KeyboardType::NonAlphabetic, true), // Corsair Katar Pro Wireless (Bluetooth) (0x1bae, 0x1b1c, KeyboardType::NonAlphabetic, true), // Kensington Pro Fit Full-size (0x1bcf, 0x08a0, KeyboardType::NonAlphabetic, true), // Huion HS64 (0x256c, 0x006d, KeyboardType::NonAlphabetic, true), // XP-Pen Star G640 (0x28bd, 0x0914, KeyboardType::NonAlphabetic, true), // XP-Pen Artist 12 Pro (0x28bd, 0x091f, KeyboardType::NonAlphabetic, true), // XP-Pen Deco mini7W (0x28bd, 0x0928, KeyboardType::NonAlphabetic, true), ];
libs/input/rust/keyboard_classifier.rs +38 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ //! TODO(b/263559234): Data store implementation to store information about past classification use crate::input::{DeviceId, InputDevice, KeyboardType}; use crate::keyboard_classification_config::CLASSIFIED_DEVICES; use crate::{DeviceClass, ModifierState}; use std::collections::HashMap; Loading Loading @@ -126,6 +127,14 @@ impl KeyboardClassifier { (KeyboardType::NonAlphabetic, true) }; } // Check in known device list for classification for data in CLASSIFIED_DEVICES.iter() { if device.identifier.vendor == data.0 && device.identifier.product == data.1 { return (data.2, data.3); } } // Any composite device with multiple device classes should be categorized as non-alphabetic // keyboard initially if device.classes.contains(DeviceClass::Touch) Loading Loading @@ -169,6 +178,7 @@ impl KeyboardClassifier { #[cfg(test)] mod tests { use crate::input::{DeviceId, InputDevice, KeyboardType}; use crate::keyboard_classification_config::CLASSIFIED_DEVICES; use crate::keyboard_classifier::KeyboardClassifier; use crate::{DeviceClass, ModifierState, RustInputDeviceIdentifier}; Loading Loading @@ -326,6 +336,17 @@ mod tests { assert!(!classifier.is_finalized(DEVICE_ID)); } #[test] fn classify_known_devices() { let mut classifier = KeyboardClassifier::new(); for device in CLASSIFIED_DEVICES.iter() { classifier .notify_keyboard_changed(create_device_with_vendor_product_ids(device.0, device.1)); assert_eq!(classifier.get_keyboard_type(DEVICE_ID), device.2); assert_eq!(classifier.is_finalized(DEVICE_ID), device.3); } } fn create_device(classes: DeviceClass) -> InputDevice { InputDevice { device_id: DEVICE_ID, Loading @@ -342,4 +363,21 @@ mod tests { classes, } } fn create_device_with_vendor_product_ids(vendor: u16, product: u16) -> InputDevice { InputDevice { device_id: DEVICE_ID, identifier: RustInputDeviceIdentifier { name: "test_device".to_string(), location: "location".to_string(), unique_id: "unique_id".to_string(), bus: 123, vendor, product, version: 567, descriptor: "descriptor".to_string(), }, classes: DeviceClass::Keyboard | DeviceClass::AlphabeticKey | DeviceClass::External, } } }
libs/input/rust/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ mod input; mod input_verifier; mod keyboard_classification_config; mod keyboard_classifier; pub use input::{ Loading