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::{Usages, hid_usage_to_input3_key};
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 Some(CoordinateUnit::RegisteredDimensions) => {
265 let dimensions =
266 payload.display_dimensions.expect("missing dimensions");
267 if dimensions.min_x >= dimensions.max_x
268 || dimensions.min_y >= dimensions.max_y
269 {
270 panic!("invalid dimensions");
271 }
272 (dimensions.min_x, dimensions.max_x, dimensions.min_y, dimensions.max_y)
273 }
274 _ => (-1000, 1000, -1000, 1000),
275 };
276
277 register_touch_screen(
278 registry,
279 &mut task_group,
280 device,
281 got_input_reports_reader,
282 min_x,
283 max_x,
284 min_y,
285 max_y,
286 )
287 .await;
288
289 responder.send().expect("Failed to respond to RegisterTouchScreen request");
290 }
291 RegistryRequest::RegisterTouchScreenAndGetDeviceInfo {
292 payload, responder, ..
293 } => {
294 info!("register touchscreen");
295 let device = payload
296 .device
297 .expect("no touchscreen device provided in registration request");
298 let (min_x, max_x, min_y, max_y) = match payload.coordinate_unit {
299 Some(CoordinateUnit::PhysicalPixels) => {
300 let display_info_proxy =
301 connect_to_protocol::<display_info::InfoMarker>()
302 .expect("failed to connect to display info service");
303 let display_dimensions = display_info_proxy
304 .get_metrics()
305 .await
306 .expect("failed to get display metrics")
307 .extent_in_px
308 .expect("display metrics missing extent in px");
309 (
310 0,
311 display_dimensions.width as i64,
312 0,
313 display_dimensions.height as i64,
314 )
315 }
316 Some(CoordinateUnit::RegisteredDimensions) => {
317 let dimensions =
318 payload.display_dimensions.expect("missing dimensions");
319 if dimensions.min_x >= dimensions.max_x
320 || dimensions.min_y >= dimensions.max_y
321 {
322 panic!("invalid dimensions");
323 }
324 (dimensions.min_x, dimensions.max_x, dimensions.min_y, dimensions.max_y)
325 }
326 _ => (-1000, 1000, -1000, 1000),
327 };
328
329 let device_id = register_touch_screen(
330 registry,
331 &mut task_group,
332 device,
333 got_input_reports_reader,
334 min_x,
335 max_x,
336 min_y,
337 max_y,
338 )
339 .await;
340
341 responder
342 .send(RegistryRegisterTouchScreenAndGetDeviceInfoResponse {
343 device_id: Some(device_id),
344 ..Default::default()
345 })
346 .expect("Failed to respond to RegisterTouchScreenAndGetDeviceInfo request");
347 }
348 RegistryRequest::RegisterMediaButtonsDevice { payload, responder, .. } => {
349 info!("register media buttons device");
350 let device = payload
351 .device
352 .expect("no media buttons device provided in registration request");
353
354 register_media_button(
355 registry,
356 &mut task_group,
357 device,
358 got_input_reports_reader,
359 )
360 .await;
361
362 responder
363 .send()
364 .expect("Failed to respond to RegisterMediaButtonsDevice request");
365 }
366 RegistryRequest::RegisterMediaButtonsDeviceAndGetDeviceInfo {
367 payload,
368 responder,
369 ..
370 } => {
371 info!("register media buttons device");
372 let device = payload
373 .device
374 .expect("no media buttons device provided in registration request");
375
376 let device_id = register_media_button(
377 registry,
378 &mut task_group,
379 device,
380 got_input_reports_reader,
381 )
382 .await;
383
384 responder.send(RegistryRegisterMediaButtonsDeviceAndGetDeviceInfoResponse {
385 device_id: Some(device_id),
386 ..Default::default()
387 }).expect(
388 "Failed to respond to RegisterMediaButtonsDeviceAndGetDeviceInfo request",
389 );
390 }
391 RegistryRequest::RegisterKeyboard { payload, responder, .. } => {
392 info!("register keyboard device");
393 let device = payload
394 .device
395 .expect("no keyboard device provided in registration request");
396
397 register_keyboard(registry, &mut task_group, device, got_input_reports_reader)
398 .await;
399
400 responder.send().expect("Failed to respond to RegisterKeyboard request");
401 }
402 RegistryRequest::RegisterKeyboardAndGetDeviceInfo {
403 payload, responder, ..
404 } => {
405 info!("register keyboard device");
406 let device = payload
407 .device
408 .expect("no keyboard device provided in registration request");
409
410 let device_id = register_keyboard(
411 registry,
412 &mut task_group,
413 device,
414 got_input_reports_reader,
415 )
416 .await;
417
418 responder
419 .send(RegistryRegisterKeyboardAndGetDeviceInfoResponse {
420 device_id: Some(device_id),
421 ..Default::default()
422 })
423 .expect("Failed to respond to RegisterKeyboardAndGetDeviceInfo request");
424 }
425 RegistryRequest::RegisterMouse { payload, responder } => {
426 info!("register mouse device");
427 let device = payload.device.expect("no mouse provided in registration request");
428
429 register_mouse(registry, &mut task_group, device, got_input_reports_reader)
430 .await;
431
432 responder.send().expect("Failed to respond to RegisterMouse request");
433 }
434 RegistryRequest::RegisterMouseAndGetDeviceInfo { payload, responder } => {
435 info!("register mouse device");
436 let device = payload.device.expect("no mouse provided in registration request");
437
438 let device_id =
439 register_mouse(registry, &mut task_group, device, got_input_reports_reader)
440 .await;
441
442 responder
443 .send(RegistryRegisterMouseAndGetDeviceInfoResponse {
444 device_id: Some(device_id),
445 ..Default::default()
446 })
447 .expect("Failed to respond to RegisterMouse request");
448 }
449 }
450
451 task_group.join().await;
452 Ok(())
453 })
454 .await
455 .expect("failed to serve test realm factory request stream");
456}
457
458fn input_report_for_touch_contacts(
459 contacts: Vec<(u32, math::Vec_)>,
460 trace_id: Option<u64>,
461) -> InputReport {
462 let contact_input_reports = contacts
463 .into_iter()
464 .map(|(contact_id, location)| ContactInputReport {
465 contact_id: Some(contact_id),
466 position_x: Some(location.x as i64),
467 position_y: Some(location.y as i64),
468 contact_width: Some(0),
469 contact_height: Some(0),
470 ..Default::default()
471 })
472 .collect();
473
474 let touch_input_report = TouchInputReport {
475 contacts: Some(contact_input_reports),
476 pressed_buttons: Some(vec![]),
477 ..Default::default()
478 };
479
480 InputReport {
481 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
482 touch: Some(touch_input_report),
483 trace_id,
484 ..Default::default()
485 }
486}
487
488async fn handle_touchscreen_request_stream(
490 touchscreen_device: input_device::InputDevice,
491 mut request_stream: TouchScreenRequestStream,
492) {
493 while let Some(request) = request_stream.next().await {
494 match request {
495 Ok(TouchScreenRequest::SimulateTap { payload, responder }) => {
496 if let Some(tap_location) = payload.tap_location {
497 {
498 fuchsia_trace::duration!(c"input", c"simulate_tap_down");
499 let trace_id = fuchsia_trace::Id::random();
500 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
501 touchscreen_device
502 .send_input_report(input_report_for_touch_contacts(
503 vec![(1, tap_location)],
504 Some(trace_id.into()),
505 ))
506 .expect("Failed to send tap input report");
507 }
508
509 fuchsia_trace::duration!(c"input", c"simulate_tap_up");
512 let trace_id = fuchsia_trace::Id::random();
513 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
514 touchscreen_device
515 .send_input_report(input_report_for_touch_contacts(
516 vec![],
517 Some(trace_id.into()),
518 ))
519 .expect("failed to send empty input report");
520
521 responder.send().expect("Failed to send SimulateTap response");
522 } else {
523 warn!("SimulateTap request missing tap location");
524 }
525 }
526 Ok(TouchScreenRequest::SimulateSwipe { payload, responder }) => {
527 let start_location = payload.start_location.expect("missing start location");
529 let end_location = payload.end_location.expect("missing end location");
530 let move_event_count = payload.move_event_count.expect("missing move event count");
531 assert_ne!(move_event_count, 0);
532 let duration_nanos = payload.duration.unwrap_or(0);
533 let delay_nanos = duration_nanos / ((move_event_count as i64) + 1);
534 let delay = fasync::MonotonicDuration::from_nanos(delay_nanos);
535
536 let start_x_f = start_location.x as f64;
537 let start_y_f = start_location.y as f64;
538 let end_x_f = end_location.x as f64;
539 let end_y_f = end_location.y as f64;
540 let move_event_count_f = move_event_count as f64;
541 let step_size_x = (end_x_f - start_x_f) / move_event_count_f;
542 let step_size_y = (end_y_f - start_y_f) / move_event_count_f;
543
544 for i in 0..move_event_count + 1 {
547 let i_f = i as f64;
548 let event_x = start_x_f + (i_f * step_size_x);
549 let event_y = start_y_f + (i_f * step_size_y);
550
551 fuchsia_trace::duration!(c"input", c"simulate_swipe_move", "idx"=>i);
552 let trace_id = fuchsia_trace::Id::random();
553 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
554
555 touchscreen_device
556 .send_input_report(input_report_for_touch_contacts(
557 vec![(1, math::Vec_ { x: event_x as i32, y: event_y as i32 })],
558 Some(trace_id.into()),
559 ))
560 .expect("Failed to send tap input report");
561 delay.sleep();
562 }
563
564 fuchsia_trace::duration!(c"input", c"simulate_swipe_up");
567 let trace_id = fuchsia_trace::Id::random();
568 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
569 touchscreen_device
570 .send_input_report(input_report_for_touch_contacts(
571 vec![],
572 Some(trace_id.into()),
573 ))
574 .expect("failed to send empty input report");
575
576 responder.send().expect("Failed to send SimulateSwipe response");
577 }
578 Ok(TouchScreenRequest::SimulateMultiTap { payload, responder }) => {
579 let tap_locations = payload.tap_locations.expect("missing tap locations");
580
581 {
582 fuchsia_trace::duration!(c"input", c"simulate_multi_tap_down");
583 let trace_id = fuchsia_trace::Id::random();
584 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
585 touchscreen_device
586 .send_input_report(input_report_for_touch_contacts(
587 tap_locations
588 .into_iter()
589 .enumerate()
590 .map(|(i, it)| (i as u32, it))
591 .collect(),
592 Some(trace_id.into()),
593 ))
594 .expect("Failed to send tap input report");
595 }
596
597 fuchsia_trace::duration!(c"input", c"simulate_multi_tap_up");
600 let trace_id = fuchsia_trace::Id::random();
601 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
602 touchscreen_device
603 .send_input_report(input_report_for_touch_contacts(
604 vec![],
605 Some(trace_id.into()),
606 ))
607 .expect("failed to send empty input report");
608 responder.send().expect("Failed to send SimulateMultiTap response");
609 }
610 Ok(TouchScreenRequest::SimulateMultiFingerGesture { payload, responder }) => {
611 let start_locations = payload.start_locations.expect("missing start locations");
613 let end_locations = payload.end_locations.expect("missing end locations");
614 let move_event_count = payload.move_event_count.expect("missing move event count");
615 let finger_count = payload.finger_count.expect("missing finger count") as usize;
616
617 let move_event_count_f = move_event_count as f32;
618
619 let mut steps: Vec<math::VecF> = vec![];
620
621 for finger in 0..finger_count {
622 let start_x = start_locations[finger].x as f32;
623 let start_y = start_locations[finger].y as f32;
624 let end_x = end_locations[finger].x as f32;
625 let end_y = end_locations[finger].y as f32;
626 let step_x = (end_x - start_x) / move_event_count_f;
627 let step_y = (end_y - start_y) / move_event_count_f;
628 steps.push(math::VecF { x: step_x, y: step_y });
629 }
630
631 for i in 0..move_event_count {
634 let i_f = i as f32;
635
636 let mut contacts: Vec<(u32, math::Vec_)> = vec![];
637
638 for finger in 0..finger_count {
639 let start_x = start_locations[finger].x as f32;
640 let start_y = start_locations[finger].y as f32;
641 let event_x = (start_x + i_f * steps[finger].x) as i32;
642 let event_y = (start_y + i_f * steps[finger].y) as i32;
643 contacts.push((finger as u32, math::Vec_ { x: event_x, y: event_y }));
644 }
645
646 fuchsia_trace::duration!(c"input", c"simulate_multi_finger_gesture_move", "idx"=>i);
647 let trace_id = fuchsia_trace::Id::random();
648 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
649
650 touchscreen_device
651 .send_input_report(input_report_for_touch_contacts(
652 contacts,
653 Some(trace_id.into()),
654 ))
655 .expect("Failed to send tap input report");
656 }
657
658 fuchsia_trace::duration!(c"input", c"simulate_multi_finger_gesture_up");
661 let trace_id = fuchsia_trace::Id::random();
662 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
663 touchscreen_device
664 .send_input_report(input_report_for_touch_contacts(
665 vec![],
666 Some(trace_id.into()),
667 ))
668 .expect("failed to send empty input report");
669
670 responder.send().expect("Failed to send SimulateMultiFingerGesture response");
671 }
672 Ok(TouchScreenRequest::SimulateTouchEvent { report, responder }) => {
673 fuchsia_trace::duration!(c"input", c"simulate_touch_event");
674 let trace_id = fuchsia_trace::Id::random();
675 fuchsia_trace::flow_begin!(c"input", c"input_report", trace_id);
676 let input_report = InputReport {
677 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
678 touch: Some(report),
679 trace_id: Some(trace_id.into()),
680 ..Default::default()
681 };
682 touchscreen_device
683 .send_input_report(input_report)
684 .expect("failed to send empty input report");
685 responder.send().expect("Failed to send SimulateTouchEvent response");
686 }
687 Err(e) => {
688 error!("Error on touchscreen channel: {}", e);
689 return;
690 }
691 }
692 }
693}
694
695async fn handle_media_buttons_device_request_stream(
697 media_buttons_device: input_device::InputDevice,
698 mut request_stream: MediaButtonsDeviceRequestStream,
699) {
700 while let Some(request) = request_stream.next().await {
701 match request {
702 Ok(MediaButtonsDeviceRequest::SimulateButtonPress { payload, responder }) => {
703 if let Some(button) = payload.button {
704 let media_buttons_input_report = ConsumerControlInputReport {
705 pressed_buttons: Some(vec![button]),
706 ..Default::default()
707 };
708
709 let input_report = InputReport {
710 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
711 consumer_control: Some(media_buttons_input_report),
712 ..Default::default()
713 };
714
715 media_buttons_device
716 .send_input_report(input_report)
717 .expect("Failed to send button press input report");
718
719 let empty_report = InputReport {
723 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
724 consumer_control: Some(ConsumerControlInputReport {
725 pressed_buttons: Some(vec![]),
726 ..Default::default()
727 }),
728 ..Default::default()
729 };
730
731 media_buttons_device
732 .send_input_report(empty_report)
733 .expect("Failed to send button release input report");
734
735 responder.send().expect("Failed to send SimulateButtonPress response");
736 } else {
737 warn!("SimulateButtonPress request missing button");
738 }
739 }
740 Ok(MediaButtonsDeviceRequest::SendButtonsState { payload, responder }) => {
741 let buttons = match payload.buttons {
742 Some(buttons) => buttons,
743 None => vec![],
744 };
745 let input_report = InputReport {
746 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
747 consumer_control: Some(ConsumerControlInputReport {
748 pressed_buttons: Some(buttons),
749 ..Default::default()
750 }),
751 ..Default::default()
752 };
753
754 media_buttons_device
755 .send_input_report(input_report)
756 .expect("Failed to send button press input report");
757
758 responder.send().expect("Failed to send SimulateButtonsPress response");
759 }
760 Err(e) => {
761 error!("Error on media buttons device channel: {}", e);
762 return;
763 }
764 }
765 }
766}
767
768async fn handle_keyboard_request_stream(
770 keyboard_device: input_device::InputDevice,
771 mut request_stream: KeyboardRequestStream,
772) {
773 while let Some(request) = request_stream.next().await {
774 match request {
775 Ok(KeyboardRequest::SimulateUsAsciiTextEntry { payload, responder }) => {
776 if let Some(text) = payload.text {
777 let key_sequence = derive_key_sequence(&keymaps::US_QWERTY, &text)
778 .expect("Failed to derive key sequence");
779
780 let mut key_iter = key_sequence.into_iter().peekable();
781 while let Some(keyboard_report) = key_iter.next() {
782 let input_report = InputReport {
783 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
784 keyboard: Some(KeyboardInputReport {
785 pressed_keys3: Some(convert_keyboard_report_to_keys(
786 &keyboard_report,
787 )),
788 ..Default::default()
789 }),
790 ..Default::default()
791 };
792
793 keyboard_device
794 .send_input_report(input_report)
795 .expect("Failed to send key event report");
796
797 if key_iter.peek().is_some() {
798 fuchsia_async::Timer::new(Duration::from_millis(100)).await;
799 }
800 }
801
802 responder.send().expect("Failed to send SimulateTextEntry response");
803 } else {
804 warn!("SimulateTextEntry request missing text");
805 }
806 }
807 Ok(KeyboardRequest::SimulateKeyEvent { payload, responder }) => {
808 let keyboard_report = payload.report.expect("no report");
809 let input_report = InputReport {
810 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
811 keyboard: Some(keyboard_report),
812 ..Default::default()
813 };
814
815 keyboard_device
816 .send_input_report(input_report)
817 .expect("Failed to send key event report");
818
819 responder.send().expect("Failed to send SimulateKeyEvent response");
820 }
821 Ok(KeyboardRequest::SimulateKeyPress { payload, responder }) => {
822 let key_code = payload.key_code.expect("no key code");
823
824 let down_report = InputReport {
825 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
826 keyboard: Some(KeyboardInputReport {
827 pressed_keys3: Some(vec![key_code]),
828 ..Default::default()
829 }),
830 ..Default::default()
831 };
832
833 let up_report = InputReport {
834 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
835 keyboard: Some(KeyboardInputReport {
836 pressed_keys3: Some(vec![]),
837 ..Default::default()
838 }),
839 ..Default::default()
840 };
841
842 keyboard_device.send_input_report(down_report).expect("Failed to send key down");
843
844 keyboard_device.send_input_report(up_report).expect("Failed to send key up");
845
846 responder.send().expect("Failed to send SimulateKeyPress response");
847 }
848 Err(e) => {
849 error!("Error on keyboard device channel: {}", e);
850 return;
851 }
852 }
853 }
854}
855
856async fn handle_mouse_request_stream(
858 mouse_device: input_device::InputDevice,
859 mut request_stream: MouseRequestStream,
860) {
861 while let Some(request) = request_stream.next().await {
862 match request {
863 Ok(MouseRequest::SimulateMouseEvent { payload, responder }) => {
864 let mut mouse_input_report = MouseInputReport {
865 movement_x: payload.movement_x,
866 movement_y: payload.movement_y,
867 scroll_v: payload.scroll_v_detent,
868 scroll_h: payload.scroll_h_detent,
869 ..Default::default()
870 };
871 if let Some(pressed_buttons) = payload.pressed_buttons {
872 mouse_input_report.pressed_buttons = Some(
873 pressed_buttons
874 .into_iter()
875 .map(|b| {
876 b.into_primitive()
877 .try_into()
878 .expect("failed to convert MouseButton to u8")
879 })
880 .collect(),
881 );
882 }
883
884 let input_report = InputReport {
885 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
886 mouse: Some(mouse_input_report),
887 ..Default::default()
888 };
889
890 mouse_device
891 .send_input_report(input_report)
892 .expect("Failed to send key event report");
893
894 responder.send().expect("Failed to send SimulateMouseEvent response");
895 }
896 Err(e) => {
897 error!("Error on keyboard device channel: {}", e);
898 return;
899 }
900 }
901 }
902}
903
904#[cfg(test)]
905mod tests {
906 use super::{KeyboardReport, Usages, derive_key_sequence};
913 use pretty_assertions::assert_eq;
914
915 macro_rules! reports {
917 ( $( [ $( $usages:expr ),* ] ),* $( , )? ) => {
918 Some(vec![
919 $(
920 KeyboardReport {
921 pressed_keys: vec![$($usages as u32),*]
922 }
923 ),*
924 ])
925 }
926 }
927
928 #[test]
929 fn lowercase() {
930 assert_eq!(
931 derive_key_sequence(&keymaps::US_QWERTY, "lowercase"),
932 reports![
933 [Usages::HidUsageKeyL],
934 [Usages::HidUsageKeyO],
935 [Usages::HidUsageKeyW],
936 [Usages::HidUsageKeyE],
937 [Usages::HidUsageKeyR],
938 [Usages::HidUsageKeyC],
939 [Usages::HidUsageKeyA],
940 [Usages::HidUsageKeyS],
941 [Usages::HidUsageKeyE],
942 [],
943 ]
944 );
945 }
946
947 #[test]
948 fn numerics() {
949 assert_eq!(
950 derive_key_sequence(&keymaps::US_QWERTY, "0123456789"),
951 reports![
952 [Usages::HidUsageKey0],
953 [Usages::HidUsageKey1],
954 [Usages::HidUsageKey2],
955 [Usages::HidUsageKey3],
956 [Usages::HidUsageKey4],
957 [Usages::HidUsageKey5],
958 [Usages::HidUsageKey6],
959 [Usages::HidUsageKey7],
960 [Usages::HidUsageKey8],
961 [Usages::HidUsageKey9],
962 [],
963 ]
964 );
965 }
966
967 #[test]
968 fn internet_text_entry() {
969 assert_eq!(
970 derive_key_sequence(&keymaps::US_QWERTY, "http://127.0.0.1:8080"),
971 reports![
972 [Usages::HidUsageKeyH],
973 [Usages::HidUsageKeyT],
974 [],
975 [Usages::HidUsageKeyT],
976 [Usages::HidUsageKeyP],
977 [Usages::HidUsageKeyLeftShift],
981 [Usages::HidUsageKeySemicolon, Usages::HidUsageKeyLeftShift],
982 [],
983 [Usages::HidUsageKeySlash],
984 [],
985 [Usages::HidUsageKeySlash],
986 [Usages::HidUsageKey1],
987 [Usages::HidUsageKey2],
988 [Usages::HidUsageKey7],
989 [Usages::HidUsageKeyDot],
990 [Usages::HidUsageKey0],
991 [Usages::HidUsageKeyDot],
992 [Usages::HidUsageKey0],
993 [Usages::HidUsageKeyDot],
994 [Usages::HidUsageKey1],
995 [Usages::HidUsageKeyLeftShift],
996 [Usages::HidUsageKeySemicolon, Usages::HidUsageKeyLeftShift],
997 [],
998 [Usages::HidUsageKey8],
999 [Usages::HidUsageKey0],
1000 [Usages::HidUsageKey8],
1001 [Usages::HidUsageKey0],
1002 [],
1003 ]
1004 );
1005 }
1006
1007 #[test]
1008 fn sentence() {
1009 assert_eq!(
1010 derive_key_sequence(&keymaps::US_QWERTY, "Hello, world!"),
1011 reports![
1012 [Usages::HidUsageKeyLeftShift],
1013 [Usages::HidUsageKeyH, Usages::HidUsageKeyLeftShift],
1014 [],
1015 [Usages::HidUsageKeyE],
1016 [Usages::HidUsageKeyL],
1017 [],
1018 [Usages::HidUsageKeyL],
1019 [Usages::HidUsageKeyO],
1020 [Usages::HidUsageKeyComma],
1021 [Usages::HidUsageKeySpace],
1022 [Usages::HidUsageKeyW],
1023 [Usages::HidUsageKeyO],
1024 [Usages::HidUsageKeyR],
1025 [Usages::HidUsageKeyL],
1026 [Usages::HidUsageKeyD],
1027 [Usages::HidUsageKeyLeftShift],
1028 [Usages::HidUsageKey1, Usages::HidUsageKeyLeftShift],
1029 [],
1030 ]
1031 );
1032 }
1033
1034 #[test]
1035 fn hold_shift() {
1036 assert_eq!(
1037 derive_key_sequence(&keymaps::US_QWERTY, "ALL'S WELL!"),
1038 reports![
1039 [Usages::HidUsageKeyLeftShift],
1040 [Usages::HidUsageKeyA, Usages::HidUsageKeyLeftShift],
1041 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1042 [Usages::HidUsageKeyLeftShift],
1043 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1044 [],
1045 [Usages::HidUsageKeyApostrophe],
1046 [Usages::HidUsageKeyLeftShift],
1047 [Usages::HidUsageKeyS, Usages::HidUsageKeyLeftShift],
1048 [Usages::HidUsageKeySpace, Usages::HidUsageKeyLeftShift],
1049 [Usages::HidUsageKeyW, Usages::HidUsageKeyLeftShift],
1050 [Usages::HidUsageKeyE, Usages::HidUsageKeyLeftShift],
1051 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1052 [Usages::HidUsageKeyLeftShift],
1053 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1054 [Usages::HidUsageKey1, Usages::HidUsageKeyLeftShift],
1055 [],
1056 ]
1057 );
1058 }
1059
1060 #[test]
1061 fn tab_and_newline() {
1062 assert_eq!(
1063 derive_key_sequence(&keymaps::US_QWERTY, "\tHello\n"),
1064 reports![
1065 [Usages::HidUsageKeyTab],
1066 [Usages::HidUsageKeyLeftShift],
1067 [Usages::HidUsageKeyH, Usages::HidUsageKeyLeftShift],
1068 [],
1069 [Usages::HidUsageKeyE],
1070 [Usages::HidUsageKeyL],
1071 [],
1072 [Usages::HidUsageKeyL],
1073 [Usages::HidUsageKeyO],
1074 [Usages::HidUsageKeyEnter],
1075 [],
1076 ]
1077 );
1078 }
1079}