1717//! Bounce keys input filter implementation.
1818//! Bounce keys is an accessibility feature to aid users who have physical disabilities, that
1919//! allows the user to configure the device to ignore rapid, repeated key presses of the same key.
20- use crate :: input_filter:: Filter ;
20+ use crate :: input_filter:: { Filter , VIRTUAL_KEYBOARD_DEVICE_ID } ;
2121
2222use android_hardware_input_common:: aidl:: android:: hardware:: input:: common:: Source :: Source ;
2323use com_android_server_inputflinger:: aidl:: com:: android:: server:: inputflinger:: {
2424 DeviceInfo :: DeviceInfo , KeyEvent :: KeyEvent , KeyEventAction :: KeyEventAction ,
2525} ;
26+ use input:: KeyboardType ;
2627use log:: debug;
2728use std:: collections:: { HashMap , HashSet } ;
2829
@@ -42,7 +43,7 @@ pub struct BounceKeysFilter {
4243 next : Box < dyn Filter + Send + Sync > ,
4344 key_event_map : HashMap < i32 , LastUpKeyEvent > ,
4445 blocked_events : Vec < BlockedEvent > ,
45- external_devices : HashSet < i32 > ,
46+ supported_devices : HashSet < i32 > ,
4647 bounce_key_threshold_ns : i64 ,
4748}
4849
@@ -56,15 +57,15 @@ impl BounceKeysFilter {
5657 next,
5758 key_event_map : HashMap :: new ( ) ,
5859 blocked_events : Vec :: new ( ) ,
59- external_devices : HashSet :: new ( ) ,
60+ supported_devices : HashSet :: new ( ) ,
6061 bounce_key_threshold_ns,
6162 }
6263 }
6364}
6465
6566impl Filter for BounceKeysFilter {
6667 fn notify_key ( & mut self , event : & KeyEvent ) {
67- if !( self . external_devices . contains ( & event. deviceId ) && event. source == Source :: KEYBOARD ) {
68+ if !( self . supported_devices . contains ( & event. deviceId ) && event. source == Source :: KEYBOARD ) {
6869 self . next . notify_key ( event) ;
6970 return ;
7071 }
@@ -110,10 +111,17 @@ impl Filter for BounceKeysFilter {
110111 self . blocked_events . retain ( |blocked_event| {
111112 device_infos. iter ( ) . any ( |x| blocked_event. device_id == x. deviceId )
112113 } ) ;
113- self . external_devices . clear ( ) ;
114+ self . supported_devices . clear ( ) ;
114115 for device_info in device_infos {
115- if device_info. external {
116- self . external_devices . insert ( device_info. deviceId ) ;
116+ if device_info. deviceId == VIRTUAL_KEYBOARD_DEVICE_ID {
117+ continue ;
118+ }
119+ if device_info. keyboardType == KeyboardType :: None as i32 {
120+ continue ;
121+ }
122+ // Support Alphabetic keyboards and Non-alphabetic external keyboards
123+ if device_info. external || device_info. keyboardType == KeyboardType :: Alphabetic as i32 {
124+ self . supported_devices . insert ( device_info. deviceId ) ;
117125 }
118126 }
119127 self . next . notify_devices_changed ( device_infos) ;
@@ -127,11 +135,12 @@ impl Filter for BounceKeysFilter {
127135#[ cfg( test) ]
128136mod tests {
129137 use crate :: bounce_keys_filter:: BounceKeysFilter ;
130- use crate :: input_filter:: { test_filter:: TestFilter , Filter } ;
138+ use crate :: input_filter:: { test_filter:: TestFilter , Filter , VIRTUAL_KEYBOARD_DEVICE_ID } ;
131139 use android_hardware_input_common:: aidl:: android:: hardware:: input:: common:: Source :: Source ;
132140 use com_android_server_inputflinger:: aidl:: com:: android:: server:: inputflinger:: {
133141 DeviceInfo :: DeviceInfo , KeyEvent :: KeyEvent , KeyEventAction :: KeyEventAction ,
134142 } ;
143+ use input:: KeyboardType ;
135144
136145 static BASE_KEY_EVENT : KeyEvent = KeyEvent {
137146 id : 1 ,
@@ -156,6 +165,7 @@ mod tests {
156165 Box :: new ( next. clone ( ) ) ,
157166 1 , /* device_id */
158167 100 , /* threshold */
168+ KeyboardType :: Alphabetic ,
159169 ) ;
160170
161171 let event = KeyEvent { action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
@@ -181,12 +191,68 @@ mod tests {
181191 }
182192
183193 #[ test]
184- fn test_is_notify_key_doesnt_block_for_internal_keyboard ( ) {
194+ fn test_is_notify_key_blocks_for_internal_keyboard ( ) {
195+ let mut next = TestFilter :: new ( ) ;
196+ let mut filter = setup_filter_with_internal_device (
197+ Box :: new ( next. clone ( ) ) ,
198+ 1 , /* device_id */
199+ 100 , /* threshold */
200+ KeyboardType :: Alphabetic ,
201+ ) ;
202+
203+ let event = KeyEvent { action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
204+ filter. notify_key ( & event) ;
205+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
206+
207+ let event = KeyEvent { action : KeyEventAction :: UP , ..BASE_KEY_EVENT } ;
208+ filter. notify_key ( & event) ;
209+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
210+
211+ next. clear ( ) ;
212+ let event = KeyEvent { action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
213+ filter. notify_key ( & event) ;
214+ assert ! ( next. last_event( ) . is_none( ) ) ;
215+
216+ let event = KeyEvent { eventTime : 100 , action : KeyEventAction :: UP , ..BASE_KEY_EVENT } ;
217+ filter. notify_key ( & event) ;
218+ assert ! ( next. last_event( ) . is_none( ) ) ;
219+
220+ let event = KeyEvent { eventTime : 200 , action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
221+ filter. notify_key ( & event) ;
222+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
223+ }
224+
225+ #[ test]
226+ fn test_is_notify_key_doesnt_block_for_internal_non_alphabetic_keyboard ( ) {
185227 let next = TestFilter :: new ( ) ;
186228 let mut filter = setup_filter_with_internal_device (
187229 Box :: new ( next. clone ( ) ) ,
188230 1 , /* device_id */
189231 100 , /* threshold */
232+ KeyboardType :: NonAlphabetic ,
233+ ) ;
234+
235+ let event = KeyEvent { action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
236+ filter. notify_key ( & event) ;
237+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
238+
239+ let event = KeyEvent { action : KeyEventAction :: UP , ..BASE_KEY_EVENT } ;
240+ filter. notify_key ( & event) ;
241+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
242+
243+ let event = KeyEvent { action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
244+ filter. notify_key ( & event) ;
245+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
246+ }
247+
248+ #[ test]
249+ fn test_is_notify_key_doesnt_block_for_virtual_keyboard ( ) {
250+ let next = TestFilter :: new ( ) ;
251+ let mut filter = setup_filter_with_internal_device (
252+ Box :: new ( next. clone ( ) ) ,
253+ VIRTUAL_KEYBOARD_DEVICE_ID , /* device_id */
254+ 100 , /* threshold */
255+ KeyboardType :: Alphabetic ,
190256 ) ;
191257
192258 let event = KeyEvent { action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
@@ -209,6 +275,7 @@ mod tests {
209275 Box :: new ( next. clone ( ) ) ,
210276 1 , /* device_id */
211277 100 , /* threshold */
278+ KeyboardType :: NonAlphabetic ,
212279 ) ;
213280
214281 let event =
@@ -233,12 +300,60 @@ mod tests {
233300 let mut filter = setup_filter_with_devices (
234301 Box :: new ( next. clone ( ) ) ,
235302 & [
236- DeviceInfo { deviceId : 1 , external : true } ,
237- DeviceInfo { deviceId : 2 , external : true } ,
303+ DeviceInfo {
304+ deviceId : 1 ,
305+ external : true ,
306+ keyboardType : KeyboardType :: Alphabetic as i32 ,
307+ } ,
308+ DeviceInfo {
309+ deviceId : 2 ,
310+ external : true ,
311+ keyboardType : KeyboardType :: Alphabetic as i32 ,
312+ } ,
313+ ] ,
314+ 100 , /* threshold */
315+ ) ;
316+
317+ // Bounce key scenario on the external keyboard
318+ let event = KeyEvent { deviceId : 1 , action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
319+ filter. notify_key ( & event) ;
320+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
321+
322+ let event = KeyEvent { deviceId : 1 , action : KeyEventAction :: UP , ..BASE_KEY_EVENT } ;
323+ filter. notify_key ( & event) ;
324+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
325+
326+ next. clear ( ) ;
327+ let event = KeyEvent { deviceId : 1 , action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
328+ filter. notify_key ( & event) ;
329+ assert ! ( next. last_event( ) . is_none( ) ) ;
330+
331+ let event = KeyEvent { deviceId : 2 , action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
332+ filter. notify_key ( & event) ;
333+ assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
334+ }
335+
336+ #[ test]
337+ fn test_is_notify_key_for_external_and_internal_alphabetic_keyboards ( ) {
338+ let mut next = TestFilter :: new ( ) ;
339+ let mut filter = setup_filter_with_devices (
340+ Box :: new ( next. clone ( ) ) ,
341+ & [
342+ DeviceInfo {
343+ deviceId : 1 ,
344+ external : false ,
345+ keyboardType : KeyboardType :: Alphabetic as i32 ,
346+ } ,
347+ DeviceInfo {
348+ deviceId : 2 ,
349+ external : true ,
350+ keyboardType : KeyboardType :: Alphabetic as i32 ,
351+ } ,
238352 ] ,
239353 100 , /* threshold */
240354 ) ;
241355
356+ // Bounce key scenario on the internal keyboard
242357 let event = KeyEvent { deviceId : 1 , action : KeyEventAction :: DOWN , ..BASE_KEY_EVENT } ;
243358 filter. notify_key ( & event) ;
244359 assert_eq ! ( next. last_event( ) . unwrap( ) , event) ;
@@ -261,10 +376,15 @@ mod tests {
261376 next : Box < dyn Filter + Send + Sync > ,
262377 device_id : i32 ,
263378 threshold : i64 ,
379+ keyboard_type : KeyboardType ,
264380 ) -> BounceKeysFilter {
265381 setup_filter_with_devices (
266382 next,
267- & [ DeviceInfo { deviceId : device_id, external : true } ] ,
383+ & [ DeviceInfo {
384+ deviceId : device_id,
385+ external : true ,
386+ keyboardType : keyboard_type as i32 ,
387+ } ] ,
268388 threshold,
269389 )
270390 }
@@ -273,10 +393,15 @@ mod tests {
273393 next : Box < dyn Filter + Send + Sync > ,
274394 device_id : i32 ,
275395 threshold : i64 ,
396+ keyboard_type : KeyboardType ,
276397 ) -> BounceKeysFilter {
277398 setup_filter_with_devices (
278399 next,
279- & [ DeviceInfo { deviceId : device_id, external : false } ] ,
400+ & [ DeviceInfo {
401+ deviceId : device_id,
402+ external : false ,
403+ keyboardType : keyboard_type as i32 ,
404+ } ] ,
280405 threshold,
281406 )
282407 }
0 commit comments