1use crate::input_device::{self, Handled, InputDeviceDescriptor, InputDeviceEvent, InputEvent};
22use crate::input_handler::InputHandlerStatus;
23use crate::keyboard_binding::KeyboardEvent;
24use crate::metrics;
25use anyhow::{Context, Result, anyhow};
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::StreamExt;
31use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
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 let result: Result<input_device::InputEvent, _> = event.clone().try_into();
315 if let Ok(e) = result {
316 self.inspect_status.count_received_event(&e.event_time);
317 }
318 self.process_event(event, &output).await?
319 }
320 AnyEvent::Timeout => self.process_event(event, &output).await?,
321 }
322 }
323 output.close_channel();
326
327 Err(anyhow!("recv loop is never supposed to terminate"))
334 }
335
336 pub fn set_handler_healthy(self: std::rc::Rc<Self>) {
337 self.inspect_status.health_node.borrow_mut().set_ok();
338 }
339
340 pub fn set_handler_unhealthy(self: std::rc::Rc<Self>, msg: &str) {
341 self.inspect_status.health_node.borrow_mut().set_unhealthy(msg);
342 }
343
344 fn set_state(self: &Rc<Self>, state: State) {
346 log::debug!("set state: {:?}", &state);
347 self.state.replace(state);
348 }
349
350 fn get_state(self: &Rc<Self>) -> State {
352 self.state.borrow().clone()
353 }
354
355 async fn process_event(
358 self: &Rc<Self>,
359 event: AnyEvent,
360 output: &UnboundedSender<InputEvent>,
361 ) -> Result<()> {
362 let old_state = self.get_state();
363 log::debug!("process_event: current state: {:?}", &old_state);
364 log::debug!("process_event: inbound event: {:?}", &event);
365 match (old_state, event.clone()) {
366 (State::Dormant, AnyEvent::Keyboard(ev, descriptor, ..)) => {
369 match (ev.get_event_type_folded(), repeatability(ev.get_key_meaning())) {
370 (KeyEventType::Pressed, Repeatability::Yes) => {
373 let _delay_timer = new_autorepeat_timer(
374 self.event_sink.clone(),
375 self.settings.delay,
376 self.metrics_logger.clone(),
377 );
378 self.set_state(State::Armed {
379 armed_event: ev,
380 armed_descriptor: descriptor,
381 _delay_timer,
382 });
383 }
384
385 (_, _) => {}
387 }
388 unbounded_send_logged(&output, event.try_into()?)?;
389 }
390
391 (State::Dormant, AnyEvent::Timeout) => {
396 log::warn!("spurious timeout in the autorepeater");
400 }
401
402 (State::Armed { armed_event, .. }, AnyEvent::Keyboard(ev, descriptor, ..)) => {
417 match (ev.get_event_type_folded(), repeatability(ev.get_key_meaning())) {
418 (KeyEventType::Pressed, Repeatability::Yes) => {
419 let _delay_timer = new_autorepeat_timer(
420 self.event_sink.clone(),
421 self.settings.delay,
422 self.metrics_logger.clone(),
423 );
424 self.set_state(State::Armed {
425 armed_event: ev,
426 armed_descriptor: descriptor,
427 _delay_timer,
428 });
429 }
430
431 (KeyEventType::Released, Repeatability::Yes) => {
432 if KeyboardEvent::same_key(&armed_event, &ev) {
436 self.set_state(State::Dormant);
437 }
438 }
439
440 _ => {}
442 }
443 unbounded_send_logged(&output, event.try_into()?)?;
444 }
445
446 (State::Armed { armed_event, armed_descriptor, .. }, AnyEvent::Timeout) => {
448 let _delay_timer = new_autorepeat_timer(
449 self.event_sink.clone(),
450 self.settings.period,
451 self.metrics_logger.clone(),
452 );
453 let new_event = armed_event
454 .clone()
455 .into_with_repeat_sequence(armed_event.get_repeat_sequence() + 1);
456 let new_event_time = input_device::event_time_or_now(None);
457
458 self.set_state(State::Armed {
459 armed_event: new_event.clone(),
460 armed_descriptor: armed_descriptor.clone(),
461 _delay_timer,
462 });
463 let autorepeat_event =
465 AnyEvent::Keyboard(new_event, armed_descriptor, new_event_time, Handled::No);
466 unbounded_send_logged(&output, autorepeat_event.try_into()?)?;
467 }
468
469 (_, AnyEvent::NonKeyboard(event)) => {
471 unbounded_send_logged(&output, event)?;
472 }
473 }
474 Ok(())
475 }
476}
477
478#[cfg(test)]
479mod tests {
480 use super::*;
481 use crate::testing_utilities;
482 use fidl_fuchsia_input::Key;
483 use fuchsia_async::TestExecutor;
484
485 use futures::Future;
486 use pretty_assertions::assert_eq;
487 use std::pin::pin;
488 use std::task::Poll;
489
490 fn default_settings() -> Settings {
494 Settings {
495 delay: MonotonicDuration::from_millis(500),
496 period: MonotonicDuration::from_seconds(1),
497 }
498 }
499
500 fn new_event(
502 key: Key,
503 event_type: KeyEventType,
504 key_meaning: Option<KeyMeaning>,
505 repeat_sequence: u32,
506 ) -> InputEvent {
507 testing_utilities::create_keyboard_event_with_key_meaning_and_repeat_sequence(
508 key,
509 event_type,
510 None,
511 zx::MonotonicInstant::ZERO,
512 &InputDeviceDescriptor::Fake,
513 None,
514 key_meaning,
515 repeat_sequence,
516 )
517 }
518
519 fn new_handled_event(
520 key: Key,
521 event_type: KeyEventType,
522 key_meaning: Option<KeyMeaning>,
523 repeat_sequence: u32,
524 ) -> InputEvent {
525 let event = new_event(key, event_type, key_meaning, repeat_sequence);
526 InputEvent { handled: Handled::Yes, ..event }
528 }
529
530 async fn wait_for_millis(millis: i64) {
532 wait_for_duration(zx::MonotonicDuration::from_millis(millis)).await;
533 }
534
535 async fn wait_for_duration(duration: MonotonicDuration) {
536 fuchsia_async::Timer::new(MonotonicInstant::after(duration)).await;
537 }
538
539 fn remove_event_time(events: Vec<InputEvent>) -> Vec<InputEvent> {
543 events
544 .into_iter()
545 .map(
546 |InputEvent {
547 device_event,
548 device_descriptor,
549 event_time: _,
550 handled,
551 trace_id: _,
552 }| {
553 InputEvent {
554 device_event,
555 device_descriptor,
556 event_time: zx::MonotonicInstant::ZERO,
557 handled,
558 trace_id: None,
559 }
560 },
561 )
562 .collect()
563 }
564
565 const SLACK_DURATION: MonotonicDuration = zx::MonotonicDuration::from_millis(5000);
568
569 async fn assert_events(output: UnboundedReceiver<InputEvent>, expected: Vec<InputEvent>) {
571 wait_for_duration(SLACK_DURATION).await;
575 assert_eq!(
576 remove_event_time(output.take(expected.len()).collect::<Vec<InputEvent>>().await),
577 expected
578 );
579 }
580
581 fn run_in_fake_time<F>(
599 executor: &mut TestExecutor,
600 main_fut: &mut F,
601 total_duration: MonotonicDuration,
602 ) where
603 F: Future<Output = ()> + Unpin,
604 {
605 const INCREMENT: MonotonicDuration = zx::MonotonicDuration::from_millis(13);
606 let total_duration = total_duration + SLACK_DURATION;
609 let mut current = zx::MonotonicDuration::from_millis(0);
610 let mut poll_status = Poll::Pending;
611
612 while current < total_duration && poll_status == Poll::Pending {
617 executor.set_fake_time(MonotonicInstant::after(INCREMENT));
618 executor.wake_expired_timers();
619 poll_status = executor.run_until_stalled(main_fut);
620 current = current + INCREMENT;
621 }
622 assert_eq!(
623 poll_status,
624 Poll::Ready(()),
625 "the main future did not complete, perhaps increase total_duration?"
626 );
627 }
628
629 #[test]
648 fn basic_press_and_release_only() {
649 let mut executor = TestExecutor::new_with_fake_time();
653
654 let (input, receiver) = mpsc::unbounded();
657
658 let inspector = fuchsia_inspect::Inspector::default();
659 let test_node = inspector.root().create_child("test_node");
660
661 let handler = Autorepeater::new_with_settings(
671 receiver,
672 default_settings(),
673 &test_node,
674 metrics::MetricsLogger::default(),
675 );
676
677 let (sender, output) = mpsc::unbounded();
681
682 let handler_task = Task::local(async move { handler.run(sender).await });
684
685 let main_fut = async move {
687 input
692 .unbounded_send(new_event(
693 Key::A,
694 KeyEventType::Pressed,
695 Some(KeyMeaning::Codepoint('a' as u32)),
696 0,
697 ))
698 .unwrap();
699
700 wait_for_millis(1).await;
703
704 input
705 .unbounded_send(new_event(
706 Key::A,
707 KeyEventType::Released,
708 Some(KeyMeaning::Codepoint('a' as u32)),
709 0,
710 ))
711 .unwrap();
712
713 assert_events(
716 output,
717 vec![
718 new_event(
719 Key::A,
720 KeyEventType::Pressed,
721 Some(KeyMeaning::Codepoint('a' as u32)),
722 0,
723 ),
724 new_event(
725 Key::A,
726 KeyEventType::Released,
727 Some(KeyMeaning::Codepoint('a' as u32)),
728 0,
729 ),
730 ],
731 )
732 .await;
733 };
734
735 let mut joined_fut = Task::local(async move {
739 let _r = futures::join!(handler_task, main_fut);
740 });
741 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
742 }
743
744 #[test]
745 fn basic_sync_and_cancel_only() {
746 let mut executor = TestExecutor::new_with_fake_time();
747 let (input, receiver) = mpsc::unbounded();
748 let inspector = fuchsia_inspect::Inspector::default();
749 let test_node = inspector.root().create_child("test_node");
750 let handler = Autorepeater::new_with_settings(
751 receiver,
752 default_settings(),
753 &test_node,
754 metrics::MetricsLogger::default(),
755 );
756 let (sender, output) = mpsc::unbounded();
757 let handler_task = Task::local(async move { handler.run(sender).await });
758
759 let main_fut = async move {
760 input
761 .unbounded_send(new_event(
762 Key::A,
763 KeyEventType::Sync,
764 Some(KeyMeaning::Codepoint('a' as u32)),
765 0,
766 ))
767 .unwrap();
768 wait_for_millis(1).await;
769
770 input
771 .unbounded_send(new_event(
772 Key::A,
773 KeyEventType::Cancel,
774 Some(KeyMeaning::Codepoint('a' as u32)),
775 0,
776 ))
777 .unwrap();
778 assert_events(
779 output,
780 vec![
781 new_event(
782 Key::A,
783 KeyEventType::Pressed,
784 Some(KeyMeaning::Codepoint('a' as u32)),
785 0,
786 ),
787 new_event(
788 Key::A,
789 KeyEventType::Released,
790 Some(KeyMeaning::Codepoint('a' as u32)),
791 0,
792 ),
793 ],
794 )
795 .await;
796 };
797 let mut joined_fut = Task::local(async move {
798 let _r = futures::join!(handler_task, main_fut);
799 });
800 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
801 }
802
803 #[test]
805 fn handled_events_are_forwarded() {
806 let mut executor = TestExecutor::new_with_fake_time();
807 let (input, receiver) = mpsc::unbounded();
808 let inspector = fuchsia_inspect::Inspector::default();
809 let test_node = inspector.root().create_child("test_node");
810 let handler = Autorepeater::new_with_settings(
811 receiver,
812 default_settings(),
813 &test_node,
814 metrics::MetricsLogger::default(),
815 );
816 let (sender, output) = mpsc::unbounded();
817 let handler_task = Task::local(async move { handler.run(sender).await });
818
819 let main_fut = async move {
820 input
821 .unbounded_send(new_handled_event(
822 Key::A,
823 KeyEventType::Pressed,
824 Some(KeyMeaning::Codepoint('a' as u32)),
825 0,
826 ))
827 .unwrap();
828
829 wait_for_millis(2000).await;
830
831 input
832 .unbounded_send(new_handled_event(
833 Key::A,
834 KeyEventType::Released,
835 Some(KeyMeaning::Codepoint('a' as u32)),
836 0,
837 ))
838 .unwrap();
839
840 assert_events(
841 output,
842 vec![
843 new_handled_event(
844 Key::A,
845 KeyEventType::Pressed,
846 Some(KeyMeaning::Codepoint('a' as u32)),
847 0,
848 ),
849 new_handled_event(
850 Key::A,
851 KeyEventType::Released,
852 Some(KeyMeaning::Codepoint('a' as u32)),
853 0,
854 ),
855 ],
856 )
857 .await;
858 };
859
860 let mut joined_fut = Task::local(async move {
861 let _r = futures::join!(handler_task, main_fut);
862 });
863 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
864 }
865
866 #[test]
869 fn autorepeat_simple() {
870 let mut executor = TestExecutor::new_with_fake_time();
871
872 let (input, receiver) = mpsc::unbounded();
873 let inspector = fuchsia_inspect::Inspector::default();
874 let test_node = inspector.root().create_child("test_node");
875 let handler = Autorepeater::new_with_settings(
876 receiver,
877 default_settings(),
878 &test_node,
879 metrics::MetricsLogger::default(),
880 );
881 let (sender, output) = mpsc::unbounded();
882 let handler_task = Task::local(async move { handler.run(sender).await });
883
884 let main_fut = async move {
885 input
886 .unbounded_send(new_event(
887 Key::A,
888 KeyEventType::Pressed,
889 Some(KeyMeaning::Codepoint('a' as u32)),
890 0,
891 ))
892 .unwrap();
893
894 wait_for_millis(2000).await;
895
896 input
897 .unbounded_send(new_event(
898 Key::A,
899 KeyEventType::Released,
900 Some(KeyMeaning::Codepoint('a' as u32)),
901 0,
902 ))
903 .unwrap();
904
905 assert_events(
911 output,
912 vec![
913 new_event(
914 Key::A,
915 KeyEventType::Pressed,
916 Some(KeyMeaning::Codepoint('a' as u32)),
917 0,
918 ),
919 new_event(
920 Key::A,
921 KeyEventType::Pressed,
922 Some(KeyMeaning::Codepoint('a' as u32)),
923 1,
924 ),
925 new_event(
926 Key::A,
927 KeyEventType::Pressed,
928 Some(KeyMeaning::Codepoint('a' as u32)),
929 2,
930 ),
931 new_event(
932 Key::A,
933 KeyEventType::Released,
934 Some(KeyMeaning::Codepoint('a' as u32)),
935 0,
936 ),
937 ],
938 )
939 .await;
940 };
941 let mut joined_fut = Task::local(async move {
942 let _r = futures::join!(handler_task, main_fut);
943 });
944 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
945 }
946
947 #[test]
951 fn autorepeat_simple_longer() {
952 let mut executor = TestExecutor::new_with_fake_time();
953
954 let (input, receiver) = mpsc::unbounded();
955 let inspector = fuchsia_inspect::Inspector::default();
956 let test_node = inspector.root().create_child("test_node");
957 let handler = Autorepeater::new_with_settings(
958 receiver,
959 default_settings(),
960 &test_node,
961 metrics::MetricsLogger::default(),
962 );
963 let (sender, output) = mpsc::unbounded();
964 let handler_task = Task::local(async move { handler.run(sender).await });
965
966 let main_fut = async move {
967 input
968 .unbounded_send(new_event(
969 Key::A,
970 KeyEventType::Pressed,
971 Some(KeyMeaning::Codepoint('a' as u32)),
972 0,
973 ))
974 .unwrap();
975
976 wait_for_millis(3000).await;
977
978 input
979 .unbounded_send(new_event(
980 Key::A,
981 KeyEventType::Released,
982 Some(KeyMeaning::Codepoint('a' as u32)),
983 0,
984 ))
985 .unwrap();
986
987 assert_events(
988 output,
989 vec![
990 new_event(
991 Key::A,
992 KeyEventType::Pressed,
993 Some(KeyMeaning::Codepoint('a' as u32)),
994 0,
995 ),
996 new_event(
997 Key::A,
998 KeyEventType::Pressed,
999 Some(KeyMeaning::Codepoint('a' as u32)),
1000 1,
1001 ),
1002 new_event(
1003 Key::A,
1004 KeyEventType::Pressed,
1005 Some(KeyMeaning::Codepoint('a' as u32)),
1006 2,
1007 ),
1008 new_event(
1009 Key::A,
1010 KeyEventType::Pressed,
1011 Some(KeyMeaning::Codepoint('a' as u32)),
1012 3,
1013 ),
1014 new_event(
1015 Key::A,
1016 KeyEventType::Released,
1017 Some(KeyMeaning::Codepoint('a' as u32)),
1018 0,
1019 ),
1020 ],
1021 )
1022 .await;
1023 };
1024 let mut joined_fut = Task::local(async move {
1025 let _r = futures::join!(handler_task, main_fut);
1026 });
1027 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1028 }
1029
1030 #[test]
1037 fn autorepeat_takeover() {
1038 let mut executor = TestExecutor::new_with_fake_time();
1039
1040 let (input, receiver) = mpsc::unbounded();
1041 let inspector = fuchsia_inspect::Inspector::default();
1042 let test_node = inspector.root().create_child("test_node");
1043 let handler = Autorepeater::new_with_settings(
1044 receiver,
1045 default_settings(),
1046 &test_node,
1047 metrics::MetricsLogger::default(),
1048 );
1049 let (sender, output) = mpsc::unbounded();
1050 let handler_task = Task::local(async move { handler.run(sender).await });
1051
1052 let main_fut = async move {
1053 input
1054 .unbounded_send(new_event(
1055 Key::A,
1056 KeyEventType::Pressed,
1057 Some(KeyMeaning::Codepoint('a' as u32)),
1058 0,
1059 ))
1060 .unwrap();
1061
1062 wait_for_millis(1600).await;
1063
1064 input
1065 .unbounded_send(new_event(
1066 Key::B,
1067 KeyEventType::Pressed,
1068 Some(KeyMeaning::Codepoint('b' as u32)),
1069 0,
1070 ))
1071 .unwrap();
1072
1073 wait_for_millis(2000).await;
1074
1075 input
1076 .unbounded_send(new_event(
1077 Key::A,
1078 KeyEventType::Released,
1079 Some(KeyMeaning::Codepoint('a' as u32)),
1080 0,
1081 ))
1082 .unwrap();
1083
1084 wait_for_millis(1000).await;
1085
1086 input
1087 .unbounded_send(new_event(
1088 Key::B,
1089 KeyEventType::Released,
1090 Some(KeyMeaning::Codepoint('b' as u32)),
1091 0,
1092 ))
1093 .unwrap();
1094
1095 assert_events(
1096 output,
1097 vec![
1098 new_event(
1099 Key::A,
1100 KeyEventType::Pressed,
1101 Some(KeyMeaning::Codepoint('a' as u32)),
1102 0,
1103 ),
1104 new_event(
1105 Key::A,
1106 KeyEventType::Pressed,
1107 Some(KeyMeaning::Codepoint('a' as u32)),
1108 1,
1109 ),
1110 new_event(
1111 Key::A,
1112 KeyEventType::Pressed,
1113 Some(KeyMeaning::Codepoint('a' as u32)),
1114 2,
1115 ),
1116 new_event(
1117 Key::B,
1118 KeyEventType::Pressed,
1119 Some(KeyMeaning::Codepoint('b' as u32)),
1120 0,
1121 ),
1122 new_event(
1123 Key::B,
1124 KeyEventType::Pressed,
1125 Some(KeyMeaning::Codepoint('b' as u32)),
1126 1,
1127 ),
1128 new_event(
1129 Key::B,
1130 KeyEventType::Pressed,
1131 Some(KeyMeaning::Codepoint('b' as u32)),
1132 2,
1133 ),
1134 new_event(
1135 Key::A,
1136 KeyEventType::Released,
1137 Some(KeyMeaning::Codepoint('a' as u32)),
1138 0,
1139 ),
1140 new_event(
1141 Key::B,
1142 KeyEventType::Pressed,
1143 Some(KeyMeaning::Codepoint('b' as u32)),
1144 3,
1145 ),
1146 new_event(
1147 Key::B,
1148 KeyEventType::Released,
1149 Some(KeyMeaning::Codepoint('b' as u32)),
1150 0,
1151 ),
1152 ],
1153 )
1154 .await;
1155 };
1156 let mut joined_fut = Task::local(async move {
1157 let _r = futures::join!(handler_task, main_fut);
1158 });
1159 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1160 }
1161
1162 #[test]
1169 fn autorepeat_takeover_and_back() {
1170 let mut executor = TestExecutor::new_with_fake_time();
1171
1172 let (input, receiver) = mpsc::unbounded();
1173 let inspector = fuchsia_inspect::Inspector::default();
1174 let test_node = inspector.root().create_child("test_node");
1175 let handler = Autorepeater::new_with_settings(
1176 receiver,
1177 default_settings(),
1178 &test_node,
1179 metrics::MetricsLogger::default(),
1180 );
1181 let (sender, output) = mpsc::unbounded();
1182 let handler_task = Task::local(async move { handler.run(sender).await });
1183
1184 let main_fut = async move {
1185 input
1186 .unbounded_send(new_event(
1187 Key::A,
1188 KeyEventType::Pressed,
1189 Some(KeyMeaning::Codepoint('a' as u32)),
1190 0,
1191 ))
1192 .unwrap();
1193
1194 wait_for_millis(2000).await;
1195
1196 input
1197 .unbounded_send(new_event(
1198 Key::B,
1199 KeyEventType::Pressed,
1200 Some(KeyMeaning::Codepoint('b' as u32)),
1201 0,
1202 ))
1203 .unwrap();
1204
1205 wait_for_millis(2000).await;
1206
1207 input
1208 .unbounded_send(new_event(
1209 Key::B,
1210 KeyEventType::Released,
1211 Some(KeyMeaning::Codepoint('b' as u32)),
1212 0,
1213 ))
1214 .unwrap();
1215
1216 wait_for_millis(2000).await;
1217
1218 input
1219 .unbounded_send(new_event(
1220 Key::A,
1221 KeyEventType::Released,
1222 Some(KeyMeaning::Codepoint('a' as u32)),
1223 0,
1224 ))
1225 .unwrap();
1226
1227 wait_for_millis(2000).await;
1229
1230 assert_events(
1231 output,
1232 vec![
1233 new_event(
1234 Key::A,
1235 KeyEventType::Pressed,
1236 Some(KeyMeaning::Codepoint('a' as u32)),
1237 0,
1238 ),
1239 new_event(
1240 Key::A,
1241 KeyEventType::Pressed,
1242 Some(KeyMeaning::Codepoint('a' as u32)),
1243 1,
1244 ),
1245 new_event(
1246 Key::A,
1247 KeyEventType::Pressed,
1248 Some(KeyMeaning::Codepoint('a' as u32)),
1249 2,
1250 ),
1251 new_event(
1252 Key::B,
1253 KeyEventType::Pressed,
1254 Some(KeyMeaning::Codepoint('b' as u32)),
1255 0,
1256 ),
1257 new_event(
1258 Key::B,
1259 KeyEventType::Pressed,
1260 Some(KeyMeaning::Codepoint('b' as u32)),
1261 1,
1262 ),
1263 new_event(
1264 Key::B,
1265 KeyEventType::Pressed,
1266 Some(KeyMeaning::Codepoint('b' as u32)),
1267 2,
1268 ),
1269 new_event(
1270 Key::B,
1271 KeyEventType::Released,
1272 Some(KeyMeaning::Codepoint('b' as u32)),
1273 0,
1274 ),
1275 new_event(
1277 Key::A,
1278 KeyEventType::Released,
1279 Some(KeyMeaning::Codepoint('a' as u32)),
1280 0,
1281 ),
1282 ],
1283 )
1284 .await;
1285 };
1286 let mut joined_fut = Task::local(async move {
1287 let _r = futures::join!(handler_task, main_fut);
1288 });
1289 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1290 }
1291
1292 #[test]
1293 fn no_autorepeat_for_left_shift() {
1294 let mut executor = TestExecutor::new_with_fake_time();
1295
1296 let (input, receiver) = mpsc::unbounded();
1297 let inspector = fuchsia_inspect::Inspector::default();
1298 let test_node = inspector.root().create_child("test_node");
1299 let handler = Autorepeater::new_with_settings(
1300 receiver,
1301 default_settings(),
1302 &test_node,
1303 metrics::MetricsLogger::default(),
1304 );
1305 let (sender, output) = mpsc::unbounded();
1306 let handler_task = Task::local(async move { handler.run(sender).await });
1307
1308 let main_fut = async move {
1309 input
1310 .unbounded_send(new_event(
1311 Key::LeftShift,
1312 KeyEventType::Pressed,
1313 Some(KeyMeaning::Codepoint(0)),
1317 0,
1318 ))
1319 .unwrap();
1320
1321 wait_for_millis(5000).await;
1322
1323 input
1324 .unbounded_send(new_event(
1325 Key::LeftShift,
1326 KeyEventType::Released,
1327 Some(KeyMeaning::Codepoint(0)),
1328 0,
1329 ))
1330 .unwrap();
1331
1332 assert_events(
1333 output,
1334 vec![
1335 new_event(
1336 Key::LeftShift,
1337 KeyEventType::Pressed,
1338 Some(KeyMeaning::Codepoint(0)),
1339 0,
1340 ),
1341 new_event(
1342 Key::LeftShift,
1343 KeyEventType::Released,
1344 Some(KeyMeaning::Codepoint(0)),
1345 0,
1346 ),
1347 ],
1348 )
1349 .await;
1350 };
1351 let mut joined_fut = Task::local(async move {
1352 let _r = futures::join!(handler_task, main_fut);
1353 });
1354 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1355 }
1356
1357 #[test]
1361 fn shift_a_encapsulated() {
1362 let mut executor = TestExecutor::new_with_fake_time();
1363
1364 let (input, receiver) = mpsc::unbounded();
1365 let inspector = fuchsia_inspect::Inspector::default();
1366 let test_node = inspector.root().create_child("test_node");
1367 let handler = Autorepeater::new_with_settings(
1368 receiver,
1369 default_settings(),
1370 &test_node,
1371 metrics::MetricsLogger::default(),
1372 );
1373 let (sender, output) = mpsc::unbounded();
1374 let handler_task = Task::local(async move { handler.run(sender).await });
1375
1376 let main_fut = async move {
1377 input
1378 .unbounded_send(new_event(
1379 Key::LeftShift,
1380 KeyEventType::Pressed,
1381 Some(KeyMeaning::Codepoint(0)),
1382 0,
1383 ))
1384 .unwrap();
1385
1386 wait_for_millis(2000).await;
1387
1388 input
1389 .unbounded_send(new_event(
1390 Key::A,
1391 KeyEventType::Pressed,
1392 Some(KeyMeaning::Codepoint('A' as u32)),
1393 0,
1394 ))
1395 .unwrap();
1396
1397 wait_for_millis(2000).await;
1398
1399 input
1400 .unbounded_send(new_event(
1401 Key::A,
1402 KeyEventType::Released,
1403 Some(KeyMeaning::Codepoint('A' as u32)),
1404 0,
1405 ))
1406 .unwrap();
1407
1408 wait_for_millis(2000).await;
1409
1410 input
1411 .unbounded_send(new_event(
1412 Key::LeftShift,
1413 KeyEventType::Released,
1414 Some(KeyMeaning::Codepoint(0)),
1415 0,
1416 ))
1417 .unwrap();
1418
1419 assert_events(
1420 output,
1421 vec![
1422 new_event(
1423 Key::LeftShift,
1424 KeyEventType::Pressed,
1425 Some(KeyMeaning::Codepoint(0)),
1426 0,
1427 ),
1428 new_event(
1429 Key::A,
1430 KeyEventType::Pressed,
1431 Some(KeyMeaning::Codepoint('A' as u32)),
1432 0,
1433 ),
1434 new_event(
1435 Key::A,
1436 KeyEventType::Pressed,
1437 Some(KeyMeaning::Codepoint('A' as u32)),
1438 1,
1439 ),
1440 new_event(
1441 Key::A,
1442 KeyEventType::Pressed,
1443 Some(KeyMeaning::Codepoint('A' as u32)),
1444 2,
1445 ),
1446 new_event(
1447 Key::A,
1448 KeyEventType::Released,
1449 Some(KeyMeaning::Codepoint('A' as u32)),
1450 0,
1451 ),
1452 new_event(
1453 Key::LeftShift,
1454 KeyEventType::Released,
1455 Some(KeyMeaning::Codepoint(0)),
1456 0,
1457 ),
1458 ],
1459 )
1460 .await;
1461 };
1462 let mut joined_fut = Task::local(async move {
1463 let _r = futures::join!(handler_task, main_fut);
1464 });
1465 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1466 }
1467
1468 #[test]
1472 fn shift_a_interleaved() {
1473 let mut executor = TestExecutor::new_with_fake_time();
1474
1475 let (input, receiver) = mpsc::unbounded();
1476 let inspector = fuchsia_inspect::Inspector::default();
1477 let test_node = inspector.root().create_child("test_node");
1478 let handler = Autorepeater::new_with_settings(
1479 receiver,
1480 default_settings(),
1481 &test_node,
1482 metrics::MetricsLogger::default(),
1483 );
1484 let (sender, output) = mpsc::unbounded();
1485 let handler_task = Task::local(async move { handler.run(sender).await });
1486
1487 let main_fut = async move {
1488 input
1489 .unbounded_send(new_event(
1490 Key::LeftShift,
1491 KeyEventType::Pressed,
1492 Some(KeyMeaning::Codepoint(0)),
1493 0,
1494 ))
1495 .unwrap();
1496
1497 wait_for_millis(2000).await;
1498
1499 input
1500 .unbounded_send(new_event(
1501 Key::A,
1502 KeyEventType::Pressed,
1503 Some(KeyMeaning::Codepoint('A' as u32)),
1504 0,
1505 ))
1506 .unwrap();
1507
1508 wait_for_millis(2000).await;
1509
1510 input
1511 .unbounded_send(new_event(
1512 Key::LeftShift,
1513 KeyEventType::Released,
1514 Some(KeyMeaning::Codepoint(0)),
1515 0,
1516 ))
1517 .unwrap();
1518
1519 wait_for_millis(2000).await;
1520
1521 input
1522 .unbounded_send(new_event(
1523 Key::A,
1524 KeyEventType::Released,
1525 Some(KeyMeaning::Codepoint('A' as u32)),
1526 0,
1527 ))
1528 .unwrap();
1529
1530 assert_events(
1531 output,
1532 vec![
1533 new_event(
1534 Key::LeftShift,
1535 KeyEventType::Pressed,
1536 Some(KeyMeaning::Codepoint(0)),
1537 0,
1538 ),
1539 new_event(
1540 Key::A,
1541 KeyEventType::Pressed,
1542 Some(KeyMeaning::Codepoint('A' as u32)),
1543 0,
1544 ),
1545 new_event(
1546 Key::A,
1547 KeyEventType::Pressed,
1548 Some(KeyMeaning::Codepoint('A' as u32)),
1549 1,
1550 ),
1551 new_event(
1552 Key::A,
1553 KeyEventType::Pressed,
1554 Some(KeyMeaning::Codepoint('A' as u32)),
1555 2,
1556 ),
1557 new_event(
1558 Key::LeftShift,
1559 KeyEventType::Released,
1560 Some(KeyMeaning::Codepoint(0)),
1561 0,
1562 ),
1563 new_event(
1569 Key::A,
1570 KeyEventType::Pressed,
1571 Some(KeyMeaning::Codepoint('A' as u32)),
1572 3,
1573 ),
1574 new_event(
1575 Key::A,
1576 KeyEventType::Pressed,
1577 Some(KeyMeaning::Codepoint('A' as u32)),
1578 4,
1579 ),
1580 new_event(
1581 Key::A,
1582 KeyEventType::Released,
1583 Some(KeyMeaning::Codepoint('A' as u32)),
1584 0,
1585 ),
1586 ],
1587 )
1588 .await;
1589 };
1590 let mut joined_fut = pin!(async move {
1591 let _r = futures::join!(main_fut, handler_task);
1592 });
1593 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1594 }
1595
1596 #[test]
1597 fn autorepeater_initialized_with_inspect_node() {
1598 let mut executor = TestExecutor::new_with_fake_time();
1599
1600 let (_, receiver) = mpsc::unbounded();
1601 let inspector = fuchsia_inspect::Inspector::default();
1602 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
1603 let _autorepeater =
1604 Autorepeater::new(receiver, &fake_handlers_node, metrics::MetricsLogger::default());
1605 diagnostics_assertions::assert_data_tree!(@executor executor, inspector, root: {
1606 input_handlers_node: {
1607 autorepeater: {
1608 events_received_count: 0u64,
1609 events_handled_count: 0u64,
1610 last_received_timestamp_ns: 0u64,
1611 "fuchsia.inspect.Health": {
1612 status: "STARTING_UP",
1613 start_timestamp_nanos: diagnostics_assertions::AnyProperty
1616 },
1617 }
1618 }
1619 });
1620 }
1621
1622 #[test]
1623 fn autorepeat_inspect_counts_events() {
1624 let mut executor = TestExecutor::new_with_fake_time();
1625
1626 let (input, receiver) = mpsc::unbounded();
1627 let inspector = fuchsia_inspect::Inspector::default();
1628 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
1629 let handler = Autorepeater::new_with_settings(
1630 receiver,
1631 default_settings(),
1632 &fake_handlers_node,
1633 metrics::MetricsLogger::default(),
1634 );
1635 let (sender, _output) = mpsc::unbounded();
1636 let handler_task = Task::local(async move { handler.run(sender).await });
1637
1638 let main_fut = async move {
1639 input
1640 .unbounded_send(new_event(
1641 Key::A,
1642 KeyEventType::Pressed,
1643 Some(KeyMeaning::Codepoint('a' as u32)),
1644 0,
1645 ))
1646 .unwrap();
1647
1648 wait_for_millis(1600).await;
1649
1650 input
1651 .unbounded_send(new_event(
1652 Key::B,
1653 KeyEventType::Pressed,
1654 Some(KeyMeaning::Codepoint('b' as u32)),
1655 0,
1656 ))
1657 .unwrap();
1658
1659 wait_for_millis(2000).await;
1660
1661 input
1662 .unbounded_send(new_event(
1663 Key::A,
1664 KeyEventType::Released,
1665 Some(KeyMeaning::Codepoint('a' as u32)),
1666 0,
1667 ))
1668 .unwrap();
1669
1670 wait_for_millis(1000).await;
1671
1672 input
1673 .unbounded_send(new_handled_event(
1674 Key::C,
1675 KeyEventType::Pressed,
1676 Some(KeyMeaning::Codepoint('c' as u32)),
1677 0,
1678 ))
1679 .unwrap();
1680
1681 input
1682 .unbounded_send(new_event(
1683 Key::B,
1684 KeyEventType::Released,
1685 Some(KeyMeaning::Codepoint('b' as u32)),
1686 0,
1687 ))
1688 .unwrap();
1689
1690 wait_for_duration(SLACK_DURATION).await;
1691
1692 diagnostics_assertions::assert_data_tree!(inspector, root: {
1695 input_handlers_node: {
1696 autorepeater: {
1697 events_received_count: 4u64,
1698 events_handled_count: 0u64,
1699 last_received_timestamp_ns: 0u64,
1700 "fuchsia.inspect.Health": {
1701 status: "STARTING_UP",
1702 start_timestamp_nanos: diagnostics_assertions::AnyProperty
1705 },
1706 }
1707 }
1708 });
1709 };
1710 let mut joined_fut = Task::local(async move {
1711 let _r = futures::join!(handler_task, main_fut);
1712 });
1713 run_in_fake_time(&mut executor, &mut joined_fut, zx::MonotonicDuration::from_seconds(10));
1714 }
1715}