// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//!
use {
    crate::{input_device, input_handler::UnhandledInputHandler, mouse_binding, utils::Position},
    async_trait::async_trait,
    fuchsia_syslog::fx_log_err,
    fuchsia_zircon as zx,
    std::{cell::RefCell, convert::From, num::FpCategory, option::Option, rc::Rc},
};

pub struct PointerMotionSensorScaleHandler {
    mutable_state: RefCell<MutableState>,
}

struct MutableState {
    /// The time of the last processed mouse move event.
    last_move_timestamp: Option<zx::Time>,
}

#[async_trait(?Send)]
impl UnhandledInputHandler for PointerMotionSensorScaleHandler {
    async fn handle_unhandled_input_event(
        self: Rc<Self>,
        unhandled_input_event: input_device::UnhandledInputEvent,
    ) -> Vec<input_device::InputEvent> {
        match unhandled_input_event {
            // TODO(https://fxbug.dev/98699) Disable scaling when in immersive mode.
            input_device::UnhandledInputEvent {
                device_event:
                    input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
                        location:
                            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
                                counts: raw_motion,
                                millimeters: _,
                            }),
                        wheel_delta_v,
                        wheel_delta_h,
                        // Only the `Move` phase carries non-zero motion.
                        phase: phase @ mouse_binding::MousePhase::Move,
                        affected_buttons,
                        pressed_buttons,
                    }),
                device_descriptor: device_descriptor @ input_device::InputDeviceDescriptor::Mouse(_),
                event_time,
                trace_id: _,
            } => {
                let scaled_motion = self.scale_motion(raw_motion, event_time);
                let input_event = input_device::InputEvent {
                    device_event: input_device::InputDeviceEvent::Mouse(
                        mouse_binding::MouseEvent {
                            location: mouse_binding::MouseLocation::Relative(
                                mouse_binding::RelativeLocation {
                                    counts: scaled_motion,
                                    // TODO(https://fxbug.dev/102568): Implement millimeters.
                                    millimeters: Position::zero(),
                                },
                            ),
                            wheel_delta_v,
                            wheel_delta_h,
                            phase,
                            affected_buttons,
                            pressed_buttons,
                        },
                    ),
                    device_descriptor,
                    event_time,
                    handled: input_device::Handled::No,
                    trace_id: None,
                };
                vec![input_event]
            }
            _ => vec![input_device::InputEvent::from(unhandled_input_event)],
        }
    }
}

// The absolute value of the movement reported by the mouse when the mouse
// moves one millimeter.
// * This value was measured on an Atlas touchpad operating in mouse mode,
//   and is ~300 counts-per-inch.
// * This value _should_ be read from the mouse's input descriptor, once
//   the value is added to said descriptor.
//
// TODO(https://fxbug.dev/98919): Use device-specific values.
const COUNTS_PER_MM: f32 = 12.0;

// The minimum reasonable delay between intentional mouse movements.
// This value
// * Is used to compensate for time compression if the driver gets
//   backlogged.
// * Is set to accommodate up to 10 kHZ event reporting.
//
// TODO(https://fxbug.dev/98920): Use the polling rate instead of event timestamps.
const MIN_PLAUSIBLE_EVENT_DELAY: zx::Duration = zx::Duration::from_micros(100);

// The maximum reasonable delay between intentional mouse movements.
// This value is used to compute speed for the first mouse motion after
// a long idle period.
//
// Alternatively:
// 1. The code could use the uncapped delay. However, this would lead to
//    very slow initial motion after a long idle period.
// 2. Wait until a second report comes in. However, older mice generate
//    reports at 125 HZ, which would mean an 8 msec delay.
//
// TODO(https://fxbug.dev/98920): Use the polling rate instead of event timestamps.
const MAX_PLAUSIBLE_EVENT_DELAY: zx::Duration = zx::Duration::from_millis(50);

const MAX_SENSOR_COUNTS_PER_INCH: f32 = 20_000.0; // From https://sensor.fyi/sensors
const MAX_SENSOR_COUNTS_PER_MM: f32 = MAX_SENSOR_COUNTS_PER_INCH / 12.7;
const MIN_MEASURABLE_DISTANCE_MM: f32 = 1.0 / MAX_SENSOR_COUNTS_PER_MM;
const MAX_PLAUSIBLE_EVENT_DELAY_SECS: f32 = MAX_PLAUSIBLE_EVENT_DELAY.into_nanos() as f32 / 1E9;
const MIN_MEASURABLE_VELOCITY_MM_PER_SEC: f32 =
    MIN_MEASURABLE_DISTANCE_MM / MAX_PLAUSIBLE_EVENT_DELAY_SECS;

// Define the buckets which determine which mapping to use.
// * Speeds below the beginning of the medium range use the low-speed mapping.
// * Speeds within the medium range use the medium-speed mapping.
// * Speeds above the end of the medium range use the high-speed mapping.
const MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC: f32 = 32.0;
const MEDIUM_SPEED_RANGE_END_MM_PER_SEC: f32 = 150.0;

// A linear factor affecting the responsiveness of the pointer to motion.
// A higher numbness indicates lower responsiveness.
const NUMBNESS: f32 = 37.5;

impl PointerMotionSensorScaleHandler {
    /// Creates a new [`PointerMotionSensorScaleHandler`].
    ///
    /// Returns `Rc<Self>`.
    pub fn new() -> Rc<Self> {
        Rc::new(Self { mutable_state: RefCell::new(MutableState { last_move_timestamp: None }) })
    }

    // Linearly scales `movement_mm_per_sec`.
    //
    // Given the values of `MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC` and
    // `NUMBNESS` above, this results in downscaling the motion.
    fn scale_low_speed_motion(movement_mm_per_sec: f32) -> f32 {
        const LINEAR_SCALE_FACTOR: f32 = MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC / NUMBNESS;
        LINEAR_SCALE_FACTOR * movement_mm_per_sec
    }

    // Quadratically scales `movement_mm_per_sec`.
    //
    // The scale factor is chosen so that the composite curve is
    // continuous as the speed transitions from the low-speed
    // bucket to the medium-speed bucket.
    //
    // Note that the composite curve is _not_ differentiable at the
    // transition from low-speed to medium-speed, since the
    // slope on the left side of the point
    // (MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC / NUMBNESS)
    // is different from the slope on the right side of the point
    // (2 * MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC / NUMBNESS).
    //
    // However, the transition works well enough in practice.
    fn scale_medium_speed_motion(movement_mm_per_sec: f32) -> f32 {
        const QUARDRATIC_SCALE_FACTOR: f32 = 1.0 / NUMBNESS;
        QUARDRATIC_SCALE_FACTOR * movement_mm_per_sec * movement_mm_per_sec
    }

    // Linearly scales `movement_mm_per_sec`.
    //
    // The parameters are chosen so that
    // 1. The composite curve is continuous as the speed transitions
    //    from the medium-speed bucket to the high-speed bucket.
    // 2. The composite curve is differentiable.
    fn scale_high_speed_motion(movement_mm_per_sec: f32) -> f32 {
        // Use linear scaling equal to the slope of `scale_medium_speed_motion()`
        // at the transition point.
        const LINEAR_SCALE_FACTOR: f32 = 2.0 * (MEDIUM_SPEED_RANGE_END_MM_PER_SEC / NUMBNESS);

        // Compute offset so the composite curve is continuous.
        const Y_AT_MEDIUM_SPEED_RANGE_END_MM_PER_SEC: f32 =
            MEDIUM_SPEED_RANGE_END_MM_PER_SEC * MEDIUM_SPEED_RANGE_END_MM_PER_SEC / NUMBNESS;
        const OFFSET: f32 = Y_AT_MEDIUM_SPEED_RANGE_END_MM_PER_SEC
            - LINEAR_SCALE_FACTOR * MEDIUM_SPEED_RANGE_END_MM_PER_SEC;

        // Apply the computed transformation.
        LINEAR_SCALE_FACTOR * movement_mm_per_sec + OFFSET
    }

    // Scales Euclidean velocity by one of the scale_*_speed_motion() functions above,
    // choosing the function based on `MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC` and
    // `MEDIUM_SPEED_RANGE_END_MM_PER_SEC`.
    fn scale_euclidean_velocity(raw_velocity: f32) -> f32 {
        if (0.0..MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC).contains(&raw_velocity) {
            Self::scale_low_speed_motion(raw_velocity)
        } else if (MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC..MEDIUM_SPEED_RANGE_END_MM_PER_SEC)
            .contains(&raw_velocity)
        {
            Self::scale_medium_speed_motion(raw_velocity)
        } else {
            Self::scale_high_speed_motion(raw_velocity)
        }
    }

    /// Scales `movement_counts`.
    fn scale_motion(&self, movement_counts: Position, event_time: zx::Time) -> Position {
        // Determine the duration of this `movement`.
        let elapsed_time_secs =
            match self.mutable_state.borrow_mut().last_move_timestamp.replace(event_time) {
                Some(last_event_time) => (event_time - last_event_time)
                    .clamp(MIN_PLAUSIBLE_EVENT_DELAY, MAX_PLAUSIBLE_EVENT_DELAY),
                None => MAX_PLAUSIBLE_EVENT_DELAY,
            }
            .into_nanos() as f32
                / 1E9;

        // Compute the velocity in each dimension.
        let x_mm_per_sec = movement_counts.x / COUNTS_PER_MM / elapsed_time_secs;
        let y_mm_per_sec = movement_counts.y / COUNTS_PER_MM / elapsed_time_secs;

        let euclidean_velocity =
            f32::sqrt(x_mm_per_sec * x_mm_per_sec + y_mm_per_sec * y_mm_per_sec);
        if euclidean_velocity < MIN_MEASURABLE_VELOCITY_MM_PER_SEC {
            // Avoid division by zero that would come from computing `scale_factor` below.
            return movement_counts;
        }

        // Compute the scaling factor to be applied to each dimension.
        //
        // Geometrically, this is a bit dodgy when there's movement along both
        // dimensions. Specifically: the `OFFSET` for high-speed motion should be
        // constant, but the way its used here scales the offset based on velocity.
        //
        // Nonetheless, this works well enough in practice.
        let scale_factor = Self::scale_euclidean_velocity(euclidean_velocity) / euclidean_velocity;

        // Apply the scale factor and return the result.
        let scaled_movement_counts = scale_factor * movement_counts;

        match (scaled_movement_counts.x.classify(), scaled_movement_counts.y.classify()) {
            (FpCategory::Infinite | FpCategory::Nan, _)
            | (_, FpCategory::Infinite | FpCategory::Nan) => {
                // Backstop, in case the code above missed some cases of bad arithmetic.
                // Avoid sending `Infinite` or `Nan` values, since such values will
                // poison the `current_position` in `MouseInjectorHandlerInner`.
                // That manifests as the pointer becoming invisible, and never
                // moving again.
                //
                // TODO(https://fxbug.dev/98995) Add a triage rule to highlight the
                // implications of this message.
                fx_log_err!(
                    "skipped motion; scaled movement of {:?} is infinite or NaN; x is {:?}, and y is {:?}",
                    scaled_movement_counts,
                    scaled_movement_counts.x.classify(),
                    scaled_movement_counts.y.classify(),
                );
                Position { x: 0.0, y: 0.0 }
            }
            _ => scaled_movement_counts,
        }
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        assert_matches::assert_matches,
        fuchsia_zircon as zx,
        maplit::hashset,
        std::cell::Cell,
        test_util::{assert_gt, assert_lt, assert_near},
    };

    const DEVICE_DESCRIPTOR: input_device::InputDeviceDescriptor =
        input_device::InputDeviceDescriptor::Mouse(mouse_binding::MouseDeviceDescriptor {
            device_id: 0,
            absolute_x_range: None,
            absolute_y_range: None,
            wheel_v_range: None,
            wheel_h_range: None,
            buttons: None,
        });

    // Maximum tolerable difference between "equal" scale factors. This is
    // likely higher than FP rounding error can explain, but still small
    // enough that there would be no user-perceptible difference.
    //
    // Rationale for not being user-perceptible: this requires the raw
    // movement to have a count of 100,000, before there's a unit change
    // in the scaled motion.
    //
    // On even the highest resolution sensor (per https://sensor.fyi/sensors),
    // that would require 127mm (5 inches) of motion within one sampling
    // interval.
    //
    // In the unlikely case that the high resolution sensor is paired
    // with a low polling rate, that works out to 127mm/8msec, or _at least_
    // 57 km/hr.
    const SCALE_EPSILON: f32 = 1.0 / 100_000.0;

    std::thread_local! {static NEXT_EVENT_TIME: Cell<i64> = Cell::new(0)}

    fn make_unhandled_input_event(
        mouse_event: mouse_binding::MouseEvent,
    ) -> input_device::UnhandledInputEvent {
        let event_time = NEXT_EVENT_TIME.with(|t| {
            let old = t.get();
            t.set(old + 1);
            old
        });
        input_device::UnhandledInputEvent {
            device_event: input_device::InputDeviceEvent::Mouse(mouse_event),
            device_descriptor: DEVICE_DESCRIPTOR.clone(),
            event_time: zx::Time::from_nanos(event_time),
            trace_id: None,
        }
    }

    // While its generally preferred to write tests against the public API of
    // a module, these tests
    // 1. Can't be written against the public API (since that API doesn't
    //    provide a way to control which curve is used for scaling), and
    // 2. Validate important properties of the module.
    mod internal_computations {
        use super::*;

        #[fuchsia::test]
        fn transition_from_low_to_medium_is_continuous() {
            assert_near!(
                PointerMotionSensorScaleHandler::scale_low_speed_motion(
                    MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC
                ),
                PointerMotionSensorScaleHandler::scale_medium_speed_motion(
                    MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC
                ),
                SCALE_EPSILON
            );
        }

        // As noted in `scale_motion()`, the offset will be applied imperfectly,
        // so the externally visible transition may not be continuous.
        //
        // However, it's still valuable to verify that the internal building block
        // works as intended.
        #[fuchsia::test]
        fn transition_from_medium_to_high_is_continuous() {
            assert_near!(
                PointerMotionSensorScaleHandler::scale_medium_speed_motion(
                    MEDIUM_SPEED_RANGE_END_MM_PER_SEC
                ),
                PointerMotionSensorScaleHandler::scale_high_speed_motion(
                    MEDIUM_SPEED_RANGE_END_MM_PER_SEC
                ),
                SCALE_EPSILON
            );
        }
    }

    mod motion_scaling {
        use super::*;

        #[ignore]
        #[fuchsia::test(allow_stalls = false)]
        async fn plot_example_curve() {
            let duration = zx::Duration::from_millis(8);
            for count in 1..1000 {
                let scaled_count =
                    get_scaled_motion(Position { x: count as f32, y: 0.0 }, duration).await;
                fx_log_err!("{}, {}", count, scaled_count.x);
            }
        }

        async fn get_scaled_motion(movement_counts: Position, duration: zx::Duration) -> Position {
            let handler = PointerMotionSensorScaleHandler::new();

            // Send a don't-care value through to seed the last timestamp.
            let input_event = input_device::UnhandledInputEvent {
                device_event: input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
                    location: mouse_binding::MouseLocation::Relative(Default::default()),
                    wheel_delta_v: None,
                    wheel_delta_h: None,
                    phase: mouse_binding::MousePhase::Move,
                    affected_buttons: hashset! {},
                    pressed_buttons: hashset! {},
                }),
                device_descriptor: DEVICE_DESCRIPTOR.clone(),
                event_time: zx::Time::from_nanos(0),
                trace_id: None,
            };
            handler.clone().handle_unhandled_input_event(input_event).await;

            // Send in the requested motion.
            let input_event = input_device::UnhandledInputEvent {
                device_event: input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
                    location: mouse_binding::MouseLocation::Relative(
                        mouse_binding::RelativeLocation {
                            counts: movement_counts,
                            millimeters: Position::zero(),
                        },
                    ),
                    wheel_delta_v: None,
                    wheel_delta_h: None,
                    phase: mouse_binding::MousePhase::Move,
                    affected_buttons: hashset! {},
                    pressed_buttons: hashset! {},
                }),
                device_descriptor: DEVICE_DESCRIPTOR.clone(),
                event_time: zx::Time::from_nanos(duration.into_nanos()),
                trace_id: None,
            };
            let transformed_events =
                handler.clone().handle_unhandled_input_event(input_event).await;

            // Provide a useful debug message if the transformed event doesn't have the expected
            // overall structure.
            assert_matches!(
                transformed_events.as_slice(),
                [input_device::InputEvent {
                    device_event: input_device::InputDeviceEvent::Mouse(
                        mouse_binding::MouseEvent {
                            location: mouse_binding::MouseLocation::Relative(
                                mouse_binding::RelativeLocation { .. }
                            ),
                            ..
                        }
                    ),
                    ..
                }]
            );

            // Return the transformed motion.
            if let input_device::InputEvent {
                device_event:
                    input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
                        location:
                            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
                                counts: movement_counts,
                                millimeters: _,
                            }),
                        ..
                    }),
                ..
            } = transformed_events[0]
            {
                movement_counts
            } else {
                unreachable!()
            }
        }

        fn velocity_to_count(velocity_mm_per_sec: f32, duration: zx::Duration) -> f32 {
            velocity_mm_per_sec * (duration.into_nanos() as f32 / 1E9) * COUNTS_PER_MM
        }

        #[fuchsia::test(allow_stalls = false)]
        async fn low_speed_horizontal_motion_scales_linearly() {
            const TICK_DURATION: zx::Duration = zx::Duration::from_millis(8);
            const MOTION_A_COUNTS: f32 = 1.0;
            const MOTION_B_COUNTS: f32 = 2.0;
            assert_lt!(
                MOTION_B_COUNTS,
                velocity_to_count(MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC, TICK_DURATION)
            );

            let scaled_a =
                get_scaled_motion(Position { x: MOTION_A_COUNTS, y: 0.0 }, TICK_DURATION).await;
            let scaled_b =
                get_scaled_motion(Position { x: MOTION_B_COUNTS, y: 0.0 }, TICK_DURATION).await;
            assert_near!(scaled_b.x / scaled_a.x, 2.0, SCALE_EPSILON);
        }

        #[fuchsia::test(allow_stalls = false)]
        async fn low_speed_vertical_motion_scales_linearly() {
            const TICK_DURATION: zx::Duration = zx::Duration::from_millis(8);
            const MOTION_A_COUNTS: f32 = 1.0;
            const MOTION_B_COUNTS: f32 = 2.0;
            assert_lt!(
                MOTION_B_COUNTS,
                velocity_to_count(MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC, TICK_DURATION)
            );

            let scaled_a =
                get_scaled_motion(Position { x: 0.0, y: MOTION_A_COUNTS }, TICK_DURATION).await;
            let scaled_b =
                get_scaled_motion(Position { x: 0.0, y: MOTION_B_COUNTS }, TICK_DURATION).await;
            assert_near!(scaled_b.y / scaled_a.y, 2.0, SCALE_EPSILON);
        }

        #[fuchsia::test(allow_stalls = false)]
        async fn low_speed_45degree_motion_scales_dimensions_equally() {
            const TICK_DURATION: zx::Duration = zx::Duration::from_millis(8);
            const MOTION_COUNTS: f32 = 1.0;
            assert_lt!(
                MOTION_COUNTS,
                velocity_to_count(MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC, TICK_DURATION)
            );

            let scaled =
                get_scaled_motion(Position { x: MOTION_COUNTS, y: MOTION_COUNTS }, TICK_DURATION)
                    .await;
            assert_near!(scaled.x, scaled.y, SCALE_EPSILON);
        }

        #[fuchsia::test(allow_stalls = false)]
        async fn medium_speed_motion_scales_quadratically() {
            const TICK_DURATION: zx::Duration = zx::Duration::from_millis(8);
            const MOTION_A_COUNTS: f32 = 7.0;
            const MOTION_B_COUNTS: f32 = 14.0;
            assert_gt!(
                MOTION_A_COUNTS,
                velocity_to_count(MEDIUM_SPEED_RANGE_BEGIN_MM_PER_SEC, TICK_DURATION)
            );
            assert_lt!(
                MOTION_B_COUNTS,
                velocity_to_count(MEDIUM_SPEED_RANGE_END_MM_PER_SEC, TICK_DURATION)
            );

            let scaled_a =
                get_scaled_motion(Position { x: MOTION_A_COUNTS, y: 0.0 }, TICK_DURATION).await;
            let scaled_b =
                get_scaled_motion(Position { x: MOTION_B_COUNTS, y: 0.0 }, TICK_DURATION).await;
            assert_near!(scaled_b.x / scaled_a.x, 4.0, SCALE_EPSILON);
        }

        // Given the handling of `OFFSET` for high-speed motion, (see comment
        // in `scale_motion()`), high speed motion scaling is _not_ linear for
        // the range of values of practical interest.
        //
        // Thus, this tests verifies a weaker property.
        #[fuchsia::test(allow_stalls = false)]
        async fn high_speed_motion_scaling_is_increasing() {
            const TICK_DURATION: zx::Duration = zx::Duration::from_millis(8);
            const MOTION_A_COUNTS: f32 = 16.0;
            const MOTION_B_COUNTS: f32 = 20.0;
            assert_gt!(
                MOTION_A_COUNTS,
                velocity_to_count(MEDIUM_SPEED_RANGE_END_MM_PER_SEC, TICK_DURATION)
            );

            let scaled_a =
                get_scaled_motion(Position { x: MOTION_A_COUNTS, y: 0.0 }, TICK_DURATION).await;
            let scaled_b =
                get_scaled_motion(Position { x: MOTION_B_COUNTS, y: 0.0 }, TICK_DURATION).await;
            assert_gt!(scaled_b.x, scaled_a.x)
        }

        #[fuchsia::test(allow_stalls = false)]
        async fn zero_motion_maps_to_zero_motion() {
            const TICK_DURATION: zx::Duration = zx::Duration::from_millis(8);
            let scaled = get_scaled_motion(Position { x: 0.0, y: 0.0 }, TICK_DURATION).await;
            assert_eq!(scaled, Position::zero())
        }

        #[fuchsia::test(allow_stalls = false)]
        async fn zero_duration_does_not_crash() {
            get_scaled_motion(Position { x: 1.0, y: 0.0 }, zx::Duration::from_millis(0)).await;
        }
    }

    mod metadata_preservation {
        use super::*;

        #[fuchsia::test(allow_stalls = false)]
        async fn does_not_consume_event() {
            let handler = PointerMotionSensorScaleHandler::new();
            let input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
                location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
                    counts: Position { x: 1.5, y: 4.5 },
                    millimeters: Position::zero(),
                }),
                wheel_delta_v: None,
                wheel_delta_h: None,
                phase: mouse_binding::MousePhase::Move,
                affected_buttons: hashset! {},
                pressed_buttons: hashset! {},
            });
            assert_matches!(
                handler.clone().handle_unhandled_input_event(input_event).await.as_slice(),
                [input_device::InputEvent { handled: input_device::Handled::No, .. }]
            );
        }

        // Downstream handlers, and components consuming the `MouseEvent`, may be
        // sensitive to the speed of motion. So it's important to preserve timestamps.
        #[fuchsia::test(allow_stalls = false)]
        async fn preserves_event_time() {
            let handler = PointerMotionSensorScaleHandler::new();
            let mut input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
                location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
                    counts: Position { x: 1.5, y: 4.5 },
                    millimeters: Position::zero(),
                }),
                wheel_delta_v: None,
                wheel_delta_h: None,
                phase: mouse_binding::MousePhase::Move,
                affected_buttons: hashset! {},
                pressed_buttons: hashset! {},
            });
            const EVENT_TIME: zx::Time = zx::Time::from_nanos(42);
            input_event.event_time = EVENT_TIME;
            assert_matches!(
                handler.clone().handle_unhandled_input_event(input_event).await.as_slice(),
                [input_device::InputEvent { event_time: EVENT_TIME, .. }]
            );
        }
    }
}
