1use crate::input_device::{self, Handled, InputDeviceDescriptor, InputDeviceEvent, InputEvent};
22use crate::input_handler::InputHandlerStatus;
23use crate::keyboard_binding::KeyboardEvent;
24use crate::metrics;
25use anyhow::{anyhow, Context, Result};
26use fidl_fuchsia_settings as fsettings;
27use fidl_fuchsia_ui_input3::{self as finput3, KeyEventType, KeyMeaning};
28use fuchsia_async::{MonotonicInstant, Task, Timer};
29use fuchsia_inspect::health::Reporter;
30use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
31use futures::StreamExt;
32use metrics_registry::*;
33use std::cell::RefCell;
34use std::rc::Rc;
35use zx::MonotonicDuration;
36
37const RESERVED_MODIFIER_RANGE: std::ops::Range<u32> = finput3::NonPrintableKey::Alt.into_primitive()
40 ..finput3::NonPrintableKey::Enter.into_primitive();
41
42#[derive(Debug, PartialEq, Clone, Copy)]
45pub struct Settings {
46 delay: MonotonicDuration,
48 period: MonotonicDuration,
51}
52
53impl Default for Settings {
54 fn default() -> Self {
55 Settings {
56 delay: MonotonicDuration::from_millis(250),
57 period: MonotonicDuration::from_millis(50),
58 }
59 }
60}
61
62impl From<fsettings::Autorepeat> for Settings {
63 fn from(s: fsettings::Autorepeat) -> Self {
65 Self {
66 delay: MonotonicDuration::from_nanos(s.delay),
67 period: MonotonicDuration::from_nanos(s.period),
68 }
69 }
70}
71
72impl Settings {
73 pub fn into_with_delay(self, delay: MonotonicDuration) -> Self {
75 Self { delay, ..self }
76 }
77
78 pub fn into_with_period(self, period: MonotonicDuration) -> Self {
80 Self { period, ..self }
81 }
82}
83
84enum Repeatability {
86 Yes,
88 No,
90}
91
92fn repeatability(key_meaning: Option<KeyMeaning>) -> Repeatability {
95 match key_meaning {
96 Some(KeyMeaning::Codepoint(0)) => Repeatability::No,
97 Some(KeyMeaning::Codepoint(_)) => Repeatability::Yes, Some(KeyMeaning::NonPrintableKey(k)) => {
99 if RESERVED_MODIFIER_RANGE.contains(&k.into_primitive()) {
100 Repeatability::No
101 } else {
102 Repeatability::Yes
103 }
104 }
105 None => Repeatability::Yes, }
107}
108
109#[derive(Debug, Clone)]
111enum AnyEvent {
112 Keyboard(KeyboardEvent, InputDeviceDescriptor, zx::MonotonicInstant, Handled),
114 NonKeyboard(InputEvent),
116 Timeout,
118}
119
120impl TryInto<InputEvent> for AnyEvent {
121 type Error = anyhow::Error;
122
123 fn try_into(self) -> Result<InputEvent> {
124 match self {
125 AnyEvent::NonKeyboard(ev) => Ok(ev),
126 AnyEvent::Keyboard(ev, device_descriptor, event_time, handled) => Ok(InputEvent {
127 device_event: InputDeviceEvent::Keyboard(ev.into_with_folded_event()),
128 device_descriptor: device_descriptor,
129 event_time,
130 handled,
131 trace_id: None,
132 }),
133 _ => Err(anyhow!("not an InputEvent: {:?}", &self)),
134 }
135 }
136}
137
138#[allow(clippy::large_enum_variant)] #[derive(Debug, Clone)]
141enum State {
142 Dormant,
144 Armed {
147 armed_event: KeyboardEvent,
149 armed_descriptor: InputDeviceDescriptor,
151 _delay_timer: Rc<Task<()>>,
155 },
156}
157
158impl Default for State {
159 fn default() -> Self {
160 State::Dormant
161 }
162}
163
164fn unbounded_send_logged<T>(sink: &UnboundedSender<T>, event: T) -> Result<()>
166where
167 for<'a> &'a T: std::fmt::Debug,
168 T: 'static + Sync + Send,
169{
170 log::debug!("unbounded_send_logged: {:?}", &event);
171 sink.unbounded_send(event)?;
172 Ok(())
173}
174
175fn new_autorepeat_timer(
180 sink: UnboundedSender<AnyEvent>,
181 delay: MonotonicDuration,
182 metrics_logger: metrics::MetricsLogger,
183) -> Rc<Task<()>> {
184 let task = Task::local(async move {
185 Timer::new(MonotonicInstant::after(delay)).await;
186 log::debug!("autorepeat timeout");
187 unbounded_send_logged(&sink, AnyEvent::Timeout).unwrap_or_else(|e| {
188 metrics_logger.log_error(
189 InputPipelineErrorMetricDimensionEvent::AutorepeatCouldNotFireTimer,
190 std::format!("could not fire autorepeat timer: {:?}", e),
191 );
192 });
193 });
194 Rc::new(task)
195}
196
197pub struct Autorepeater {
202 event_sink: UnboundedSender<AnyEvent>,
205
206 event_source: RefCell<UnboundedReceiver<AnyEvent>>,
208
209 state: RefCell<State>,
211
212 settings: Settings,
214
215 _event_feeder: Task<()>,
217
218 inspect_status: InputHandlerStatus,
220
221 metrics_logger: metrics::MetricsLogger,
223}
224
225impl Autorepeater {
226 pub fn new(
230 source: UnboundedReceiver<InputEvent>,
231 input_handlers_node: &fuchsia_inspect::Node,
232 metrics_logger: metrics::MetricsLogger,
233 ) -> Rc<Self> {
234 Self::new_with_settings(source, Default::default(), input_handlers_node, metrics_logger)
235 }
236
237 fn new_with_settings(
238 mut source: UnboundedReceiver<InputEvent>,
239 settings: Settings,
240 input_handlers_node: &fuchsia_inspect::Node,
241 metrics_logger: metrics::MetricsLogger,
242 ) -> Rc<Self> {
243 let (event_sink, event_source) = mpsc::unbounded();
244 let inspect_status = InputHandlerStatus::new(
245 input_handlers_node,
246 "autorepeater",
247 true,
248 );
249 let cloned_metrics_logger = metrics_logger.clone();
250
251 let event_feeder = {
258 let event_sink = event_sink.clone();
259 Task::local(async move {
260 while let Some(event) = source.next().await {
261 match event {
262 InputEvent {
263 device_event: InputDeviceEvent::Keyboard(k),
264 device_descriptor,
265 event_time,
266 handled,
267 trace_id: _,
268 } if handled == Handled::No => unbounded_send_logged(
269 &event_sink,
270 AnyEvent::Keyboard(k, device_descriptor, event_time, handled),
271 )
272 .context("while forwarding a keyboard event"),
273 InputEvent {
274 device_event: _,
275 device_descriptor: _,
276 event_time: _,
277 handled: _,
278 trace_id: _,
279 } => unbounded_send_logged(&event_sink, AnyEvent::NonKeyboard(event))
280 .context("while forwarding a non-keyboard event"),
281 }
282 .unwrap_or_else(|e| {
283 cloned_metrics_logger.log_error(
284 InputPipelineErrorMetricDimensionEvent::AutorepeatCouldNotRunAutorepeat,
285 std::format!("could not run autorepeat: {:?}", e),
286 );
287 });
288 }
289 event_sink.close_channel();
290 })
291 };
292
293 Rc::new(Autorepeater {
294 event_sink,
295 event_source: RefCell::new(event_source),
296 state: RefCell::new(Default::default()),
297 settings,
298 _event_feeder: event_feeder,
299 inspect_status,
300 metrics_logger,
301 })
302 }
303
304 pub async fn run(self: &Rc<Self>, output: UnboundedSender<InputEvent>) -> Result<()> {
307 log::info!("key autorepeater installed");
308 let src = &mut *(self.event_source.borrow_mut());
309 while let Some(event) = src.next().await {
310 match event {
311 AnyEvent::NonKeyboard(input_event) => unbounded_send_logged(&output, input_event)?,
313 AnyEvent::Keyboard(_, _, _, _) => {
314 if let Ok(e) = event.clone().try_into() {
315 self.inspect_status.count_received_event(e);
316 }
317 self.process_event(event, &output).await?
318 }
319 AnyEvent::Timeout => self.process_event(event, &output).await?,
320 }
321 }
322 output.close_channel();
325
326 Err(anyhow!("recv loop is never supposed to terminate"))
333 }
334
335 pub fn set_handler_healthy(self: std::rc::Rc<Self>) {
336 self.inspect_status.health_node.borrow_mut().set_ok();
337 }
338
339 pub fn set_handler_unhealthy(self: std::rc::Rc<Self>, msg: &str) {
340 self.inspect_status.health_node.borrow_mut().set_unhealthy(msg);
341 }
342
343 fn set_state(self: &Rc<Self>, state: State) {
345 log::debug!("set state: {:?}", &state);
346 self.state.replace(state);
347 }
348
349 fn get_state(self: &Rc<Self>) -> State {
351 self.state.borrow().clone()
352 }
353
354 async fn process_event(
357 self: &Rc<Self>,
358 event: AnyEvent,
359 output: &UnboundedSender<InputEvent>,
360 ) -> Result<()> {
361 let old_state = self.get_state();
362 log::debug!("process_event: current state: {:?}", &old_state);
363 log::debug!("process_event: inbound event: {:?}", &event);
364 match (old_state, event.clone()) {
365 (State::Dormant, AnyEvent::Keyboard(ev, descriptor, ..)) => {
368 match (ev.get_event_type_folded(), repeatability(ev.get_key_meaning())) {
369 (KeyEventType::Pressed, Repeatability::Yes) => {
372 let _delay_timer = new_autorepeat_timer(
373 self.event_sink.clone(),
374 self.settings.delay,
375 self.metrics_logger.clone(),
376 );
377 self.set_state(State::Armed {
378 armed_event: ev,
379 armed_descriptor: descriptor,
380 _delay_timer,
381 });
382 }
383
384 (_, _) => {}
386 }
387 unbounded_send_logged(&output, event.try_into()?)?;
388 }
389
390 (State::Dormant, AnyEvent::Timeout) => {
395 log::warn!("spurious timeout in the autorepeater");
399 }
400
401 (State::Armed { armed_event, .. }, AnyEvent::Keyboard(ev, descriptor, ..)) => {
416 match (ev.get_event_type_folded(), repeatability(ev.get_key_meaning())) {
417 (KeyEventType::Pressed, Repeatability::Yes) => {
418 let _delay_timer = new_autorepeat_timer(
419 self.event_sink.clone(),
420 self.settings.delay,
421 self.metrics_logger.clone(),
422 );
423 self.set_state(State::Armed {
424 armed_event: ev,
425 armed_descriptor: descriptor,
426 _delay_timer,
427 });
428 }
429
430 (KeyEventType::Released, Repeatability::Yes) => {
431 if KeyboardEvent::same_key(&armed_event, &ev) {
435 self.set_state(State::Dormant);
436 }
437 }
438
439 _ => {}
441 }
442 unbounded_send_logged(&output, event.try_into()?)?;
443 }
444
445 (State::Armed { armed_event, armed_descriptor, .. }, AnyEvent::Timeout) => {
447 let _delay_timer = new_autorepeat_timer(
448 self.event_sink.clone(),
449 self.settings.period,
450 self.metrics_logger.clone(),
451 );
452 let new_event = armed_event
453 .clone()
454 .into_with_repeat_sequence(armed_event.get_repeat_sequence() + 1);
455 let new_event_time = input_device::event_time_or_now(None);
456
457 self.set_state(State::Armed {
458 armed_event: new_event.clone(),
459 armed_descriptor: armed_descriptor.clone(),
460 _delay_timer,
461 });
462 let autorepeat_event =
464 AnyEvent::Keyboard(new_event, armed_descriptor, new_event_time, Handled::No);
465 unbounded_send_logged(&output, autorepeat_event.try_into()?)?;
466 }
467
468 (_, AnyEvent::NonKeyboard(event)) => {
470 unbounded_send_logged(&output, event)?;
471 }
472 }
473 Ok(())
474 }
475}
476
477#[cfg(test)]
478mod tests {
479 use super::*;
480 use crate::testing_utilities;
481 use fidl_fuchsia_input::Key;
482 use fuchsia_async::TestExecutor;
483
484 use futures::Future;
485 use pretty_assertions::assert_eq;
486 use std::pin::pin;
487 use std::task::Poll;
488
489 fn default_settings() -> Settings {
493 Settings {
494 delay: MonotonicDuration::from_millis(500),
495 period: MonotonicDuration::from_seconds(1),
496 }
497 }
498
499 fn new_event(
501 key: Key,
502 event_type: KeyEventType,
503 key_meaning: Option<KeyMeaning>,
504 repeat_sequence: u32,
505 ) -> InputEvent {
506 testing_utilities::create_keyboard_event_with_key_meaning_and_repeat_sequence(
507 key,
508 event_type,
509 None,
510 zx::MonotonicInstant::ZERO,
511 &InputDeviceDescriptor::Fake,
512 None,
513 key_meaning,
514 repeat_sequence,
515 )
516 }
517
518 fn new_handled_event(
519 key: Key,
520 event_type: KeyEventType,
521 key_meaning: Option<KeyMeaning>,
522 repeat_sequence: u32,
523 ) -> InputEvent {
524 let event = new_event(key, event_type, key_meaning, repeat_sequence);
525 InputEvent { handled: Handled::Yes, ..event }
527 }
528
529 async fn wait_for_millis(millis: i64) {
531 wait_for_duration(zx::MonotonicDuration::from_millis(millis)).await;
532 }
533
534 async fn wait_for_duration(duration: MonotonicDuration) {
535 fuchsia_async::Timer::new(MonotonicInstant::after(duration)).await;
536 }
537
538 fn remove_event_time(events: Vec<InputEvent>) -> Vec<InputEvent> {
542 events
543 .into_iter()
544 .map(
545 |InputEvent {
546 device_event,
547 device_descriptor,
548 event_time: _,
549 handled,
550 trace_id: _,
551 }| {
552 InputEvent {
553 device_event,
554 device_descriptor,
555 event_time: zx::MonotonicInstant::ZERO,
556 handled,
557 trace_id: None,
558 }
559 },
560 )
561 .collect()
562 }
563
564 const SLACK_DURATION: MonotonicDuration = zx::MonotonicDuration::from_millis(5000);
567
568 async fn assert_events(output: UnboundedReceiver<InputEvent>, expected: Vec<InputEvent>) {
570 wait_for_duration(SLACK_DURATION).await;
574 assert_eq!(
575 remove_event_time(output.take(expected.len()).collect::<Vec<InputEvent>>().await),
576 expected
577 );
578 }
579
580 fn run_in_fake_time<F>(
598 executor: &mut TestExecutor,
599 main_fut: &mut F,
600 total_duration: MonotonicDuration,
601 ) where
602 F: Future<Output = ()> + Unpin,
603 {
604 const INCREMENT: MonotonicDuration = zx::MonotonicDuration::from_millis(13);
605 let total_duration = total_duration + SLACK_DURATION;
608 let mut current = zx::MonotonicDuration::from_millis(0);
609 let mut poll_status = Poll::Pending;
610
611 while current < total_duration && poll_status == Poll::Pending {
616 executor.set_fake_time(MonotonicInstant::after(INCREMENT));
617 executor.wake_expired_timers();
618 poll_status = executor.run_until_stalled(main_fut);
619 current = current + INCREMENT;
620 }
621 assert_eq!(
622 poll_status,
623 Poll::Ready(()),
624 "the main future did not complete, perhaps increase total_duration?"
625 );
626 }
627
628 #[test]
647 fn basic_press_and_release_only() {
648 let mut executor = TestExecutor::new_with_fake_time();
652
653 let (input, receiver) = mpsc::unbounded();
656
657 let inspector = fuchsia_inspect::Inspector::default();
658 let test_node = inspector.root().create_child("test_node");
659
660 let handler = Autorepeater::new_with_settings(
670 receiver,
671 default_settings(),
672 &test_node,
673 metrics::MetricsLogger::default(),
674 );
675
676 let (sender, output) = mpsc::unbounded();
680
681 let handler_task = Task::local(async move { handler.run(sender).await });
683
684 let main_fut = async move {
686 input
691 .unbounded_send(new_event(
692 Key::A,
693 KeyEventType::Pressed,
694 Some(KeyMeaning::Codepoint('a' as u32)),
695 0,
696 ))
697 .unwrap();
698
699 wait_for_millis(1).await;
702
703 input
704 .unbounded_send(new_event(
705 Key::A,
706 KeyEventType::Released,
707 Some(KeyMeaning::Codepoint('a' as u32)),
708 0,
709 ))
710 .unwrap();
711
712 assert_events(
715 output,
716 vec![
717 new_event(
718 Key::A,
719 KeyEventType::Pressed,
720 Some(KeyMeaning::Codepoint('a' as u32)),
721 0,
722 ),
723 new_event(
724 Key::A,
725 KeyEventType::Released,
726 Some(KeyMeaning::Codepoint('a' as u32)),
727 0,
728 ),
729 ],
730 )
731 .await;
732 };
733
734 let mut joined_fut = Task::local(async move {
738 let _r = futures::join!(handler_task, main_fut);
739 });
740 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
741 }
742
743 #[test]
744 fn basic_sync_and_cancel_only() {
745 let mut executor = TestExecutor::new_with_fake_time();
746 let (input, receiver) = mpsc::unbounded();
747 let inspector = fuchsia_inspect::Inspector::default();
748 let test_node = inspector.root().create_child("test_node");
749 let handler = Autorepeater::new_with_settings(
750 receiver,
751 default_settings(),
752 &test_node,
753 metrics::MetricsLogger::default(),
754 );
755 let (sender, output) = mpsc::unbounded();
756 let handler_task = Task::local(async move { handler.run(sender).await });
757
758 let main_fut = async move {
759 input
760 .unbounded_send(new_event(
761 Key::A,
762 KeyEventType::Sync,
763 Some(KeyMeaning::Codepoint('a' as u32)),
764 0,
765 ))
766 .unwrap();
767 wait_for_millis(1).await;
768
769 input
770 .unbounded_send(new_event(
771 Key::A,
772 KeyEventType::Cancel,
773 Some(KeyMeaning::Codepoint('a' as u32)),
774 0,
775 ))
776 .unwrap();
777 assert_events(
778 output,
779 vec![
780 new_event(
781 Key::A,
782 KeyEventType::Pressed,
783 Some(KeyMeaning::Codepoint('a' as u32)),
784 0,
785 ),
786 new_event(
787 Key::A,
788 KeyEventType::Released,
789 Some(KeyMeaning::Codepoint('a' as u32)),
790 0,
791 ),
792 ],
793 )
794 .await;
795 };
796 let mut joined_fut = Task::local(async move {
797 let _r = futures::join!(handler_task, main_fut);
798 });
799 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
800 }
801
802 #[test]
804 fn handled_events_are_forwarded() {
805 let mut executor = TestExecutor::new_with_fake_time();
806 let (input, receiver) = mpsc::unbounded();
807 let inspector = fuchsia_inspect::Inspector::default();
808 let test_node = inspector.root().create_child("test_node");
809 let handler = Autorepeater::new_with_settings(
810 receiver,
811 default_settings(),
812 &test_node,
813 metrics::MetricsLogger::default(),
814 );
815 let (sender, output) = mpsc::unbounded();
816 let handler_task = Task::local(async move { handler.run(sender).await });
817
818 let main_fut = async move {
819 input
820 .unbounded_send(new_handled_event(
821 Key::A,
822 KeyEventType::Pressed,
823 Some(KeyMeaning::Codepoint('a' as u32)),
824 0,
825 ))
826 .unwrap();
827
828 wait_for_millis(2000).await;
829
830 input
831 .unbounded_send(new_handled_event(
832 Key::A,
833 KeyEventType::Released,
834 Some(KeyMeaning::Codepoint('a' as u32)),
835 0,
836 ))
837 .unwrap();
838
839 assert_events(
840 output,
841 vec![
842 new_handled_event(
843 Key::A,
844 KeyEventType::Pressed,
845 Some(KeyMeaning::Codepoint('a' as u32)),
846 0,
847 ),
848 new_handled_event(
849 Key::A,
850 KeyEventType::Released,
851 Some(KeyMeaning::Codepoint('a' as u32)),
852 0,
853 ),
854 ],
855 )
856 .await;
857 };
858
859 let mut joined_fut = Task::local(async move {
860 let _r = futures::join!(handler_task, main_fut);
861 });
862 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
863 }
864
865 #[test]
868 fn autorepeat_simple() {
869 let mut executor = TestExecutor::new_with_fake_time();
870
871 let (input, receiver) = mpsc::unbounded();
872 let inspector = fuchsia_inspect::Inspector::default();
873 let test_node = inspector.root().create_child("test_node");
874 let handler = Autorepeater::new_with_settings(
875 receiver,
876 default_settings(),
877 &test_node,
878 metrics::MetricsLogger::default(),
879 );
880 let (sender, output) = mpsc::unbounded();
881 let handler_task = Task::local(async move { handler.run(sender).await });
882
883 let main_fut = async move {
884 input
885 .unbounded_send(new_event(
886 Key::A,
887 KeyEventType::Pressed,
888 Some(KeyMeaning::Codepoint('a' as u32)),
889 0,
890 ))
891 .unwrap();
892
893 wait_for_millis(2000).await;
894
895 input
896 .unbounded_send(new_event(
897 Key::A,
898 KeyEventType::Released,
899 Some(KeyMeaning::Codepoint('a' as u32)),
900 0,
901 ))
902 .unwrap();
903
904 assert_events(
910 output,
911 vec![
912 new_event(
913 Key::A,
914 KeyEventType::Pressed,
915 Some(KeyMeaning::Codepoint('a' as u32)),
916 0,
917 ),
918 new_event(
919 Key::A,
920 KeyEventType::Pressed,
921 Some(KeyMeaning::Codepoint('a' as u32)),
922 1,
923 ),
924 new_event(
925 Key::A,
926 KeyEventType::Pressed,
927 Some(KeyMeaning::Codepoint('a' as u32)),
928 2,
929 ),
930 new_event(
931 Key::A,
932 KeyEventType::Released,
933 Some(KeyMeaning::Codepoint('a' as u32)),
934 0,
935 ),
936 ],
937 )
938 .await;
939 };
940 let mut joined_fut = Task::local(async move {
941 let _r = futures::join!(handler_task, main_fut);
942 });
943 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
944 }
945
946 #[test]
950 fn autorepeat_simple_longer() {
951 let mut executor = TestExecutor::new_with_fake_time();
952
953 let (input, receiver) = mpsc::unbounded();
954 let inspector = fuchsia_inspect::Inspector::default();
955 let test_node = inspector.root().create_child("test_node");
956 let handler = Autorepeater::new_with_settings(
957 receiver,
958 default_settings(),
959 &test_node,
960 metrics::MetricsLogger::default(),
961 );
962 let (sender, output) = mpsc::unbounded();
963 let handler_task = Task::local(async move { handler.run(sender).await });
964
965 let main_fut = async move {
966 input
967 .unbounded_send(new_event(
968 Key::A,
969 KeyEventType::Pressed,
970 Some(KeyMeaning::Codepoint('a' as u32)),
971 0,
972 ))
973 .unwrap();
974
975 wait_for_millis(3000).await;
976
977 input
978 .unbounded_send(new_event(
979 Key::A,
980 KeyEventType::Released,
981 Some(KeyMeaning::Codepoint('a' as u32)),
982 0,
983 ))
984 .unwrap();
985
986 assert_events(
987 output,
988 vec![
989 new_event(
990 Key::A,
991 KeyEventType::Pressed,
992 Some(KeyMeaning::Codepoint('a' as u32)),
993 0,
994 ),
995 new_event(
996 Key::A,
997 KeyEventType::Pressed,
998 Some(KeyMeaning::Codepoint('a' as u32)),
999 1,
1000 ),
1001 new_event(
1002 Key::A,
1003 KeyEventType::Pressed,
1004 Some(KeyMeaning::Codepoint('a' as u32)),
1005 2,
1006 ),
1007 new_event(
1008 Key::A,
1009 KeyEventType::Pressed,
1010 Some(KeyMeaning::Codepoint('a' as u32)),
1011 3,
1012 ),
1013 new_event(
1014 Key::A,
1015 KeyEventType::Released,
1016 Some(KeyMeaning::Codepoint('a' as u32)),
1017 0,
1018 ),
1019 ],
1020 )
1021 .await;
1022 };
1023 let mut joined_fut = Task::local(async move {
1024 let _r = futures::join!(handler_task, main_fut);
1025 });
1026 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1027 }
1028
1029 #[test]
1036 fn autorepeat_takeover() {
1037 let mut executor = TestExecutor::new_with_fake_time();
1038
1039 let (input, receiver) = mpsc::unbounded();
1040 let inspector = fuchsia_inspect::Inspector::default();
1041 let test_node = inspector.root().create_child("test_node");
1042 let handler = Autorepeater::new_with_settings(
1043 receiver,
1044 default_settings(),
1045 &test_node,
1046 metrics::MetricsLogger::default(),
1047 );
1048 let (sender, output) = mpsc::unbounded();
1049 let handler_task = Task::local(async move { handler.run(sender).await });
1050
1051 let main_fut = async move {
1052 input
1053 .unbounded_send(new_event(
1054 Key::A,
1055 KeyEventType::Pressed,
1056 Some(KeyMeaning::Codepoint('a' as u32)),
1057 0,
1058 ))
1059 .unwrap();
1060
1061 wait_for_millis(1600).await;
1062
1063 input
1064 .unbounded_send(new_event(
1065 Key::B,
1066 KeyEventType::Pressed,
1067 Some(KeyMeaning::Codepoint('b' as u32)),
1068 0,
1069 ))
1070 .unwrap();
1071
1072 wait_for_millis(2000).await;
1073
1074 input
1075 .unbounded_send(new_event(
1076 Key::A,
1077 KeyEventType::Released,
1078 Some(KeyMeaning::Codepoint('a' as u32)),
1079 0,
1080 ))
1081 .unwrap();
1082
1083 wait_for_millis(1000).await;
1084
1085 input
1086 .unbounded_send(new_event(
1087 Key::B,
1088 KeyEventType::Released,
1089 Some(KeyMeaning::Codepoint('b' as u32)),
1090 0,
1091 ))
1092 .unwrap();
1093
1094 assert_events(
1095 output,
1096 vec![
1097 new_event(
1098 Key::A,
1099 KeyEventType::Pressed,
1100 Some(KeyMeaning::Codepoint('a' as u32)),
1101 0,
1102 ),
1103 new_event(
1104 Key::A,
1105 KeyEventType::Pressed,
1106 Some(KeyMeaning::Codepoint('a' as u32)),
1107 1,
1108 ),
1109 new_event(
1110 Key::A,
1111 KeyEventType::Pressed,
1112 Some(KeyMeaning::Codepoint('a' as u32)),
1113 2,
1114 ),
1115 new_event(
1116 Key::B,
1117 KeyEventType::Pressed,
1118 Some(KeyMeaning::Codepoint('b' as u32)),
1119 0,
1120 ),
1121 new_event(
1122 Key::B,
1123 KeyEventType::Pressed,
1124 Some(KeyMeaning::Codepoint('b' as u32)),
1125 1,
1126 ),
1127 new_event(
1128 Key::B,
1129 KeyEventType::Pressed,
1130 Some(KeyMeaning::Codepoint('b' as u32)),
1131 2,
1132 ),
1133 new_event(
1134 Key::A,
1135 KeyEventType::Released,
1136 Some(KeyMeaning::Codepoint('a' as u32)),
1137 0,
1138 ),
1139 new_event(
1140 Key::B,
1141 KeyEventType::Pressed,
1142 Some(KeyMeaning::Codepoint('b' as u32)),
1143 3,
1144 ),
1145 new_event(
1146 Key::B,
1147 KeyEventType::Released,
1148 Some(KeyMeaning::Codepoint('b' as u32)),
1149 0,
1150 ),
1151 ],
1152 )
1153 .await;
1154 };
1155 let mut joined_fut = Task::local(async move {
1156 let _r = futures::join!(handler_task, main_fut);
1157 });
1158 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1159 }
1160
1161 #[test]
1168 fn autorepeat_takeover_and_back() {
1169 let mut executor = TestExecutor::new_with_fake_time();
1170
1171 let (input, receiver) = mpsc::unbounded();
1172 let inspector = fuchsia_inspect::Inspector::default();
1173 let test_node = inspector.root().create_child("test_node");
1174 let handler = Autorepeater::new_with_settings(
1175 receiver,
1176 default_settings(),
1177 &test_node,
1178 metrics::MetricsLogger::default(),
1179 );
1180 let (sender, output) = mpsc::unbounded();
1181 let handler_task = Task::local(async move { handler.run(sender).await });
1182
1183 let main_fut = async move {
1184 input
1185 .unbounded_send(new_event(
1186 Key::A,
1187 KeyEventType::Pressed,
1188 Some(KeyMeaning::Codepoint('a' as u32)),
1189 0,
1190 ))
1191 .unwrap();
1192
1193 wait_for_millis(2000).await;
1194
1195 input
1196 .unbounded_send(new_event(
1197 Key::B,
1198 KeyEventType::Pressed,
1199 Some(KeyMeaning::Codepoint('b' as u32)),
1200 0,
1201 ))
1202 .unwrap();
1203
1204 wait_for_millis(2000).await;
1205
1206 input
1207 .unbounded_send(new_event(
1208 Key::B,
1209 KeyEventType::Released,
1210 Some(KeyMeaning::Codepoint('b' as u32)),
1211 0,
1212 ))
1213 .unwrap();
1214
1215 wait_for_millis(2000).await;
1216
1217 input
1218 .unbounded_send(new_event(
1219 Key::A,
1220 KeyEventType::Released,
1221 Some(KeyMeaning::Codepoint('a' as u32)),
1222 0,
1223 ))
1224 .unwrap();
1225
1226 wait_for_millis(2000).await;
1228
1229 assert_events(
1230 output,
1231 vec![
1232 new_event(
1233 Key::A,
1234 KeyEventType::Pressed,
1235 Some(KeyMeaning::Codepoint('a' as u32)),
1236 0,
1237 ),
1238 new_event(
1239 Key::A,
1240 KeyEventType::Pressed,
1241 Some(KeyMeaning::Codepoint('a' as u32)),
1242 1,
1243 ),
1244 new_event(
1245 Key::A,
1246 KeyEventType::Pressed,
1247 Some(KeyMeaning::Codepoint('a' as u32)),
1248 2,
1249 ),
1250 new_event(
1251 Key::B,
1252 KeyEventType::Pressed,
1253 Some(KeyMeaning::Codepoint('b' as u32)),
1254 0,
1255 ),
1256 new_event(
1257 Key::B,
1258 KeyEventType::Pressed,
1259 Some(KeyMeaning::Codepoint('b' as u32)),
1260 1,
1261 ),
1262 new_event(
1263 Key::B,
1264 KeyEventType::Pressed,
1265 Some(KeyMeaning::Codepoint('b' as u32)),
1266 2,
1267 ),
1268 new_event(
1269 Key::B,
1270 KeyEventType::Released,
1271 Some(KeyMeaning::Codepoint('b' as u32)),
1272 0,
1273 ),
1274 new_event(
1276 Key::A,
1277 KeyEventType::Released,
1278 Some(KeyMeaning::Codepoint('a' as u32)),
1279 0,
1280 ),
1281 ],
1282 )
1283 .await;
1284 };
1285 let mut joined_fut = Task::local(async move {
1286 let _r = futures::join!(handler_task, main_fut);
1287 });
1288 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1289 }
1290
1291 #[test]
1292 fn no_autorepeat_for_left_shift() {
1293 let mut executor = TestExecutor::new_with_fake_time();
1294
1295 let (input, receiver) = mpsc::unbounded();
1296 let inspector = fuchsia_inspect::Inspector::default();
1297 let test_node = inspector.root().create_child("test_node");
1298 let handler = Autorepeater::new_with_settings(
1299 receiver,
1300 default_settings(),
1301 &test_node,
1302 metrics::MetricsLogger::default(),
1303 );
1304 let (sender, output) = mpsc::unbounded();
1305 let handler_task = Task::local(async move { handler.run(sender).await });
1306
1307 let main_fut = async move {
1308 input
1309 .unbounded_send(new_event(
1310 Key::LeftShift,
1311 KeyEventType::Pressed,
1312 Some(KeyMeaning::Codepoint(0)),
1316 0,
1317 ))
1318 .unwrap();
1319
1320 wait_for_millis(5000).await;
1321
1322 input
1323 .unbounded_send(new_event(
1324 Key::LeftShift,
1325 KeyEventType::Released,
1326 Some(KeyMeaning::Codepoint(0)),
1327 0,
1328 ))
1329 .unwrap();
1330
1331 assert_events(
1332 output,
1333 vec![
1334 new_event(
1335 Key::LeftShift,
1336 KeyEventType::Pressed,
1337 Some(KeyMeaning::Codepoint(0)),
1338 0,
1339 ),
1340 new_event(
1341 Key::LeftShift,
1342 KeyEventType::Released,
1343 Some(KeyMeaning::Codepoint(0)),
1344 0,
1345 ),
1346 ],
1347 )
1348 .await;
1349 };
1350 let mut joined_fut = Task::local(async move {
1351 let _r = futures::join!(handler_task, main_fut);
1352 });
1353 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1354 }
1355
1356 #[test]
1360 fn shift_a_encapsulated() {
1361 let mut executor = TestExecutor::new_with_fake_time();
1362
1363 let (input, receiver) = mpsc::unbounded();
1364 let inspector = fuchsia_inspect::Inspector::default();
1365 let test_node = inspector.root().create_child("test_node");
1366 let handler = Autorepeater::new_with_settings(
1367 receiver,
1368 default_settings(),
1369 &test_node,
1370 metrics::MetricsLogger::default(),
1371 );
1372 let (sender, output) = mpsc::unbounded();
1373 let handler_task = Task::local(async move { handler.run(sender).await });
1374
1375 let main_fut = async move {
1376 input
1377 .unbounded_send(new_event(
1378 Key::LeftShift,
1379 KeyEventType::Pressed,
1380 Some(KeyMeaning::Codepoint(0)),
1381 0,
1382 ))
1383 .unwrap();
1384
1385 wait_for_millis(2000).await;
1386
1387 input
1388 .unbounded_send(new_event(
1389 Key::A,
1390 KeyEventType::Pressed,
1391 Some(KeyMeaning::Codepoint('A' as u32)),
1392 0,
1393 ))
1394 .unwrap();
1395
1396 wait_for_millis(2000).await;
1397
1398 input
1399 .unbounded_send(new_event(
1400 Key::A,
1401 KeyEventType::Released,
1402 Some(KeyMeaning::Codepoint('A' as u32)),
1403 0,
1404 ))
1405 .unwrap();
1406
1407 wait_for_millis(2000).await;
1408
1409 input
1410 .unbounded_send(new_event(
1411 Key::LeftShift,
1412 KeyEventType::Released,
1413 Some(KeyMeaning::Codepoint(0)),
1414 0,
1415 ))
1416 .unwrap();
1417
1418 assert_events(
1419 output,
1420 vec![
1421 new_event(
1422 Key::LeftShift,
1423 KeyEventType::Pressed,
1424 Some(KeyMeaning::Codepoint(0)),
1425 0,
1426 ),
1427 new_event(
1428 Key::A,
1429 KeyEventType::Pressed,
1430 Some(KeyMeaning::Codepoint('A' as u32)),
1431 0,
1432 ),
1433 new_event(
1434 Key::A,
1435 KeyEventType::Pressed,
1436 Some(KeyMeaning::Codepoint('A' as u32)),
1437 1,
1438 ),
1439 new_event(
1440 Key::A,
1441 KeyEventType::Pressed,
1442 Some(KeyMeaning::Codepoint('A' as u32)),
1443 2,
1444 ),
1445 new_event(
1446 Key::A,
1447 KeyEventType::Released,
1448 Some(KeyMeaning::Codepoint('A' as u32)),
1449 0,
1450 ),
1451 new_event(
1452 Key::LeftShift,
1453 KeyEventType::Released,
1454 Some(KeyMeaning::Codepoint(0)),
1455 0,
1456 ),
1457 ],
1458 )
1459 .await;
1460 };
1461 let mut joined_fut = Task::local(async move {
1462 let _r = futures::join!(handler_task, main_fut);
1463 });
1464 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1465 }
1466
1467 #[test]
1471 fn shift_a_interleaved() {
1472 let mut executor = TestExecutor::new_with_fake_time();
1473
1474 let (input, receiver) = mpsc::unbounded();
1475 let inspector = fuchsia_inspect::Inspector::default();
1476 let test_node = inspector.root().create_child("test_node");
1477 let handler = Autorepeater::new_with_settings(
1478 receiver,
1479 default_settings(),
1480 &test_node,
1481 metrics::MetricsLogger::default(),
1482 );
1483 let (sender, output) = mpsc::unbounded();
1484 let handler_task = Task::local(async move { handler.run(sender).await });
1485
1486 let main_fut = async move {
1487 input
1488 .unbounded_send(new_event(
1489 Key::LeftShift,
1490 KeyEventType::Pressed,
1491 Some(KeyMeaning::Codepoint(0)),
1492 0,
1493 ))
1494 .unwrap();
1495
1496 wait_for_millis(2000).await;
1497
1498 input
1499 .unbounded_send(new_event(
1500 Key::A,
1501 KeyEventType::Pressed,
1502 Some(KeyMeaning::Codepoint('A' as u32)),
1503 0,
1504 ))
1505 .unwrap();
1506
1507 wait_for_millis(2000).await;
1508
1509 input
1510 .unbounded_send(new_event(
1511 Key::LeftShift,
1512 KeyEventType::Released,
1513 Some(KeyMeaning::Codepoint(0)),
1514 0,
1515 ))
1516 .unwrap();
1517
1518 wait_for_millis(2000).await;
1519
1520 input
1521 .unbounded_send(new_event(
1522 Key::A,
1523 KeyEventType::Released,
1524 Some(KeyMeaning::Codepoint('A' as u32)),
1525 0,
1526 ))
1527 .unwrap();
1528
1529 assert_events(
1530 output,
1531 vec![
1532 new_event(
1533 Key::LeftShift,
1534 KeyEventType::Pressed,
1535 Some(KeyMeaning::Codepoint(0)),
1536 0,
1537 ),
1538 new_event(
1539 Key::A,
1540 KeyEventType::Pressed,
1541 Some(KeyMeaning::Codepoint('A' as u32)),
1542 0,
1543 ),
1544 new_event(
1545 Key::A,
1546 KeyEventType::Pressed,
1547 Some(KeyMeaning::Codepoint('A' as u32)),
1548 1,
1549 ),
1550 new_event(
1551 Key::A,
1552 KeyEventType::Pressed,
1553 Some(KeyMeaning::Codepoint('A' as u32)),
1554 2,
1555 ),
1556 new_event(
1557 Key::LeftShift,
1558 KeyEventType::Released,
1559 Some(KeyMeaning::Codepoint(0)),
1560 0,
1561 ),
1562 new_event(
1568 Key::A,
1569 KeyEventType::Pressed,
1570 Some(KeyMeaning::Codepoint('A' as u32)),
1571 3,
1572 ),
1573 new_event(
1574 Key::A,
1575 KeyEventType::Pressed,
1576 Some(KeyMeaning::Codepoint('A' as u32)),
1577 4,
1578 ),
1579 new_event(
1580 Key::A,
1581 KeyEventType::Released,
1582 Some(KeyMeaning::Codepoint('A' as u32)),
1583 0,
1584 ),
1585 ],
1586 )
1587 .await;
1588 };
1589 let mut joined_fut = pin!(async move {
1590 let _r = futures::join!(main_fut, handler_task);
1591 });
1592 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1593 }
1594
1595 #[test]
1596 fn autorepeater_initialized_with_inspect_node() {
1597 let _executor = TestExecutor::new_with_fake_time();
1598
1599 let (_, receiver) = mpsc::unbounded();
1600 let inspector = fuchsia_inspect::Inspector::default();
1601 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
1602 let _autorepeater =
1603 Autorepeater::new(receiver, &fake_handlers_node, metrics::MetricsLogger::default());
1604 diagnostics_assertions::assert_data_tree!(inspector, root: {
1605 input_handlers_node: {
1606 autorepeater: {
1607 events_received_count: 0u64,
1608 events_handled_count: 0u64,
1609 last_received_timestamp_ns: 0u64,
1610 "fuchsia.inspect.Health": {
1611 status: "STARTING_UP",
1612 start_timestamp_nanos: diagnostics_assertions::AnyProperty
1615 },
1616 }
1617 }
1618 });
1619 }
1620
1621 #[test]
1622 fn autorepeat_inspect_counts_events() {
1623 let mut executor = TestExecutor::new_with_fake_time();
1624
1625 let (input, receiver) = mpsc::unbounded();
1626 let inspector = fuchsia_inspect::Inspector::default();
1627 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
1628 let handler = Autorepeater::new_with_settings(
1629 receiver,
1630 default_settings(),
1631 &fake_handlers_node,
1632 metrics::MetricsLogger::default(),
1633 );
1634 let (sender, _output) = mpsc::unbounded();
1635 let handler_task = Task::local(async move { handler.run(sender).await });
1636
1637 let main_fut = async move {
1638 input
1639 .unbounded_send(new_event(
1640 Key::A,
1641 KeyEventType::Pressed,
1642 Some(KeyMeaning::Codepoint('a' as u32)),
1643 0,
1644 ))
1645 .unwrap();
1646
1647 wait_for_millis(1600).await;
1648
1649 input
1650 .unbounded_send(new_event(
1651 Key::B,
1652 KeyEventType::Pressed,
1653 Some(KeyMeaning::Codepoint('b' as u32)),
1654 0,
1655 ))
1656 .unwrap();
1657
1658 wait_for_millis(2000).await;
1659
1660 input
1661 .unbounded_send(new_event(
1662 Key::A,
1663 KeyEventType::Released,
1664 Some(KeyMeaning::Codepoint('a' as u32)),
1665 0,
1666 ))
1667 .unwrap();
1668
1669 wait_for_millis(1000).await;
1670
1671 input
1672 .unbounded_send(new_handled_event(
1673 Key::C,
1674 KeyEventType::Pressed,
1675 Some(KeyMeaning::Codepoint('c' as u32)),
1676 0,
1677 ))
1678 .unwrap();
1679
1680 input
1681 .unbounded_send(new_event(
1682 Key::B,
1683 KeyEventType::Released,
1684 Some(KeyMeaning::Codepoint('b' as u32)),
1685 0,
1686 ))
1687 .unwrap();
1688
1689 wait_for_duration(SLACK_DURATION).await;
1690
1691 diagnostics_assertions::assert_data_tree!(inspector, root: {
1694 input_handlers_node: {
1695 autorepeater: {
1696 events_received_count: 4u64,
1697 events_handled_count: 0u64,
1698 last_received_timestamp_ns: 0u64,
1699 "fuchsia.inspect.Health": {
1700 status: "STARTING_UP",
1701 start_timestamp_nanos: diagnostics_assertions::AnyProperty
1704 },
1705 }
1706 }
1707 });
1708 };
1709 let mut joined_fut = Task::local(async move {
1710 let _r = futures::join!(handler_task, main_fut);
1711 });
1712 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1713 }
1714}