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_math as math;
13use fidl_fuchsia_power_system as fps;
14use fidl_fuchsia_time_alarms as fta;
15use fidl_fuchsia_ui_display_singleton as display_info;
16use fidl_fuchsia_ui_input::KeyboardReport;
17use fidl_fuchsia_ui_test_input::{
18 CoordinateUnit, KeyboardMarker, KeyboardRequest, KeyboardRequestStream,
19 MediaButtonsDeviceMarker, MediaButtonsDeviceRequest, MediaButtonsDeviceRequestStream,
20 MouseMarker, MouseRequest, MouseRequestStream,
21 RegistryRegisterKeyboardAndGetDeviceInfoResponse,
22 RegistryRegisterMediaButtonsDeviceAndGetDeviceInfoResponse,
23 RegistryRegisterMouseAndGetDeviceInfoResponse,
24 RegistryRegisterTouchScreenAndGetDeviceInfoResponse, RegistryRequest, RegistryRequestStream,
25 TouchScreenMarker, TouchScreenRequest, TouchScreenRequestStream,
26};
27use fuchsia_async as fasync;
28use fuchsia_component::client::connect_to_protocol;
29use fuchsia_trace::Scope;
30use futures::stream::FuturesUnordered;
31use futures::{StreamExt, TryStreamExt};
32use keymaps::inverse_keymap::{InverseKeymap, Shift};
33use keymaps::usages::{Usages, hid_usage_to_input3_key};
34use log::{error, info, warn};
35use std::time::Duration;
36
37mod input_device;
38mod input_device_registry;
39mod input_reports_reader;
40
41pub(crate) static INPUT_CATEGORY: &str = "input";
42
43fn new_fake_device_info() -> DeviceInformation {
45 DeviceInformation {
46 product_id: Some(42),
47 vendor_id: Some(43),
48 version: Some(u32::MAX),
49 polling_rate: Some(1000),
50 ..Default::default()
51 }
52}
53
54fn derive_key_sequence(keymap: &keymaps::Keymap<'_>, input: &str) -> Option<Vec<KeyboardReport>> {
80 let inverse_keymap = InverseKeymap::new(keymap);
81 let mut reports = vec![];
82 let mut shift_pressed = false;
83 let mut last_usage = None;
84
85 for ch in input.chars() {
86 let key_stroke = inverse_keymap.get(&ch)?;
87
88 match key_stroke.shift {
89 Shift::Yes if !shift_pressed => {
90 shift_pressed = true;
91 last_usage = Some(0);
92 }
93 Shift::No if shift_pressed => {
94 shift_pressed = false;
95 last_usage = Some(0);
96 }
97 _ => {
98 if last_usage == Some(key_stroke.usage) {
99 last_usage = Some(0);
100 }
101 }
102 }
103
104 if let Some(0) = last_usage {
105 reports.push(KeyboardReport {
106 pressed_keys: if shift_pressed {
107 vec![Usages::HidUsageKeyLeftShift as u32]
108 } else {
109 vec![]
110 },
111 });
112 }
113
114 last_usage = Some(key_stroke.usage);
115
116 reports.push(KeyboardReport {
117 pressed_keys: if shift_pressed {
118 vec![key_stroke.usage, Usages::HidUsageKeyLeftShift as u32]
119 } else {
120 vec![key_stroke.usage]
121 },
122 });
123 }
124
125 reports.push(KeyboardReport { pressed_keys: vec![] });
126
127 Some(reports)
128}
129
130fn convert_keyboard_report_to_keys(report: &KeyboardReport) -> Vec<Key> {
131 report
132 .pressed_keys
133 .iter()
134 .map(|&usage| {
135 hid_usage_to_input3_key(usage.try_into().expect("failed to convert usage to u16"))
136 .unwrap_or_else(|| panic!("no Key for usage {:?}", usage))
137 })
138 .collect()
139}
140
141async fn register_touch_screen(
142 mut registry: input_device_registry::InputDeviceRegistry,
143 scope: &fasync::Scope,
144 device_server_end: fidl::endpoints::ServerEnd<TouchScreenMarker>,
145 got_input_reports_reader: AsyncEvent,
146 min_x: i64,
147 max_x: i64,
148 min_y: i64,
149 max_y: i64,
150) -> input_device::DeviceId {
151 let device = registry
152 .add_touchscreen_device(min_x, max_x, min_y, max_y)
153 .await
154 .expect("failed to create fake touchscreen device");
155 let device_id = device.device_id;
156
157 scope.spawn(async move {
158 handle_touchscreen_request_stream(device, device_server_end.into_stream()).await;
159 });
160
161 info!("wait for input-pipeline setup input-reader");
162 let _ = got_input_reports_reader.wait().await;
163 info!("input-pipeline setup input-reader.");
164
165 device_id
166}
167
168async fn register_media_button(
169 mut registry: input_device_registry::InputDeviceRegistry,
170 scope: &fasync::Scope,
171 device_server_end: fidl::endpoints::ServerEnd<MediaButtonsDeviceMarker>,
172 got_input_reports_reader: AsyncEvent,
173) -> input_device::DeviceId {
174 let device = registry
175 .add_media_buttons_device()
176 .await
177 .expect("failed to create fake media buttons device");
178 let device_id = device.device_id;
179
180 let activity_governor = connect_to_protocol::<fps::ActivityGovernorMarker>().ok();
181 let wake_alarm_proxy = connect_to_protocol::<fta::WakeAlarmsMarker>().ok();
182 scope.spawn(async move {
183 handle_media_buttons_device_request_stream(
184 device,
185 device_server_end.into_stream(),
186 activity_governor,
187 wake_alarm_proxy,
188 )
189 .await;
190 });
191
192 info!("wait for input-pipeline setup input-reader");
193 let _ = got_input_reports_reader.wait().await;
194 info!("input-pipeline setup input-reader.");
195
196 device_id
197}
198
199async fn register_keyboard(
200 mut registry: input_device_registry::InputDeviceRegistry,
201 scope: &fasync::Scope,
202 device_server_end: fidl::endpoints::ServerEnd<KeyboardMarker>,
203 got_input_reports_reader: AsyncEvent,
204) -> input_device::DeviceId {
205 let device = registry.add_keyboard_device().await.expect("failed to create fake keyboard");
206 let device_id = device.device_id;
207
208 scope.spawn(async move {
209 handle_keyboard_request_stream(device, device_server_end.into_stream()).await;
210 });
211
212 info!("wait for input-pipeline setup input-reader");
213 let _ = got_input_reports_reader.wait().await;
214 info!("input-pipeline setup input-reader.");
215
216 device_id
217}
218
219async fn register_mouse(
220 mut registry: input_device_registry::InputDeviceRegistry,
221 scope: &fasync::Scope,
222 device_server_end: fidl::endpoints::ServerEnd<MouseMarker>,
223 got_input_reports_reader: AsyncEvent,
224) -> input_device::DeviceId {
225 let device = registry.add_mouse_device().await.expect("failed to create fake mouse");
226 let device_id = device.device_id;
227
228 scope.spawn(async move {
229 handle_mouse_request_stream(device, device_server_end.into_stream()).await;
230 });
231
232 info!("wait for input-pipeline setup input-reader");
233 let _ = got_input_reports_reader.wait().await;
234 info!("input-pipeline setup input-reader.");
235
236 device_id
237}
238
239pub async fn handle_registry_request_stream(request_stream: RegistryRequestStream) {
241 request_stream
242 .try_for_each_concurrent(None, |request| async {
243 let input_device_registry = connect_to_protocol::<InputDeviceRegistryMarker>()
244 .expect("connect to input_device_registry");
245 let got_input_reports_reader = AsyncEvent::new();
246
247 let registry = input_device_registry::InputDeviceRegistry::new(
248 input_device_registry,
249 got_input_reports_reader.clone(),
250 );
251 let scope = fasync::Scope::new();
252
253 match request {
254 RegistryRequest::RegisterTouchScreen { payload, responder, .. } => {
255 info!("register touchscreen");
256 let device = payload
257 .device
258 .expect("no touchscreen device provided in registration request");
259 let (min_x, max_x, min_y, max_y) = match payload.coordinate_unit {
260 Some(CoordinateUnit::PhysicalPixels) => {
261 let display_info_proxy =
262 connect_to_protocol::<display_info::InfoMarker>()
263 .expect("failed to connect to display info service");
264 let display_dimensions = display_info_proxy
265 .get_metrics()
266 .await
267 .expect("failed to get display metrics")
268 .extent_in_px
269 .expect("display metrics missing extent in px");
270 (
271 0,
272 display_dimensions.width as i64,
273 0,
274 display_dimensions.height as i64,
275 )
276 }
277 Some(CoordinateUnit::RegisteredDimensions) => {
278 let dimensions =
279 payload.display_dimensions.expect("missing dimensions");
280 if dimensions.min_x >= dimensions.max_x
281 || dimensions.min_y >= dimensions.max_y
282 {
283 panic!("invalid dimensions");
284 }
285 (dimensions.min_x, dimensions.max_x, dimensions.min_y, dimensions.max_y)
286 }
287 _ => (-1000, 1000, -1000, 1000),
288 };
289
290 register_touch_screen(
291 registry,
292 &scope,
293 device,
294 got_input_reports_reader,
295 min_x,
296 max_x,
297 min_y,
298 max_y,
299 )
300 .await;
301
302 responder.send().expect("Failed to respond to RegisterTouchScreen request");
303 }
304 RegistryRequest::RegisterTouchScreenAndGetDeviceInfo {
305 payload, responder, ..
306 } => {
307 info!("register touchscreen");
308 let device = payload
309 .device
310 .expect("no touchscreen device provided in registration request");
311 let (min_x, max_x, min_y, max_y) = match payload.coordinate_unit {
312 Some(CoordinateUnit::PhysicalPixels) => {
313 let display_info_proxy =
314 connect_to_protocol::<display_info::InfoMarker>()
315 .expect("failed to connect to display info service");
316 let display_dimensions = display_info_proxy
317 .get_metrics()
318 .await
319 .expect("failed to get display metrics")
320 .extent_in_px
321 .expect("display metrics missing extent in px");
322 (
323 0,
324 display_dimensions.width as i64,
325 0,
326 display_dimensions.height as i64,
327 )
328 }
329 Some(CoordinateUnit::RegisteredDimensions) => {
330 let dimensions =
331 payload.display_dimensions.expect("missing dimensions");
332 if dimensions.min_x >= dimensions.max_x
333 || dimensions.min_y >= dimensions.max_y
334 {
335 panic!("invalid dimensions");
336 }
337 (dimensions.min_x, dimensions.max_x, dimensions.min_y, dimensions.max_y)
338 }
339 _ => (-1000, 1000, -1000, 1000),
340 };
341
342 let device_id = register_touch_screen(
343 registry,
344 &scope,
345 device,
346 got_input_reports_reader,
347 min_x,
348 max_x,
349 min_y,
350 max_y,
351 )
352 .await;
353
354 responder
355 .send(RegistryRegisterTouchScreenAndGetDeviceInfoResponse {
356 device_id: Some(device_id),
357 ..Default::default()
358 })
359 .expect("Failed to respond to RegisterTouchScreenAndGetDeviceInfo request");
360 }
361 RegistryRequest::RegisterMediaButtonsDevice { payload, responder, .. } => {
362 info!("register media buttons device");
363 let device = payload
364 .device
365 .expect("no media buttons device provided in registration request");
366
367 register_media_button(registry, &scope, device, got_input_reports_reader).await;
368
369 responder
370 .send()
371 .expect("Failed to respond to RegisterMediaButtonsDevice request");
372 }
373 RegistryRequest::RegisterMediaButtonsDeviceAndGetDeviceInfo {
374 payload,
375 responder,
376 ..
377 } => {
378 info!("register media buttons device");
379 let device = payload
380 .device
381 .expect("no media buttons device provided in registration request");
382
383 let device_id =
384 register_media_button(registry, &scope, device, got_input_reports_reader)
385 .await;
386
387 responder.send(RegistryRegisterMediaButtonsDeviceAndGetDeviceInfoResponse {
388 device_id: Some(device_id),
389 ..Default::default()
390 }).expect(
391 "Failed to respond to RegisterMediaButtonsDeviceAndGetDeviceInfo request",
392 );
393 }
394 RegistryRequest::RegisterKeyboard { payload, responder, .. } => {
395 info!("register keyboard device");
396 let device = payload
397 .device
398 .expect("no keyboard device provided in registration request");
399
400 register_keyboard(registry, &scope, device, got_input_reports_reader).await;
401
402 responder.send().expect("Failed to respond to RegisterKeyboard request");
403 }
404 RegistryRequest::RegisterKeyboardAndGetDeviceInfo {
405 payload, responder, ..
406 } => {
407 info!("register keyboard device");
408 let device = payload
409 .device
410 .expect("no keyboard device provided in registration request");
411
412 let device_id =
413 register_keyboard(registry, &scope, device, got_input_reports_reader).await;
414
415 responder
416 .send(RegistryRegisterKeyboardAndGetDeviceInfoResponse {
417 device_id: Some(device_id),
418 ..Default::default()
419 })
420 .expect("Failed to respond to RegisterKeyboardAndGetDeviceInfo request");
421 }
422 RegistryRequest::RegisterMouse { payload, responder } => {
423 info!("register mouse device");
424 let device = payload.device.expect("no mouse provided in registration request");
425
426 register_mouse(registry, &scope, device, got_input_reports_reader).await;
427
428 responder.send().expect("Failed to respond to RegisterMouse request");
429 }
430 RegistryRequest::RegisterMouseAndGetDeviceInfo { payload, responder } => {
431 info!("register mouse device");
432 let device = payload.device.expect("no mouse provided in registration request");
433
434 let device_id =
435 register_mouse(registry, &scope, device, got_input_reports_reader).await;
436
437 responder
438 .send(RegistryRegisterMouseAndGetDeviceInfoResponse {
439 device_id: Some(device_id),
440 ..Default::default()
441 })
442 .expect("Failed to respond to RegisterMouse request");
443 }
444 }
445
446 scope.join().await;
447 Ok(())
448 })
449 .await
450 .expect("failed to serve test realm factory request stream");
451}
452
453fn input_report_for_touch_contacts(
454 contacts: Vec<(u32, math::Vec_)>,
455 trace_id: Option<u64>,
456) -> InputReport {
457 let contact_input_reports = contacts
458 .into_iter()
459 .map(|(contact_id, location)| ContactInputReport {
460 contact_id: Some(contact_id),
461 position_x: Some(location.x as i64),
462 position_y: Some(location.y as i64),
463 contact_width: Some(0),
464 contact_height: Some(0),
465 ..Default::default()
466 })
467 .collect();
468
469 let touch_input_report = TouchInputReport {
470 contacts: Some(contact_input_reports),
471 pressed_buttons: Some(vec![]),
472 ..Default::default()
473 };
474
475 InputReport {
476 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
477 touch: Some(touch_input_report),
478 trace_id,
479 ..Default::default()
480 }
481}
482
483async fn handle_touchscreen_request_stream(
485 touchscreen_device: input_device::InputDevice,
486 mut request_stream: TouchScreenRequestStream,
487) {
488 while let Some(request) = request_stream.next().await {
489 match request {
490 Ok(TouchScreenRequest::SimulateTap { payload, responder }) => {
491 let tap_location = payload.tap_location.expect("missing tap location");
492 {
493 fuchsia_trace::duration!("input", "simulate_tap_down");
494 let trace_id = fuchsia_trace::Id::new();
495 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
496 touchscreen_device
497 .send_input_report(input_report_for_touch_contacts(
498 vec![(1, tap_location)],
499 Some(trace_id.into()),
500 ))
501 .expect("Failed to send touch down input report");
502 }
503
504 fuchsia_trace::duration!("input", "simulate_tap_up");
507 let trace_id = fuchsia_trace::Id::new();
508 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
509 touchscreen_device
510 .send_input_report(input_report_for_touch_contacts(
511 vec![],
512 Some(trace_id.into()),
513 ))
514 .expect("failed to send touch up input report");
515
516 responder.send().expect("Failed to send SimulateTap response");
517 }
518 Ok(TouchScreenRequest::SimulateSwipe { payload, responder }) => {
519 let start_location = payload.start_location.expect("missing start location");
521 let end_location = payload.end_location.expect("missing end location");
522 let move_event_count = payload.move_event_count.expect("missing move event count");
523 assert_ne!(move_event_count, 0);
524 let duration_nanos = payload.duration.unwrap_or(0);
525 let delay_nanos = duration_nanos / ((move_event_count as i64) + 1);
526 let delay = fasync::MonotonicDuration::from_nanos(delay_nanos);
527
528 let start_x_f = start_location.x as f64;
529 let start_y_f = start_location.y as f64;
530 let end_x_f = end_location.x as f64;
531 let end_y_f = end_location.y as f64;
532 let move_event_count_f = move_event_count as f64;
533 let step_size_x = (end_x_f - start_x_f) / move_event_count_f;
534 let step_size_y = (end_y_f - start_y_f) / move_event_count_f;
535
536 for i in 0..move_event_count + 1 {
539 let i_f = i as f64;
540 let event_x = start_x_f + (i_f * step_size_x);
541 let event_y = start_y_f + (i_f * step_size_y);
542
543 {
544 fuchsia_trace::duration!("input", "simulate_swipe_move", "idx"=>i);
545 let trace_id = fuchsia_trace::Id::new();
546 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
547
548 touchscreen_device
549 .send_input_report(input_report_for_touch_contacts(
550 vec![(1, math::Vec_ { x: event_x as i32, y: event_y as i32 })],
551 Some(trace_id.into()),
552 ))
553 .expect("Failed to send tap input report");
554 }
555 fasync::Timer::new(delay).await;
556 }
557
558 fuchsia_trace::duration!("input", "simulate_swipe_up");
561 let trace_id = fuchsia_trace::Id::new();
562 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
563 touchscreen_device
564 .send_input_report(input_report_for_touch_contacts(
565 vec![],
566 Some(trace_id.into()),
567 ))
568 .expect("failed to send empty input report");
569
570 responder.send().expect("Failed to send SimulateSwipe response");
571 }
572 Ok(TouchScreenRequest::SimulateMultiTap { payload, responder }) => {
573 let tap_locations = payload.tap_locations.expect("missing tap locations");
574
575 {
576 fuchsia_trace::duration!("input", "simulate_multi_tap_down");
577 let trace_id = fuchsia_trace::Id::new();
578 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
579 touchscreen_device
580 .send_input_report(input_report_for_touch_contacts(
581 tap_locations
582 .into_iter()
583 .enumerate()
584 .map(|(i, it)| (i as u32, it))
585 .collect(),
586 Some(trace_id.into()),
587 ))
588 .expect("Failed to send tap input report");
589 }
590
591 fuchsia_trace::duration!("input", "simulate_multi_tap_up");
594 let trace_id = fuchsia_trace::Id::new();
595 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
596 touchscreen_device
597 .send_input_report(input_report_for_touch_contacts(
598 vec![],
599 Some(trace_id.into()),
600 ))
601 .expect("failed to send empty input report");
602 responder.send().expect("Failed to send SimulateMultiTap response");
603 }
604 Ok(TouchScreenRequest::SimulateMultiFingerGesture { payload, responder }) => {
605 let start_locations = payload.start_locations.expect("missing start locations");
607 let end_locations = payload.end_locations.expect("missing end locations");
608 let move_event_count = payload.move_event_count.expect("missing move event count");
609 let finger_count = payload.finger_count.expect("missing finger count") as usize;
610
611 let move_event_count_f = move_event_count as f32;
612
613 let mut steps: Vec<math::VecF> = vec![];
614
615 for finger in 0..finger_count {
616 let start_x = start_locations[finger].x as f32;
617 let start_y = start_locations[finger].y as f32;
618 let end_x = end_locations[finger].x as f32;
619 let end_y = end_locations[finger].y as f32;
620 let step_x = (end_x - start_x) / move_event_count_f;
621 let step_y = (end_y - start_y) / move_event_count_f;
622 steps.push(math::VecF { x: step_x, y: step_y });
623 }
624
625 for i in 0..move_event_count {
628 let i_f = i as f32;
629
630 let mut contacts: Vec<(u32, math::Vec_)> = vec![];
631
632 for finger in 0..finger_count {
633 let start_x = start_locations[finger].x as f32;
634 let start_y = start_locations[finger].y as f32;
635 let event_x = (start_x + i_f * steps[finger].x) as i32;
636 let event_y = (start_y + i_f * steps[finger].y) as i32;
637 contacts.push((finger as u32, math::Vec_ { x: event_x, y: event_y }));
638 }
639
640 fuchsia_trace::duration!("input", "simulate_multi_finger_gesture_move", "idx"=>i);
641 let trace_id = fuchsia_trace::Id::new();
642 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
643
644 touchscreen_device
645 .send_input_report(input_report_for_touch_contacts(
646 contacts,
647 Some(trace_id.into()),
648 ))
649 .expect("Failed to send tap input report");
650 }
651
652 fuchsia_trace::duration!("input", "simulate_multi_finger_gesture_up");
655 let trace_id = fuchsia_trace::Id::new();
656 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
657 touchscreen_device
658 .send_input_report(input_report_for_touch_contacts(
659 vec![],
660 Some(trace_id.into()),
661 ))
662 .expect("failed to send empty input report");
663
664 responder.send().expect("Failed to send SimulateMultiFingerGesture response");
665 }
666 Ok(TouchScreenRequest::SimulateTouchEvent { report, responder }) => {
667 fuchsia_trace::duration!("input", "simulate_touch_event");
668 let trace_id = fuchsia_trace::Id::new();
669 fuchsia_trace::flow_begin!("input", "input_report", trace_id);
670 let input_report = InputReport {
671 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
672 touch: Some(report),
673 trace_id: Some(trace_id.into()),
674 ..Default::default()
675 };
676 touchscreen_device
677 .send_input_report(input_report)
678 .expect("failed to send empty input report");
679 responder.send().expect("Failed to send SimulateTouchEvent response");
680 }
681 Err(e) => {
682 error!("Error on touchscreen channel: {}", e);
683 return;
684 }
685 }
686 }
687}
688
689async fn handle_media_buttons_device_request_stream(
691 media_buttons_device: input_device::InputDevice,
692 request_stream: MediaButtonsDeviceRequestStream,
693 activity_governor: Option<fps::ActivityGovernorProxy>,
694 wake_alarm_proxy: Option<fta::WakeAlarmsProxy>,
695) {
696 let mut request_stream = request_stream.fuse();
697 let (alarm_sender, mut alarm_receiver) = futures::channel::mpsc::unbounded();
698
699 let mut scheduled_inputs = FuturesUnordered::new();
701
702 loop {
703 futures::select! {
704 request = request_stream.next() => {
705 match request {
706 Some(Ok(MediaButtonsDeviceRequest::SimulateButtonPress { payload, responder })) => {
707 if let Some(button) = payload.button {
708 let wake_lease = if let Some(ref ag) = activity_governor {
709 acquire_and_deposit_lease(ag, "input-helper-button").await
710 } else {
711 None
712 };
713 send_media_button_press_and_release(&media_buttons_device, button, wake_lease);
714 responder.send().expect("Failed to send SimulateButtonPress response");
715 } else {
716 warn!("SimulateButtonPress request missing button");
717 let _ = responder.send();
718 }
719 }
720 Some(Ok(MediaButtonsDeviceRequest::SendButtonsState { payload, responder })) => {
721 let buttons = match payload.buttons {
722 Some(buttons) => buttons,
723 None => vec![],
724 };
725 let wake_lease = if let Some(ref ag) = activity_governor {
726 acquire_and_deposit_lease(ag, "input-helper-button-state").await
727 } else {
728 None
729 };
730 let input_report = InputReport {
731 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
732 consumer_control: Some(ConsumerControlInputReport {
733 pressed_buttons: Some(buttons),
734 ..Default::default()
735 }),
736 wake_lease,
737 ..Default::default()
738 };
739
740 media_buttons_device
741 .send_input_report(input_report)
742 .expect("Failed to send button press input report");
743
744 responder.send().expect("Failed to send SimulateButtonPress response");
745 }
746
747 Some(Ok(MediaButtonsDeviceRequest::ScheduleSimulateButtonPress { payload, responder })) => {
748 let button = payload.button.expect("missing button");
749 let delay = zx::Duration::from_nanos(payload.delay.expect("missing delay"));
750 let sender = alarm_sender.clone();
751 let proxy = wake_alarm_proxy.clone();
752
753 scheduled_inputs.push(
754 fasync::Task::local(async move {
755 if let Some(alarm_proxy) = proxy {
756 let time = zx::BootInstant::after(delay);
759 info!("scheduling button press for {:?}", time);
760 fuchsia_trace::instant!(
761 INPUT_CATEGORY,
762 "WakeupTest:TimerSet",
763 Scope::Process
764 );
765 let (_lease, peer) = zx::EventPair::create();
766 match alarm_proxy
767 .set_and_wait(time, fta::SetMode::KeepAlive(peer), "input_helper_button")
768 .await
769 {
770 Ok(Ok(lease_token)) => {
771 let _ = sender.unbounded_send(Some((button, lease_token)));
772 }
773 Ok(Err(e)) => {
774 error!("Failed to set wakeup alarm: {:?}", e);
775 }
776 Err(e) => {
777 error!("FIDL error: {:?}", e);
778 }
779 }
780 } else {
781 error!("failed to connect to WakeAlarms protocol");
782 }
783 }));
784 responder.send().expect("Failed to send ScheduleSimulateButtonPress response");
785 }
786 Some(Err(e)) => {
787 error!("Error on media buttons device channel: {}", e);
788 break;
789 }
790 None => break,
791 }
792 },
793 fired_alarm = alarm_receiver.next() => {
796 if let Some(Some((button, lease_token))) = fired_alarm {
797 info!("wake alarm fired, sending button event");
798 fuchsia_trace::duration!(INPUT_CATEGORY,"WakeupTest:OnTimer");
801
802 if let Ok(local_lease) = lease_token.duplicate_handle(zx::Rights::SAME_RIGHTS) {
804 deposit_wake_lease(local_lease, zx::MonotonicDuration::from_millis(100));
805 }
806
807 send_media_button_press_and_release(&media_buttons_device, button, Some(lease_token));
808 }
809 },
810 _ = scheduled_inputs.select_next_some() => {},
811 }
812 }
813}
814
815fn deposit_wake_lease(lease: zx::EventPair, duration: zx::MonotonicDuration) {
816 fasync::Task::local(async move {
817 fasync::Timer::new(fasync::MonotonicInstant::after(duration)).await;
818 std::mem::drop(lease);
819 })
820 .detach();
821}
822
823async fn acquire_and_deposit_lease(
825 ag: &fps::ActivityGovernorProxy,
826 name: &str,
827) -> Option<zx::EventPair> {
828 match ag.acquire_wake_lease(name).await {
829 Ok(Ok(lease)) => {
830 if let Ok(local_lease) = lease.duplicate_handle(zx::Rights::SAME_RIGHTS) {
831 deposit_wake_lease(local_lease, zx::MonotonicDuration::from_millis(100));
832 }
833 Some(lease)
834 }
835 Ok(Err(e)) => {
836 error!("Failed to acquire wake lease {name}: {:?}", e);
837 None
838 }
839 Err(e) => {
840 error!("FIDL error acquiring wake lease {name}: {:?}", e);
841 None
842 }
843 }
844}
845
846fn send_media_button_press_and_release(
847 media_buttons_device: &input_device::InputDevice,
848 button: fidl_fuchsia_input_report::ConsumerControlButton,
849 wake_lease: Option<zx::EventPair>,
850) {
851 let media_buttons_input_report =
852 ConsumerControlInputReport { pressed_buttons: Some(vec![button]), ..Default::default() };
853
854 let release_wake_lease =
855 wake_lease.as_ref().and_then(|lease| lease.duplicate_handle(zx::Rights::SAME_RIGHTS).ok());
856
857 let input_report = InputReport {
858 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
859 consumer_control: Some(media_buttons_input_report),
860 wake_lease,
861 ..Default::default()
862 };
863
864 media_buttons_device
865 .send_input_report(input_report)
866 .expect("Failed to send button press input report");
867
868 let empty_report = InputReport {
872 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
873 consumer_control: Some(ConsumerControlInputReport {
874 pressed_buttons: Some(vec![]),
875 ..Default::default()
876 }),
877 wake_lease: release_wake_lease,
878 ..Default::default()
879 };
880
881 media_buttons_device
882 .send_input_report(empty_report)
883 .expect("Failed to send button release input report");
884}
885
886async fn handle_keyboard_request_stream(
888 keyboard_device: input_device::InputDevice,
889 mut request_stream: KeyboardRequestStream,
890) {
891 while let Some(request) = request_stream.next().await {
892 match request {
893 Ok(KeyboardRequest::SimulateUsAsciiTextEntry { payload, responder }) => {
894 if let Some(text) = payload.text {
895 let key_sequence = derive_key_sequence(&keymaps::US_QWERTY, &text)
896 .expect("Failed to derive key sequence");
897
898 let mut key_iter = key_sequence.into_iter().peekable();
899 while let Some(keyboard_report) = key_iter.next() {
900 let input_report = InputReport {
901 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
902 keyboard: Some(KeyboardInputReport {
903 pressed_keys3: Some(convert_keyboard_report_to_keys(
904 &keyboard_report,
905 )),
906 ..Default::default()
907 }),
908 ..Default::default()
909 };
910
911 keyboard_device
912 .send_input_report(input_report)
913 .expect("Failed to send key event report");
914
915 if key_iter.peek().is_some() {
916 fuchsia_async::Timer::new(Duration::from_millis(100)).await;
917 }
918 }
919
920 responder.send().expect("Failed to send SimulateTextEntry response");
921 } else {
922 warn!("SimulateTextEntry request missing text");
923 }
924 }
925 Ok(KeyboardRequest::SimulateKeyEvent { payload, responder }) => {
926 let keyboard_report = payload.report.expect("no report");
927 let input_report = InputReport {
928 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
929 keyboard: Some(keyboard_report),
930 ..Default::default()
931 };
932
933 keyboard_device
934 .send_input_report(input_report)
935 .expect("Failed to send key event report");
936
937 responder.send().expect("Failed to send SimulateKeyEvent response");
938 }
939 Ok(KeyboardRequest::SimulateKeyPress { payload, responder }) => {
940 let key_code = payload.key_code.expect("no key code");
941
942 let down_report = InputReport {
943 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
944 keyboard: Some(KeyboardInputReport {
945 pressed_keys3: Some(vec![key_code]),
946 ..Default::default()
947 }),
948 ..Default::default()
949 };
950
951 let up_report = InputReport {
952 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
953 keyboard: Some(KeyboardInputReport {
954 pressed_keys3: Some(vec![]),
955 ..Default::default()
956 }),
957 ..Default::default()
958 };
959
960 keyboard_device.send_input_report(down_report).expect("Failed to send key down");
961
962 keyboard_device.send_input_report(up_report).expect("Failed to send key up");
963
964 responder.send().expect("Failed to send SimulateKeyPress response");
965 }
966 Err(e) => {
967 error!("Error on keyboard device channel: {}", e);
968 return;
969 }
970 }
971 }
972}
973
974async fn handle_mouse_request_stream(
976 mouse_device: input_device::InputDevice,
977 mut request_stream: MouseRequestStream,
978) {
979 while let Some(request) = request_stream.next().await {
980 match request {
981 Ok(MouseRequest::SimulateMouseEvent { payload, responder }) => {
982 let mut mouse_input_report = MouseInputReport {
983 movement_x: payload.movement_x,
984 movement_y: payload.movement_y,
985 scroll_v: payload.scroll_v_detent,
986 scroll_h: payload.scroll_h_detent,
987 ..Default::default()
988 };
989 if let Some(pressed_buttons) = payload.pressed_buttons {
990 mouse_input_report.pressed_buttons = Some(
991 pressed_buttons
992 .into_iter()
993 .map(|b| {
994 b.into_primitive()
995 .try_into()
996 .expect("failed to convert MouseButton to u8")
997 })
998 .collect(),
999 );
1000 }
1001
1002 let input_report = InputReport {
1003 event_time: Some(fasync::MonotonicInstant::now().into_nanos()),
1004 mouse: Some(mouse_input_report),
1005 ..Default::default()
1006 };
1007
1008 mouse_device
1009 .send_input_report(input_report)
1010 .expect("Failed to send key event report");
1011
1012 responder.send().expect("Failed to send SimulateMouseEvent response");
1013 }
1014 Err(e) => {
1015 error!("Error on keyboard device channel: {}", e);
1016 return;
1017 }
1018 }
1019 }
1020}
1021
1022#[cfg(test)]
1023mod tests {
1024 use super::{
1031 KeyboardReport, Usages, derive_key_sequence, handle_media_buttons_device_request_stream,
1032 };
1033 use pretty_assertions::assert_eq;
1034
1035 macro_rules! reports {
1037 ( $( [ $( $usages:expr ),* ] ),* $( , )? ) => {
1038 Some(vec![
1039 $(
1040 KeyboardReport {
1041 pressed_keys: vec![$($usages as u32),*]
1042 }
1043 ),*
1044 ])
1045 }
1046 }
1047
1048 #[test]
1049 fn lowercase() {
1050 assert_eq!(
1051 derive_key_sequence(&keymaps::US_QWERTY, "lowercase"),
1052 reports![
1053 [Usages::HidUsageKeyL],
1054 [Usages::HidUsageKeyO],
1055 [Usages::HidUsageKeyW],
1056 [Usages::HidUsageKeyE],
1057 [Usages::HidUsageKeyR],
1058 [Usages::HidUsageKeyC],
1059 [Usages::HidUsageKeyA],
1060 [Usages::HidUsageKeyS],
1061 [Usages::HidUsageKeyE],
1062 [],
1063 ]
1064 );
1065 }
1066
1067 #[test]
1068 fn numerics() {
1069 assert_eq!(
1070 derive_key_sequence(&keymaps::US_QWERTY, "0123456789"),
1071 reports![
1072 [Usages::HidUsageKey0],
1073 [Usages::HidUsageKey1],
1074 [Usages::HidUsageKey2],
1075 [Usages::HidUsageKey3],
1076 [Usages::HidUsageKey4],
1077 [Usages::HidUsageKey5],
1078 [Usages::HidUsageKey6],
1079 [Usages::HidUsageKey7],
1080 [Usages::HidUsageKey8],
1081 [Usages::HidUsageKey9],
1082 [],
1083 ]
1084 );
1085 }
1086
1087 #[test]
1088 fn internet_text_entry() {
1089 assert_eq!(
1090 derive_key_sequence(&keymaps::US_QWERTY, "http://127.0.0.1:8080"),
1091 reports![
1092 [Usages::HidUsageKeyH],
1093 [Usages::HidUsageKeyT],
1094 [],
1095 [Usages::HidUsageKeyT],
1096 [Usages::HidUsageKeyP],
1097 [Usages::HidUsageKeyLeftShift],
1101 [Usages::HidUsageKeySemicolon, Usages::HidUsageKeyLeftShift],
1102 [],
1103 [Usages::HidUsageKeySlash],
1104 [],
1105 [Usages::HidUsageKeySlash],
1106 [Usages::HidUsageKey1],
1107 [Usages::HidUsageKey2],
1108 [Usages::HidUsageKey7],
1109 [Usages::HidUsageKeyDot],
1110 [Usages::HidUsageKey0],
1111 [Usages::HidUsageKeyDot],
1112 [Usages::HidUsageKey0],
1113 [Usages::HidUsageKeyDot],
1114 [Usages::HidUsageKey1],
1115 [Usages::HidUsageKeyLeftShift],
1116 [Usages::HidUsageKeySemicolon, Usages::HidUsageKeyLeftShift],
1117 [],
1118 [Usages::HidUsageKey8],
1119 [Usages::HidUsageKey0],
1120 [Usages::HidUsageKey8],
1121 [Usages::HidUsageKey0],
1122 [],
1123 ]
1124 );
1125 }
1126
1127 #[test]
1128 fn sentence() {
1129 assert_eq!(
1130 derive_key_sequence(&keymaps::US_QWERTY, "Hello, world!"),
1131 reports![
1132 [Usages::HidUsageKeyLeftShift],
1133 [Usages::HidUsageKeyH, Usages::HidUsageKeyLeftShift],
1134 [],
1135 [Usages::HidUsageKeyE],
1136 [Usages::HidUsageKeyL],
1137 [],
1138 [Usages::HidUsageKeyL],
1139 [Usages::HidUsageKeyO],
1140 [Usages::HidUsageKeyComma],
1141 [Usages::HidUsageKeySpace],
1142 [Usages::HidUsageKeyW],
1143 [Usages::HidUsageKeyO],
1144 [Usages::HidUsageKeyR],
1145 [Usages::HidUsageKeyL],
1146 [Usages::HidUsageKeyD],
1147 [Usages::HidUsageKeyLeftShift],
1148 [Usages::HidUsageKey1, Usages::HidUsageKeyLeftShift],
1149 [],
1150 ]
1151 );
1152 }
1153
1154 #[test]
1155 fn hold_shift() {
1156 assert_eq!(
1157 derive_key_sequence(&keymaps::US_QWERTY, "ALL'S WELL!"),
1158 reports![
1159 [Usages::HidUsageKeyLeftShift],
1160 [Usages::HidUsageKeyA, Usages::HidUsageKeyLeftShift],
1161 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1162 [Usages::HidUsageKeyLeftShift],
1163 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1164 [],
1165 [Usages::HidUsageKeyApostrophe],
1166 [Usages::HidUsageKeyLeftShift],
1167 [Usages::HidUsageKeyS, Usages::HidUsageKeyLeftShift],
1168 [Usages::HidUsageKeySpace, Usages::HidUsageKeyLeftShift],
1169 [Usages::HidUsageKeyW, Usages::HidUsageKeyLeftShift],
1170 [Usages::HidUsageKeyE, Usages::HidUsageKeyLeftShift],
1171 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1172 [Usages::HidUsageKeyLeftShift],
1173 [Usages::HidUsageKeyL, Usages::HidUsageKeyLeftShift],
1174 [Usages::HidUsageKey1, Usages::HidUsageKeyLeftShift],
1175 [],
1176 ]
1177 );
1178 }
1179
1180 #[test]
1181 fn tab_and_newline() {
1182 assert_eq!(
1183 derive_key_sequence(&keymaps::US_QWERTY, "\tHello\n"),
1184 reports![
1185 [Usages::HidUsageKeyTab],
1186 [Usages::HidUsageKeyLeftShift],
1187 [Usages::HidUsageKeyH, Usages::HidUsageKeyLeftShift],
1188 [],
1189 [Usages::HidUsageKeyE],
1190 [Usages::HidUsageKeyL],
1191 [],
1192 [Usages::HidUsageKeyL],
1193 [Usages::HidUsageKeyO],
1194 [Usages::HidUsageKeyEnter],
1195 [],
1196 ]
1197 );
1198 }
1199
1200 #[fuchsia::test]
1201 async fn test_schedule_power_button_press() {
1202 use fidl_fuchsia_input_report::{ConsumerControlButton, InputReport};
1203 use fidl_fuchsia_time_alarms as fta;
1204 use fidl_fuchsia_ui_test_input::MediaButtonsDeviceMarker;
1205 use futures::{FutureExt, StreamExt};
1206
1207 let (report_sender, mut report_receiver) =
1208 futures::channel::mpsc::unbounded::<InputReport>();
1209 let input_device = crate::input_device::InputDevice::new_for_test(report_sender);
1210
1211 let (proxy, stream) =
1212 fidl::endpoints::create_proxy_and_stream::<MediaButtonsDeviceMarker>();
1213
1214 let (alarm_proxy, mut alarm_stream) =
1215 fidl::endpoints::create_proxy_and_stream::<fta::WakeAlarmsMarker>();
1216 let alarm_proxy_clone = alarm_proxy.clone();
1217
1218 let handler_fut = handle_media_buttons_device_request_stream(
1219 input_device,
1220 stream,
1221 None,
1222 Some(alarm_proxy_clone),
1223 );
1224
1225 let test_fut = async {
1226 let schedule_fut = proxy.schedule_simulate_button_press(
1227 &fidl_fuchsia_ui_test_input::MediaButtonsDeviceScheduleSimulateButtonPressRequest {
1228 button: Some(ConsumerControlButton::Power),
1229 delay: Some(zx::Duration::<zx::BootTimeline>::from_millis(750).into_nanos()), ..Default::default()
1231 },
1232 );
1233
1234 schedule_fut.await.expect("failed to schedule");
1235
1236 if let Some(Ok(fta::WakeAlarmsRequest::SetAndWait { responder, .. })) =
1238 alarm_stream.next().await
1239 {
1240 let (lease, _peer) = zx::EventPair::create();
1241 responder.send(Ok(lease)).expect("failed to respond");
1242 }
1243
1244 let press_report: InputReport = report_receiver.next().await.expect("no press report");
1246 assert!(press_report.consumer_control.is_some());
1247 let cc = press_report.consumer_control.unwrap();
1248 assert_eq!(cc.pressed_buttons, Some(vec![ConsumerControlButton::Power]));
1249 assert!(press_report.wake_lease.is_some());
1250
1251 let release_report: InputReport =
1253 report_receiver.next().await.expect("no release report");
1254 let cc = release_report.consumer_control.unwrap();
1255 assert_eq!(cc.pressed_buttons, Some(vec![]));
1256 assert!(release_report.wake_lease.is_some());
1257 };
1258
1259 futures::select! {
1260 _ = handler_fut.fuse() => panic!("handler exited early"),
1261 _ = test_fut.fuse() => (),
1262 }
1263 }
1264}