1#![warn(missing_docs)]
6
7use crate::modern_backend::input_reports_reader::InputReportsReader;
8use crate::synthesizer;
9use crate::usages::hid_usage_to_input3_key;
10use anyhow::{format_err, Context as _, Error};
11use async_trait::async_trait;
12use fidl::endpoints::ServerEnd;
13use fidl::Error as FidlError;
14use fidl_fuchsia_input::Key;
15use fidl_fuchsia_input_report::{
16 ConsumerControlButton, ConsumerControlInputReport, ContactInputReport, DeviceDescriptor,
17 FeatureReport, InputDeviceRequest, InputDeviceRequestStream, InputReport,
18 InputReportsReaderMarker, KeyboardInputReport, MouseInputReport, TouchInputReport,
19 TOUCH_MAX_CONTACTS,
20};
21use fidl_fuchsia_ui_input::{KeyboardReport, Touch};
22use fuchsia_async as fasync;
23use futures::{future, pin_mut, StreamExt, TryFutureExt};
24use std::convert::TryFrom as _;
25
26pub(super) struct InputDevice {
42 report_sender: futures::channel::mpsc::UnboundedSender<InputReport>,
46
47 input_device_task: fasync::Task<Result<(), Error>>,
49}
50
51impl std::convert::From<synthesizer::MediaButton> for ConsumerControlButton {
52 fn from(synthesizer_button: synthesizer::MediaButton) -> Self {
53 match synthesizer_button {
54 synthesizer::MediaButton::VolumeUp => Self::VolumeUp,
55 synthesizer::MediaButton::VolumeDown => Self::VolumeDown,
56 synthesizer::MediaButton::MicMute => Self::MicMute,
57 synthesizer::MediaButton::FactoryReset => Self::FactoryReset,
58 synthesizer::MediaButton::Pause => Self::Pause,
59 synthesizer::MediaButton::CameraDisable => Self::CameraDisable,
60 }
61 }
62}
63
64#[async_trait(?Send)]
65impl synthesizer::InputDevice for self::InputDevice {
66 fn media_buttons(
67 &mut self,
68 pressed_buttons: Vec<synthesizer::MediaButton>,
69 time: u64,
70 ) -> Result<(), Error> {
71 self.report_sender
72 .unbounded_send(InputReport {
73 event_time: Some(i64::try_from(time).context("converting time to i64")?),
74 consumer_control: Some(ConsumerControlInputReport {
75 pressed_buttons: Some(pressed_buttons.into_iter().map(Into::into).collect()),
76 ..Default::default()
77 }),
78 ..Default::default()
79 })
80 .context("sending media button InputReport")
81 }
82
83 fn key_press(&mut self, report: KeyboardReport, time: u64) -> Result<(), Error> {
85 self.key_press_internal(report, time, Self::convert_keyboard_report_to_keys)
86 }
87
88 fn key_press_raw(&mut self, report: KeyboardReport, time: u64) -> Result<(), Error> {
89 self.key_press_internal(report, time, Self::convert_keyboard_report_to_keys_no_transform)
90 }
91
92 fn key_press_usage(&mut self, usage: Option<u32>, time: u64) -> Result<(), Error> {
94 self.key_press(KeyboardReport { pressed_keys: usage.into_iter().collect() }, time)
95 }
96
97 fn tap(&mut self, pos: Option<(u32, u32)>, time: u64) -> Result<(), Error> {
98 let fingers = pos.and_then(|(x, y)| {
99 Some(vec![Touch { finger_id: 1, x: x as i32, y: y as i32, width: 0, height: 0 }])
100 });
101 self.multi_finger_tap(fingers, time)
102 }
103
104 fn multi_finger_tap(&mut self, fingers: Option<Vec<Touch>>, time: u64) -> Result<(), Error> {
105 let num_fingers = match &fingers {
106 Some(fingers_vec) => fingers_vec.len(),
107 None => 0,
108 };
109 if num_fingers > usize::try_from(TOUCH_MAX_CONTACTS).context("usize is at least 32 bits")? {
110 return Err(format_err!(
111 "Got {} fingers, but max is {}",
112 num_fingers,
113 TOUCH_MAX_CONTACTS
114 ));
115 }
116 self.multi_finger_tap_internal(
117 TouchInputReport {
118 contacts: Some(fingers.map_or_else(Vec::new, |fingers_vec| {
119 fingers_vec
120 .into_iter()
121 .map(|finger| ContactInputReport {
122 contact_id: Some(finger.finger_id),
123 position_x: Some(i64::from(finger.x)),
124 position_y: Some(i64::from(finger.y)),
125 contact_width: Some(i64::from(finger.width)),
126 contact_height: Some(i64::from(finger.height)),
127 ..Default::default()
128 })
129 .collect()
130 })),
131 pressed_buttons: Some(vec![]),
132 ..Default::default()
133 },
134 time,
135 )
136 }
137
138 fn mouse(&mut self, report: MouseInputReport, time: u64) -> Result<(), Error> {
139 self.report_sender
140 .unbounded_send(InputReport {
141 event_time: Some(i64::try_from(time).context("converting time to i64")?),
142 mouse: Some(report),
143 ..Default::default()
144 })
145 .context("error sending mouse InputReport")
146 }
147
148 async fn flush(self: Box<Self>) -> Result<(), Error> {
149 let Self { input_device_task, report_sender } = *self;
150 std::mem::drop(report_sender); input_device_task.await
152 }
153}
154
155impl InputDevice {
156 pub(super) fn new(
160 request_stream: InputDeviceRequestStream,
161 descriptor: DeviceDescriptor,
162 ) -> Self {
163 let (report_sender, report_receiver) = futures::channel::mpsc::unbounded::<InputReport>();
164
165 let input_device_task =
167 fasync::Task::local(Self::serve_reports(request_stream, descriptor, report_receiver));
168
169 Self { report_sender, input_device_task }
170 }
171
172 async fn serve_reports(
192 request_stream: InputDeviceRequestStream,
193 descriptor: DeviceDescriptor,
194 report_receiver: futures::channel::mpsc::UnboundedReceiver<InputReport>,
195 ) -> Result<(), Error> {
196 let mut input_reports_reader_server_end_stream = request_stream
199 .filter_map(|r| future::ready(Self::handle_device_request(r, &descriptor)));
200 let input_reports_reader_fut = {
201 let reader_server_end = input_reports_reader_server_end_stream
202 .next()
203 .await
204 .ok_or_else(|| format_err!("stream ended without a call to GetInputReportsReader"))?
205 .context("handling InputDeviceRequest")?;
206 InputReportsReader { request_stream: reader_server_end.into_stream(), report_receiver }
207 .into_future()
208 };
209 pin_mut!(input_reports_reader_fut);
210
211 let input_device_server_fut = async {
214 match input_reports_reader_server_end_stream.next().await {
215 Some(Ok(_server_end)) => {
216 Err(format_err!(
221 "InputDevice does not support multiple GetInputReportsReader calls"
222 ))
223 }
224 Some(Err(e)) => Err(e.context("handling InputDeviceRequest")),
225 None => Ok(()),
226 }
227 };
228 pin_mut!(input_device_server_fut);
229
230 future::select(
235 input_device_server_fut.and_then(|_: ()| future::pending()),
236 input_reports_reader_fut,
237 )
238 .await
239 .factor_first()
240 .0
241 }
242
243 fn key_press_internal(
246 &mut self,
247 report: KeyboardReport,
248 time: u64,
249 transform: fn(r: &KeyboardReport) -> Result<Vec<Key>, Error>,
250 ) -> Result<(), Error> {
251 self.report_sender
252 .unbounded_send(InputReport {
253 event_time: Some(i64::try_from(time).context("converting time to i64")?),
254 keyboard: Some(KeyboardInputReport {
255 pressed_keys3: Some(transform(&report)?),
256 ..Default::default()
257 }),
258 ..Default::default()
259 })
260 .context("sending key press InputReport")
261 }
262
263 fn multi_finger_tap_internal(
264 &mut self,
265 touch: TouchInputReport,
266 time: u64,
267 ) -> Result<(), Error> {
268 self.report_sender
269 .unbounded_send(InputReport {
270 event_time: Some(i64::try_from(time).context("converting time to i64")?),
271 touch: Some(touch),
272 ..Default::default()
273 })
274 .context("sending touch InputReport")
275 }
276
277 fn handle_device_request(
286 request: Result<InputDeviceRequest, FidlError>,
287 descriptor: &DeviceDescriptor,
288 ) -> Option<Result<ServerEnd<InputReportsReaderMarker>, Error>> {
289 match request {
290 Ok(InputDeviceRequest::GetInputReportsReader { reader: reader_server_end, .. }) => {
291 Some(Ok(reader_server_end))
292 }
293 Ok(InputDeviceRequest::GetDescriptor { responder }) => {
294 match responder.send(&descriptor) {
295 Ok(()) => None,
296 Err(e) => {
297 Some(Err(anyhow::Error::from(e).context("sending GetDescriptor response")))
298 }
299 }
300 }
301 Ok(InputDeviceRequest::GetFeatureReport { responder }) => {
302 match responder.send(Ok(&FeatureReport::default())) {
303 Ok(()) => None,
304 Err(e) => Some(Err(
305 anyhow::Error::from(e).context("sending GetFeatureReport response")
306 )),
307 }
308 }
309 Err(e) => {
310 panic!("InputDevice got an error while reading request: {:?}", &e);
317 }
318 _ => {
319 panic!(
321 "InputDevice::handle_device_request does not support this request: {:?}",
322 &request
323 );
324 }
325 }
326 }
327
328 fn convert_keyboard_report_to_keys(report: &KeyboardReport) -> Result<Vec<Key>, Error> {
329 report
330 .pressed_keys
331 .iter()
332 .map(|&usage| {
333 hid_usage_to_input3_key(usage as u16)
334 .ok_or_else(|| format_err!("no Key for usage {:?}", usage))
335 })
336 .collect()
337 }
338
339 fn convert_keyboard_report_to_keys_no_transform(
348 report: &KeyboardReport,
349 ) -> Result<Vec<Key>, Error> {
350 report
351 .pressed_keys
352 .iter()
353 .map(|&usage| {
354 Key::from_primitive(usage)
355 .ok_or_else(|| anyhow::anyhow!("could not convert to input::Key: {}", &usage))
356 })
357 .collect()
358 }
359}
360
361#[cfg(test)]
362mod tests {
363 use super::synthesizer::InputDevice as _;
364 use super::*;
365 use fidl::endpoints;
366 use fidl_fuchsia_input_report::{
367 DeviceDescriptor, InputDeviceMarker, KeyboardDescriptor, KeyboardInputDescriptor,
368 };
369 use fuchsia_async as fasync;
370
371 const DEFAULT_REPORT_TIMESTAMP: u64 = 0;
372
373 mod responds_to_get_feature_report_request {
374 use super::*;
375
376 #[fasync::run_until_stalled(test)]
377 async fn single_request_before_call_to_get_feature_report() -> Result<(), Error> {
378 let (proxy, request_stream) = endpoints::create_proxy_and_stream::<InputDeviceMarker>();
379 let input_device_server_fut =
380 Box::new(InputDevice::new(request_stream, DeviceDescriptor::default())).flush();
381 let get_feature_report_fut = proxy.get_feature_report();
382 std::mem::drop(proxy); let (_, get_feature_report_result) =
385 future::join(input_device_server_fut, get_feature_report_fut).await;
386 assert_eq!(
387 get_feature_report_result.context("fidl error")?,
388 Ok(FeatureReport::default())
389 );
390 Ok(())
391 }
392 }
393
394 mod responds_to_get_descriptor_request {
395 use super::utils::{make_input_device_proxy_and_struct, make_keyboard_descriptor};
396 use super::*;
397 use assert_matches::assert_matches;
398 use futures::task::Poll;
399
400 #[fasync::run_until_stalled(test)]
401 async fn single_request_before_call_to_get_input_reports_reader() -> Result<(), Error> {
402 let (proxy, request_stream) = endpoints::create_proxy_and_stream::<InputDeviceMarker>();
403 let input_device_server_fut =
404 Box::new(InputDevice::new(request_stream, make_keyboard_descriptor(vec![Key::A])))
405 .flush();
406 let get_descriptor_fut = proxy.get_descriptor();
407 std::mem::drop(proxy); let (_, get_descriptor_result) =
410 future::join(input_device_server_fut, get_descriptor_fut).await;
411 assert_eq!(
412 get_descriptor_result.context("fidl error")?,
413 make_keyboard_descriptor(vec![Key::A])
414 );
415 Ok(())
416 }
417
418 #[test]
419 fn multiple_requests_before_call_to_get_input_reports_reader() -> Result<(), Error> {
420 let mut executor = fasync::TestExecutor::new();
421 let (proxy, request_stream) = endpoints::create_proxy_and_stream::<InputDeviceMarker>();
422 let mut input_device_server_fut =
423 Box::new(InputDevice::new(request_stream, make_keyboard_descriptor(vec![Key::A])))
424 .flush();
425
426 let mut get_descriptor_fut = proxy.get_descriptor();
427 assert_matches!(
428 executor.run_until_stalled(&mut input_device_server_fut),
429 Poll::Pending
430 );
431 std::mem::drop(executor.run_until_stalled(&mut get_descriptor_fut));
432
433 let mut get_descriptor_fut = proxy.get_descriptor();
434 let _ = executor.run_until_stalled(&mut input_device_server_fut);
435 assert_matches!(
436 executor.run_until_stalled(&mut get_descriptor_fut),
437 Poll::Ready(Ok(_))
438 );
439
440 Ok(())
441 }
442
443 #[test]
444 fn after_call_to_get_input_reports_reader_with_report_pending() -> Result<(), Error> {
445 let mut executor = fasync::TestExecutor::new();
446 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
447 input_device
448 .key_press(KeyboardReport { pressed_keys: vec![] }, DEFAULT_REPORT_TIMESTAMP)
449 .context("internal error queuing input event")?;
450
451 let input_device_server_fut = input_device.flush();
452 pin_mut!(input_device_server_fut);
453
454 let (_input_reports_reader_proxy, input_reports_reader_server_end) =
455 endpoints::create_proxy::<InputReportsReaderMarker>();
456 input_device_proxy
457 .get_input_reports_reader(input_reports_reader_server_end)
458 .context("sending get_input_reports_reader request")?;
459 assert_matches!(
460 executor.run_until_stalled(&mut input_device_server_fut),
461 Poll::Pending
462 );
463
464 let mut get_descriptor_fut = input_device_proxy.get_descriptor();
465 assert_matches!(
466 executor.run_until_stalled(&mut input_device_server_fut),
467 Poll::Pending
468 );
469 assert_matches!(executor.run_until_stalled(&mut get_descriptor_fut), Poll::Ready(_));
470 Ok(())
471 }
472 }
473
474 mod report_contents {
475 use super::utils::{get_input_reports, make_input_device_proxy_and_struct};
476 use super::*;
477 use crate::usages::Usages;
478 use assert_matches::assert_matches;
479 use std::convert::TryInto as _;
480
481 #[fasync::run_until_stalled(test)]
482 async fn media_buttons_generates_empty_consumer_controls_input_report() -> Result<(), Error>
483 {
484 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
485 input_device.media_buttons(vec![], DEFAULT_REPORT_TIMESTAMP)?;
486
487 let input_reports = get_input_reports(input_device, input_device_proxy).await;
488 assert_eq!(
489 input_reports.as_slice(),
490 [InputReport {
491 event_time: Some(
492 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
493 ),
494 consumer_control: Some(ConsumerControlInputReport {
495 pressed_buttons: Some(vec![]),
496 ..Default::default()
497 }),
498 ..Default::default()
499 }]
500 );
501 Ok(())
502 }
503
504 #[fasync::run_until_stalled(test)]
505 async fn media_buttons_generates_full_consumer_controls_input_report() -> Result<(), Error>
506 {
507 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
508 input_device.media_buttons(
509 vec![
510 synthesizer::MediaButton::VolumeUp,
511 synthesizer::MediaButton::VolumeDown,
512 synthesizer::MediaButton::MicMute,
513 synthesizer::MediaButton::FactoryReset,
514 synthesizer::MediaButton::Pause,
515 synthesizer::MediaButton::CameraDisable,
516 ],
517 DEFAULT_REPORT_TIMESTAMP,
518 )?;
519
520 let input_reports = get_input_reports(input_device, input_device_proxy).await;
521 assert_eq!(
522 input_reports.as_slice(),
523 [InputReport {
524 event_time: Some(
525 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
526 ),
527 consumer_control: Some(ConsumerControlInputReport {
528 pressed_buttons: Some(vec![
529 ConsumerControlButton::VolumeUp,
530 ConsumerControlButton::VolumeDown,
531 ConsumerControlButton::MicMute,
532 ConsumerControlButton::FactoryReset,
533 ConsumerControlButton::Pause,
534 ConsumerControlButton::CameraDisable,
535 ]),
536 ..Default::default()
537 }),
538 ..Default::default()
539 }]
540 );
541 Ok(())
542 }
543
544 #[fasync::run_until_stalled(test)]
545 async fn media_buttons_generates_partial_consumer_controls_input_report(
546 ) -> Result<(), Error> {
547 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
548 input_device.media_buttons(
549 vec![
550 synthesizer::MediaButton::VolumeUp,
551 synthesizer::MediaButton::MicMute,
552 synthesizer::MediaButton::Pause,
553 ],
554 DEFAULT_REPORT_TIMESTAMP,
555 )?;
556
557 let input_reports = get_input_reports(input_device, input_device_proxy).await;
558 assert_eq!(
559 input_reports.as_slice(),
560 [InputReport {
561 event_time: Some(
562 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
563 ),
564 consumer_control: Some(ConsumerControlInputReport {
565 pressed_buttons: Some(vec![
566 ConsumerControlButton::VolumeUp,
567 ConsumerControlButton::MicMute,
568 ConsumerControlButton::Pause,
569 ]),
570 ..Default::default()
571 }),
572 ..Default::default()
573 }]
574 );
575 Ok(())
576 }
577
578 #[fasync::run_until_stalled(test)]
579 async fn key_press_generates_expected_keyboard_input_report() -> Result<(), Error> {
580 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
581 input_device.key_press(
582 KeyboardReport {
583 pressed_keys: vec![Usages::HidUsageKeyA as u32, Usages::HidUsageKeyB as u32],
584 },
585 DEFAULT_REPORT_TIMESTAMP,
586 )?;
587
588 let input_reports = get_input_reports(input_device, input_device_proxy).await;
589 assert_eq!(
590 input_reports.as_slice(),
591 [InputReport {
592 event_time: Some(
593 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
594 ),
595 keyboard: Some(KeyboardInputReport {
596 pressed_keys3: Some(vec![Key::A, Key::B]),
597 ..Default::default()
598 }),
599 ..Default::default()
600 }]
601 );
602 Ok(())
603 }
604
605 #[fasync::run_until_stalled(test)]
606 async fn key_press_usage_generates_expected_keyboard_input_report_for_some(
607 ) -> Result<(), Error> {
608 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
609 input_device
610 .key_press_usage(Some(Usages::HidUsageKeyA as u32), DEFAULT_REPORT_TIMESTAMP)?;
611
612 let input_reports = get_input_reports(input_device, input_device_proxy).await;
613 assert_eq!(
614 input_reports.as_slice(),
615 [InputReport {
616 event_time: Some(
617 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
618 ),
619 keyboard: Some(KeyboardInputReport {
620 pressed_keys3: Some(vec![Key::A]),
621 ..Default::default()
622 }),
623 ..Default::default()
624 }]
625 );
626 Ok(())
627 }
628
629 #[fasync::run_until_stalled(test)]
630 async fn key_press_usage_generates_expected_keyboard_input_report_for_none(
631 ) -> Result<(), Error> {
632 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
633 input_device.key_press_usage(None, DEFAULT_REPORT_TIMESTAMP)?;
634
635 let input_reports = get_input_reports(input_device, input_device_proxy).await;
636 assert_eq!(
637 input_reports.as_slice(),
638 [InputReport {
639 event_time: Some(
640 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
641 ),
642 keyboard: Some(KeyboardInputReport {
643 pressed_keys3: Some(vec![]),
644 ..Default::default()
645 }),
646 ..Default::default()
647 }]
648 );
649 Ok(())
650 }
651
652 #[fasync::run_until_stalled(test)]
653 async fn key_press_returns_error_if_usage_cannot_be_mapped_to_key() {
654 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
655 assert_matches!(
656 input_device.key_press(
657 KeyboardReport { pressed_keys: vec![0xffff_ffff] },
658 DEFAULT_REPORT_TIMESTAMP
659 ),
660 Err(_)
661 );
662 }
663
664 #[fasync::run_until_stalled(test)]
665 async fn key_press_usage_returns_error_if_usage_cannot_be_mapped_to_key() {
666 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
667 assert_matches!(
668 input_device.key_press_usage(Some(0xffff_ffff), DEFAULT_REPORT_TIMESTAMP),
669 Err(_)
670 );
671 }
672
673 #[fasync::run_until_stalled(test)]
674 async fn key_events_generates_expected_keyboard_response() -> Result<(), Error> {
675 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
676 input_device.key_press_raw(
677 KeyboardReport {
678 pressed_keys: vec![Key::A.into_primitive(), Key::B.into_primitive()],
679 },
680 DEFAULT_REPORT_TIMESTAMP,
681 )?;
682
683 let input_reports = get_input_reports(input_device, _input_device_proxy).await;
684 assert_eq!(
685 input_reports.as_slice(),
686 [InputReport {
687 event_time: Some(
688 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
689 ),
690 keyboard: Some(KeyboardInputReport {
691 pressed_keys3: Some(vec![Key::A, Key::B]),
692 ..Default::default()
693 }),
694 ..Default::default()
695 }]
696 );
697 Ok(())
698 }
699
700 #[fasync::run_until_stalled(test)]
701 async fn tap_generates_expected_report_for_some() -> Result<(), Error> {
702 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
703 input_device.tap(Some((10, 20)), DEFAULT_REPORT_TIMESTAMP)?;
704
705 let input_reports = get_input_reports(input_device, _input_device_proxy).await;
706 assert_eq!(
707 input_reports.as_slice(),
708 [InputReport {
709 event_time: Some(
710 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
711 ),
712 touch: Some(TouchInputReport {
713 contacts: Some(vec![ContactInputReport {
714 contact_id: Some(1),
715 position_x: Some(10),
716 position_y: Some(20),
717 pressure: None,
718 contact_width: Some(0),
719 contact_height: Some(0),
720 ..Default::default()
721 }]),
722 pressed_buttons: Some(vec![]),
723 ..Default::default()
724 }),
725 ..Default::default()
726 }]
727 );
728 Ok(())
729 }
730
731 #[fasync::run_until_stalled(test)]
732 async fn tap_generates_expected_report_for_none() -> Result<(), Error> {
733 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
734 input_device.tap(None, DEFAULT_REPORT_TIMESTAMP)?;
735
736 let input_reports = get_input_reports(input_device, _input_device_proxy).await;
737 assert_eq!(
738 input_reports.as_slice(),
739 [InputReport {
740 event_time: Some(
741 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
742 ),
743 touch: Some(TouchInputReport {
744 contacts: Some(vec![]),
745 pressed_buttons: Some(vec![]),
746 ..Default::default()
747 }),
748 ..Default::default()
749 }]
750 );
751 Ok(())
752 }
753
754 #[fasync::run_until_stalled(test)]
755 async fn multi_finger_tap_generates_report_for_single_finger() -> Result<(), Error> {
756 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
757 input_device.multi_finger_tap(
758 Some(vec![Touch { finger_id: 5, x: 10, y: 20, width: 100, height: 200 }]),
759 DEFAULT_REPORT_TIMESTAMP,
760 )?;
761
762 let input_reports = get_input_reports(input_device, _input_device_proxy).await;
763 assert_eq!(
764 input_reports.as_slice(),
765 [InputReport {
766 event_time: Some(
767 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
768 ),
769 touch: Some(TouchInputReport {
770 contacts: Some(vec![ContactInputReport {
771 contact_id: Some(5),
772 position_x: Some(10),
773 position_y: Some(20),
774 pressure: None,
775 contact_width: Some(100),
776 contact_height: Some(200),
777 ..Default::default()
778 }]),
779 pressed_buttons: Some(vec![]),
780 ..Default::default()
781 }),
782 ..Default::default()
783 }]
784 );
785 Ok(())
786 }
787
788 #[fasync::run_until_stalled(test)]
789 async fn multi_finger_tap_generates_expected_report_for_two_fingers() -> Result<(), Error> {
790 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
791 input_device.multi_finger_tap(
792 Some(vec![
793 Touch { finger_id: 5, x: 10, y: 20, width: 100, height: 200 },
794 Touch { finger_id: 0, x: 30, y: 40, width: 300, height: 400 },
795 ]),
796 DEFAULT_REPORT_TIMESTAMP,
797 )?;
798
799 let input_reports = get_input_reports(input_device, _input_device_proxy).await;
800 assert_eq!(
801 input_reports.as_slice(),
802 [InputReport {
803 event_time: Some(
804 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
805 ),
806 touch: Some(TouchInputReport {
807 contacts: Some(vec![
808 ContactInputReport {
809 contact_id: Some(5),
810 position_x: Some(10),
811 position_y: Some(20),
812 pressure: None,
813 contact_width: Some(100),
814 contact_height: Some(200),
815 ..Default::default()
816 },
817 ContactInputReport {
818 contact_id: Some(0),
819 position_x: Some(30),
820 position_y: Some(40),
821 pressure: None,
822 contact_width: Some(300),
823 contact_height: Some(400),
824 ..Default::default()
825 }
826 ]),
827 pressed_buttons: Some(vec![]),
828 ..Default::default()
829 }),
830 ..Default::default()
831 }]
832 );
833 Ok(())
834 }
835
836 #[fasync::run_until_stalled(test)]
837 async fn multi_finger_tap_generates_expected_report_for_zero_fingers() -> Result<(), Error>
838 {
839 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
840 input_device.multi_finger_tap(Some(vec![]), DEFAULT_REPORT_TIMESTAMP)?;
841
842 let input_reports = get_input_reports(input_device, _input_device_proxy).await;
843 assert_eq!(
844 input_reports.as_slice(),
845 [InputReport {
846 event_time: Some(
847 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
848 ),
849 touch: Some(TouchInputReport {
850 contacts: Some(vec![]),
851 pressed_buttons: Some(vec![]),
852 ..Default::default()
853 }),
854 ..Default::default()
855 }]
856 );
857 Ok(())
858 }
859
860 #[fasync::run_until_stalled(test)]
861 async fn multi_finger_tap_generates_expected_report_for_none() -> Result<(), Error> {
862 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
863 input_device.multi_finger_tap(None, DEFAULT_REPORT_TIMESTAMP)?;
864
865 let input_reports = get_input_reports(input_device, _input_device_proxy).await;
866 assert_eq!(
867 input_reports.as_slice(),
868 [InputReport {
869 event_time: Some(
870 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
871 ),
872 touch: Some(TouchInputReport {
873 contacts: Some(vec![]),
874 pressed_buttons: Some(vec![]),
875 ..Default::default()
876 }),
877 ..Default::default()
878 }]
879 );
880 Ok(())
881 }
882
883 #[fasync::run_until_stalled(test)]
884 async fn multi_finger_tap_returns_error_when_num_fingers_is_to_large() {
885 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
886 assert_matches!(
887 input_device.multi_finger_tap(
888 Some(
889 (0..=TOUCH_MAX_CONTACTS)
890 .map(|i| Touch {
891 finger_id: i,
892 x: i as i32,
893 y: i as i32,
894 width: i,
895 height: i
896 })
897 .collect(),
898 ),
899 DEFAULT_REPORT_TIMESTAMP,
900 ),
901 Err(_)
902 );
903 }
904
905 #[fasync::run_until_stalled(test)]
906 async fn mouse_generates_empty_mouse_input_report() -> Result<(), Error> {
907 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
908 input_device.mouse(MouseInputReport::default(), DEFAULT_REPORT_TIMESTAMP)?;
909
910 let input_reports = get_input_reports(input_device, input_device_proxy).await;
911 assert_eq!(
912 input_reports.as_slice(),
913 [InputReport {
914 event_time: Some(
915 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
916 ),
917 mouse: Some(MouseInputReport::default()),
918 ..Default::default()
919 }]
920 );
921 Ok(())
922 }
923
924 #[fasync::run_until_stalled(test)]
925 async fn mouse_generates_full_mouse_input_report() -> Result<(), Error> {
926 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
927 input_device.mouse(
928 MouseInputReport {
929 movement_x: Some(10),
930 movement_y: Some(15),
931 pressed_buttons: Some(vec![1, 2, 3]),
932 scroll_v: Some(1),
933 scroll_h: Some(-1),
934 ..Default::default()
935 },
936 DEFAULT_REPORT_TIMESTAMP,
937 )?;
938
939 let input_reports = get_input_reports(input_device, input_device_proxy).await;
940 assert_eq!(
941 input_reports.as_slice(),
942 [InputReport {
943 event_time: Some(
944 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
945 ),
946 mouse: Some(MouseInputReport {
947 movement_x: Some(10),
948 movement_y: Some(15),
949 pressed_buttons: Some(vec![1, 2, 3]),
950 scroll_v: Some(1),
951 scroll_h: Some(-1),
952 ..Default::default()
953 }),
954 ..Default::default()
955 }]
956 );
957 Ok(())
958 }
959
960 #[fasync::run_until_stalled(test)]
961 async fn mouse_generates_partial_mouse_input_report() -> Result<(), Error> {
962 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
963 input_device.mouse(
964 MouseInputReport {
965 movement_x: Some(10),
966 movement_y: Some(15),
967 pressed_buttons: Some(vec![]),
968 ..Default::default()
969 },
970 DEFAULT_REPORT_TIMESTAMP,
971 )?;
972
973 let input_reports = get_input_reports(input_device, input_device_proxy).await;
974 assert_eq!(
975 input_reports.as_slice(),
976 [InputReport {
977 event_time: Some(
978 DEFAULT_REPORT_TIMESTAMP.try_into().expect("converting to i64")
979 ),
980 mouse: Some(MouseInputReport {
981 movement_x: Some(10),
982 movement_y: Some(15),
983 pressed_buttons: Some(vec![]),
984 ..Default::default()
985 }),
986 ..Default::default()
987 }]
988 );
989 Ok(())
990 }
991 }
992
993 mod future_resolution {
994 use super::utils::{make_input_device_proxy_and_struct, make_input_reports_reader_proxy};
995 use super::*;
996 use futures::task::Poll;
997
998 mod yields_ok_after_all_reports_are_sent_to_input_reports_reader {
999 use super::*;
1000 use assert_matches::assert_matches;
1001
1002 #[test]
1003 fn if_device_request_channel_was_closed() {
1004 let mut executor = fasync::TestExecutor::new();
1005 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1006 let input_reports_reader_proxy =
1007 make_input_reports_reader_proxy(&input_device_proxy);
1008 input_device
1009 .key_press(KeyboardReport { pressed_keys: vec![] }, DEFAULT_REPORT_TIMESTAMP)
1010 .expect("queuing input report");
1011
1012 let _input_reports_fut = input_reports_reader_proxy.read_input_reports();
1013 let mut input_device_fut = input_device.flush();
1014 std::mem::drop(input_device_proxy); assert_matches!(
1016 executor.run_until_stalled(&mut input_device_fut),
1017 Poll::Ready(Ok(()))
1018 );
1019 }
1020
1021 #[test]
1022 fn even_if_device_request_channel_is_open() {
1023 let mut executor = fasync::TestExecutor::new();
1024 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1025 let input_reports_reader_proxy =
1026 make_input_reports_reader_proxy(&input_device_proxy);
1027 input_device
1028 .key_press(KeyboardReport { pressed_keys: vec![] }, DEFAULT_REPORT_TIMESTAMP)
1029 .expect("queuing input report");
1030
1031 let _input_reports_fut = input_reports_reader_proxy.read_input_reports();
1032 let mut input_device_fut = input_device.flush();
1033 assert_matches!(
1034 executor.run_until_stalled(&mut input_device_fut),
1035 Poll::Ready(Ok(()))
1036 );
1037 }
1038
1039 #[test]
1040 fn even_if_reports_was_empty_and_device_request_channel_is_open() {
1041 let mut executor = fasync::TestExecutor::new();
1042 let (input_device_proxy, input_device) = make_input_device_proxy_and_struct();
1043 let input_reports_reader_proxy =
1044 make_input_reports_reader_proxy(&input_device_proxy);
1045 let _input_reports_fut = input_reports_reader_proxy.read_input_reports();
1046 let mut input_device_fut = input_device.flush();
1047 assert_matches!(
1048 executor.run_until_stalled(&mut input_device_fut),
1049 Poll::Ready(Ok(()))
1050 );
1051 }
1052 }
1053
1054 mod yields_err_if_peer_closed_device_channel_without_calling_get_input_reports_reader {
1055 use super::*;
1056 use assert_matches::assert_matches;
1057
1058 #[test]
1059 fn if_reports_were_available() {
1060 let mut executor = fasync::TestExecutor::new();
1061 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1062 input_device
1063 .key_press(KeyboardReport { pressed_keys: vec![] }, DEFAULT_REPORT_TIMESTAMP)
1064 .expect("queuing input report");
1065
1066 let mut input_device_fut = input_device.flush();
1067 std::mem::drop(input_device_proxy);
1068 assert_matches!(
1069 executor.run_until_stalled(&mut input_device_fut),
1070 Poll::Ready(Err(_))
1071 )
1072 }
1073
1074 #[test]
1075 fn even_if_no_reports_were_available() {
1076 let mut executor = fasync::TestExecutor::new();
1077 let (input_device_proxy, input_device) = make_input_device_proxy_and_struct();
1078 let mut input_device_fut = input_device.flush();
1079 std::mem::drop(input_device_proxy);
1080 assert_matches!(
1081 executor.run_until_stalled(&mut input_device_fut),
1082 Poll::Ready(Err(_))
1083 )
1084 }
1085 }
1086
1087 mod is_pending_if_peer_has_device_channel_open_and_has_not_called_get_input_reports_reader {
1088 use super::*;
1089 use assert_matches::assert_matches;
1090
1091 #[test]
1092 fn if_reports_were_available() {
1093 let mut executor = fasync::TestExecutor::new();
1094 let (_input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1095 input_device
1096 .key_press(KeyboardReport { pressed_keys: vec![] }, DEFAULT_REPORT_TIMESTAMP)
1097 .expect("queuing input report");
1098
1099 let mut input_device_fut = input_device.flush();
1100 assert_matches!(executor.run_until_stalled(&mut input_device_fut), Poll::Pending)
1101 }
1102
1103 #[test]
1104 fn even_if_no_reports_were_available() {
1105 let mut executor = fasync::TestExecutor::new();
1106 let (_input_device_proxy, input_device) = make_input_device_proxy_and_struct();
1107 let mut input_device_fut = input_device.flush();
1108 assert_matches!(executor.run_until_stalled(&mut input_device_fut), Poll::Pending)
1109 }
1110
1111 #[test]
1112 fn even_if_get_device_descriptor_has_been_called() {
1113 let mut executor = fasync::TestExecutor::new();
1114 let (input_device_proxy, input_device) = make_input_device_proxy_and_struct();
1115 let mut input_device_fut = input_device.flush();
1116 let _get_descriptor_fut = input_device_proxy.get_descriptor();
1117 assert_matches!(executor.run_until_stalled(&mut input_device_fut), Poll::Pending)
1118 }
1119 }
1120
1121 mod is_pending_if_peer_has_not_read_any_reports_when_a_report_is_available {
1122 use super::*;
1123 use assert_matches::assert_matches;
1124
1125 #[test]
1126 fn if_device_request_channel_is_open() {
1127 let mut executor = fasync::TestExecutor::new();
1128 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1129 let _input_reports_reader_proxy =
1130 make_input_reports_reader_proxy(&input_device_proxy);
1131 input_device
1132 .key_press(KeyboardReport { pressed_keys: vec![] }, DEFAULT_REPORT_TIMESTAMP)
1133 .expect("queuing input report");
1134
1135 let mut input_device_fut = input_device.flush();
1136 assert_matches!(executor.run_until_stalled(&mut input_device_fut), Poll::Pending)
1137 }
1138
1139 #[test]
1140 fn even_if_device_channel_is_closed() {
1141 let mut executor = fasync::TestExecutor::new();
1142 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1143 let _input_reports_reader_proxy =
1144 make_input_reports_reader_proxy(&input_device_proxy);
1145 input_device
1146 .key_press(KeyboardReport { pressed_keys: vec![] }, DEFAULT_REPORT_TIMESTAMP)
1147 .expect("queuing input report");
1148
1149 let mut input_device_fut = input_device.flush();
1150 std::mem::drop(input_device_proxy); assert_matches!(executor.run_until_stalled(&mut input_device_fut), Poll::Pending)
1152 }
1153 }
1154
1155 mod is_pending_if_peer_did_not_read_all_reports {
1156 use super::*;
1157 use assert_matches::assert_matches;
1158 use fidl_fuchsia_input_report::MAX_DEVICE_REPORT_COUNT;
1159
1160 #[test]
1161 fn if_device_request_channel_is_open() {
1162 let mut executor = fasync::TestExecutor::new();
1163 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1164 let input_reports_reader_proxy =
1165 make_input_reports_reader_proxy(&input_device_proxy);
1166 (0..=MAX_DEVICE_REPORT_COUNT).for_each(|_| {
1167 input_device
1168 .key_press(
1169 KeyboardReport { pressed_keys: vec![] },
1170 DEFAULT_REPORT_TIMESTAMP,
1171 )
1172 .expect("queuing input report");
1173 });
1174
1175 let _input_reports_fut = input_reports_reader_proxy.read_input_reports();
1177 let mut input_device_fut = input_device.flush();
1178 assert_matches!(executor.run_until_stalled(&mut input_device_fut), Poll::Pending)
1179 }
1180
1181 #[test]
1182 fn even_if_device_request_channel_is_closed() {
1183 let mut executor = fasync::TestExecutor::new();
1184 let (input_device_proxy, mut input_device) = make_input_device_proxy_and_struct();
1185 let input_reports_reader_proxy =
1186 make_input_reports_reader_proxy(&input_device_proxy);
1187 (0..=MAX_DEVICE_REPORT_COUNT).for_each(|_| {
1188 input_device
1189 .key_press(
1190 KeyboardReport { pressed_keys: vec![] },
1191 DEFAULT_REPORT_TIMESTAMP,
1192 )
1193 .expect("queuing input report");
1194 });
1195
1196 let _input_reports_fut = input_reports_reader_proxy.read_input_reports();
1198 let mut input_device_fut = input_device.flush();
1199 std::mem::drop(input_device_proxy); assert_matches!(executor.run_until_stalled(&mut input_device_fut), Poll::Pending)
1201 }
1202 }
1203 }
1204
1205 mod unsupported_use_cases {
1208 use super::utils::make_input_device_proxy_and_struct;
1209 use super::*;
1210 use assert_matches::assert_matches;
1211
1212 #[fasync::run_until_stalled(test)]
1213 async fn multiple_get_input_reports_reader_requests_yield_error() -> Result<(), Error> {
1214 let (input_device_proxy, input_device) = make_input_device_proxy_and_struct();
1215
1216 let (_input_reports_reader_proxy, input_reports_reader_server_end) =
1217 endpoints::create_proxy::<InputReportsReaderMarker>();
1218 input_device_proxy
1219 .get_input_reports_reader(input_reports_reader_server_end)
1220 .expect("sending first get_input_reports_reader request");
1221
1222 let (_input_reports_reader_proxy, input_reports_reader_server_end) =
1223 endpoints::create_proxy::<InputReportsReaderMarker>();
1224 input_device_proxy
1225 .get_input_reports_reader(input_reports_reader_server_end)
1226 .expect("sending second get_input_reports_reader request");
1227
1228 let input_device_fut = input_device.flush();
1229 assert_matches!(input_device_fut.await, Err(_));
1230 Ok(())
1231 }
1232 }
1233
1234 mod utils {
1235 use super::*;
1236 use fidl_fuchsia_input_report::{InputDeviceProxy, InputReportsReaderProxy};
1237
1238 pub(super) fn make_keyboard_descriptor(keys: Vec<Key>) -> DeviceDescriptor {
1241 DeviceDescriptor {
1242 keyboard: Some(KeyboardDescriptor {
1243 input: Some(KeyboardInputDescriptor {
1244 keys3: Some(keys),
1245 ..Default::default()
1246 }),
1247 ..Default::default()
1248 }),
1249 ..Default::default()
1250 }
1251 }
1252
1253 pub(super) fn make_input_device_proxy_and_struct() -> (InputDeviceProxy, Box<InputDevice>) {
1261 let (input_device_proxy, input_device_request_stream) =
1262 endpoints::create_proxy_and_stream::<InputDeviceMarker>();
1263 let input_device = Box::new(InputDevice::new(
1264 input_device_request_stream,
1265 DeviceDescriptor::default(),
1266 ));
1267 (input_device_proxy, input_device)
1268 }
1269
1270 pub(super) fn make_input_reports_reader_proxy(
1277 input_device_proxy: &InputDeviceProxy,
1278 ) -> InputReportsReaderProxy {
1279 let (input_reports_reader_proxy, input_reports_reader_server_end) =
1280 endpoints::create_proxy::<InputReportsReaderMarker>();
1281 input_device_proxy
1282 .get_input_reports_reader(input_reports_reader_server_end)
1283 .expect("sending get_input_reports_reader request");
1284 input_reports_reader_proxy
1285 }
1286
1287 pub(super) async fn get_input_reports(
1295 input_device: Box<InputDevice>,
1296 input_device_proxy: InputDeviceProxy,
1297 ) -> Vec<InputReport> {
1298 let input_reports_reader_proxy = make_input_reports_reader_proxy(&input_device_proxy);
1299 let input_device_server_fut = input_device.flush();
1300 let input_reports_fut = input_reports_reader_proxy.read_input_reports();
1301 std::mem::drop(input_reports_reader_proxy); std::mem::drop(input_device_proxy); future::join(input_device_server_fut, input_reports_fut)
1304 .await
1305 .1
1306 .expect("fidl error")
1307 .map_err(zx::Status::from_raw)
1308 .expect("service error")
1309 }
1310 }
1311}