Merge "Bounce keys and Slow keys should work for composite keyboards" into main
diff --git a/services/inputflinger/rust/bounce_keys_filter.rs b/services/inputflinger/rust/bounce_keys_filter.rs
index dbee388..e05e8e5 100644
--- a/services/inputflinger/rust/bounce_keys_filter.rs
+++ b/services/inputflinger/rust/bounce_keys_filter.rs
@@ -65,7 +65,10 @@
 
 impl Filter for BounceKeysFilter {
     fn notify_key(&mut self, event: &KeyEvent) {
-        if !(self.supported_devices.contains(&event.deviceId) && event.source == Source::KEYBOARD) {
+        // Check if it is a supported device and event source contains Source::KEYBOARD
+        if !(self.supported_devices.contains(&event.deviceId)
+            && event.source.0 & Source::KEYBOARD.0 != 0)
+        {
             self.next.notify_key(event);
             return;
         }
@@ -200,6 +203,41 @@
     }
 
     #[test]
+    fn test_is_notify_key_for_tv_remote() {
+        let mut next = TestFilter::new();
+        let mut filter = setup_filter_with_external_device(
+            Box::new(next.clone()),
+            1,   /* device_id */
+            100, /* threshold */
+            KeyboardType::NonAlphabetic,
+        );
+
+        let source = Source(Source::KEYBOARD.0 | Source::DPAD.0);
+        let event = KeyEvent { action: KeyEventAction::DOWN, source, ..BASE_KEY_EVENT };
+        filter.notify_key(&event);
+        assert_eq!(next.last_event().unwrap(), event);
+
+        let event = KeyEvent { action: KeyEventAction::UP, source, ..BASE_KEY_EVENT };
+        filter.notify_key(&event);
+        assert_eq!(next.last_event().unwrap(), event);
+
+        next.clear();
+        let event = KeyEvent { action: KeyEventAction::DOWN, source, ..BASE_KEY_EVENT };
+        filter.notify_key(&event);
+        assert!(next.last_event().is_none());
+
+        let event =
+            KeyEvent { eventTime: 100, action: KeyEventAction::UP, source, ..BASE_KEY_EVENT };
+        filter.notify_key(&event);
+        assert!(next.last_event().is_none());
+
+        let event =
+            KeyEvent { eventTime: 200, action: KeyEventAction::DOWN, source, ..BASE_KEY_EVENT };
+        filter.notify_key(&event);
+        assert_eq!(next.last_event().unwrap(), event);
+    }
+
+    #[test]
     fn test_is_notify_key_blocks_for_internal_keyboard() {
         let mut next = TestFilter::new();
         let mut filter = setup_filter_with_internal_device(
diff --git a/services/inputflinger/rust/slow_keys_filter.rs b/services/inputflinger/rust/slow_keys_filter.rs
index 3fe4c6f..8830aac 100644
--- a/services/inputflinger/rust/slow_keys_filter.rs
+++ b/services/inputflinger/rust/slow_keys_filter.rs
@@ -100,7 +100,7 @@
             // acquire write lock
             let mut slow_filter = self.write_inner();
             if !(slow_filter.supported_devices.contains(&event.deviceId)
-                && event.source == Source::KEYBOARD)
+                && event.source.0 & Source::KEYBOARD.0 != 0)
             {
                 slow_filter.next.notify_key(event);
                 return;
@@ -296,6 +296,63 @@
     }
 
     #[test]
+    fn test_notify_key_for_tv_remote_when_key_pressed_for_threshold_time() {
+        let test_callbacks = TestCallbacks::new();
+        let test_thread = get_thread(test_callbacks.clone());
+        let next = TestFilter::new();
+        let mut filter = setup_filter_with_external_device(
+            Box::new(next.clone()),
+            test_thread.clone(),
+            1, /* device_id */
+            SLOW_KEYS_THRESHOLD_NS,
+            KeyboardType::NonAlphabetic,
+        );
+        let down_time = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap().num_nanoseconds();
+        let source = Source(Source::KEYBOARD.0 | Source::DPAD.0);
+        filter.notify_key(&KeyEvent {
+            action: KeyEventAction::DOWN,
+            downTime: down_time,
+            eventTime: down_time,
+            source,
+            ..BASE_KEY_EVENT
+        });
+        assert!(next.last_event().is_none());
+
+        std::thread::sleep(Duration::from_nanos(2 * SLOW_KEYS_THRESHOLD_NS as u64));
+        assert_eq!(
+            next.last_event().unwrap(),
+            KeyEvent {
+                action: KeyEventAction::DOWN,
+                downTime: down_time + SLOW_KEYS_THRESHOLD_NS,
+                eventTime: down_time + SLOW_KEYS_THRESHOLD_NS,
+                source,
+                policyFlags: POLICY_FLAG_DISABLE_KEY_REPEAT,
+                ..BASE_KEY_EVENT
+            }
+        );
+
+        let up_time = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap().num_nanoseconds();
+        filter.notify_key(&KeyEvent {
+            action: KeyEventAction::UP,
+            downTime: down_time,
+            eventTime: up_time,
+            source,
+            ..BASE_KEY_EVENT
+        });
+
+        assert_eq!(
+            next.last_event().unwrap(),
+            KeyEvent {
+                action: KeyEventAction::UP,
+                downTime: down_time + SLOW_KEYS_THRESHOLD_NS,
+                eventTime: up_time,
+                source,
+                ..BASE_KEY_EVENT
+            }
+        );
+    }
+
+    #[test]
     fn test_notify_key_for_internal_alphabetic_keyboard_when_key_pressed_for_threshold_time() {
         let test_callbacks = TestCallbacks::new();
         let test_thread = get_thread(test_callbacks.clone());