1#![warn(clippy::await_holding_refcell_ref)]
6
7use crate::input_handler::{Handler, InputHandler, InputHandlerStatus};
8use crate::utils::{self, CursorMessage, Position, Size};
9use crate::{
10 Dispatcher, Incoming, MonotonicInstant, Transport, input_device, metrics, mouse_binding,
11};
12use anyhow::{Context, Error, Result, anyhow};
13use async_trait::async_trait;
14use async_utils::hanging_get::client::HangingGetStream;
15use fidl_fuchsia_input_report::Range;
16use fidl_fuchsia_ui_pointerinjector_configuration as pointerinjector_config;
17use fidl_next_fuchsia_ui_pointerinjector as pointerinjector;
18use fuchsia_inspect::health::Reporter;
19use futures::SinkExt;
20use futures::channel::mpsc::Sender;
21use futures::stream::StreamExt;
22use metrics_registry::*;
23use sorted_vec_map::SortedVecMap;
24use std::cell::{Ref, RefCell, RefMut};
25use std::rc::Rc;
26
27pub struct MouseInjectorHandler {
30 mutable_state: RefCell<MutableState>,
32
33 context_view_ref: fidl_fuchsia_ui_views::ViewRef,
36
37 target_view_ref: fidl_fuchsia_ui_views::ViewRef,
40
41 max_position: Position,
44
45 injector_registry_proxy: fidl_next::Client<pointerinjector::Registry, Transport>,
47
48 configuration_proxy: pointerinjector_config::SetupProxy,
50
51 pub inspect_status: InputHandlerStatus,
53
54 metrics_logger: metrics::MetricsLogger,
55}
56
57struct MutableState {
58 viewport: Option<pointerinjector::Viewport>,
61
62 injectors: SortedVecMap<u32, fidl_next::Client<pointerinjector::Device, Transport>>,
64
65 current_position: Position,
67
68 cursor_message_sender: Sender<CursorMessage>,
70}
71
72impl Handler for MouseInjectorHandler {
73 fn set_handler_healthy(self: std::rc::Rc<Self>) {
74 self.inspect_status.health_node.borrow_mut().set_ok();
75 }
76
77 fn set_handler_unhealthy(self: std::rc::Rc<Self>, msg: &str) {
78 self.inspect_status.health_node.borrow_mut().set_unhealthy(msg);
79 }
80
81 fn get_name(&self) -> &'static str {
82 "MouseInjectorHandler"
83 }
84
85 fn interest(&self) -> Vec<input_device::InputEventType> {
86 vec![input_device::InputEventType::Mouse]
87 }
88}
89
90#[async_trait(?Send)]
91impl InputHandler for MouseInjectorHandler {
92 async fn handle_input_event(
93 self: Rc<Self>,
94 mut input_event: input_device::InputEvent,
95 ) -> Vec<input_device::InputEvent> {
96 fuchsia_trace::duration!("input", "mouse_injector_handler");
97 match input_event {
98 input_device::InputEvent {
99 device_event: input_device::InputDeviceEvent::Mouse(ref mut mouse_event),
100 device_descriptor:
101 input_device::InputDeviceDescriptor::Mouse(ref mouse_device_descriptor),
102 event_time,
103 handled: input_device::Handled::No,
104 trace_id,
105 } => {
106 fuchsia_trace::duration!("input", "mouse_injector_handler[processing]");
107 let trace_id = match trace_id {
108 Some(id) => {
109 fuchsia_trace::flow_step!("input", "event_in_input_pipeline", id.into());
110 id
111 }
112 None => fuchsia_trace::Id::new(),
113 };
114
115 self.inspect_status.count_received_event(&event_time);
116 if let Err(e) =
118 self.update_cursor_renderer(mouse_event, &mouse_device_descriptor).await
119 {
120 self.metrics_logger.log_error(
121 InputPipelineErrorMetricDimensionEvent::MouseInjectorUpdateCursorRendererFailed,
122 std::format!("update_cursor_renderer failed: {}", e));
123 }
124
125 if let Err(e) = self
127 .ensure_injector_registered(mouse_event, &mouse_device_descriptor, event_time)
128 .await
129 {
130 self.metrics_logger.log_error(
131 InputPipelineErrorMetricDimensionEvent::MouseInjectorEnsureInjectorRegisteredFailed,
132 std::format!("ensure_injector_registered failed: {}", e));
133 }
134
135 if let Err(e) = self.send_event_to_scenic(
137 mouse_event,
138 &mouse_device_descriptor,
139 event_time,
140 trace_id.into(),
141 ) {
142 self.metrics_logger.log_error(
143 InputPipelineErrorMetricDimensionEvent::MouseInjectorSendEventToScenicFailed,
144 std::format!("send_event_to_scenic failed: {}", e));
145 }
146
147 input_event.handled = input_device::Handled::Yes;
149 self.inspect_status.count_handled_event();
150 }
151 _ => {
152 self.metrics_logger.log_error(
153 InputPipelineErrorMetricDimensionEvent::HandlerReceivedUninterestedEvent,
154 std::format!(
155 "{} uninterested input event: {:?}",
156 self.get_name(),
157 input_event.get_event_type()
158 ),
159 );
160 }
161 }
162 vec![input_event]
163 }
164}
165
166impl MouseInjectorHandler {
167 pub async fn new(
180 incoming: &Incoming,
181 display_size: Size,
182 cursor_message_sender: Sender<CursorMessage>,
183 input_handlers_node: &fuchsia_inspect::Node,
184 metrics_logger: metrics::MetricsLogger,
185 ) -> Result<Rc<Self>, Error> {
186 let configuration_proxy =
187 incoming.connect_protocol::<pointerinjector_config::SetupProxy>()?;
188 let injector_registry_proxy =
189 incoming.connect_protocol_next::<pointerinjector::Registry>()?.spawn();
190
191 Self::new_handler(
192 configuration_proxy,
193 injector_registry_proxy,
194 display_size,
195 cursor_message_sender,
196 input_handlers_node,
197 metrics_logger,
198 )
199 .await
200 }
201
202 pub async fn new_with_config_proxy(
218 incoming: &Incoming,
219 configuration_proxy: pointerinjector_config::SetupProxy,
220 display_size: Size,
221 cursor_message_sender: Sender<CursorMessage>,
222 input_handlers_node: &fuchsia_inspect::Node,
223 metrics_logger: metrics::MetricsLogger,
224 ) -> Result<Rc<Self>, Error> {
225 let injector_registry_proxy =
226 incoming.connect_protocol_next::<pointerinjector::Registry>()?.spawn();
227 Self::new_handler(
228 configuration_proxy,
229 injector_registry_proxy,
230 display_size,
231 cursor_message_sender,
232 input_handlers_node,
233 metrics_logger,
234 )
235 .await
236 }
237
238 fn inner(&self) -> Ref<'_, MutableState> {
239 self.mutable_state.borrow()
240 }
241
242 fn inner_mut(&self) -> RefMut<'_, MutableState> {
243 self.mutable_state.borrow_mut()
244 }
245
246 async fn new_handler(
262 configuration_proxy: pointerinjector_config::SetupProxy,
263 injector_registry_proxy: fidl_next::Client<pointerinjector::Registry, Transport>,
264 display_size: Size,
265 cursor_message_sender: Sender<CursorMessage>,
266 input_handlers_node: &fuchsia_inspect::Node,
267 metrics_logger: metrics::MetricsLogger,
268 ) -> Result<Rc<Self>, Error> {
269 let (context_view_ref, target_view_ref) = configuration_proxy.get_view_refs().await?;
271 let inspect_status = InputHandlerStatus::new(
272 input_handlers_node,
273 "mouse_injector_handler",
274 false,
275 );
276 let handler = Rc::new(Self {
277 mutable_state: RefCell::new(MutableState {
278 viewport: None,
279 injectors: SortedVecMap::new(),
280 current_position: Position {
282 x: display_size.width / 2.0,
283 y: display_size.height / 2.0,
284 },
285 cursor_message_sender,
286 }),
287 context_view_ref,
288 target_view_ref,
289 max_position: Position { x: display_size.width, y: display_size.height },
290 injector_registry_proxy,
291 configuration_proxy,
292 inspect_status,
293 metrics_logger,
294 });
295
296 Ok(handler)
297 }
298
299 async fn ensure_injector_registered(
307 self: &Rc<Self>,
308 mouse_event: &mut mouse_binding::MouseEvent,
309 mouse_descriptor: &mouse_binding::MouseDeviceDescriptor,
310 event_time: zx::MonotonicInstant,
311 ) -> Result<(), anyhow::Error> {
312 if self.inner().injectors.contains_key(&mouse_descriptor.device_id) {
313 return Ok(());
314 }
315
316 let (device_proxy, device_server) =
318 fidl_next::fuchsia::create_channel::<pointerinjector::Device>();
319 let device_proxy = Dispatcher::client_from_zx_channel(device_proxy).spawn();
320 let context = fuchsia_scenic::duplicate_view_ref(&self.context_view_ref)
321 .context("Failed to duplicate context view ref.")?;
322 let context = fidl_next_fuchsia_ui_views::ViewRef { reference: context.reference };
323 let target = fuchsia_scenic::duplicate_view_ref(&self.target_view_ref)
324 .context("Failed to duplicate target view ref.")?;
325 let target = fidl_next_fuchsia_ui_views::ViewRef { reference: target.reference };
326
327 let viewport = self.inner().viewport.clone();
328 let config = pointerinjector::Config {
329 device_id: Some(mouse_descriptor.device_id),
330 device_type: Some(pointerinjector::DeviceType::Mouse),
331 context: Some(pointerinjector::Context::View(context)),
332 target: Some(pointerinjector::Target::View(target)),
333 viewport,
334 dispatch_policy: Some(pointerinjector::DispatchPolicy::MouseHoverAndLatchInTarget),
335 scroll_v_range: utils::axis_to_next(mouse_descriptor.wheel_v_range.as_ref()),
336 scroll_h_range: utils::axis_to_next(mouse_descriptor.wheel_h_range.as_ref()),
337 buttons: mouse_descriptor.buttons.clone(),
338 ..Default::default()
339 };
340
341 self.injector_registry_proxy
343 .register(config, device_server)
344 .await
345 .context("Failed to register injector.")?;
346 log::info!("Registered injector with device id {:?}", mouse_descriptor.device_id);
347
348 self.inner_mut().injectors.insert(mouse_descriptor.device_id, device_proxy.clone());
350
351 let events_to_send = vec![self.create_pointer_sample_event(
353 mouse_event,
354 event_time,
355 pointerinjector::EventPhase::Add,
356 self.inner().current_position,
357 None,
358 None,
359 )];
360 device_proxy
361 .inject_events(events_to_send)
362 .send_immediately()
363 .context("Failed to ADD new MouseDevice.")?;
364
365 Ok(())
366 }
367
368 async fn update_cursor_renderer(
379 &self,
380 mouse_event: &mouse_binding::MouseEvent,
381 mouse_descriptor: &mouse_binding::MouseDeviceDescriptor,
382 ) -> Result<(), anyhow::Error> {
383 let mut new_position = match (mouse_event.location, mouse_descriptor) {
384 (
385 mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation { counts }),
386 _,
387 ) => self.inner().current_position + counts,
388 (
389 mouse_binding::MouseLocation::Absolute(position),
390 mouse_binding::MouseDeviceDescriptor {
391 absolute_x_range: Some(x_range),
392 absolute_y_range: Some(y_range),
393 ..
394 },
395 ) => self.scale_absolute_position(&position, &x_range, &y_range),
396 (mouse_binding::MouseLocation::Absolute(_), _) => {
397 return Err(anyhow!(
398 "Received an Absolute mouse location without absolute device ranges."
399 ));
400 }
401 };
402 Position::clamp(&mut new_position, Position::zero(), self.max_position);
403 self.inner_mut().current_position = new_position;
404
405 let mut cursor_message_sender = self.inner().cursor_message_sender.clone();
406 cursor_message_sender
407 .send(CursorMessage::SetPosition(new_position))
408 .await
409 .context("Failed to send current mouse position to cursor renderer")?;
410
411 Ok(())
412 }
413
414 fn scale_absolute_position(
422 &self,
423 position: &Position,
424 x_range: &Range,
425 y_range: &Range,
426 ) -> Position {
427 let range_min = Position { x: x_range.min as f32, y: y_range.min as f32 };
428 let range_max = Position { x: x_range.max as f32, y: y_range.max as f32 };
429 self.max_position * ((*position - range_min) / (range_max - range_min))
430 }
431
432 fn send_event_to_scenic(
439 &self,
440 mouse_event: &mut mouse_binding::MouseEvent,
441 mouse_descriptor: &mouse_binding::MouseDeviceDescriptor,
442 event_time: zx::MonotonicInstant,
443 tracing_id: u64,
444 ) -> Result<(), anyhow::Error> {
445 let injector = self.inner().injectors.get(&mouse_descriptor.device_id).cloned();
446 if let Some(injector) = injector {
447 let relative_motion = match mouse_event.location {
448 mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
449 counts: offset_counts,
450 }) if mouse_event.phase == mouse_binding::MousePhase::Move => {
451 Some([offset_counts.x, offset_counts.y])
452 }
453 _ => None,
454 };
455 let events_to_send = vec![self.create_pointer_sample_event(
456 mouse_event,
457 event_time,
458 pointerinjector::EventPhase::Change,
459 self.inner().current_position,
460 relative_motion,
461 Some(tracing_id),
462 )];
463
464 fuchsia_trace::flow_begin!("input", "dispatch_event_to_scenic", tracing_id.into());
465
466 _ = injector.inject_events(events_to_send).send_immediately();
467
468 Ok(())
469 } else {
470 Err(anyhow::format_err!(
471 "No injector found for mouse device {}.",
472 mouse_descriptor.device_id
473 ))
474 }
475 }
476
477 fn create_pointer_sample_event(
486 &self,
487 mouse_event: &mut mouse_binding::MouseEvent,
488 event_time: zx::MonotonicInstant,
489 phase: pointerinjector::EventPhase,
490 current_position: Position,
491 relative_motion: Option<[f32; 2]>,
492 trace_id: Option<u64>,
493 ) -> pointerinjector::Event {
494 let pointer_sample = pointerinjector::PointerSample {
495 pointer_id: Some(0),
496 phase: Some(phase),
497 position_in_viewport: Some([current_position.x, current_position.y]),
498 scroll_v: mouse_event.wheel_delta_v.as_ref().map(|delta| delta.ticks),
499 scroll_h: mouse_event.wheel_delta_h.as_ref().map(|delta| delta.ticks),
500 scroll_v_physical_pixel: match mouse_event.wheel_delta_v {
501 Some(mouse_binding::WheelDelta { physical_pixel: Some(pixel), .. }) => {
502 Some(pixel.into())
503 }
504 _ => None,
505 },
506 scroll_h_physical_pixel: match mouse_event.wheel_delta_h {
507 Some(mouse_binding::WheelDelta { physical_pixel: Some(pixel), .. }) => {
508 Some(pixel.into())
509 }
510 _ => None,
511 },
512 is_precision_scroll: match mouse_event.phase {
513 mouse_binding::MousePhase::Wheel => match mouse_event.is_precision_scroll {
514 Some(mouse_binding::PrecisionScroll::Yes) => Some(true),
515 Some(mouse_binding::PrecisionScroll::No) => Some(false),
516 None => {
517 self.metrics_logger.log_error(
518 InputPipelineErrorMetricDimensionEvent::MouseInjectorMissingIsPrecisionScroll,
519 "mouse wheel event does not have value in is_precision_scroll.");
520 None
521 }
522 },
523 _ => None,
524 },
525 pressed_buttons: Some(mouse_event.pressed_buttons.clone().into()),
526 relative_motion,
527 ..Default::default()
528 };
529 pointerinjector::Event {
530 timestamp: Some(event_time.into_nanos()),
531 data: Some(pointerinjector::Data::PointerSample(pointer_sample)),
532 trace_flow_id: trace_id,
533 wake_lease: mouse_event.wake_lease.take(),
534 ..Default::default()
535 }
536 }
537
538 pub async fn watch_viewport(self: Rc<Self>) {
540 let configuration_proxy = self.configuration_proxy.clone();
541 let mut viewport_stream = HangingGetStream::new(
542 configuration_proxy,
543 pointerinjector_config::SetupProxy::watch_viewport,
544 );
545 loop {
546 match viewport_stream.next().await {
547 Some(Ok(new_viewport)) => {
548 self.inner_mut().viewport = Some(utils::viewport_to_next(&new_viewport));
550
551 let injectors =
553 self.inner().injectors.iter().map(|(_, v)| v).cloned().collect::<Vec<_>>();
554 for injector in injectors {
555 let events = vec![pointerinjector::Event {
556 timestamp: Some(MonotonicInstant::now().into_nanos()),
557 data: Some(pointerinjector::Data::Viewport(utils::viewport_to_next(
558 &new_viewport,
559 ))),
560 trace_flow_id: Some(fuchsia_trace::Id::new().into()),
561 ..Default::default()
562 }];
563 injector
564 .inject_events(events)
565 .await
566 .expect("Failed to inject updated viewport.");
567 }
568 }
569 Some(Err(e)) => {
570 self.metrics_logger.log_error(
571 InputPipelineErrorMetricDimensionEvent::MouseInjectorErrorWhileReadingViewportUpdate,
572 std::format!("Error while reading viewport update: {}", e));
573 return;
574 }
575 None => {
576 self.metrics_logger.log_error(
577 InputPipelineErrorMetricDimensionEvent::MouseInjectorViewportUpdateStreamTerminatedUnexpectedly,
578 "Viewport update stream terminated unexpectedly");
579 return;
580 }
581 }
582 }
583 }
584}
585
586#[cfg(test)]
587mod tests {
588 use super::*;
589 use crate::testing_utilities::{
590 assert_handler_ignores_input_event_sequence, create_mouse_event,
591 create_mouse_event_with_handled, create_mouse_pointer_sample_event,
592 create_mouse_pointer_sample_event_phase_add,
593 create_mouse_pointer_sample_event_with_wheel_physical_pixel, next_client_old_stream,
594 };
595 use assert_matches::assert_matches;
596 use fidl_fuchsia_input_report as fidl_input_report;
597 use fidl_fuchsia_ui_pointerinjector as pointerinjector;
598 use fidl_next_fuchsia_ui_pointerinjector as pointerinjector_next;
599 use fuchsia_async as fasync;
600 use futures::channel::mpsc;
601 use pretty_assertions::assert_eq;
602 use sorted_vec_map::SortedVecSet;
603 use std::ops::Add;
604 use test_case::test_case;
605
606 const DISPLAY_WIDTH_IN_PHYSICAL_PX: f32 = 100.0;
607 const DISPLAY_HEIGHT_IN_PHYSICAL_PX: f32 = 100.0;
608 const DESCRIPTOR: input_device::InputDeviceDescriptor =
610 input_device::InputDeviceDescriptor::Mouse(mouse_binding::MouseDeviceDescriptor {
611 device_id: 1,
612 absolute_x_range: Some(fidl_input_report::Range { min: 0, max: 100 }),
613 absolute_y_range: Some(fidl_input_report::Range { min: 0, max: 100 }),
614 wheel_v_range: Some(fidl_input_report::Axis {
615 range: fidl_input_report::Range { min: -1, max: 1 },
616 unit: fidl_input_report::Unit {
617 type_: fidl_input_report::UnitType::Other,
618 exponent: 0,
619 },
620 }),
621 wheel_h_range: Some(fidl_input_report::Axis {
622 range: fidl_input_report::Range { min: -1, max: 1 },
623 unit: fidl_input_report::Unit {
624 type_: fidl_input_report::UnitType::Other,
625 exponent: 0,
626 },
627 }),
628 buttons: None,
629 });
630
631 async fn handle_configuration_request_stream(
633 stream: &mut pointerinjector_config::SetupRequestStream,
634 ) {
635 if let Some(Ok(request)) = stream.next().await {
636 match request {
637 pointerinjector_config::SetupRequest::GetViewRefs { responder, .. } => {
638 let context = fuchsia_scenic::ViewRefPair::new()
639 .expect("Failed to create viewrefpair.")
640 .view_ref;
641 let target = fuchsia_scenic::ViewRefPair::new()
642 .expect("Failed to create viewrefpair.")
643 .view_ref;
644 let _ = responder.send(context, target);
645 }
646 _ => {}
647 };
648 }
649 }
650
651 async fn handle_registry_request_stream(
654 mut stream: pointerinjector::RegistryRequestStream,
655 injector_sender: futures::channel::oneshot::Sender<pointerinjector::DeviceRequestStream>,
656 ) {
657 if let Some(request) = stream.next().await {
658 match request {
659 Ok(pointerinjector::RegistryRequest::Register {
660 config: _,
661 injector,
662 responder,
663 ..
664 }) => {
665 let injector_stream = injector.into_stream();
666 let _ = injector_sender.send(injector_stream);
667 responder.send().expect("failed to respond");
668 }
669 _ => {}
670 };
671 } else {
672 panic!("RegistryRequestStream failed.");
673 }
674 }
675
676 async fn handle_registry_request_stream2(
678 mut stream: pointerinjector::RegistryRequestStream,
679 injector_sender: mpsc::UnboundedSender<Vec<pointerinjector::Event>>,
680 ) {
681 let (injector, responder) = match stream.next().await {
682 Some(Ok(pointerinjector::RegistryRequest::Register {
683 config: _,
684 injector,
685 responder,
686 ..
687 })) => (injector, responder),
688 other => panic!("expected register request, but got {:?}", other),
689 };
690 let injector_stream: pointerinjector::DeviceRequestStream = injector.into_stream();
691 responder.send().expect("failed to respond");
692 injector_stream
693 .for_each(|request| {
694 futures::future::ready({
695 match request {
696 Ok(pointerinjector::DeviceRequest::Inject { .. }) => {
697 panic!("DeviceRequest::Inject is deprecated.");
698 }
699 Ok(pointerinjector::DeviceRequest::InjectEvents { events, .. }) => {
700 let _ = injector_sender.unbounded_send(events);
701 }
702 Err(e) => panic!("FIDL error {}", e),
703 }
704 })
705 })
706 .await;
707 }
708
709 async fn handle_device_request_stream(
712 injector_stream_receiver: futures::channel::oneshot::Receiver<
713 pointerinjector::DeviceRequestStream,
714 >,
715 expected_events: Vec<pointerinjector::Event>,
716 ) {
717 let mut injector_stream =
718 injector_stream_receiver.await.expect("Failed to get DeviceRequestStream.");
719 for expected_event in expected_events {
720 match injector_stream.next().await {
721 Some(Ok(pointerinjector::DeviceRequest::Inject { .. })) => {
722 panic!("DeviceRequest::Inject is deprecated.");
723 }
724 Some(Ok(pointerinjector::DeviceRequest::InjectEvents { events, .. })) => {
725 assert_eq!(events, vec![expected_event]);
726 }
727 Some(Err(e)) => panic!("FIDL error {}", e),
728 None => panic!("Expected another event."),
729 }
730 }
731 }
732
733 fn create_viewport(min: f32, max: f32) -> pointerinjector::Viewport {
735 pointerinjector::Viewport {
736 extents: Some([[min, min], [max, max]]),
737 viewport_to_context_transform: None,
738 ..Default::default()
739 }
740 }
741
742 fn create_viewport_next(min: f32, max: f32) -> pointerinjector_next::Viewport {
743 pointerinjector_next::Viewport {
744 extents: Some([[min, min], [max, max]]),
745 viewport_to_context_transform: None,
746 ..Default::default()
747 }
748 }
749
750 #[fuchsia::test]
753 fn receives_viewport_updates() {
754 let mut exec = fasync::TestExecutor::new();
755
756 let (configuration_proxy, mut configuration_request_stream) =
758 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
759 let (injector_registry_proxy, _) =
760 fidl_next::fuchsia::create_channel::<pointerinjector_next::Registry>();
761 let injector_registry_proxy =
762 Dispatcher::client_from_zx_channel(injector_registry_proxy).spawn();
763 let (sender, _) = futures::channel::mpsc::channel::<CursorMessage>(0);
764
765 let inspector = fuchsia_inspect::Inspector::default();
766 let test_node = inspector.root().create_child("test_node");
767
768 let mouse_handler_fut = MouseInjectorHandler::new_handler(
770 configuration_proxy,
771 injector_registry_proxy,
772 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
773 sender,
774 &test_node,
775 metrics::MetricsLogger::default(),
776 );
777 let config_request_stream_fut =
778 handle_configuration_request_stream(&mut configuration_request_stream);
779 let (mouse_handler_res, _) = exec.run_singlethreaded(futures::future::join(
780 mouse_handler_fut,
781 config_request_stream_fut,
782 ));
783 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
784
785 let (injector_device_proxy, mut injector_device_request_stream) =
787 next_client_old_stream::<pointerinjector::DeviceMarker, pointerinjector_next::Device>();
788 mouse_handler.inner_mut().injectors.insert(1, injector_device_proxy);
789
790 {
792 let watch_viewport_fut = mouse_handler.clone().watch_viewport();
794 futures::pin_mut!(watch_viewport_fut);
795 assert!(exec.run_until_stalled(&mut watch_viewport_fut).is_pending());
796
797 match exec.run_singlethreaded(&mut configuration_request_stream.next()) {
799 Some(Ok(pointerinjector_config::SetupRequest::WatchViewport {
800 responder, ..
801 })) => {
802 responder.send(&create_viewport(0.0, 100.0)).expect("Failed to send viewport.");
803 }
804 other => panic!("Received unexpected value: {:?}", other),
805 };
806 assert!(exec.run_until_stalled(&mut watch_viewport_fut).is_pending());
807
808 exec.run_singlethreaded(async {
810 match injector_device_request_stream.next().await {
811 Some(Ok(pointerinjector::DeviceRequest::Inject { .. })) => {
812 panic!("DeviceRequest::Inject is deprecated.");
813 }
814 Some(Ok(pointerinjector::DeviceRequest::InjectEvents { events, .. })) => {
815 assert_eq!(events.len(), 1);
816 assert!(events[0].data.is_some());
817 assert_eq!(
818 events[0].data,
819 Some(pointerinjector::Data::Viewport(create_viewport(0.0, 100.0)))
820 );
821 }
822 other => panic!("Received unexpected value: {:?}", other),
823 }
824 });
825
826 assert!(exec.run_until_stalled(&mut watch_viewport_fut).is_pending());
828
829 match exec.run_singlethreaded(&mut configuration_request_stream.next()) {
831 Some(Ok(pointerinjector_config::SetupRequest::WatchViewport {
832 responder, ..
833 })) => {
834 responder
835 .send(&create_viewport(100.0, 200.0))
836 .expect("Failed to send viewport.");
837 }
838 other => panic!("Received unexpected value: {:?}", other),
839 };
840
841 assert!(exec.run_until_stalled(&mut watch_viewport_fut).is_pending());
843 }
844
845 exec.run_singlethreaded(async {
847 match injector_device_request_stream.next().await {
848 Some(Ok(pointerinjector::DeviceRequest::Inject { .. })) => {
849 panic!("DeviceRequest::Inject is deprecated.");
850 }
851 Some(Ok(pointerinjector::DeviceRequest::InjectEvents { events, .. })) => {
852 assert_eq!(events.len(), 1);
853 assert!(events[0].data.is_some());
854 assert_eq!(
855 events[0].data,
856 Some(pointerinjector::Data::Viewport(create_viewport(100.0, 200.0)))
857 );
858 }
859 other => panic!("Received unexpected value: {:?}", other),
860 }
861 });
862
863 let expected_viewport = create_viewport_next(100.0, 200.0);
865 assert_eq!(mouse_handler.inner().viewport, Some(expected_viewport));
866 }
867
868 fn wheel_delta_ticks(
869 ticks: i64,
870 physical_pixel: Option<f32>,
871 ) -> Option<mouse_binding::WheelDelta> {
872 Some(mouse_binding::WheelDelta { ticks, physical_pixel })
873 }
874
875 #[test_case(
878 mouse_binding::MouseLocation::Relative(
879 mouse_binding::RelativeLocation {
880 counts: Position { x: 10.0, y: 20.0 }
881 }),
882 Position {
883 x: DISPLAY_WIDTH_IN_PHYSICAL_PX / 2.0 + 10.0,
884 y: DISPLAY_HEIGHT_IN_PHYSICAL_PX / 2.0 + 20.0,
885 },
886 [10.0, 20.0]; "Valid move event."
887 )]
888 #[test_case(
889 mouse_binding::MouseLocation::Relative(
890 mouse_binding::RelativeLocation {
891 counts: Position {
892 x: DISPLAY_WIDTH_IN_PHYSICAL_PX + 2.0,
893 y: DISPLAY_HEIGHT_IN_PHYSICAL_PX + 1.0,
894 }}),
895 Position {
896 x: DISPLAY_WIDTH_IN_PHYSICAL_PX,
897 y: DISPLAY_HEIGHT_IN_PHYSICAL_PX,
898 },
899 [
900 DISPLAY_WIDTH_IN_PHYSICAL_PX + 2.0,
901 DISPLAY_HEIGHT_IN_PHYSICAL_PX + 1.0,
902 ]; "Move event exceeds max bounds."
903 )]
904 #[test_case(
905 mouse_binding::MouseLocation::Relative(
906 mouse_binding::RelativeLocation {
907 counts: Position {
908 x: -(DISPLAY_WIDTH_IN_PHYSICAL_PX + 2.0),
909 y: -(DISPLAY_HEIGHT_IN_PHYSICAL_PX + 1.0),
910 }}),
911 Position { x: 0.0, y: 0.0 },
912 [
913 -(DISPLAY_WIDTH_IN_PHYSICAL_PX + 2.0),
914 -(DISPLAY_HEIGHT_IN_PHYSICAL_PX + 1.0),
915 ]; "Move event exceeds min bounds."
916 )]
917 #[fuchsia::test(allow_stalls = false)]
918 async fn move_event(
919 move_location: mouse_binding::MouseLocation,
920 expected_position: Position,
921 expected_relative_motion: [f32; 2],
922 ) {
923 let (configuration_proxy, mut configuration_request_stream) =
925 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
926 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
927 pointerinjector::RegistryMarker,
928 pointerinjector_next::Registry,
929 >();
930 let config_request_stream_fut =
931 handle_configuration_request_stream(&mut configuration_request_stream);
932
933 let (sender, mut receiver) = futures::channel::mpsc::channel::<CursorMessage>(1);
935 let inspector = fuchsia_inspect::Inspector::default();
936 let test_node = inspector.root().create_child("test_node");
937 let mouse_handler_fut = MouseInjectorHandler::new_handler(
938 configuration_proxy,
939 injector_registry_proxy,
940 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
941 sender,
942 &test_node,
943 metrics::MetricsLogger::default(),
944 );
945 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
946 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
947
948 let event_time = zx::MonotonicInstant::get();
949 let input_event = create_mouse_event(
950 move_location,
951 None, None, None, mouse_binding::MousePhase::Move,
955 SortedVecSet::new(),
956 SortedVecSet::new(),
957 event_time,
958 &DESCRIPTOR,
959 );
960
961 let handle_event_fut = mouse_handler.handle_input_event(input_event);
963 let expected_events = vec![
964 create_mouse_pointer_sample_event_phase_add(vec![], expected_position, event_time),
965 create_mouse_pointer_sample_event(
966 pointerinjector::EventPhase::Change,
967 vec![],
968 expected_position,
969 Some(expected_relative_motion),
970 None, None, None, event_time,
974 ),
975 ];
976
977 let (injector_stream_sender, injector_stream_receiver) =
981 futures::channel::oneshot::channel::<pointerinjector::DeviceRequestStream>();
982 let registry_fut = handle_registry_request_stream(
983 injector_registry_request_stream,
984 injector_stream_sender,
985 );
986 let device_fut = handle_device_request_stream(injector_stream_receiver, expected_events);
987
988 let (handle_result, _, _) = futures::join!(handle_event_fut, registry_fut, device_fut);
991 match receiver.next().await {
992 Some(CursorMessage::SetPosition(position)) => {
993 pretty_assertions::assert_eq!(position, expected_position);
994 }
995 Some(CursorMessage::SetVisibility(_)) => {
996 panic!("Received unexpected cursor visibility update.")
997 }
998 None => panic!("Did not receive cursor update."),
999 }
1000
1001 assert_matches!(
1003 handle_result.as_slice(),
1004 [input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
1005 );
1006 }
1007
1008 #[fuchsia::test(allow_stalls = false)]
1011 async fn move_absolute_event() {
1012 const DEVICE_ID: u32 = 1;
1013
1014 let (configuration_proxy, mut configuration_request_stream) =
1016 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
1017 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
1018 pointerinjector::RegistryMarker,
1019 pointerinjector_next::Registry,
1020 >();
1021 let config_request_stream_fut =
1022 handle_configuration_request_stream(&mut configuration_request_stream);
1023
1024 let (sender, mut receiver) = futures::channel::mpsc::channel::<CursorMessage>(1);
1026 let inspector = fuchsia_inspect::Inspector::default();
1027 let test_node = inspector.root().create_child("test_node");
1028 let mouse_handler_fut = MouseInjectorHandler::new_handler(
1029 configuration_proxy,
1030 injector_registry_proxy,
1031 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
1032 sender,
1033 &test_node,
1034 metrics::MetricsLogger::default(),
1035 );
1036 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
1037 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
1038
1039 let cursor_location =
1055 mouse_binding::MouseLocation::Absolute(Position { x: -25.0, y: 25.0 });
1056 let event_time = zx::MonotonicInstant::get();
1057 let descriptor =
1058 input_device::InputDeviceDescriptor::Mouse(mouse_binding::MouseDeviceDescriptor {
1059 device_id: DEVICE_ID,
1060 absolute_x_range: Some(fidl_input_report::Range { min: -50, max: 50 }),
1061 absolute_y_range: Some(fidl_input_report::Range { min: -50, max: 50 }),
1062 wheel_v_range: None,
1063 wheel_h_range: None,
1064 buttons: None,
1065 });
1066 let input_event = create_mouse_event(
1067 cursor_location,
1068 None, None, None, mouse_binding::MousePhase::Move,
1072 SortedVecSet::new(),
1073 SortedVecSet::new(),
1074 event_time,
1075 &descriptor,
1076 );
1077
1078 let handle_event_fut = mouse_handler.handle_input_event(input_event);
1080 let expected_position = Position {
1081 x: DISPLAY_WIDTH_IN_PHYSICAL_PX * 0.25,
1082 y: DISPLAY_WIDTH_IN_PHYSICAL_PX * 0.75,
1083 };
1084 let expected_events = vec![
1085 create_mouse_pointer_sample_event_phase_add(vec![], expected_position, event_time),
1086 create_mouse_pointer_sample_event(
1087 pointerinjector::EventPhase::Change,
1088 vec![],
1089 expected_position,
1090 None, None, None, None, event_time,
1095 ),
1096 ];
1097
1098 let (injector_stream_sender, injector_stream_receiver) =
1102 futures::channel::oneshot::channel::<pointerinjector::DeviceRequestStream>();
1103 let registry_fut = handle_registry_request_stream(
1104 injector_registry_request_stream,
1105 injector_stream_sender,
1106 );
1107 let device_fut = handle_device_request_stream(injector_stream_receiver, expected_events);
1108
1109 let (handle_result, _, _) = futures::join!(handle_event_fut, registry_fut, device_fut);
1112 match receiver.next().await {
1113 Some(CursorMessage::SetPosition(position)) => {
1114 assert_eq!(position, expected_position);
1115 }
1116 Some(CursorMessage::SetVisibility(_)) => {
1117 panic!("Received unexpected cursor visibility update.")
1118 }
1119 None => panic!("Did not receive cursor update."),
1120 }
1121
1122 assert_matches!(
1124 handle_result.as_slice(),
1125 [input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
1126 );
1127 }
1128
1129 #[test_case(
1131 mouse_binding::MousePhase::Down,
1132 vec![1], vec![1]; "Down event injects button press state."
1133 )]
1134 #[test_case(
1135 mouse_binding::MousePhase::Up,
1136 vec![1], vec![]; "Up event injects button press state."
1137 )]
1138 #[fuchsia::test(allow_stalls = false)]
1139 async fn button_state_event(
1140 phase: mouse_binding::MousePhase,
1141 affected_buttons: Vec<mouse_binding::MouseButton>,
1142 pressed_buttons: Vec<mouse_binding::MouseButton>,
1143 ) {
1144 let (configuration_proxy, mut configuration_request_stream) =
1146 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
1147 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
1148 pointerinjector::RegistryMarker,
1149 pointerinjector_next::Registry,
1150 >();
1151 let config_request_stream_fut =
1152 handle_configuration_request_stream(&mut configuration_request_stream);
1153
1154 let (sender, mut receiver) = futures::channel::mpsc::channel::<CursorMessage>(1);
1156 let inspector = fuchsia_inspect::Inspector::default();
1157 let test_node = inspector.root().create_child("test_node");
1158 let mouse_handler_fut = MouseInjectorHandler::new_handler(
1159 configuration_proxy,
1160 injector_registry_proxy,
1161 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
1162 sender,
1163 &test_node,
1164 metrics::MetricsLogger::default(),
1165 );
1166 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
1167 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
1168
1169 let cursor_location = mouse_binding::MouseLocation::Absolute(Position { x: 0.0, y: 0.0 });
1170 let event_time = zx::MonotonicInstant::get();
1171
1172 let input_event = create_mouse_event(
1173 cursor_location,
1174 None, None, None, phase,
1178 affected_buttons.clone().into(),
1179 pressed_buttons.clone().into(),
1180 event_time,
1181 &DESCRIPTOR,
1182 );
1183
1184 let handle_event_fut = mouse_handler.handle_input_event(input_event);
1186 let expected_position = Position { x: 0.0, y: 0.0 };
1187 let expected_events = vec![
1188 create_mouse_pointer_sample_event_phase_add(
1189 pressed_buttons.clone().into(),
1190 expected_position,
1191 event_time,
1192 ),
1193 create_mouse_pointer_sample_event(
1194 pointerinjector::EventPhase::Change,
1195 pressed_buttons.clone().into(),
1196 expected_position,
1197 None, None, None, None, event_time,
1202 ),
1203 ];
1204
1205 let (injector_stream_sender, injector_stream_receiver) =
1209 futures::channel::oneshot::channel::<pointerinjector::DeviceRequestStream>();
1210 let registry_fut = handle_registry_request_stream(
1211 injector_registry_request_stream,
1212 injector_stream_sender,
1213 );
1214 let device_fut = handle_device_request_stream(injector_stream_receiver, expected_events);
1215
1216 let (handle_result, _, _) = futures::join!(handle_event_fut, registry_fut, device_fut);
1219 match receiver.next().await {
1220 Some(CursorMessage::SetPosition(position)) => {
1221 pretty_assertions::assert_eq!(position, expected_position);
1222 }
1223 Some(CursorMessage::SetVisibility(_)) => {
1224 panic!("Received unexpected cursor visibility update.")
1225 }
1226 None => panic!("Did not receive cursor update."),
1227 }
1228
1229 assert_matches!(
1231 handle_result.as_slice(),
1232 [input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
1233 );
1234 }
1235
1236 #[fuchsia::test(allow_stalls = false)]
1238 async fn down_up_event() {
1239 let (configuration_proxy, mut configuration_request_stream) =
1241 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
1242 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
1243 pointerinjector::RegistryMarker,
1244 pointerinjector_next::Registry,
1245 >();
1246 let config_request_stream_fut =
1247 handle_configuration_request_stream(&mut configuration_request_stream);
1248
1249 let (sender, mut receiver) = futures::channel::mpsc::channel::<CursorMessage>(2);
1253 let inspector = fuchsia_inspect::Inspector::default();
1254 let test_node = inspector.root().create_child("test_node");
1255 let mouse_handler_fut = MouseInjectorHandler::new_handler(
1256 configuration_proxy,
1257 injector_registry_proxy,
1258 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
1259 sender,
1260 &test_node,
1261 metrics::MetricsLogger::default(),
1262 );
1263 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
1264 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
1265
1266 let cursor_location = mouse_binding::MouseLocation::Absolute(Position { x: 0.0, y: 0.0 });
1267 let event_time1 = zx::MonotonicInstant::get();
1268 let event_time2 = event_time1.add(zx::MonotonicDuration::from_micros(1));
1269
1270 let event1 = create_mouse_event(
1271 cursor_location,
1272 None, None, None, mouse_binding::MousePhase::Down,
1276 SortedVecSet::from(vec![1]),
1277 SortedVecSet::from(vec![1]),
1278 event_time1,
1279 &DESCRIPTOR,
1280 );
1281
1282 let event2 = create_mouse_event(
1283 cursor_location,
1284 None, None, None, mouse_binding::MousePhase::Up,
1288 SortedVecSet::from(vec![1]),
1289 SortedVecSet::new(),
1290 event_time2,
1291 &DESCRIPTOR,
1292 );
1293
1294 let expected_position = Position { x: 0.0, y: 0.0 };
1295
1296 let (injector_stream_sender, injector_stream_receiver) =
1300 mpsc::unbounded::<Vec<pointerinjector::Event>>();
1301 let mut injector_stream_receiver = injector_stream_receiver.ready_chunks(2);
1303 let registry_fut = handle_registry_request_stream2(
1304 injector_registry_request_stream,
1305 injector_stream_sender,
1306 );
1307
1308 let _registry_task = fasync::Task::local(registry_fut);
1310
1311 mouse_handler.clone().handle_input_event(event1).await;
1312 assert_eq!(
1313 injector_stream_receiver
1314 .next()
1315 .await
1316 .map(|events| events.into_iter().flatten().collect()),
1317 Some(vec![
1318 create_mouse_pointer_sample_event_phase_add(
1319 vec![1],
1320 expected_position,
1321 event_time1,
1322 ),
1323 create_mouse_pointer_sample_event(
1324 pointerinjector::EventPhase::Change,
1325 vec![1],
1326 expected_position,
1327 None, None, None, None, event_time1,
1332 )
1333 ])
1334 );
1335
1336 mouse_handler.clone().handle_input_event(event2).await;
1338 assert_eq!(
1339 injector_stream_receiver
1340 .next()
1341 .await
1342 .map(|events| events.into_iter().flatten().collect()),
1343 Some(vec![create_mouse_pointer_sample_event(
1344 pointerinjector::EventPhase::Change,
1345 vec![],
1346 expected_position,
1347 None, None, None, None, event_time2,
1352 )])
1353 );
1354
1355 match receiver.next().await {
1357 Some(CursorMessage::SetPosition(position)) => {
1358 assert_eq!(position, expected_position);
1359 }
1360 Some(CursorMessage::SetVisibility(_)) => {
1361 panic!("Received unexpected cursor visibility update.")
1362 }
1363 None => panic!("Did not receive cursor update."),
1364 }
1365 }
1366
1367 #[fuchsia::test(allow_stalls = false)]
1377 async fn down_down_up_up_event() {
1378 let (configuration_proxy, mut configuration_request_stream) =
1380 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
1381 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
1382 pointerinjector::RegistryMarker,
1383 pointerinjector_next::Registry,
1384 >();
1385 let config_request_stream_fut =
1386 handle_configuration_request_stream(&mut configuration_request_stream);
1387
1388 let (sender, mut receiver) = futures::channel::mpsc::channel::<CursorMessage>(4);
1392 let inspector = fuchsia_inspect::Inspector::default();
1393 let test_node = inspector.root().create_child("test_node");
1394 let mouse_handler_fut = MouseInjectorHandler::new_handler(
1395 configuration_proxy,
1396 injector_registry_proxy,
1397 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
1398 sender,
1399 &test_node,
1400 metrics::MetricsLogger::default(),
1401 );
1402 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
1403 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
1404
1405 let cursor_location = mouse_binding::MouseLocation::Absolute(Position { x: 0.0, y: 0.0 });
1406 let event_time1 = zx::MonotonicInstant::get();
1407 let event_time2 = event_time1.add(zx::MonotonicDuration::from_micros(1));
1408 let event_time3 = event_time2.add(zx::MonotonicDuration::from_micros(1));
1409 let event_time4 = event_time3.add(zx::MonotonicDuration::from_micros(1));
1410
1411 let event1 = create_mouse_event(
1412 cursor_location,
1413 None, None, None, mouse_binding::MousePhase::Down,
1417 SortedVecSet::from(vec![1]),
1418 SortedVecSet::from(vec![1]),
1419 event_time1,
1420 &DESCRIPTOR,
1421 );
1422 let event2 = create_mouse_event(
1423 cursor_location,
1424 None, None, None, mouse_binding::MousePhase::Down,
1428 SortedVecSet::from(vec![2]),
1429 SortedVecSet::from(vec![1, 2]),
1430 event_time2,
1431 &DESCRIPTOR,
1432 );
1433 let event3 = create_mouse_event(
1434 cursor_location,
1435 None, None, None, mouse_binding::MousePhase::Up,
1439 SortedVecSet::from(vec![1]),
1440 SortedVecSet::from(vec![2]),
1441 event_time3,
1442 &DESCRIPTOR,
1443 );
1444 let event4 = create_mouse_event(
1445 cursor_location,
1446 None, None, None, mouse_binding::MousePhase::Up,
1450 SortedVecSet::from(vec![2]),
1451 SortedVecSet::new(),
1452 event_time4,
1453 &DESCRIPTOR,
1454 );
1455
1456 let expected_position = Position { x: 0.0, y: 0.0 };
1457
1458 let (injector_stream_sender, injector_stream_receiver) =
1462 mpsc::unbounded::<Vec<pointerinjector::Event>>();
1463 let mut injector_stream_receiver = injector_stream_receiver.ready_chunks(2);
1465 let registry_fut = handle_registry_request_stream2(
1466 injector_registry_request_stream,
1467 injector_stream_sender,
1468 );
1469
1470 let _registry_task = fasync::Task::local(registry_fut);
1472 mouse_handler.clone().handle_input_event(event1).await;
1473 assert_eq!(
1474 injector_stream_receiver
1475 .next()
1476 .await
1477 .map(|events| events.into_iter().flatten().collect()),
1478 Some(vec![
1479 create_mouse_pointer_sample_event_phase_add(
1480 vec![1],
1481 expected_position,
1482 event_time1,
1483 ),
1484 create_mouse_pointer_sample_event(
1485 pointerinjector::EventPhase::Change,
1486 vec![1],
1487 expected_position,
1488 None, None, None, None, event_time1,
1493 )
1494 ])
1495 );
1496
1497 mouse_handler.clone().handle_input_event(event2).await;
1499 let pointer_sample_event2: Vec<_> = injector_stream_receiver
1500 .next()
1501 .await
1502 .map(|events| events.into_iter().flatten().collect())
1503 .expect("Failed to receive pointer sample event.");
1504 let expected_event_time: i64 = event_time2.into_nanos();
1505 assert_eq!(pointer_sample_event2.len(), 1);
1506
1507 match &pointer_sample_event2[0] {
1510 pointerinjector::Event {
1511 timestamp: Some(actual_event_time),
1512 data:
1513 Some(pointerinjector::Data::PointerSample(pointerinjector::PointerSample {
1514 pointer_id: Some(0),
1515 phase: Some(pointerinjector::EventPhase::Change),
1516 position_in_viewport: Some(actual_position),
1517 scroll_v: None,
1518 scroll_h: None,
1519 pressed_buttons: Some(actual_buttons),
1520 relative_motion: None,
1521 ..
1522 })),
1523 ..
1524 } => {
1525 assert_eq!(*actual_event_time, expected_event_time);
1526 assert_eq!(actual_position[0], expected_position.x);
1527 assert_eq!(actual_position[1], expected_position.y);
1528 assert_eq!(actual_buttons.as_slice(), &[1u8, 2u8]);
1529 }
1530 _ => panic!("Unexpected pointer sample event: {:?}", pointer_sample_event2[0]),
1531 }
1532
1533 mouse_handler.clone().handle_input_event(event3).await;
1535 assert_eq!(
1536 injector_stream_receiver
1537 .next()
1538 .await
1539 .map(|events| events.into_iter().flatten().collect()),
1540 Some(vec![create_mouse_pointer_sample_event(
1541 pointerinjector::EventPhase::Change,
1542 vec![2],
1543 expected_position,
1544 None, None, None, None, event_time3,
1549 )])
1550 );
1551
1552 mouse_handler.clone().handle_input_event(event4).await;
1554 assert_eq!(
1555 injector_stream_receiver
1556 .next()
1557 .await
1558 .map(|events| events.into_iter().flatten().collect()),
1559 Some(vec![create_mouse_pointer_sample_event(
1560 pointerinjector::EventPhase::Change,
1561 vec![],
1562 expected_position,
1563 None, None, None, None, event_time4,
1568 )])
1569 );
1570
1571 match receiver.next().await {
1573 Some(CursorMessage::SetPosition(position)) => {
1574 assert_eq!(position, expected_position);
1575 }
1576 Some(CursorMessage::SetVisibility(_)) => {
1577 panic!("Received unexpected cursor visibility update.")
1578 }
1579 None => panic!("Did not receive cursor update."),
1580 }
1581 }
1582
1583 #[fuchsia::test(allow_stalls = false)]
1585 async fn down_move_up_event() {
1586 let (configuration_proxy, mut configuration_request_stream) =
1588 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
1589 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
1590 pointerinjector::RegistryMarker,
1591 pointerinjector_next::Registry,
1592 >();
1593 let config_request_stream_fut =
1594 handle_configuration_request_stream(&mut configuration_request_stream);
1595
1596 let (sender, mut receiver) = futures::channel::mpsc::channel::<CursorMessage>(3);
1600 let inspector = fuchsia_inspect::Inspector::default();
1601 let test_node = inspector.root().create_child("test_node");
1602 let mouse_handler_fut = MouseInjectorHandler::new_handler(
1603 configuration_proxy,
1604 injector_registry_proxy,
1605 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
1606 sender,
1607 &test_node,
1608 metrics::MetricsLogger::default(),
1609 );
1610 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
1611 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
1612
1613 let event_time1 = zx::MonotonicInstant::get();
1614 let event_time2 = event_time1.add(zx::MonotonicDuration::from_micros(1));
1615 let event_time3 = event_time2.add(zx::MonotonicDuration::from_micros(1));
1616 let zero_position = Position { x: 0.0, y: 0.0 };
1617 let expected_position = Position { x: 10.0, y: 5.0 };
1618 let expected_relative_motion = [10.0, 5.0];
1619 let event1 = create_mouse_event(
1620 mouse_binding::MouseLocation::Absolute(Position { x: 0.0, y: 0.0 }),
1621 None, None, None, mouse_binding::MousePhase::Down,
1625 SortedVecSet::from(vec![1]),
1626 SortedVecSet::from(vec![1]),
1627 event_time1,
1628 &DESCRIPTOR,
1629 );
1630 let event2 = create_mouse_event(
1631 mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
1632 counts: Position { x: 10.0, y: 5.0 },
1633 }),
1634 None, None, None, mouse_binding::MousePhase::Move,
1638 SortedVecSet::from(vec![1]),
1639 SortedVecSet::from(vec![1]),
1640 event_time2,
1641 &DESCRIPTOR,
1642 );
1643 let event3 = create_mouse_event(
1644 mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
1645 counts: Position { x: 0.0, y: 0.0 },
1646 }),
1647 None, None, None, mouse_binding::MousePhase::Up,
1651 SortedVecSet::from(vec![1]),
1652 SortedVecSet::new(),
1653 event_time3,
1654 &DESCRIPTOR,
1655 );
1656
1657 let (injector_stream_sender, injector_stream_receiver) =
1661 mpsc::unbounded::<Vec<pointerinjector::Event>>();
1662 let mut injector_stream_receiver = injector_stream_receiver.ready_chunks(2);
1664 let registry_fut = handle_registry_request_stream2(
1665 injector_registry_request_stream,
1666 injector_stream_sender,
1667 );
1668
1669 let _registry_task = fasync::Task::local(registry_fut);
1671 mouse_handler.clone().handle_input_event(event1).await;
1672 assert_eq!(
1673 injector_stream_receiver
1674 .next()
1675 .await
1676 .map(|events| events.into_iter().flatten().collect()),
1677 Some(vec![
1678 create_mouse_pointer_sample_event_phase_add(vec![1], zero_position, event_time1,),
1679 create_mouse_pointer_sample_event(
1680 pointerinjector::EventPhase::Change,
1681 vec![1],
1682 zero_position,
1683 None, None, None, None, event_time1,
1688 )
1689 ])
1690 );
1691
1692 match receiver.next().await {
1694 Some(CursorMessage::SetPosition(position)) => {
1695 assert_eq!(position, zero_position);
1696 }
1697 Some(CursorMessage::SetVisibility(_)) => {
1698 panic!("Received unexpected cursor visibility update.")
1699 }
1700 None => panic!("Did not receive cursor update."),
1701 }
1702
1703 mouse_handler.clone().handle_input_event(event2).await;
1705 assert_eq!(
1706 injector_stream_receiver
1707 .next()
1708 .await
1709 .map(|events| events.into_iter().flatten().collect()),
1710 Some(vec![create_mouse_pointer_sample_event(
1711 pointerinjector::EventPhase::Change,
1712 vec![1],
1713 expected_position,
1714 Some(expected_relative_motion),
1715 None, None, None, event_time2,
1719 )])
1720 );
1721
1722 match receiver.next().await {
1724 Some(CursorMessage::SetPosition(position)) => {
1725 assert_eq!(position, expected_position);
1726 }
1727 Some(CursorMessage::SetVisibility(_)) => {
1728 panic!("Received unexpected cursor visibility update.")
1729 }
1730 None => panic!("Did not receive cursor update."),
1731 }
1732
1733 mouse_handler.clone().handle_input_event(event3).await;
1735 assert_eq!(
1736 injector_stream_receiver
1737 .next()
1738 .await
1739 .map(|events| events.into_iter().flatten().collect()),
1740 Some(vec![create_mouse_pointer_sample_event(
1741 pointerinjector::EventPhase::Change,
1742 vec![],
1743 expected_position,
1744 None, None, None, None, event_time3,
1749 )])
1750 );
1751
1752 match receiver.next().await {
1754 Some(CursorMessage::SetPosition(position)) => {
1755 assert_eq!(position, expected_position);
1756 }
1757 Some(CursorMessage::SetVisibility(_)) => {
1758 panic!("Received unexpected cursor visibility update.")
1759 }
1760 None => panic!("Did not receive cursor update."),
1761 }
1762 }
1763
1764 #[fuchsia::test(allow_stalls = false)]
1766 async fn handler_ignores_handled_events() {
1767 let (configuration_proxy, mut configuration_request_stream) =
1769 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
1770 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
1771 pointerinjector::RegistryMarker,
1772 pointerinjector_next::Registry,
1773 >();
1774 let config_request_stream_fut =
1775 handle_configuration_request_stream(&mut configuration_request_stream);
1776
1777 let (sender, mut receiver) = futures::channel::mpsc::channel::<CursorMessage>(1);
1779 let inspector = fuchsia_inspect::Inspector::default();
1780 let test_node = inspector.root().create_child("test_node");
1781 let mouse_handler_fut = MouseInjectorHandler::new_handler(
1782 configuration_proxy,
1783 injector_registry_proxy,
1784 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
1785 sender,
1786 &test_node,
1787 metrics::MetricsLogger::default(),
1788 );
1789 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
1790 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
1791
1792 let cursor_relative_position = Position { x: 50.0, y: 75.0 };
1793 let cursor_location =
1794 mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
1795 counts: Position { x: cursor_relative_position.x, y: cursor_relative_position.y },
1796 });
1797 let event_time = zx::MonotonicInstant::get();
1798 let input_events = vec![create_mouse_event_with_handled(
1799 cursor_location,
1800 None, None, None, mouse_binding::MousePhase::Move,
1804 SortedVecSet::new(),
1805 SortedVecSet::new(),
1806 event_time,
1807 &DESCRIPTOR,
1808 input_device::Handled::Yes,
1809 )];
1810
1811 assert_handler_ignores_input_event_sequence(
1812 mouse_handler,
1813 input_events,
1814 injector_registry_request_stream,
1815 )
1816 .await;
1817
1818 assert!(receiver.next().await.is_none());
1820 }
1821
1822 fn zero_relative_location() -> mouse_binding::MouseLocation {
1823 mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
1824 counts: Position { x: 0.0, y: 0.0 },
1825 })
1826 }
1827
1828 #[test_case(
1829 create_mouse_event(
1830 zero_relative_location(),
1831 wheel_delta_ticks(1, None), None, Some(mouse_binding::PrecisionScroll::No), mouse_binding::MousePhase::Wheel,
1835 SortedVecSet::new(),
1836 SortedVecSet::new(),
1837 zx::MonotonicInstant::ZERO,
1838 &DESCRIPTOR,
1839 ),
1840 create_mouse_pointer_sample_event(
1841 pointerinjector::EventPhase::Change,
1842 vec![],
1843 Position { x: 50.0, y: 50.0 },
1844 None, Some(1), None, Some(false), zx::MonotonicInstant::ZERO,
1849 ); "v tick scroll"
1850 )]
1851 #[test_case(
1852 create_mouse_event(
1853 zero_relative_location(),
1854 None, wheel_delta_ticks(1, None), Some(mouse_binding::PrecisionScroll::No), mouse_binding::MousePhase::Wheel,
1858 SortedVecSet::new(),
1859 SortedVecSet::new(),
1860 zx::MonotonicInstant::ZERO,
1861 &DESCRIPTOR,
1862 ),
1863 create_mouse_pointer_sample_event(
1864 pointerinjector::EventPhase::Change,
1865 vec![],
1866 Position { x: 50.0, y: 50.0 },
1867 None, None, Some(1), Some(false), zx::MonotonicInstant::ZERO,
1872 ); "h tick scroll"
1873 )]
1874 #[test_case(
1875 create_mouse_event(
1876 zero_relative_location(),
1877 wheel_delta_ticks(1, Some(120.0)), None, Some(mouse_binding::PrecisionScroll::No), mouse_binding::MousePhase::Wheel,
1881 SortedVecSet::new(),
1882 SortedVecSet::new(),
1883 zx::MonotonicInstant::ZERO,
1884 &DESCRIPTOR,
1885 ),
1886 create_mouse_pointer_sample_event_with_wheel_physical_pixel(
1887 pointerinjector::EventPhase::Change,
1888 vec![],
1889 Position { x: 50.0, y: 50.0 },
1890 None, Some(1), None, Some(120.0), None, Some(false), zx::MonotonicInstant::ZERO,
1897 ); "v tick scroll with physical pixel"
1898 )]
1899 #[test_case(
1900 create_mouse_event(
1901 zero_relative_location(),
1902 None, wheel_delta_ticks(1, Some(120.0)), Some(mouse_binding::PrecisionScroll::No), mouse_binding::MousePhase::Wheel,
1906 SortedVecSet::new(),
1907 SortedVecSet::new(),
1908 zx::MonotonicInstant::ZERO,
1909 &DESCRIPTOR,
1910 ),
1911 create_mouse_pointer_sample_event_with_wheel_physical_pixel(
1912 pointerinjector::EventPhase::Change,
1913 vec![],
1914 Position { x: 50.0, y: 50.0 },
1915 None, None, Some(1), None, Some(120.0), Some(false), zx::MonotonicInstant::ZERO,
1922 ); "h tick scroll with physical pixel"
1923 )]
1924 #[test_case(
1925 create_mouse_event(
1926 zero_relative_location(),
1927 wheel_delta_ticks(1, Some(120.0)), None, Some(mouse_binding::PrecisionScroll::Yes), mouse_binding::MousePhase::Wheel,
1931 SortedVecSet::new(),
1932 SortedVecSet::new(),
1933 zx::MonotonicInstant::ZERO,
1934 &DESCRIPTOR,
1935 ),
1936 create_mouse_pointer_sample_event_with_wheel_physical_pixel(
1937 pointerinjector::EventPhase::Change,
1938 vec![],
1939 Position { x: 50.0, y: 50.0 },
1940 None, Some(1), None, Some(120.0), None, Some(true), zx::MonotonicInstant::ZERO,
1947 ); "v precision scroll with physical pixel"
1948 )]
1949 #[test_case(
1950 create_mouse_event(
1951 zero_relative_location(),
1952 None, wheel_delta_ticks(1, Some(120.0)), Some(mouse_binding::PrecisionScroll::Yes), mouse_binding::MousePhase::Wheel,
1956 SortedVecSet::new(),
1957 SortedVecSet::new(),
1958 zx::MonotonicInstant::ZERO,
1959 &DESCRIPTOR,
1960 ),
1961 create_mouse_pointer_sample_event_with_wheel_physical_pixel(
1962 pointerinjector::EventPhase::Change,
1963 vec![],
1964 Position { x: 50.0, y: 50.0 },
1965 None, None, Some(1), None, Some(120.0), Some(true), zx::MonotonicInstant::ZERO,
1972 ); "h precision scroll with physical pixel"
1973 )]
1974 #[fuchsia::test(allow_stalls = false)]
1976 async fn scroll(event: input_device::InputEvent, want_event: pointerinjector::Event) {
1977 let (configuration_proxy, mut configuration_request_stream) =
1979 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
1980 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
1981 pointerinjector::RegistryMarker,
1982 pointerinjector_next::Registry,
1983 >();
1984 let config_request_stream_fut =
1985 handle_configuration_request_stream(&mut configuration_request_stream);
1986
1987 let (sender, _) = futures::channel::mpsc::channel::<CursorMessage>(1);
1989 let inspector = fuchsia_inspect::Inspector::default();
1990 let test_node = inspector.root().create_child("test_node");
1991 let mouse_handler_fut = MouseInjectorHandler::new_handler(
1992 configuration_proxy,
1993 injector_registry_proxy,
1994 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
1995 sender,
1996 &test_node,
1997 metrics::MetricsLogger::default(),
1998 );
1999 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
2000 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
2001
2002 let (injector_stream_sender, injector_stream_receiver) =
2006 mpsc::unbounded::<Vec<pointerinjector::Event>>();
2007 let mut injector_stream_receiver = injector_stream_receiver.ready_chunks(2);
2009 let registry_fut = handle_registry_request_stream2(
2010 injector_registry_request_stream,
2011 injector_stream_sender,
2012 );
2013
2014 let event_time = zx::MonotonicInstant::get();
2015
2016 let event = input_device::InputEvent { event_time, ..event };
2017
2018 let want_event =
2019 pointerinjector::Event { timestamp: Some(event_time.into_nanos()), ..want_event };
2020
2021 let _registry_task = fasync::Task::local(registry_fut);
2023
2024 mouse_handler.clone().handle_input_event(event).await;
2025 let got_events: Vec<_> = injector_stream_receiver
2026 .next()
2027 .await
2028 .map(|events| events.into_iter().flatten().collect())
2029 .unwrap();
2030 pretty_assertions::assert_eq!(got_events.len(), 2);
2031 assert_matches!(
2032 got_events[0],
2033 pointerinjector::Event {
2034 data: Some(pointerinjector::Data::PointerSample(pointerinjector::PointerSample {
2035 phase: Some(pointerinjector::EventPhase::Add),
2036 ..
2037 })),
2038 ..
2039 }
2040 );
2041
2042 pretty_assertions::assert_eq!(got_events[1], want_event);
2043 }
2044
2045 #[fuchsia::test(allow_stalls = false)]
2047 async fn down_scroll_up_scroll() {
2048 let (configuration_proxy, mut configuration_request_stream) =
2050 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
2051 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
2052 pointerinjector::RegistryMarker,
2053 pointerinjector_next::Registry,
2054 >();
2055 let config_request_stream_fut =
2056 handle_configuration_request_stream(&mut configuration_request_stream);
2057
2058 let (sender, _) = futures::channel::mpsc::channel::<CursorMessage>(1);
2060 let inspector = fuchsia_inspect::Inspector::default();
2061 let test_node = inspector.root().create_child("test_node");
2062 let mouse_handler_fut = MouseInjectorHandler::new_handler(
2063 configuration_proxy,
2064 injector_registry_proxy,
2065 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
2066 sender,
2067 &test_node,
2068 metrics::MetricsLogger::default(),
2069 );
2070 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
2071 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
2072
2073 let (injector_stream_sender, injector_stream_receiver) =
2077 mpsc::unbounded::<Vec<pointerinjector::Event>>();
2078 let mut injector_stream_receiver = injector_stream_receiver.ready_chunks(2);
2080 let registry_fut = handle_registry_request_stream2(
2081 injector_registry_request_stream,
2082 injector_stream_sender,
2083 );
2084
2085 let event_time1 = zx::MonotonicInstant::get();
2086 let event_time2 = event_time1.add(zx::MonotonicDuration::from_micros(1));
2087 let event_time3 = event_time2.add(zx::MonotonicDuration::from_micros(1));
2088 let event_time4 = event_time3.add(zx::MonotonicDuration::from_micros(1));
2089
2090 let _registry_task = fasync::Task::local(registry_fut);
2092
2093 let zero_location =
2094 mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
2095 counts: Position { x: 0.0, y: 0.0 },
2096 });
2097 let expected_position = Position { x: 50.0, y: 50.0 };
2098
2099 let down_event = create_mouse_event(
2100 zero_location,
2101 None, None, None, mouse_binding::MousePhase::Down,
2105 SortedVecSet::from(vec![1]),
2106 SortedVecSet::from(vec![1]),
2107 event_time1,
2108 &DESCRIPTOR,
2109 );
2110
2111 let wheel_event = create_mouse_event(
2112 zero_location,
2113 wheel_delta_ticks(1, None), None, Some(mouse_binding::PrecisionScroll::No), mouse_binding::MousePhase::Wheel,
2117 SortedVecSet::from(vec![1]),
2118 SortedVecSet::from(vec![1]),
2119 event_time2,
2120 &DESCRIPTOR,
2121 );
2122
2123 let up_event = create_mouse_event(
2124 zero_location,
2125 None,
2126 None,
2127 None, mouse_binding::MousePhase::Up,
2129 SortedVecSet::from(vec![1]),
2130 SortedVecSet::new(),
2131 event_time3,
2132 &DESCRIPTOR,
2133 );
2134
2135 let continue_wheel_event = create_mouse_event(
2136 zero_location,
2137 wheel_delta_ticks(1, None), None, Some(mouse_binding::PrecisionScroll::No), mouse_binding::MousePhase::Wheel,
2141 SortedVecSet::new(),
2142 SortedVecSet::new(),
2143 event_time4,
2144 &DESCRIPTOR,
2145 );
2146
2147 mouse_handler.clone().handle_input_event(down_event).await;
2149 assert_eq!(
2150 injector_stream_receiver
2151 .next()
2152 .await
2153 .map(|events| events.into_iter().flatten().collect()),
2154 Some(vec![
2155 create_mouse_pointer_sample_event_phase_add(
2156 vec![1],
2157 expected_position,
2158 event_time1,
2159 ),
2160 create_mouse_pointer_sample_event(
2161 pointerinjector::EventPhase::Change,
2162 vec![1],
2163 expected_position,
2164 None, None, None, None, event_time1,
2169 ),
2170 ])
2171 );
2172
2173 mouse_handler.clone().handle_input_event(wheel_event).await;
2175 assert_eq!(
2176 injector_stream_receiver
2177 .next()
2178 .await
2179 .map(|events| events.into_iter().flatten().collect()),
2180 Some(vec![create_mouse_pointer_sample_event(
2181 pointerinjector::EventPhase::Change,
2182 vec![1],
2183 expected_position,
2184 None, Some(1), None, Some(false), event_time2,
2189 )])
2190 );
2191
2192 mouse_handler.clone().handle_input_event(up_event).await;
2194 assert_eq!(
2195 injector_stream_receiver
2196 .next()
2197 .await
2198 .map(|events| events.into_iter().flatten().collect()),
2199 Some(vec![create_mouse_pointer_sample_event(
2200 pointerinjector::EventPhase::Change,
2201 vec![],
2202 expected_position,
2203 None, None, None, None, event_time3,
2208 )])
2209 );
2210
2211 mouse_handler.clone().handle_input_event(continue_wheel_event).await;
2213 assert_eq!(
2214 injector_stream_receiver
2215 .next()
2216 .await
2217 .map(|events| events.into_iter().flatten().collect()),
2218 Some(vec![create_mouse_pointer_sample_event(
2219 pointerinjector::EventPhase::Change,
2220 vec![],
2221 expected_position,
2222 None, Some(1), None, Some(false), event_time4,
2227 )])
2228 );
2229 }
2230
2231 #[fuchsia::test(allow_stalls = false)]
2232 async fn mouse_injector_handler_initialized_with_inspect_node() {
2233 let (configuration_proxy, mut configuration_request_stream) =
2234 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
2235 let config_request_stream_fut =
2236 handle_configuration_request_stream(&mut configuration_request_stream);
2237 let (sender, _) = futures::channel::mpsc::channel::<CursorMessage>(1);
2238 let inspector = fuchsia_inspect::Inspector::default();
2239 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
2240 let incoming = Incoming::new();
2241 let mouse_handler_fut = MouseInjectorHandler::new_with_config_proxy(
2242 &incoming,
2243 configuration_proxy,
2244 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
2245 sender,
2246 &fake_handlers_node,
2247 metrics::MetricsLogger::default(),
2248 );
2249 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
2250 let _handler = mouse_handler_res.expect("Failed to create mouse handler");
2251
2252 diagnostics_assertions::assert_data_tree!(inspector, root: {
2253 input_handlers_node: {
2254 mouse_injector_handler: {
2255 events_received_count: 0u64,
2256 events_handled_count: 0u64,
2257 last_received_timestamp_ns: 0u64,
2258 "fuchsia.inspect.Health": {
2259 status: "STARTING_UP",
2260 start_timestamp_nanos: diagnostics_assertions::AnyProperty
2263 },
2264 }
2265 }
2266 });
2267 }
2268
2269 #[fuchsia::test(allow_stalls = false)]
2270 async fn mouse_injector_handler_inspect_counts_events() {
2271 let (configuration_proxy, mut configuration_request_stream) =
2273 fidl::endpoints::create_proxy_and_stream::<pointerinjector_config::SetupMarker>();
2274 let (injector_registry_proxy, injector_registry_request_stream) = next_client_old_stream::<
2275 pointerinjector::RegistryMarker,
2276 pointerinjector_next::Registry,
2277 >();
2278 let (sender, _) = futures::channel::mpsc::channel::<CursorMessage>(1);
2279
2280 let inspector = fuchsia_inspect::Inspector::default();
2281 let fake_handlers_node = inspector.root().create_child("input_handlers_node");
2282
2283 let mouse_handler_fut = MouseInjectorHandler::new_handler(
2285 configuration_proxy,
2286 injector_registry_proxy,
2287 Size { width: DISPLAY_WIDTH_IN_PHYSICAL_PX, height: DISPLAY_HEIGHT_IN_PHYSICAL_PX },
2288 sender,
2289 &fake_handlers_node,
2290 metrics::MetricsLogger::default(),
2291 );
2292 let config_request_stream_fut =
2293 handle_configuration_request_stream(&mut configuration_request_stream);
2294
2295 let (mouse_handler_res, _) = futures::join!(mouse_handler_fut, config_request_stream_fut);
2296 let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
2297
2298 let cursor_location = mouse_binding::MouseLocation::Absolute(Position { x: 0.0, y: 0.0 });
2299 let event_time1 = zx::MonotonicInstant::get();
2300 let event_time2 = event_time1.add(zx::MonotonicDuration::from_micros(1));
2301 let event_time3 = event_time2.add(zx::MonotonicDuration::from_micros(1));
2302
2303 let input_events = vec![
2304 create_mouse_event(
2305 cursor_location,
2306 None, None, None, mouse_binding::MousePhase::Down,
2310 SortedVecSet::from(vec![1]),
2311 SortedVecSet::from(vec![1]),
2312 event_time1,
2313 &DESCRIPTOR,
2314 ),
2315 create_mouse_event(
2316 cursor_location,
2317 None, None, None, mouse_binding::MousePhase::Up,
2321 SortedVecSet::from(vec![1]),
2322 SortedVecSet::new(),
2323 event_time2,
2324 &DESCRIPTOR,
2325 ),
2326 create_mouse_event_with_handled(
2327 cursor_location,
2328 None, None, None, mouse_binding::MousePhase::Down,
2332 SortedVecSet::from(vec![1]),
2333 SortedVecSet::from(vec![1]),
2334 event_time3,
2335 &DESCRIPTOR,
2336 input_device::Handled::Yes,
2337 ),
2338 ];
2339
2340 let (injector_stream_sender, _) = mpsc::unbounded::<Vec<pointerinjector::Event>>();
2344 let registry_fut = handle_registry_request_stream2(
2345 injector_registry_request_stream,
2346 injector_stream_sender,
2347 );
2348
2349 let _registry_task = fasync::Task::local(registry_fut);
2351 for input_event in input_events {
2352 mouse_handler.clone().handle_input_event(input_event).await;
2353 }
2354
2355 let last_received_event_time: u64 = event_time2.into_nanos().try_into().unwrap();
2356
2357 diagnostics_assertions::assert_data_tree!(inspector, root: {
2358 input_handlers_node: {
2359 mouse_injector_handler: {
2360 events_received_count: 2u64,
2361 events_handled_count: 2u64,
2362 last_received_timestamp_ns: last_received_event_time,
2363 "fuchsia.inspect.Health": {
2364 status: "STARTING_UP",
2365 start_timestamp_nanos: diagnostics_assertions::AnyProperty
2368 },
2369 }
2370 }
2371 });
2372 }
2373}