1use async_utils::event::Event as AsyncEvent;
6use fidl_fuchsia_input::Key;
7use fidl_fuchsia_input_injection::InputDeviceRegistryMarker;
8use fidl_fuchsia_input_report::{
9 ConsumerControlInputReport, ContactInputReport, DeviceInformation, InputReport,
10 KeyboardInputReport, MouseInputReport, TouchInputReport,
11};
12use fidl_fuchsia_ui_input::KeyboardReport;
13use fidl_fuchsia_ui_test_input::{
14 CoordinateUnit, KeyboardMarker, KeyboardRequest, KeyboardRequestStream,
15 MediaButtonsDeviceMarker, MediaButtonsDeviceRequest, MediaButtonsDeviceRequestStream,
16 MouseMarker, MouseRequest, MouseRequestStream,
17 RegistryRegisterKeyboardAndGetDeviceInfoResponse,
18 RegistryRegisterMediaButtonsDeviceAndGetDeviceInfoResponse,
19 RegistryRegisterMouseAndGetDeviceInfoResponse,
20 RegistryRegisterTouchScreenAndGetDeviceInfoResponse, RegistryRequest, RegistryRequestStream,
21 TouchScreenMarker, TouchScreenRequest, TouchScreenRequestStream,
22};
23use fuchsia_component::client::connect_to_protocol;
24use futures::{StreamExt, TryStreamExt};
25use keymaps::inverse_keymap::{InverseKeymap, Shift};
26use keymaps::usages::{hid_usage_to_input3_key, Usages};
27use log::{error, info, warn};
28use std::time::Duration;
29use {
30 fidl_fuchsia_math as math, fidl_fuchsia_ui_display_singleton as display_info,
31 fuchsia_async as fasync,
32};
33
34mod input_device;
35mod input_device_registry;
36mod input_reports_reader;
37
38fn new_fake_device_info() -> DeviceInformation {
40 DeviceInformation {
41 product_id: Some(42),
42 vendor_id: Some(43),
43 version: Some(u32::MAX),
44 polling_rate: Some(1000),
45 ..Default::default()
46 }
47}
48
49fn derive_key_sequence(keymap: &keymaps::Keymap<'_>, input: &str) -> Option<Vec<KeyboardReport>> {
75 let inverse_keymap = InverseKeymap::new(keymap);
76 let mut reports = vec![];
77 let mut shift_pressed = false;
78 let mut last_usage = None;
79
80 for ch in input.chars() {
81 let key_stroke = inverse_keymap.get(&ch)?;
82
83 match key_stroke.shift {
84 Shift::Yes if !shift_pressed => {
85 shift_pressed = true;
86 last_usage = Some(0);
87 }
88 Shift::No if shift_pressed => {
89 shift_pressed = false;
90 last_usage = Some(0);
91 }
92 _ => {
93 if last_usage == Some(key_stroke.usage) {
94 last_usage = Some(0);
95 }
96 }
97 }
98
99 if let Some(0) = last_usage {
100 reports.push(KeyboardReport {
101 pressed_keys: if shift_pressed {
102 vec![Usages::HidUsageKeyLeftShift as u32]
103 } else {
104 vec![]
105 },
106 });
107 }
108
109 last_usage = Some(key_stroke.usage);
110
111 reports.push(KeyboardReport {
112 pressed_keys: if shift_pressed {
113 vec![key_stroke.usage, Usages::HidUsageKeyLeftShift as u32]
114 } else {
115 vec![key_stroke.usage]
116 },
117 });
118 }
119
120 reports.push(KeyboardReport { pressed_keys: vec![] });
121
122 Some(reports)
123}
124
125fn convert_keyboard_report_to_keys(report: &KeyboardReport) -> Vec<Key> {
126 report
127 .pressed_keys
128 .iter()
129 .map(|&usage| {
130 hid_usage_to_input3_key(usage.try_into().expect("failed to convert usage to u16"))
131 .unwrap_or_else(|| panic!("no Key for usage {:?}", usage))
132 })
133 .collect()
134}
135
136async fn register_touch_screen(
137 mut registry: input_device_registry::InputDeviceRegistry,
138 task_group: &mut fasync::TaskGroup,
139 device_server_end: fidl::endpoints::ServerEnd<TouchScreenMarker>,
140 got_input_reports_reader: AsyncEvent,
141 min_x: i64,
142 max_x: i64,
143 min_y: i64,
144 max_y: i64,
145) -> input_device::DeviceId {
146 let device = registry
147 .add_touchscreen_device(min_x, max_x, min_y, max_y)
148 .await
149 .expect("failed to create fake touchscreen device");
150 let device_id = device.device_id;
151
152 task_group.spawn(async move {
153 handle_touchscreen_request_stream(device, device_server_end.into_stream()).await;
154 });
155
156 info!("wait for input-pipeline setup input-reader");
157 let _ = got_input_reports_reader.wait().await;
158 info!("input-pipeline setup input-reader.");
159
160 device_id
161}
162
163async fn register_media_button(
164 mut registry: input_device_registry::InputDeviceRegistry,
165 task_group: &mut fasync::TaskGroup,
166 device_server_end: fidl::endpoints::ServerEnd<MediaButtonsDeviceMarker>,
167 got_input_reports_reader: AsyncEvent,
168) -> input_device::DeviceId {
169 let device = registry
170 .add_media_buttons_device()
171 .await
172 .expect("failed to create fake media buttons device");
173 let device_id = device.device_id;
174
175 task_group.spawn(async move {
176 handle_media_buttons_device_request_stream(device, device_server_end.into_stream()).await;
177 });
178
179 info!("wait for input-pipeline setup input-reader");
180 let _ = got_input_reports_reader.wait().await;
181 info!("input-pipeline setup input-reader.");
182
183 device_id
184}
185
186async fn register_keyboard(
187 mut registry: input_device_registry::InputDeviceRegistry,
188 task_group: &mut fasync::TaskGroup,
189 device_server_end: fidl::endpoints::ServerEnd<KeyboardMarker>,
190 got_input_reports_reader: AsyncEvent,
191) -> input_device::DeviceId {
192 let device = registry.add_keyboard_device().await.expect("failed to create fake keyboard");
193 let device_id = device.device_id;
194
195 task_group.spawn(async move {
196 handle_keyboard_request_stream(device, device_server_end.into_stream()).await;
197 });
198
199 info!("wait for input-pipeline setup input-reader");
200 let _ = got_input_reports_reader.wait().await;
201 info!("input-pipeline setup input-reader.");
202
203 device_id
204}
205
206async fn register_mouse(
207 mut registry: input_device_registry::InputDeviceRegistry,
208 task_group: &mut fasync::TaskGroup,
209 device_server_end: fidl::endpoints::ServerEnd<MouseMarker>,
210 got_input_reports_reader: AsyncEvent,
211) -> input_device::DeviceId {
212 let device = registry.add_mouse_device().await.expect("failed to create fake mouse");
213 let device_id = device.device_id;
214
215 task_group.spawn(async move {
216 handle_mouse_request_stream(device, device_server_end.into_stream()).await;
217 });
218
219 info!("wait for input-pipeline setup input-reader");
220 let _ = got_input_reports_reader.wait().await;
221 info!("input-pipeline setup input-reader.");
222
223 device_id
224}
225
226pub async fn handle_registry_request_stream(request_stream: RegistryRequestStream) {
228 request_stream
229 .try_for_each_concurrent(None, |request| async {
230 let input_device_registry = connect_to_protocol::<InputDeviceRegistryMarker>()
231 .expect("connect to input_device_registry");
232 let got_input_reports_reader = AsyncEvent::new();
233
234 let registry = input_device_registry::InputDeviceRegistry::new(
235 input_device_registry,
236 got_input_reports_reader.clone(),
237 );
238 let mut task_group = fasync::TaskGroup::new();
239
240 match request {
241 RegistryRequest::RegisterTouchScreen { payload, responder, .. } => {
242 info!("register touchscreen");
243 let device = payload
244 .device
245 .expect("no touchscreen device provided in registration request");
246 let (min_x, max_x, min_y, max_y) = match payload.coordinate_unit {
247 Some(CoordinateUnit::PhysicalPixels) => {
248 let display_info_proxy =
249 connect_to_protocol::<display_info::InfoMarker>()
250 .expect("failed to connect to display info service");
251 let display_dimensions = display_info_proxy
252 .get_metrics()
253 .await
254 .expect("failed to get display metrics")
255 .extent_in_px
256 .expect("display metrics missing extent in px");
257 (
258 0,
259 display_dimensions.width as i64,
260 0,
261 display_dimensions.height as i64,
262 )
263 }
264 _ => (-1000, 1000, -1000, 1000),
265 };
266
267 register_touch_screen(
268 registry,
269 &mut task_group,
270 device,
271 got_input_reports_reader,
272 min_x,
273 max_x,
274 min_y,
275 max_y,
276 )
277 .await;
278
279 responder.send().expect("Failed to respond to RegisterTouchScreen request");
280 }
281 RegistryRequest::RegisterTouchScreenAndGetDeviceInfo {
282 payload, responder, ..
283 } => {
284 info!("register touchscreen");
285 let device = payload
286 .device
287 .expect("no touchscreen device provided in registration request");
288 let (min_x, max_x, min_y, max_y) = match payload.coordinate_unit {
289 Some(CoordinateUnit::PhysicalPixels) => {
290 let display_info_proxy =
291 connect_to_protocol::<display_info::InfoMarker>()
292 .expect("failed to connect to display info service");
293 let display_dimensions = display_info_proxy
294 .get_metrics()
295 .await
296 .expect("failed to get display metrics")
297 .extent_in_px
298 .expect("display metrics missing extent in px");
299 (
300 0,
301 display_dimensions.width as i64,
302 0,
303 display_dimensions.height as i64,
304 )
305 }
306 _ => (-1000, 1000, -1000, 1000),
307 };
308
309 let device_id = register_touch_screen(
310 registry,
311 &mut task_group,
312 device,
313 got_input_reports_reader,
314 min_x,
315 max_x,
316 min_y,
317 max_y,
318 )
319 .await;
320
321 responder
322 .send(RegistryRegisterTouchScreenAndGetDeviceInfoResponse {
323 device_id: Some(device_id),
324 ..Default::default()
325 })
326 .expect("Failed to respond to RegisterTouchScreenAndGetDeviceInfo request");
327 }
328 RegistryRequest::RegisterMediaButtonsDevice { payload, responder, .. } => {
329 info!("register media buttons device");
330 let device = payload
331 .device
332 .expect("no media buttons device provided in registration request");
333
334 register_media_button(
335 registry,
336 &mut task_group,
337 device,
338 got_input_reports_reader,
339 )
340 .await;
341
342 responder
343 .send()
344 .expect("Failed to respond to RegisterMediaButtonsDevice request");
345 }
346 RegistryRequest::RegisterMediaButtonsDeviceAndGetDeviceInfo {
347 payload,
348 responder,
349 ..
350 } => {
351 info!("register media buttons device");
352 let device = payload
353 .device
354 .expect("no media buttons device provided in registration request");
355
356 let device_id = register_media_button(
357 registry,
358 &mut task_group,
359 device,
360 got_input_reports_reader,
361 )
362 .await;
363
364 responder.send(RegistryRegisterMediaButtonsDeviceAndGetDeviceInfoResponse {
365 device_id: Some(device_id),
366 ..Default::default()
367 }).expect(
368 "Failed to respond to RegisterMediaButtonsDeviceAndGetDeviceInfo request",
369 );
370 }
371 RegistryRequest::RegisterKeyboard { payload, responder, .. } => {
372 info!("register keyboard device");
373 let device = payload
374 .device
375 .expect("no keyboard device provided in registration request");
376
377 register_keyboard(registry, &mut task_group, device, got_input_reports_reader)
378 .await;
379
380 responder.send().expect("Failed to respond to RegisterKeyboard request");
381 }
382 RegistryRequest::RegisterKeyboardAndGetDeviceInfo {
383 payload, responder, ..
384 } => {
385 info!("register keyboard device");
386 let device = payload
387 .device
388 .expect("no keyboard device provided in registration request");
389
390 let device_id = register_keyboard(
391 registry,
392 &mut task_group,
393 device,
394 got_input_reports_reader,
395 )
396 .await;
397
398 responder
399 .send(RegistryRegisterKeyboardAndGetDeviceInfoResponse {
400 device_id: Some(device_id),
401 ..Default::default()
402 })
403 .expect("Failed to respond to RegisterKeyboardAndGetDeviceInfo request");
404 }
405 RegistryRequest::RegisterMouse { payload, responder } => {
406 info!("register mouse device");
407 let device = payload.device.expect("no mouse provided in registration request");
408
409 register_mouse(registry, &mut task_group, device, got_input_reports_reader)
410 .await;
411
412 responder.send().expect("Failed to respond to RegisterMouse request");
413 }
414 RegistryRequest::RegisterMouseAndGetDeviceInfo { payload, responder } => {
415 info!("register mouse device");
416 let device = payload.device.expect("no mouse provided in registration request");
417
418 let device_id =
419 register_mouse(registry, &mut task_group, device, got_input_reports_reader)
420 .await;
421
422 responder
423 .send(RegistryRegisterMouseAndGetDeviceInfoResponse {
424 device_id: Some(device_id),
425 ..Default::default()
426 })
427 .expect("Failed to respond to RegisterMouse request");
428 }
429 }
430
431 task_group.join().await;
432 Ok(())
433 })
434 .await
435 .expect("failed to serve test realm factory request stream");
436}
437
438fn input_report_for_touch_contacts(contacts: Vec<(u32, math::Vec_)>) -> InputReport {
439 let contact_input_reports = contacts
440 .into_iter()
441 .map(|(contact_id, location)| ContactInputReport {
442 contact_id: Some(contact_id),
443 position_x: Some(location.x as i64),
444 position_y: Some(location.y as i64),
445 contact_width: Some(0),
446 contact_height: Some(0),
447 ..Default::default()
448 })
449 .collect();
450
451 let touch_input_report = TouchInputReport {
452 contacts: Some(contact_input_reports),
453 pressed_buttons: Some(vec![]),
454 ..Default::default()
455 };
456
457 InputReport {
458 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
459 touch: Some(touch_input_report),
460 ..Default::default()
461 }
462}
463
464async fn handle_touchscreen_request_stream(
466 touchscreen_device: input_device::InputDevice,
467 mut request_stream: TouchScreenRequestStream,
468) {
469 while let Some(request) = request_stream.next().await {
470 match request {
471 Ok(TouchScreenRequest::SimulateTap { payload, responder }) => {
472 if let Some(tap_location) = payload.tap_location {
473 touchscreen_device
474 .send_input_report(input_report_for_touch_contacts(vec![(1, tap_location)]))
475 .expect("Failed to send tap input report");
476
477 touchscreen_device
480 .send_input_report(input_report_for_touch_contacts(vec![]))
481 .expect("failed to send empty input report");
482
483 responder.send().expect("Failed to send SimulateTap response");
484 } else {
485 warn!("SimulateTap request missing tap location");
486 }
487 }
488 Ok(TouchScreenRequest::SimulateSwipe { payload, responder }) => {
489 let start_location = payload.start_location.expect("missing start location");
491 let end_location = payload.end_location.expect("missing end location");
492 let move_event_count = payload.move_event_count.expect("missing move event count");
493 assert_ne!(move_event_count, 0);
494 let duration_nanos = payload.duration.unwrap_or(0);
495 let delay_nanos = duration_nanos / ((move_event_count as i64) + 1);
496 let delay = fasync::MonotonicDuration::from_nanos(delay_nanos);
497
498 let start_x_f = start_location.x as f64;
499 let start_y_f = start_location.y as f64;
500 let end_x_f = end_location.x as f64;
501 let end_y_f = end_location.y as f64;
502 let move_event_count_f = move_event_count as f64;
503 let step_size_x = (end_x_f - start_x_f) / move_event_count_f;
504 let step_size_y = (end_y_f - start_y_f) / move_event_count_f;
505
506 for i in 0..move_event_count + 1 {
509 let i_f = i as f64;
510 let event_x = start_x_f + (i_f * step_size_x);
511 let event_y = start_y_f + (i_f * step_size_y);
512 touchscreen_device
513 .send_input_report(input_report_for_touch_contacts(vec![(
514 1,
515 math::Vec_ { x: event_x as i32, y: event_y as i32 },
516 )]))
517 .expect("Failed to send tap input report");
518 delay.sleep();
519 }
520
521 touchscreen_device
524 .send_input_report(input_report_for_touch_contacts(vec![]))
525 .expect("failed to send empty input report");
526
527 responder.send().expect("Failed to send SimulateSwipe response");
528 }
529 Ok(TouchScreenRequest::SimulateMultiTap { payload, responder }) => {
530 let tap_locations = payload.tap_locations.expect("missing tap locations");
531 touchscreen_device
532 .send_input_report(input_report_for_touch_contacts(
533 tap_locations
534 .into_iter()
535 .enumerate()
536 .map(|(i, it)| (i as u32, it))
537 .collect(),
538 ))
539 .expect("Failed to send tap input report");
540
541 touchscreen_device
544 .send_input_report(input_report_for_touch_contacts(vec![]))
545 .expect("failed to send empty input report");
546 responder.send().expect("Failed to send SimulateMultiTap response");
547 }
548 Ok(TouchScreenRequest::SimulateMultiFingerGesture { payload, responder }) => {
549 let start_locations = payload.start_locations.expect("missing start locations");
551 let end_locations = payload.end_locations.expect("missing end locations");
552 let move_event_count = payload.move_event_count.expect("missing move event count");
553 let finger_count = payload.finger_count.expect("missing finger count") as usize;
554
555 let move_event_count_f = move_event_count as f32;
556
557 let mut steps: Vec<math::VecF> = vec![];
558
559 for finger in 0..finger_count {
560 let start_x = start_locations[finger].x as f32;
561 let start_y = start_locations[finger].y as f32;
562 let end_x = end_locations[finger].x as f32;
563 let end_y = end_locations[finger].y as f32;
564 let step_x = (end_x - start_x) / move_event_count_f;
565 let step_y = (end_y - start_y) / move_event_count_f;
566 steps.push(math::VecF { x: step_x, y: step_y });
567 }
568
569 for i in 0..move_event_count {
572 let i_f = i as f32;
573
574 let mut contacts: Vec<(u32, math::Vec_)> = vec![];
575
576 for finger in 0..finger_count {
577 let start_x = start_locations[finger].x as f32;
578 let start_y = start_locations[finger].y as f32;
579 let event_x = (start_x + i_f * steps[finger].x) as i32;
580 let event_y = (start_y + i_f * steps[finger].y) as i32;
581 contacts.push((finger as u32, math::Vec_ { x: event_x, y: event_y }));
582 }
583
584 touchscreen_device
585 .send_input_report(input_report_for_touch_contacts(contacts))
586 .expect("Failed to send tap input report");
587 }
588
589 touchscreen_device
592 .send_input_report(input_report_for_touch_contacts(vec![]))
593 .expect("failed to send empty input report");
594
595 responder.send().expect("Failed to send SimulateMultiFingerGesture response");
596 }
597 Ok(TouchScreenRequest::SimulateTouchEvent { report, responder }) => {
598 let input_report = InputReport {
599 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
600 touch: Some(report),
601 ..Default::default()
602 };
603 touchscreen_device
604 .send_input_report(input_report)
605 .expect("failed to send empty input report");
606 responder.send().expect("Failed to send SimulateTouchEvent response");
607 }
608 Err(e) => {
609 error!("Error on touchscreen channel: {}", e);
610 return;
611 }
612 }
613 }
614}
615
616async fn handle_media_buttons_device_request_stream(
618 media_buttons_device: input_device::InputDevice,
619 mut request_stream: MediaButtonsDeviceRequestStream,
620) {
621 while let Some(request) = request_stream.next().await {
622 match request {
623 Ok(MediaButtonsDeviceRequest::SimulateButtonPress { payload, responder }) => {
624 if let Some(button) = payload.button {
625 let media_buttons_input_report = ConsumerControlInputReport {
626 pressed_buttons: Some(vec![button]),
627 ..Default::default()
628 };
629
630 let input_report = InputReport {
631 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
632 consumer_control: Some(media_buttons_input_report),
633 ..Default::default()
634 };
635
636 media_buttons_device
637 .send_input_report(input_report)
638 .expect("Failed to send button press input report");
639
640 let empty_report = InputReport {
644 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
645 consumer_control: Some(ConsumerControlInputReport {
646 pressed_buttons: Some(vec![]),
647 ..Default::default()
648 }),
649 ..Default::default()
650 };
651
652 media_buttons_device
653 .send_input_report(empty_report)
654 .expect("Failed to send button release input report");
655
656 responder.send().expect("Failed to send SimulateButtonPress response");
657 } else {
658 warn!("SimulateButtonPress request missing button");
659 }
660 }
661 Ok(MediaButtonsDeviceRequest::SendButtonsState { payload, responder }) => {
662 let buttons = match payload.buttons {
663 Some(buttons) => buttons,
664 None => vec![],
665 };
666 let input_report = InputReport {
667 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
668 consumer_control: Some(ConsumerControlInputReport {
669 pressed_buttons: Some(buttons),
670 ..Default::default()
671 }),
672 ..Default::default()
673 };
674
675 media_buttons_device
676 .send_input_report(input_report)
677 .expect("Failed to send button press input report");
678
679 responder.send().expect("Failed to send SimulateButtonsPress response");
680 }
681 Err(e) => {
682 error!("Error on media buttons device channel: {}", e);
683 return;
684 }
685 }
686 }
687}
688
689async fn handle_keyboard_request_stream(
691 keyboard_device: input_device::InputDevice,
692 mut request_stream: KeyboardRequestStream,
693) {
694 while let Some(request) = request_stream.next().await {
695 match request {
696 Ok(KeyboardRequest::SimulateUsAsciiTextEntry { payload, responder }) => {
697 if let Some(text) = payload.text {
698 let key_sequence = derive_key_sequence(&keymaps::US_QWERTY, &text)
699 .expect("Failed to derive key sequence");
700
701 let mut key_iter = key_sequence.into_iter().peekable();
702 while let Some(keyboard_report) = key_iter.next() {
703 let input_report = InputReport {
704 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
705 keyboard: Some(KeyboardInputReport {
706 pressed_keys3: Some(convert_keyboard_report_to_keys(
707 &keyboard_report,
708 )),
709 ..Default::default()
710 }),
711 ..Default::default()
712 };
713
714 keyboard_device
715 .send_input_report(input_report)
716 .expect("Failed to send key event report");
717
718 if key_iter.peek().is_some() {
719 fuchsia_async::Timer::new(Duration::from_millis(100)).await;
720 }
721 }
722
723 responder.send().expect("Failed to send SimulateTextEntry response");
724 } else {
725 warn!("SimulateTextEntry request missing text");
726 }
727 }
728 Ok(KeyboardRequest::SimulateKeyEvent { payload, responder }) => {
729 let keyboard_report = payload.report.expect("no report");
730 let input_report = InputReport {
731 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
732 keyboard: Some(keyboard_report),
733 ..Default::default()
734 };
735
736 keyboard_device
737 .send_input_report(input_report)
738 .expect("Failed to send key event report");
739
740 responder.send().expect("Failed to send SimulateKeyEvent response");
741 }
742 Ok(KeyboardRequest::SimulateKeyPress { payload, responder }) => {
743 let key_code = payload.key_code.expect("no key code");
744
745 let down_report = InputReport {
746 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
747 keyboard: Some(KeyboardInputReport {
748 pressed_keys3: Some(vec![key_code]),
749 ..Default::default()
750 }),
751 ..Default::default()
752 };
753
754 let up_report = InputReport {
755 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
756 keyboard: Some(KeyboardInputReport {
757 pressed_keys3: Some(vec![]),
758 ..Default::default()
759 }),
760 ..Default::default()
761 };
762
763 keyboard_device.send_input_report(down_report).expect("Failed to send key down");
764
765 keyboard_device.send_input_report(up_report).expect("Failed to send key up");
766
767 responder.send().expect("Failed to send SimulateKeyPress response");
768 }
769 Err(e) => {
770 error!("Error on keyboard device channel: {}", e);
771 return;
772 }
773 }
774 }
775}
776
777async fn handle_mouse_request_stream(
779 mouse_device: input_device::InputDevice,
780 mut request_stream: MouseRequestStream,
781) {
782 while let Some(request) = request_stream.next().await {
783 match request {
784 Ok(MouseRequest::SimulateMouseEvent { payload, responder }) => {
785 let mut mouse_input_report = MouseInputReport {
786 movement_x: payload.movement_x,
787 movement_y: payload.movement_y,
788 scroll_v: payload.scroll_v_detent,
789 scroll_h: payload.scroll_h_detent,
790 ..Default::default()
791 };
792 if let Some(pressed_buttons) = payload.pressed_buttons {
793 mouse_input_report.pressed_buttons = Some(
794 pressed_buttons
795 .into_iter()
796 .map(|b| {
797 b.into_primitive()
798 .try_into()
799 .expect("failed to convert MouseButton to u8")
800 })
801 .collect(),
802 );
803 }
804
805 let input_report = InputReport {
806 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
807 mouse: Some(mouse_input_report),
808 ..Default::default()
809 };
810
811 mouse_device
812 .send_input_report(input_report)
813 .expect("Failed to send key event report");
814
815 responder.send().expect("Failed to send SimulateMouseEvent response");
816 }
817 Err(e) => {
818 error!("Error on keyboard device channel: {}", e);
819 return;
820 }
821 }
822 }
823}
824
825#[cfg(test)]
826mod tests {
827 use super::{derive_key_sequence, KeyboardReport, Usages};
834 use pretty_assertions::assert_eq;
835
836 macro_rules! reports {
838 ( $( [ $( $usages:expr ),* ] ),* $( , )? ) => {
839 Some(vec![
840 $(
841 KeyboardReport {
842 pressed_keys: vec![$($usages as u32),*]
843 }
844 ),*
845 ])
846 }
847 }
848
849 #[test]
850 fn lowercase() {
851 assert_eq!(
852 derive_key_sequence(&keymaps::US_QWERTY, "lowercase"),
853 reports![
854 [Usages::HidUsageKeyL],
855 [Usages::HidUsageKeyO],
856 [Usages::HidUsageKeyW],
857 [Usages::HidUsageKeyE],
858 [Usages::HidUsageKeyR],
859 [Usages::HidUsageKeyC],
860 [Usages::HidUsageKeyA],
861 [Usages::HidUsageKeyS],
862 [Usages::HidUsageKeyE],
863 [],
864 ]
865 );
866 }
867
868 #[test]
869 fn numerics() {
870 assert_eq!(
871 derive_key_sequence(&keymaps::US_QWERTY, "0123456789"),
872 reports![
873 [Usages::HidUsageKey0],
874 [Usages::HidUsageKey1],
875 [Usages::HidUsageKey2],
876 [Usages::HidUsageKey3],
877 [Usages::HidUsageKey4],
878 [Usages::HidUsageKey5],
879 [Usages::HidUsageKey6],
880 [Usages::HidUsageKey7],
881 [Usages::HidUsageKey8],
882 [Usages::HidUsageKey9],
883 [],
884 ]
885 );
886 }
887
888 #[test]
889 fn internet_text_entry() {
890 assert_eq!(
891 derive_key_sequence(&keymaps::US_QWERTY, "http://127.0.0.1:8080"),
892 reports![
893 [Usages::HidUsageKeyH],
894 [Usages::HidUsageKeyT],
895 [],
896 [Usages::HidUsageKeyT],
897 [Usages::HidUsageKeyP],
898 [Usages::HidUsageKeyLeftShift],
902 [Usages::HidUsageKeySemicolon, Usages::HidUsageKeyLeftShift],
903 [],
904 [Usages::HidUsageKeySlash],
905 [],
906 [Usages::HidUsageKeySlash],
907 [Usages::HidUsageKey1],
908 [Usages::HidUsageKey2],
909 [Usages::HidUsageKey7],
910 [Usages::HidUsageKeyDot],
911 [Usages::HidUsageKey0],
912 [Usages::HidUsageKeyDot],
913 [Usages::HidUsageKey0],
914 [Usages::HidUsageKeyDot],
915 [Usages::HidUsageKey1],
916 [Usages::HidUsageKeyLeftShift],
917 [Usages::HidUsageKeySemicolon, Usages::HidUsageKeyLeftShift],
918 [],
919 [Usages::HidUsageKey8],
920 [Usages::HidUsageKey0],
921 [Usages::HidUsageKey8],
922 [Usages::HidUsageKey0],
923 [],
924 ]
925 );
926 }
927
928 #[test]
929 fn sentence() {
930 assert_eq!(
931 derive_key_sequence(&keymaps::US_QWERTY, "Hello, world!"),
932 reports![
933 [Usages::HidUsageKeyLeftShift],
934 [Usages::HidUsageKeyH, Usages::HidUsageKeyLeftShift],
935 [],
936 [Usages::HidUsageKeyE],
937 [Usages::HidUsageKeyL],
938 [],
939 [Usages::HidUsageKeyL],
940 [Usages::HidUsageKeyO],
941 [Usages::HidUsageKeyComma],
942 [Usages::HidUsageKeySpace],
943 [Usages::HidUsageKeyW],
944 [Usages::HidUsageKeyO],
945 [Usages::HidUsageKeyR],
946 [Usages::HidUsageKeyL],
947 [Usages::HidUsageKeyD],
948 [Usages::HidUsageKeyLeftShift],
949 [Usages::HidUsageKey1, Usages::HidUsageKeyLeftShift],
950 [],
951 ]
952 );
953 }
954
955 #[test]
956 fn hold_shift() {
957 assert_eq!(
958 derive_key_sequence(&keymaps::US_QWERTY, "ALL'S WELL!"),
959 reports![
960 [Usages::HidUsageKeyLeftShift],
961 [Usages::HidUsageKeyA, Usages::HidUsageKeyLeftShift],
962 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
963 [Usages::HidUsageKeyLeftShift],
964 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
965 [],
966 [Usages::HidUsageKeyApostrophe],
967 [Usages::HidUsageKeyLeftShift],
968 [Usages::HidUsageKeyS, Usages::HidUsageKeyLeftShift],
969 [Usages::HidUsageKeySpace, Usages::HidUsageKeyLeftShift],
970 [Usages::HidUsageKeyW, Usages::HidUsageKeyLeftShift],
971 [Usages::HidUsageKeyE, Usages::HidUsageKeyLeftShift],
972 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
973 [Usages::HidUsageKeyLeftShift],
974 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
975 [Usages::HidUsageKey1, Usages::HidUsageKeyLeftShift],
976 [],
977 ]
978 );
979 }
980
981 #[test]
982 fn tab_and_newline() {
983 assert_eq!(
984 derive_key_sequence(&keymaps::US_QWERTY, "\tHello\n"),
985 reports![
986 [Usages::HidUsageKeyTab],
987 [Usages::HidUsageKeyLeftShift],
988 [Usages::HidUsageKeyH, Usages::HidUsageKeyLeftShift],
989 [],
990 [Usages::HidUsageKeyE],
991 [Usages::HidUsageKeyL],
992 [],
993 [Usages::HidUsageKeyL],
994 [Usages::HidUsageKeyO],
995 [Usages::HidUsageKeyEnter],
996 [],
997 ]
998 );
999 }
1000}