Skip to main content

input_synthesis/
synthesizer.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::derive_key_sequence;
6use anyhow::{Error, ensure};
7use async_trait::async_trait;
8use fidl_fuchsia_input as input;
9use fidl_fuchsia_input_report::MouseInputReport;
10use fidl_fuchsia_ui_input::{KeyboardReport, Touch};
11use fidl_fuchsia_ui_input3 as input3;
12use fuchsia_async as fasync;
13use log::debug;
14use serde::{Deserialize, Deserializer};
15use std::thread;
16use std::time::Duration;
17
18// Abstracts over input injection services (which are provided by input device registries).
19pub trait InputDeviceRegistry {
20    fn add_touchscreen_device(
21        &mut self,
22        width: u32,
23        height: u32,
24    ) -> Result<Box<dyn InputDevice>, Error>;
25    fn add_keyboard_device(&mut self) -> Result<Box<dyn InputDevice>, Error>;
26    fn add_media_buttons_device(&mut self) -> Result<Box<dyn InputDevice>, Error>;
27    fn add_mouse_device(&mut self, width: u32, height: u32) -> Result<Box<dyn InputDevice>, Error>;
28}
29
30// Abstracts over the various interactions that a user might have with an input device.
31// Note that the input-synthesis crate deliberately chooses not to "sub-type" input devices.
32// This avoids additional code complexity, and allows the crate to support tests that
33// deliberately send events that do not match the expected event type for a device.
34#[async_trait(?Send)]
35pub trait InputDevice {
36    /// Sends a media buttons report with the specified buttons pressed.
37    fn media_buttons(&mut self, pressed_buttons: Vec<MediaButton>, time: u64) -> Result<(), Error>;
38
39    /// Sends a keyboard report with keys defined mostly in terms of USB HID usage
40    /// page 7. This is sufficient for keyboard keys, but does not cover the full
41    /// extent of keys that Fuchsia supports. As result, the KeyboardReport is converted
42    /// internally into Fuchsia's encoding before being forwarded.
43    fn key_press(&mut self, keyboard: KeyboardReport, time: u64) -> Result<(), Error>;
44
45    /// Sends a keyboard report using the whole range of key codes. Key codes provided
46    /// are not modified or mapped in any way.
47    /// This differs from `key_press`, which performs special mapping for key codes
48    /// from USB HID Page 0x7.
49    fn key_press_raw(&mut self, keyboard: KeyboardReport, time: u64) -> Result<(), Error>;
50    fn key_press_usage(&mut self, usage: Option<u32>, time: u64) -> Result<(), Error>;
51    fn tap(&mut self, pos: Option<(u32, u32)>, time: u64) -> Result<(), Error>;
52    fn multi_finger_tap(&mut self, fingers: Option<Vec<Touch>>, time: u64) -> Result<(), Error>;
53
54    /// Sends a mouse report with the specified relative cursor movement and buttons pressed.
55    fn mouse(&mut self, report: MouseInputReport, time: u64) -> Result<(), Error>;
56
57    // Returns a `Future` which resolves when all input reports for this device
58    // have been sent to the FIDL peer, or when an error occurs.
59    //
60    // The possible errors are implementation-specific, but may include:
61    // * Errors reading from the FIDL peer
62    // * Errors writing to the FIDL peer
63    //
64    // # Resolves to
65    // * `Ok(())` if all reports were written successfully
66    // * `Err` otherwise
67    //
68    // # Note
69    // When the future resolves, input reports may still be sitting unread in the
70    // channel to the FIDL peer.
71    async fn flush(self: Box<Self>) -> Result<(), Error>;
72}
73
74/// The buttons supported by `media_button_event()`.
75#[derive(PartialOrd, PartialEq, Ord, Eq)]
76pub enum MediaButton {
77    VolumeUp,
78    VolumeDown,
79    MicMute,
80    FactoryReset,
81    Pause,
82    CameraDisable,
83}
84
85fn monotonic_nanos() -> Result<u64, Error> {
86    u64::try_from(zx::MonotonicInstant::get().into_nanos()).map_err(Into::into)
87}
88
89async fn repeat_with_delay(
90    times: usize,
91    delay: Duration,
92    device: &mut dyn InputDevice,
93    f1: impl Fn(usize, &mut dyn InputDevice) -> Result<(), Error>,
94    f2: impl Fn(usize, &mut dyn InputDevice) -> Result<(), Error>,
95) -> Result<(), Error> {
96    for i in 0..times {
97        f1(i, device)?;
98        fasync::Timer::new(fasync::MonotonicInstant::after(delay.into())).await;
99        f2(i, device)?;
100    }
101
102    Ok(())
103}
104
105/// Sends a media buttons report with the specified buttons pressed.
106pub async fn media_button_event<I: IntoIterator<Item = MediaButton>>(
107    pressed_buttons: I,
108    registry: &mut dyn InputDeviceRegistry,
109) -> Result<(), Error> {
110    let mut input_device = registry.add_media_buttons_device()?;
111    input_device.media_buttons(pressed_buttons.into_iter().collect(), monotonic_nanos()?)?;
112    input_device.flush().await
113}
114
115/// A single key event to be replayed by `dispatch_key_events_async`.
116///
117/// See [crate::dispatch_key_events] for details of the key event type and the event timing.
118///
119/// For example, a key press like this:
120///
121/// ```ignore
122/// Key1: _________/"""""""""""""""\\___________
123///                ^               ^--- key released
124///                `------------------- key pressed
125///       |<------>|  <-- duration_since_start (50ms)
126///       |<---------------------->| duration_since_start (100ms)
127/// ```
128///
129/// would be described with a sequence of two `TimedKeyEvent`s (pseudo-code):
130///
131/// ```
132/// [
133///    { Key1,  50ms, PRESSED  },
134///    { Key1, 100ms, RELEASED },
135/// ]
136/// ```
137///
138/// This is not overly useful in the case of a single key press, but is useful to model multiple
139/// concurrent keypresses, while allowing an arbitrary interleaving of key events.
140///
141/// Consider a more complicated timing diagram like this one:
142///
143/// ```ignore
144/// Key1: _________/"""""""""""""""\\_____________
145/// Key2: ____/"""""""""""""""\\__________________
146/// Key3: ______/"""""""""""""""\\________________
147/// Key4: _____________/"""""""""""""""\\_________
148/// Key5: ________________ __/""""""\\____________
149/// Key6: ________/""""""\\_______________________
150/// ```
151///
152/// It then becomes obvious how modeling individual events allows us to express this interaction.
153/// Furthermore anchoring `duration_since_start` to the beginning of the key sequence (instead of,
154/// for example, specifying the duration of each key press) gives a common time reference and makes
155/// it fairly easy to express the intended key interaction in terms of a `TimedKeyEvent` sequence.
156#[derive(Debug, Clone, Eq, PartialEq)]
157pub struct TimedKeyEvent {
158    /// The [input::Key] which changed state.
159    pub key: input::Key,
160    /// The duration of time,  relative to the start of the key event sequence that this `TimedKeyEvent`
161    /// is part of, at which this event happened at.
162    pub duration_since_start: Duration,
163    /// The type of state change that happened to `key`.  Was it pressed, released or something
164    /// else.
165    pub event_type: input3::KeyEventType,
166}
167
168impl TimedKeyEvent {
169    /// Creates a new [TimedKeyEvent] to inject into the input pipeline.  `key` is
170    /// the key to be pressed (using Fuchsia HID-like encoding), `type_` is the
171    /// event type (Pressed, or Released etc), and `duration_since_start` is the
172    /// duration since the start of the entire event sequence that the key event
173    /// should be scheduled at.
174    pub fn new(
175        key: input::Key,
176        type_: input3::KeyEventType,
177        duration_since_start: Duration,
178    ) -> Self {
179        Self { key, duration_since_start, event_type: type_ }
180    }
181
182    /// Deserializes a vector of `TimedKeyEvent`.
183    /// A custom deserializer is used because Vec<_> does not work
184    /// with serde, and the [TimedKeyEvent] has constituents that don't
185    /// have a derived serde representation.
186    /// See: https://github.com/serde-rs/serde/issues/723#issuecomment-382501277
187    pub fn vec<'de, D>(deserializer: D) -> Result<Vec<TimedKeyEvent>, D::Error>
188    where
189        D: Deserializer<'de>,
190    {
191        // Should correspond to TimedKeyEvent, except all fields are described by their underlying
192        // primitive values.
193        #[derive(Deserialize, Debug)]
194        struct TimedKeyEventDes {
195            // The Fuchsia encoded USB HID key, per input::Key.
196            key: u32,
197            // A Duration.
198            duration_millis: u64,
199            // An input3::TimedKeyEventType.
200            #[serde(rename = "type")]
201            type_: u32,
202        }
203
204        impl Into<TimedKeyEvent> for TimedKeyEventDes {
205            /// Reconstructs the typed elements of [TimedKeyEvent] from primitives.
206            fn into(self) -> TimedKeyEvent {
207                TimedKeyEvent::new(
208                    input::Key::from_primitive(self.key)
209                        .unwrap_or_else(|| panic!("Key::from_primitive failed on: {:?}", self)),
210                    input3::KeyEventType::from_primitive(self.type_).unwrap_or_else(|| {
211                        panic!("KeyEventType::from_primitive failed on: {:?}", self)
212                    }),
213                    Duration::from_millis(self.duration_millis),
214                )
215            }
216        }
217
218        let v = Vec::deserialize(deserializer)?;
219        Ok(v.into_iter().map(|a: TimedKeyEventDes| a.into()).collect())
220    }
221}
222
223/// Replays the sequence of events (see [Replayer::replay]) with the correct timing.
224struct Replayer<'a> {
225    // Invariant: pressed_keys.iter() must use ascending iteration
226    // ordering.
227    pressed_keys: std::collections::BTreeSet<input::Key>,
228    // The input device registry to use.
229    registry: &'a mut dyn InputDeviceRegistry,
230}
231
232impl<'a> Replayer<'a> {
233    fn new(registry: &'a mut dyn InputDeviceRegistry) -> Self {
234        Replayer { pressed_keys: std::collections::BTreeSet::new(), registry }
235    }
236
237    /// Replays the given sequence of key events with the correct timing spacing
238    /// between the events.
239    ///
240    /// All timing in [TimedKeyEvent] is relative to the instance in the monotonic clock base at which
241    /// we started replaying the entire event sequence.  The replay returns an error in case
242    /// the events are not sequenced with strictly increasing timestamps.
243    async fn replay<'b: 'a>(&mut self, events: &'b [TimedKeyEvent]) -> Result<(), Error> {
244        let mut last_key_event_at = Duration::from_micros(0);
245
246        // Verify that the key events are scheduled in a nondecreasing timestamp sequence.
247        for key_event in events {
248            if key_event.duration_since_start < last_key_event_at {
249                return Err(anyhow::anyhow!(
250                    concat!(
251                        "TimedKeyEvent was requested out of sequence: ",
252                        "TimedKeyEvent: {:?}, low watermark for duration_since_start: {:?}"
253                    ),
254                    key_event,
255                    last_key_event_at
256                ));
257            }
258            if key_event.duration_since_start == last_key_event_at {
259                // If you see this error message, read the documentation for how to send key events
260                // correctly in the TimedKeyEvent documentation.
261                return Err(anyhow::anyhow!(
262                    concat!(
263                        "TimedKeyEvent was requested at the same time instant as a previous event. ",
264                        "This is not allowed, each key event must happen at a distinct timestamp: ",
265                        "TimedKeyEvent: {:?}, low watermark for duration_since_start: {:?}"
266                    ),
267                    key_event,
268                    last_key_event_at
269                ));
270            }
271            last_key_event_at = key_event.duration_since_start;
272        }
273
274        let mut input_device = self.registry.add_keyboard_device()?;
275        let started_at = monotonic_nanos()?;
276        for key_event in events {
277            use input3::KeyEventType;
278            match key_event.event_type {
279                KeyEventType::Pressed | KeyEventType::Sync => {
280                    self.pressed_keys.insert(key_event.key.clone());
281                }
282                KeyEventType::Released | KeyEventType::Cancel => {
283                    self.pressed_keys.remove(&key_event.key);
284                }
285            }
286
287            // The sequence below should be an async task.  The complicating factor is that
288            // input_device lifetime needs to be 'static for this to be schedulable on a
289            // fuchsia::async::Task. So for the time being, we skip that part.
290            let processed_at = Duration::from_nanos(monotonic_nanos()? - started_at);
291            let desired_at = &key_event.duration_since_start;
292            if processed_at < *desired_at {
293                fasync::Timer::new(fasync::MonotonicInstant::after(
294                    (*desired_at - processed_at).into(),
295                ))
296                .await;
297            }
298            input_device.key_press_raw(self.make_input_report(), monotonic_nanos()?)?;
299        }
300
301        input_device.flush().await
302    }
303
304    /// Creates a keyboard report based on the keys that are currently pressed.
305    ///
306    /// The pressed keys are always reported in the nondecreasing order of their respective key
307    /// codes, so a single distinct key chord will be always reported as a single distinct
308    /// `KeyboardReport`.
309    fn make_input_report(&self) -> KeyboardReport {
310        KeyboardReport {
311            pressed_keys: self.pressed_keys.iter().map(|k| k.into_primitive()).collect(),
312        }
313    }
314}
315
316/// Dispatches the supplied `events` into  a keyboard device registered into `registry`, honoring
317/// the timing sequence that is described in them to the extent that they are possible to schedule.
318pub(crate) async fn dispatch_key_events_async(
319    events: &[TimedKeyEvent],
320    registry: &mut dyn InputDeviceRegistry,
321) -> Result<(), Error> {
322    Replayer::new(registry).replay(events).await
323}
324
325pub(crate) async fn keyboard_event(
326    usage: u32,
327    duration: Duration,
328    registry: &mut dyn InputDeviceRegistry,
329) -> Result<(), Error> {
330    let mut input_device = registry.add_keyboard_device()?;
331
332    repeat_with_delay(
333        1,
334        duration,
335        input_device.as_mut(),
336        |_i, device| {
337            // Key pressed.
338            device.key_press_usage(Some(usage), monotonic_nanos()?)
339        },
340        |_i, device| {
341            // Key released.
342            device.key_press_usage(None, monotonic_nanos()?)
343        },
344    )
345    .await?;
346
347    input_device.flush().await
348}
349
350/// Simulates `input` being typed on a keyboard, with `key_event_duration` between key events.
351///
352/// # Requirements
353/// * `input` must be non-empty
354/// * `input` must only contain characters representable using the current keyboard layout
355///    and locale. (At present, it is assumed that the current layout and locale are
356///   `US-QWERTY` and `en-US`, respectively.)
357///
358/// # Resolves to
359/// * `Ok(())` if the arguments met the requirements above, and the events were successfully
360///   injected.
361/// * `Err(Error)` otherwise.
362///
363/// # Corner case handling
364/// * `key_event_duration` of zero is permitted, and will result in events being generated as
365///    quickly as possible.
366pub async fn text(
367    input: String,
368    key_event_duration: Duration,
369    registry: &mut dyn InputDeviceRegistry,
370) -> Result<(), Error> {
371    let mut input_device = registry.add_keyboard_device()?;
372    let key_sequence = derive_key_sequence(&keymaps::US_QWERTY, &input)
373        .ok_or_else(|| anyhow::format_err!("Cannot translate text to key sequence"))?;
374
375    debug!(input:% = input, key_sequence:?, key_event_duration:?; "synthesizer::text");
376    let mut key_iter = key_sequence.into_iter().peekable();
377    while let Some(keyboard) = key_iter.next() {
378        input_device.key_press(keyboard, monotonic_nanos()?)?;
379        if key_iter.peek().is_some() {
380            thread::sleep(key_event_duration);
381        }
382    }
383
384    input_device.flush().await
385}
386
387pub async fn tap_event(
388    x: u32,
389    y: u32,
390    width: u32,
391    height: u32,
392    tap_event_count: usize,
393    duration: Duration,
394    registry: &mut dyn InputDeviceRegistry,
395) -> Result<(), Error> {
396    let mut input_device = registry.add_touchscreen_device(width, height)?;
397    let tap_duration = duration / tap_event_count as u32;
398
399    repeat_with_delay(
400        tap_event_count,
401        tap_duration,
402        input_device.as_mut(),
403        |_i, device| {
404            // Touch down.
405            device.tap(Some((x, y)), monotonic_nanos()?)
406        },
407        |_i, device| {
408            // Touch up.
409            device.tap(None, monotonic_nanos()?)
410        },
411    )
412    .await?;
413
414    input_device.flush().await
415}
416
417pub(crate) async fn multi_finger_tap_event(
418    fingers: Vec<Touch>,
419    width: u32,
420    height: u32,
421    tap_event_count: usize,
422    duration: Duration,
423    registry: &mut dyn InputDeviceRegistry,
424) -> Result<(), Error> {
425    let mut input_device = registry.add_touchscreen_device(width, height)?;
426    let multi_finger_tap_duration = duration / tap_event_count as u32;
427
428    repeat_with_delay(
429        tap_event_count,
430        multi_finger_tap_duration,
431        input_device.as_mut(),
432        |_i, device| {
433            // Touch down.
434            device.multi_finger_tap(Some(fingers.clone()), monotonic_nanos()?)
435        },
436        |_i, device| {
437            // Touch up.
438            device.multi_finger_tap(None, monotonic_nanos()?)
439        },
440    )
441    .await?;
442
443    input_device.flush().await
444}
445
446pub(crate) async fn swipe(
447    x0: u32,
448    y0: u32,
449    x1: u32,
450    y1: u32,
451    width: u32,
452    height: u32,
453    move_event_count: usize,
454    duration: Duration,
455    registry: &mut dyn InputDeviceRegistry,
456) -> Result<(), Error> {
457    multi_finger_swipe(
458        vec![(x0, y0)],
459        vec![(x1, y1)],
460        width,
461        height,
462        move_event_count,
463        duration,
464        registry,
465    )
466    .await
467}
468
469pub(crate) async fn multi_finger_swipe(
470    start_fingers: Vec<(u32, u32)>,
471    end_fingers: Vec<(u32, u32)>,
472    width: u32,
473    height: u32,
474    move_event_count: usize,
475    duration: Duration,
476    registry: &mut dyn InputDeviceRegistry,
477) -> Result<(), Error> {
478    ensure!(
479        start_fingers.len() == end_fingers.len(),
480        "start_fingers.len() != end_fingers.len() ({} != {})",
481        start_fingers.len(),
482        end_fingers.len()
483    );
484    ensure!(
485        u32::try_from(start_fingers.len() + 1).is_ok(),
486        "fingers exceed capacity of `finger_id`!"
487    );
488
489    let mut input_device = registry.add_touchscreen_device(width, height)?;
490
491    // Note: coordinates are coverted to `f64` before subtraction, because u32 subtraction
492    // would overflow when swiping from higher coordinates to lower coordinates.
493    let finger_delta_x = start_fingers
494        .iter()
495        .zip(end_fingers.iter())
496        .map(|((start_x, _start_y), (end_x, _end_y))| {
497            (*end_x as f64 - *start_x as f64) / std::cmp::max(move_event_count, 1) as f64
498        })
499        .collect::<Vec<_>>();
500    let finger_delta_y = start_fingers
501        .iter()
502        .zip(end_fingers.iter())
503        .map(|((_start_x, start_y), (_end_x, end_y))| {
504            (*end_y as f64 - *start_y as f64) / std::cmp::max(move_event_count, 1) as f64
505        })
506        .collect::<Vec<_>>();
507
508    let swipe_event_delay = if move_event_count > 1 {
509        // We have move_event_count + 2 events:
510        //   DOWN
511        //   MOVE x move_event_count
512        //   UP
513        // so we need (move_event_count + 1) delays.
514        duration / (move_event_count + 1) as u32
515    } else {
516        duration
517    };
518
519    repeat_with_delay(
520        move_event_count + 2, // +2 to account for DOWN and UP events
521        swipe_event_delay,
522        input_device.as_mut(),
523        |i, device| {
524            let time = monotonic_nanos()?;
525            match i {
526                // DOWN
527                0 => device.multi_finger_tap(
528                    Some(
529                        start_fingers
530                            .iter()
531                            .enumerate()
532                            .map(|(finger_index, (x, y))| Touch {
533                                finger_id: (finger_index + 1) as u32,
534                                x: *x as i32,
535                                y: *y as i32,
536                                width: 0,
537                                height: 0,
538                            })
539                            .collect(),
540                    ),
541                    time,
542                ),
543                // MOVE
544                i if i <= move_event_count => device.multi_finger_tap(
545                    Some(
546                        start_fingers
547                            .iter()
548                            .enumerate()
549                            .map(|(finger_index, (x, y))| Touch {
550                                finger_id: (finger_index + 1) as u32,
551                                x: (*x as f64 + (i as f64 * finger_delta_x[finger_index]).round())
552                                    as i32,
553                                y: (*y as f64 + (i as f64 * finger_delta_y[finger_index]).round())
554                                    as i32,
555                                width: 0,
556                                height: 0,
557                            })
558                            .collect(),
559                    ),
560                    time,
561                ),
562                // UP
563                i if i == (move_event_count + 1) => device.multi_finger_tap(None, time),
564                i => panic!("unexpected loop iteration {}", i),
565            }
566        },
567        |_, _| Ok(()),
568    )
569    .await?;
570
571    input_device.flush().await
572}
573
574/// The buttons supported by `mouse()`.
575pub type MouseButton = u8;
576
577pub async fn add_mouse_device(
578    width: u32,
579    height: u32,
580    registry: &mut dyn InputDeviceRegistry,
581) -> Result<Box<dyn InputDevice>, Error> {
582    registry.add_mouse_device(width, height)
583}
584
585#[cfg(test)]
586mod tests {
587    use super::*;
588    use anyhow::Context as _;
589    use fuchsia_async as fasync;
590    use serde::Deserialize;
591
592    #[derive(Deserialize, Debug, Eq, PartialEq)]
593    struct KeyEventsRequest {
594        #[serde(default, deserialize_with = "TimedKeyEvent::vec")]
595        pub key_events: Vec<TimedKeyEvent>,
596    }
597
598    #[test]
599    fn deserialize_key_event() -> Result<(), Error> {
600        let request_json = r#"{
601          "key_events": [
602            {
603              "key": 458756,
604              "duration_millis": 100,
605              "type": 1
606            }
607          ]
608        }"#;
609        let event: KeyEventsRequest = serde_json::from_str(&request_json)?;
610        assert_eq!(
611            event,
612            KeyEventsRequest {
613                key_events: vec![TimedKeyEvent {
614                    key: input::Key::A,
615                    duration_since_start: Duration::from_millis(100),
616                    event_type: input3::KeyEventType::Pressed,
617                },],
618            }
619        );
620        Ok(())
621    }
622
623    #[test]
624    fn deserialize_key_event_maformed_input() {
625        let tests: Vec<&'static str> = vec![
626            // "type" has a wrong value.
627            r#"{
628              "key_events": [
629                {
630                  "key": 458756,
631                  "duration_millis": 100,
632                  "type": 99999,
633                }
634              ]
635            }"#,
636            // "key" has a value that is too small.
637            r#"{
638              "key_events": [
639                {
640                  "key": 12,
641                  "duration_millis": 100,
642                  "type": 1,
643                }
644              ]
645            }"#,
646            // "type" is missing.
647            r#"{
648              "key_events": [
649                {
650                  "key": 12,
651                  "duration_millis": 100,
652                }
653              ]
654            }"#,
655            // "duration" is missing.
656            r#"{
657              "key_events": [
658                {
659                  "key": 458756,
660                  "type": 1
661                }
662              ]
663            }"#,
664            // "key" is missing.
665            r#"{
666              "key_events": [
667                {
668                  "duration_millis": 100,
669                  "type": 1
670                }
671              ]
672            }"#,
673        ];
674        for test in tests.iter() {
675            serde_json::from_str::<KeyEventsRequest>(test)
676                .expect_err(&format!("malformed input should not parse: {}", &test));
677        }
678    }
679
680    mod event_synthesis {
681        use super::*;
682        use fidl::endpoints;
683        use fidl_fuchsia_input_report::MOUSE_MAX_NUM_BUTTONS;
684        use fidl_fuchsia_ui_input::{
685            InputDeviceMarker, InputDeviceProxy as FidlInputDeviceProxy, InputDeviceRequest,
686            InputDeviceRequestStream, InputReport, MediaButtonsReport, MouseReport,
687            TouchscreenReport,
688        };
689        use futures::stream::StreamExt;
690        use std::collections::HashSet;
691
692        // Like `InputReport`, but with the `Box`-ed items inlined.
693        struct InlineInputReport {
694            event_time: u64,
695            keyboard: Option<KeyboardReport>,
696            media_buttons: Option<MediaButtonsReport>,
697            touchscreen: Option<TouchscreenReport>,
698            mouse: Option<MouseReport>,
699        }
700
701        impl InlineInputReport {
702            fn new(input_report: InputReport) -> Self {
703                Self {
704                    event_time: input_report.event_time,
705                    keyboard: input_report.keyboard.map(|boxed| *boxed),
706                    media_buttons: input_report.media_buttons.map(|boxed| *boxed),
707                    touchscreen: input_report.touchscreen.map(|boxed| *boxed),
708                    mouse: input_report.mouse.map(|boxed| *boxed),
709                }
710            }
711        }
712
713        // An `impl InputDeviceRegistry` which provides access to the `InputDeviceRequest`s sent to
714        // the device registered with the `InputDeviceRegistry`. Assumes that only one device is
715        // registered.
716        struct FakeInputDeviceRegistry {
717            event_stream: Option<InputDeviceRequestStream>,
718        }
719
720        impl InputDeviceRegistry for FakeInputDeviceRegistry {
721            fn add_touchscreen_device(
722                &mut self,
723                _width: u32,
724                _height: u32,
725            ) -> Result<Box<dyn InputDevice>, Error> {
726                self.add_device()
727            }
728
729            fn add_keyboard_device(&mut self) -> Result<Box<dyn InputDevice>, Error> {
730                self.add_device()
731            }
732
733            fn add_media_buttons_device(&mut self) -> Result<Box<dyn InputDevice>, Error> {
734                self.add_device()
735            }
736
737            fn add_mouse_device(
738                &mut self,
739                _width: u32,
740                _height: u32,
741            ) -> Result<Box<dyn InputDevice>, Error> {
742                self.add_device()
743            }
744        }
745
746        impl FakeInputDeviceRegistry {
747            fn new() -> Self {
748                Self { event_stream: None }
749            }
750
751            async fn get_events(self: Self) -> Vec<Result<InlineInputReport, String>> {
752                match self.event_stream {
753                    Some(event_stream) => {
754                        event_stream
755                            .map(|fidl_result| match fidl_result {
756                                Ok(InputDeviceRequest::DispatchReport { report, .. }) => {
757                                    Ok(InlineInputReport::new(report))
758                                }
759                                Err(fidl_error) => Err(format!("FIDL error: {}", fidl_error)),
760                            })
761                            .collect()
762                            .await
763                    }
764                    None => vec![Err(format!(
765                        "called get_events() on InputDeviceRegistry with no `event_stream`"
766                    ))],
767                }
768            }
769
770            fn add_device(&mut self) -> Result<Box<dyn InputDevice>, Error> {
771                let (proxy, event_stream) =
772                    endpoints::create_proxy_and_stream::<InputDeviceMarker>();
773                self.event_stream = Some(event_stream);
774                Ok(Box::new(FakeInputDevice::new(proxy)))
775            }
776        }
777
778        /// Returns a u32 representation of `buttons`, where each u8 of `buttons` is an id of a button and
779        /// indicates the position of a bit to set.
780        ///
781        /// This supports hashsets containing numbers from 1 to fidl_input_report::MOUSE_MAX_NUM_BUTTONS.
782        ///
783        /// # Parameters
784        /// - `buttons`: The hashset containing the position of bits to be set.
785        ///
786        /// # Example
787        /// ```
788        /// let bits = get_u32_from_buttons(&HashSet::from_iter(vec![1, 3, 5]).into_iter());
789        /// assert_eq!(bits, 21 /* ...00010101 */)
790        /// ```
791        pub fn get_u32_from_buttons(buttons: &HashSet<MouseButton>) -> u32 {
792            let mut bits: u32 = 0;
793            for button in buttons {
794                if *button > 0 && *button <= MOUSE_MAX_NUM_BUTTONS as u8 {
795                    bits = ((1 as u32) << *button - 1) | bits;
796                }
797            }
798
799            bits
800        }
801
802        // Provides an `impl InputDevice` which forwards requests to a `FidlInputDeviceProxy`.
803        // Useful when a test wants to inspect the requests to an `InputDevice`.
804        struct FakeInputDevice {
805            fidl_proxy: FidlInputDeviceProxy,
806        }
807
808        #[async_trait(?Send)]
809        impl InputDevice for FakeInputDevice {
810            fn media_buttons(
811                &mut self,
812                pressed_buttons: Vec<MediaButton>,
813                time: u64,
814            ) -> Result<(), Error> {
815                self.fidl_proxy
816                    .dispatch_report(&InputReport {
817                        event_time: time,
818                        keyboard: None,
819                        media_buttons: Some(Box::new(MediaButtonsReport {
820                            volume_up: pressed_buttons.contains(&MediaButton::VolumeUp),
821                            volume_down: pressed_buttons.contains(&MediaButton::VolumeDown),
822                            mic_mute: pressed_buttons.contains(&MediaButton::MicMute),
823                            reset: pressed_buttons.contains(&MediaButton::FactoryReset),
824                            pause: pressed_buttons.contains(&MediaButton::Pause),
825                            camera_disable: pressed_buttons.contains(&MediaButton::CameraDisable),
826                        })),
827                        mouse: None,
828                        stylus: None,
829                        touchscreen: None,
830                        sensor: None,
831                        trace_id: 0,
832                    })
833                    .map_err(Into::into)
834            }
835
836            fn key_press(&mut self, keyboard: KeyboardReport, time: u64) -> Result<(), Error> {
837                self.key_press_raw(keyboard, time)
838            }
839
840            fn key_press_raw(&mut self, keyboard: KeyboardReport, time: u64) -> Result<(), Error> {
841                self.fidl_proxy
842                    .dispatch_report(&InputReport {
843                        event_time: time,
844                        keyboard: Some(Box::new(keyboard)),
845                        media_buttons: None,
846                        mouse: None,
847                        stylus: None,
848                        touchscreen: None,
849                        sensor: None,
850                        trace_id: 0,
851                    })
852                    .map_err(Into::into)
853            }
854
855            fn key_press_usage(&mut self, usage: Option<u32>, time: u64) -> Result<(), Error> {
856                self.key_press(
857                    KeyboardReport {
858                        pressed_keys: match usage {
859                            Some(usage) => vec![usage],
860                            None => vec![],
861                        },
862                    },
863                    time,
864                )
865                .map_err(Into::into)
866            }
867
868            fn tap(&mut self, pos: Option<(u32, u32)>, time: u64) -> Result<(), Error> {
869                match pos {
870                    Some((x, y)) => self.multi_finger_tap(
871                        Some(vec![Touch {
872                            finger_id: 1,
873                            x: x as i32,
874                            y: y as i32,
875                            width: 0,
876                            height: 0,
877                        }]),
878                        time,
879                    ),
880                    None => self.multi_finger_tap(None, time),
881                }
882                .map_err(Into::into)
883            }
884
885            fn multi_finger_tap(
886                &mut self,
887                fingers: Option<Vec<Touch>>,
888                time: u64,
889            ) -> Result<(), Error> {
890                self.fidl_proxy
891                    .dispatch_report(&InputReport {
892                        event_time: time,
893                        keyboard: None,
894                        media_buttons: None,
895                        mouse: None,
896                        stylus: None,
897                        touchscreen: Some(Box::new(TouchscreenReport {
898                            touches: match fingers {
899                                Some(fingers) => fingers,
900                                None => vec![],
901                            },
902                        })),
903                        sensor: None,
904                        trace_id: 0,
905                    })
906                    .map_err(Into::into)
907            }
908
909            fn mouse(&mut self, report: MouseInputReport, time: u64) -> Result<(), Error> {
910                self.fidl_proxy
911                    .dispatch_report(&InputReport {
912                        event_time: time,
913                        keyboard: None,
914                        media_buttons: None,
915                        mouse: Some(Box::new(MouseReport {
916                            rel_x: report.movement_x.unwrap() as i32,
917                            rel_y: report.movement_y.unwrap() as i32,
918                            rel_hscroll: report.scroll_h.unwrap_or(0) as i32,
919                            rel_vscroll: report.scroll_v.unwrap_or(0) as i32,
920                            pressed_buttons: match report.pressed_buttons {
921                                Some(buttons) => {
922                                    get_u32_from_buttons(&HashSet::from_iter(buttons.into_iter()))
923                                }
924                                None => 0,
925                            },
926                        })),
927                        stylus: None,
928                        touchscreen: None,
929                        sensor: None,
930                        trace_id: 0,
931                    })
932                    .map_err(Into::into)
933            }
934
935            async fn flush(self: Box<Self>) -> Result<(), Error> {
936                Ok(())
937            }
938        }
939
940        impl FakeInputDevice {
941            fn new(fidl_proxy: FidlInputDeviceProxy) -> Self {
942                Self { fidl_proxy }
943            }
944        }
945
946        /// Transforms an `IntoIterator<Item = Result<InlineInputReport, _>>` into a
947        /// `Vec<Result</* $field-specific-type */, _>>`, by projecting `$field` out of the
948        /// `InlineInputReport`s.
949        macro_rules! project {
950            ( $events:expr, $field:ident ) => {
951                $events
952                    .into_iter()
953                    .map(|result| result.map(|report| report.$field))
954                    .collect::<Vec<_>>()
955            };
956        }
957
958        #[fasync::run_singlethreaded(test)]
959        async fn media_event_report() -> Result<(), Error> {
960            let mut fake_event_listener = FakeInputDeviceRegistry::new();
961            media_button_event(
962                vec![
963                    MediaButton::VolumeUp,
964                    MediaButton::MicMute,
965                    MediaButton::Pause,
966                    MediaButton::CameraDisable,
967                ],
968                &mut fake_event_listener,
969            )
970            .await?;
971            assert_eq!(
972                project!(fake_event_listener.get_events().await, media_buttons),
973                [Ok(Some(MediaButtonsReport {
974                    volume_up: true,
975                    volume_down: false,
976                    mic_mute: true,
977                    reset: false,
978                    pause: true,
979                    camera_disable: true,
980                }))]
981            );
982            Ok(())
983        }
984
985        #[fasync::run_singlethreaded(test)]
986        async fn keyboard_event_report() -> Result<(), Error> {
987            let mut fake_event_listener = FakeInputDeviceRegistry::new();
988            keyboard_event(40, Duration::from_millis(0), &mut fake_event_listener).await?;
989            assert_eq!(
990                project!(fake_event_listener.get_events().await, keyboard),
991                [
992                    Ok(Some(KeyboardReport { pressed_keys: vec![40] })),
993                    Ok(Some(KeyboardReport { pressed_keys: vec![] }))
994                ]
995            );
996            Ok(())
997        }
998
999        #[fasync::run_singlethreaded(test)]
1000        async fn dispatch_key_events() -> Result<(), Error> {
1001            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1002
1003            // Configures a two-key chord:
1004            // A: _/^^^^^\___
1005            // B: __/^^^\____
1006            dispatch_key_events_async(
1007                &vec![
1008                    TimedKeyEvent::new(
1009                        input::Key::A,
1010                        input3::KeyEventType::Pressed,
1011                        Duration::from_millis(10),
1012                    ),
1013                    TimedKeyEvent::new(
1014                        input::Key::B,
1015                        input3::KeyEventType::Pressed,
1016                        Duration::from_millis(20),
1017                    ),
1018                    TimedKeyEvent::new(
1019                        input::Key::B,
1020                        input3::KeyEventType::Released,
1021                        Duration::from_millis(50),
1022                    ),
1023                    TimedKeyEvent::new(
1024                        input::Key::A,
1025                        input3::KeyEventType::Released,
1026                        Duration::from_millis(60),
1027                    ),
1028                ],
1029                &mut fake_event_listener,
1030            )
1031            .await?;
1032            assert_eq!(
1033                project!(fake_event_listener.get_events().await, keyboard),
1034                [
1035                    Ok(Some(KeyboardReport { pressed_keys: vec![input::Key::A.into_primitive()] })),
1036                    Ok(Some(KeyboardReport {
1037                        pressed_keys: vec![
1038                            input::Key::A.into_primitive(),
1039                            input::Key::B.into_primitive()
1040                        ]
1041                    })),
1042                    Ok(Some(KeyboardReport { pressed_keys: vec![input::Key::A.into_primitive()] })),
1043                    Ok(Some(KeyboardReport { pressed_keys: vec![] }))
1044                ]
1045            );
1046            Ok(())
1047        }
1048
1049        #[fasync::run_singlethreaded(test)]
1050        async fn dispatch_key_events_in_wrong_sequence() -> Result<(), Error> {
1051            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1052
1053            // Configures a two-key chord in the wrong temporal order.
1054            let result = dispatch_key_events_async(
1055                &vec![
1056                    TimedKeyEvent::new(
1057                        input::Key::A,
1058                        input3::KeyEventType::Pressed,
1059                        Duration::from_millis(20),
1060                    ),
1061                    TimedKeyEvent::new(
1062                        input::Key::B,
1063                        input3::KeyEventType::Pressed,
1064                        Duration::from_millis(10),
1065                    ),
1066                ],
1067                &mut fake_event_listener,
1068            )
1069            .await;
1070            match result {
1071                Err(_) => Ok(()),
1072                Ok(_) => Err(anyhow::anyhow!("expected error but got Ok")),
1073            }
1074        }
1075
1076        #[fasync::run_singlethreaded(test)]
1077        async fn dispatch_key_events_with_same_timestamp() -> Result<(), Error> {
1078            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1079
1080            // Configures a two-key chord in the wrong temporal order.
1081            let result = dispatch_key_events_async(
1082                &vec![
1083                    TimedKeyEvent::new(
1084                        input::Key::A,
1085                        input3::KeyEventType::Pressed,
1086                        Duration::from_millis(20),
1087                    ),
1088                    TimedKeyEvent::new(
1089                        input::Key::B,
1090                        input3::KeyEventType::Pressed,
1091                        Duration::from_millis(20),
1092                    ),
1093                ],
1094                &mut fake_event_listener,
1095            )
1096            .await;
1097            match result {
1098                Err(_) => Ok(()),
1099                Ok(_) => Err(anyhow::anyhow!("expected error but got Ok")),
1100            }
1101        }
1102
1103        #[fasync::run_singlethreaded(test)]
1104        async fn text_event_report() -> Result<(), Error> {
1105            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1106            text("A".to_string(), Duration::from_millis(0), &mut fake_event_listener).await?;
1107            assert_eq!(
1108                project!(fake_event_listener.get_events().await, keyboard),
1109                [
1110                    Ok(Some(KeyboardReport { pressed_keys: vec![225] })),
1111                    Ok(Some(KeyboardReport { pressed_keys: vec![4, 225] })),
1112                    Ok(Some(KeyboardReport { pressed_keys: vec![] })),
1113                ]
1114            );
1115            Ok(())
1116        }
1117
1118        #[fasync::run_singlethreaded(test)]
1119        async fn multi_finger_tap_event_report() -> Result<(), Error> {
1120            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1121            let fingers = vec![
1122                Touch { finger_id: 1, x: 0, y: 0, width: 0, height: 0 },
1123                Touch { finger_id: 2, x: 20, y: 20, width: 0, height: 0 },
1124                Touch { finger_id: 3, x: 40, y: 40, width: 0, height: 0 },
1125                Touch { finger_id: 4, x: 60, y: 60, width: 0, height: 0 },
1126            ];
1127            multi_finger_tap_event(
1128                fingers,
1129                1000,
1130                1000,
1131                1,
1132                Duration::from_millis(0),
1133                &mut fake_event_listener,
1134            )
1135            .await?;
1136            assert_eq!(
1137                project!(fake_event_listener.get_events().await, touchscreen),
1138                [
1139                    Ok(Some(TouchscreenReport {
1140                        touches: vec![
1141                            Touch { finger_id: 1, x: 0, y: 0, width: 0, height: 0 },
1142                            Touch { finger_id: 2, x: 20, y: 20, width: 0, height: 0 },
1143                            Touch { finger_id: 3, x: 40, y: 40, width: 0, height: 0 },
1144                            Touch { finger_id: 4, x: 60, y: 60, width: 0, height: 0 },
1145                        ],
1146                    })),
1147                    Ok(Some(TouchscreenReport { touches: vec![] })),
1148                ]
1149            );
1150            Ok(())
1151        }
1152
1153        #[fasync::run_singlethreaded(test)]
1154        async fn tap_event_report() -> Result<(), Error> {
1155            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1156            tap_event(10, 10, 1000, 1000, 1, Duration::from_millis(0), &mut fake_event_listener)
1157                .await?;
1158            assert_eq!(
1159                project!(fake_event_listener.get_events().await, touchscreen),
1160                [
1161                    Ok(Some(TouchscreenReport {
1162                        touches: vec![Touch { finger_id: 1, x: 10, y: 10, width: 0, height: 0 }]
1163                    })),
1164                    Ok(Some(TouchscreenReport { touches: vec![] })),
1165                ]
1166            );
1167            Ok(())
1168        }
1169
1170        #[fasync::run_singlethreaded(test)]
1171        async fn swipe_event_report() -> Result<(), Error> {
1172            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1173            swipe(
1174                10,
1175                10,
1176                100,
1177                100,
1178                1000,
1179                1000,
1180                2,
1181                Duration::from_millis(0),
1182                &mut fake_event_listener,
1183            )
1184            .await?;
1185            assert_eq!(
1186                project!(fake_event_listener.get_events().await, touchscreen),
1187                [
1188                    Ok(Some(TouchscreenReport {
1189                        touches: vec![Touch { finger_id: 1, x: 10, y: 10, width: 0, height: 0 }],
1190                    })),
1191                    Ok(Some(TouchscreenReport {
1192                        touches: vec![Touch { finger_id: 1, x: 55, y: 55, width: 0, height: 0 }],
1193                    })),
1194                    Ok(Some(TouchscreenReport {
1195                        touches: vec![Touch { finger_id: 1, x: 100, y: 100, width: 0, height: 0 }],
1196                    })),
1197                    Ok(Some(TouchscreenReport { touches: vec![] })),
1198                ]
1199            );
1200            Ok(())
1201        }
1202
1203        #[fasync::run_singlethreaded(test)]
1204        async fn swipe_event_report_inverted() -> Result<(), Error> {
1205            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1206            swipe(
1207                100,
1208                100,
1209                10,
1210                10,
1211                1000,
1212                1000,
1213                2,
1214                Duration::from_millis(0),
1215                &mut fake_event_listener,
1216            )
1217            .await?;
1218            assert_eq!(
1219                project!(fake_event_listener.get_events().await, touchscreen),
1220                [
1221                    Ok(Some(TouchscreenReport {
1222                        touches: vec![Touch { finger_id: 1, x: 100, y: 100, width: 0, height: 0 }],
1223                    })),
1224                    Ok(Some(TouchscreenReport {
1225                        touches: vec![Touch { finger_id: 1, x: 55, y: 55, width: 0, height: 0 }],
1226                    })),
1227                    Ok(Some(TouchscreenReport {
1228                        touches: vec![Touch { finger_id: 1, x: 10, y: 10, width: 0, height: 0 }],
1229                    })),
1230                    Ok(Some(TouchscreenReport { touches: vec![] })),
1231                ]
1232            );
1233            Ok(())
1234        }
1235
1236        #[fasync::run_singlethreaded(test)]
1237        async fn multi_finger_swipe_event_report() -> Result<(), Error> {
1238            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1239            multi_finger_swipe(
1240                vec![(10, 10), (20, 20), (30, 30)],
1241                vec![(100, 100), (120, 120), (150, 150)],
1242                1000,
1243                1000,
1244                2,
1245                Duration::from_millis(0),
1246                &mut fake_event_listener,
1247            )
1248            .await?;
1249            assert_eq!(
1250                project!(fake_event_listener.get_events().await, touchscreen),
1251                [
1252                    Ok(Some(TouchscreenReport {
1253                        touches: vec![
1254                            Touch { finger_id: 1, x: 10, y: 10, width: 0, height: 0 },
1255                            Touch { finger_id: 2, x: 20, y: 20, width: 0, height: 0 },
1256                            Touch { finger_id: 3, x: 30, y: 30, width: 0, height: 0 }
1257                        ],
1258                    })),
1259                    Ok(Some(TouchscreenReport {
1260                        touches: vec![
1261                            Touch { finger_id: 1, x: 55, y: 55, width: 0, height: 0 },
1262                            Touch { finger_id: 2, x: 70, y: 70, width: 0, height: 0 },
1263                            Touch { finger_id: 3, x: 90, y: 90, width: 0, height: 0 }
1264                        ],
1265                    })),
1266                    Ok(Some(TouchscreenReport {
1267                        touches: vec![
1268                            Touch { finger_id: 1, x: 100, y: 100, width: 0, height: 0 },
1269                            Touch { finger_id: 2, x: 120, y: 120, width: 0, height: 0 },
1270                            Touch { finger_id: 3, x: 150, y: 150, width: 0, height: 0 }
1271                        ],
1272                    })),
1273                    Ok(Some(TouchscreenReport { touches: vec![] })),
1274                ]
1275            );
1276            Ok(())
1277        }
1278
1279        #[fasync::run_singlethreaded(test)]
1280        async fn multi_finger_swipe_event_report_inverted() -> Result<(), Error> {
1281            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1282            multi_finger_swipe(
1283                vec![(100, 100), (120, 120), (150, 150)],
1284                vec![(10, 10), (20, 20), (30, 30)],
1285                1000,
1286                1000,
1287                2,
1288                Duration::from_millis(0),
1289                &mut fake_event_listener,
1290            )
1291            .await?;
1292            assert_eq!(
1293                project!(fake_event_listener.get_events().await, touchscreen),
1294                [
1295                    Ok(Some(TouchscreenReport {
1296                        touches: vec![
1297                            Touch { finger_id: 1, x: 100, y: 100, width: 0, height: 0 },
1298                            Touch { finger_id: 2, x: 120, y: 120, width: 0, height: 0 },
1299                            Touch { finger_id: 3, x: 150, y: 150, width: 0, height: 0 }
1300                        ],
1301                    })),
1302                    Ok(Some(TouchscreenReport {
1303                        touches: vec![
1304                            Touch { finger_id: 1, x: 55, y: 55, width: 0, height: 0 },
1305                            Touch { finger_id: 2, x: 70, y: 70, width: 0, height: 0 },
1306                            Touch { finger_id: 3, x: 90, y: 90, width: 0, height: 0 }
1307                        ],
1308                    })),
1309                    Ok(Some(TouchscreenReport {
1310                        touches: vec![
1311                            Touch { finger_id: 1, x: 10, y: 10, width: 0, height: 0 },
1312                            Touch { finger_id: 2, x: 20, y: 20, width: 0, height: 0 },
1313                            Touch { finger_id: 3, x: 30, y: 30, width: 0, height: 0 }
1314                        ],
1315                    })),
1316                    Ok(Some(TouchscreenReport { touches: vec![] })),
1317                ]
1318            );
1319            Ok(())
1320        }
1321
1322        #[fasync::run_singlethreaded(test)]
1323        async fn multi_finger_swipe_event_zero_move_events() -> Result<(), Error> {
1324            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1325            multi_finger_swipe(
1326                vec![(10, 10), (20, 20), (30, 30)],
1327                vec![(100, 100), (120, 120), (150, 150)],
1328                1000,
1329                1000,
1330                0,
1331                Duration::from_millis(0),
1332                &mut fake_event_listener,
1333            )
1334            .await?;
1335            assert_eq!(
1336                project!(fake_event_listener.get_events().await, touchscreen),
1337                [
1338                    Ok(Some(TouchscreenReport {
1339                        touches: vec![
1340                            Touch { finger_id: 1, x: 10, y: 10, width: 0, height: 0 },
1341                            Touch { finger_id: 2, x: 20, y: 20, width: 0, height: 0 },
1342                            Touch { finger_id: 3, x: 30, y: 30, width: 0, height: 0 }
1343                        ],
1344                    })),
1345                    Ok(Some(TouchscreenReport { touches: vec![] })),
1346                ]
1347            );
1348            Ok(())
1349        }
1350
1351        #[fasync::run_singlethreaded(test)]
1352        async fn mouse_event_report() -> Result<(), Error> {
1353            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1354            add_mouse_device(100, 100, &mut fake_event_listener).await?.mouse(
1355                MouseInputReport {
1356                    movement_x: Some(10),
1357                    movement_y: Some(15),
1358                    ..Default::default()
1359                },
1360                monotonic_nanos()?,
1361            )?;
1362            assert_eq!(
1363                project!(fake_event_listener.get_events().await, mouse),
1364                [Ok(Some(MouseReport {
1365                    rel_x: 10,
1366                    rel_y: 15,
1367                    pressed_buttons: 0,
1368                    rel_hscroll: 0,
1369                    rel_vscroll: 0
1370                })),]
1371            );
1372            Ok(())
1373        }
1374
1375        #[fasync::run_singlethreaded(test)]
1376        async fn events_use_monotonic_time() -> Result<(), Error> {
1377            let mut fake_event_listener = FakeInputDeviceRegistry::new();
1378            let synthesis_start_time = monotonic_nanos()?;
1379            media_button_event(
1380                vec![
1381                    MediaButton::VolumeUp,
1382                    MediaButton::MicMute,
1383                    MediaButton::Pause,
1384                    MediaButton::CameraDisable,
1385                ],
1386                &mut fake_event_listener,
1387            )
1388            .await?;
1389
1390            let synthesis_end_time = monotonic_nanos()?;
1391            let fidl_result = fake_event_listener
1392                .get_events()
1393                .await
1394                .into_iter()
1395                .nth(0)
1396                .expect("received 0 events");
1397            let timestamp =
1398                fidl_result.map_err(anyhow::Error::msg).context("fidl call")?.event_time;
1399
1400            // Note well: neither condition is sufficient on its own, to verify that
1401            // `synthesizer` has used the correct clock. For example:
1402            //
1403            // * `timestamp >= synthesis_start_time` would be true for a `UNIX_EPOCH` clock
1404            //   with the correct time, since the elapsed time from 1970-01-01T00:00:00+00:00
1405            //   to now is (much) larger than the elapsed time from boot to `synthesis_start_time`
1406            // * `timestamp <= synthesis_end_time` would be true for a `UNIX_EPOCH` clock
1407            //   has been recently set to 0, because `synthesis_end_time` is highly unlikely to
1408            //   be near 0 (as it is monotonic from boot)
1409            //
1410            // By bracketing between monotonic clock reads before and after the event generation,
1411            // this test avoids the hazards above. The test also avoids the hazard of using a
1412            // fixed offset from the start time (which could flake on a slow builder).
1413            assert!(
1414                timestamp >= synthesis_start_time,
1415                "timestamp={} should be >= start={}",
1416                timestamp,
1417                synthesis_start_time
1418            );
1419            assert!(
1420                timestamp <= synthesis_end_time,
1421                "timestamp={} should be <= end={}",
1422                timestamp,
1423                synthesis_end_time
1424            );
1425            Ok(())
1426        }
1427    }
1428
1429    mod device_registration {
1430        use super::*;
1431        use assert_matches::assert_matches;
1432
1433        #[derive(Debug)]
1434        enum DeviceType {
1435            Keyboard,
1436            MediaButtons,
1437            Touchscreen,
1438            Mouse,
1439        }
1440
1441        // An `impl InputDeviceRegistry` which provides access to the `DeviceType`s which have been
1442        // registered with the `InputDeviceRegistry`.
1443        struct FakeInputDeviceRegistry {
1444            device_types: Vec<DeviceType>,
1445        }
1446
1447        impl InputDeviceRegistry for FakeInputDeviceRegistry {
1448            fn add_touchscreen_device(
1449                &mut self,
1450                _width: u32,
1451                _height: u32,
1452            ) -> Result<Box<dyn InputDevice>, Error> {
1453                self.add_device(DeviceType::Touchscreen)
1454            }
1455
1456            fn add_keyboard_device(&mut self) -> Result<Box<dyn InputDevice>, Error> {
1457                self.add_device(DeviceType::Keyboard)
1458            }
1459
1460            fn add_media_buttons_device(&mut self) -> Result<Box<dyn InputDevice>, Error> {
1461                self.add_device(DeviceType::MediaButtons)
1462            }
1463
1464            fn add_mouse_device(
1465                &mut self,
1466                _width: u32,
1467                _height: u32,
1468            ) -> Result<Box<dyn InputDevice>, Error> {
1469                self.add_device(DeviceType::Mouse)
1470            }
1471        }
1472
1473        impl FakeInputDeviceRegistry {
1474            fn new() -> Self {
1475                Self { device_types: vec![] }
1476            }
1477
1478            fn add_device(
1479                &mut self,
1480                device_type: DeviceType,
1481            ) -> Result<Box<dyn InputDevice>, Error> {
1482                self.device_types.push(device_type);
1483                Ok(Box::new(FakeInputDevice))
1484            }
1485        }
1486
1487        // Provides an `impl InputDevice` which always returns `Ok(())`. Useful when the
1488        // events themselves are not important to the test.
1489        struct FakeInputDevice;
1490
1491        #[async_trait(?Send)]
1492        impl InputDevice for FakeInputDevice {
1493            fn media_buttons(
1494                &mut self,
1495                _pressed_buttons: Vec<MediaButton>,
1496                _time: u64,
1497            ) -> Result<(), Error> {
1498                Ok(())
1499            }
1500
1501            fn key_press(&mut self, _keyboard: KeyboardReport, _time: u64) -> Result<(), Error> {
1502                Ok(())
1503            }
1504
1505            fn key_press_raw(
1506                &mut self,
1507                _keyboard: KeyboardReport,
1508                _time: u64,
1509            ) -> Result<(), Error> {
1510                Ok(())
1511            }
1512
1513            fn key_press_usage(&mut self, _usage: Option<u32>, _time: u64) -> Result<(), Error> {
1514                Ok(())
1515            }
1516
1517            fn tap(&mut self, _pos: Option<(u32, u32)>, _time: u64) -> Result<(), Error> {
1518                Ok(())
1519            }
1520
1521            fn multi_finger_tap(
1522                &mut self,
1523                _fingers: Option<Vec<Touch>>,
1524                _time: u64,
1525            ) -> Result<(), Error> {
1526                Ok(())
1527            }
1528
1529            fn mouse(&mut self, _report: MouseInputReport, _time: u64) -> Result<(), Error> {
1530                Ok(())
1531            }
1532
1533            async fn flush(self: Box<Self>) -> Result<(), Error> {
1534                Ok(())
1535            }
1536        }
1537
1538        #[fasync::run_until_stalled(test)]
1539        async fn media_button_event_registers_media_buttons_device() -> Result<(), Error> {
1540            let mut registry = FakeInputDeviceRegistry::new();
1541            media_button_event(vec![], &mut registry).await?;
1542            assert_matches!(registry.device_types.as_slice(), [DeviceType::MediaButtons]);
1543            Ok(())
1544        }
1545
1546        #[fasync::run_singlethreaded(test)]
1547        async fn keyboard_event_registers_keyboard() -> Result<(), Error> {
1548            let mut registry = FakeInputDeviceRegistry::new();
1549            keyboard_event(40, Duration::from_millis(0), &mut registry).await?;
1550            assert_matches!(registry.device_types.as_slice(), [DeviceType::Keyboard]);
1551            Ok(())
1552        }
1553
1554        #[fasync::run_until_stalled(test)]
1555        async fn text_event_registers_keyboard() -> Result<(), Error> {
1556            let mut registry = FakeInputDeviceRegistry::new();
1557            text("A".to_string(), Duration::from_millis(0), &mut registry).await?;
1558            assert_matches!(registry.device_types.as_slice(), [DeviceType::Keyboard]);
1559            Ok(())
1560        }
1561
1562        #[fasync::run_singlethreaded(test)]
1563        async fn multi_finger_tap_event_registers_touchscreen() -> Result<(), Error> {
1564            let mut registry = FakeInputDeviceRegistry::new();
1565            multi_finger_tap_event(vec![], 1000, 1000, 1, Duration::from_millis(0), &mut registry)
1566                .await?;
1567            assert_matches!(registry.device_types.as_slice(), [DeviceType::Touchscreen]);
1568            Ok(())
1569        }
1570
1571        #[fasync::run_singlethreaded(test)]
1572        async fn tap_event_registers_touchscreen() -> Result<(), Error> {
1573            let mut registry = FakeInputDeviceRegistry::new();
1574            tap_event(0, 0, 1000, 1000, 1, Duration::from_millis(0), &mut registry).await?;
1575            assert_matches!(registry.device_types.as_slice(), [DeviceType::Touchscreen]);
1576            Ok(())
1577        }
1578
1579        #[fasync::run_singlethreaded(test)]
1580        async fn swipe_registers_touchscreen() -> Result<(), Error> {
1581            let mut registry = FakeInputDeviceRegistry::new();
1582            swipe(0, 0, 1, 1, 1000, 1000, 1, Duration::from_millis(0), &mut registry).await?;
1583            assert_matches!(registry.device_types.as_slice(), [DeviceType::Touchscreen]);
1584            Ok(())
1585        }
1586
1587        #[fasync::run_singlethreaded(test)]
1588        async fn multi_finger_swipe_registers_touchscreen() -> Result<(), Error> {
1589            let mut registry = FakeInputDeviceRegistry::new();
1590            multi_finger_swipe(
1591                vec![],
1592                vec![],
1593                1000,
1594                1000,
1595                1,
1596                Duration::from_millis(0),
1597                &mut registry,
1598            )
1599            .await?;
1600            assert_matches!(registry.device_types.as_slice(), [DeviceType::Touchscreen]);
1601            Ok(())
1602        }
1603
1604        #[fasync::run_until_stalled(test)]
1605        async fn add_mouse_device_registers_mouse_device() -> Result<(), Error> {
1606            let mut registry = FakeInputDeviceRegistry::new();
1607            add_mouse_device(100, 100, &mut registry).await?;
1608            assert_matches!(registry.device_types.as_slice(), [DeviceType::Mouse]);
1609            Ok(())
1610        }
1611    }
1612}