1use super::gesture_arena::{
6 self, DetailedReasonFloat, DetailedReasonInt, DetailedReasonUint, ExamineEventResult,
7 ProcessBufferedEventsResult, Reason, RecognizedGesture, TouchpadEvent, VerifyEventResult,
8 PRIMARY_BUTTON,
9};
10use crate::mouse_binding::{MouseEvent, MouseLocation, MousePhase, RelativeLocation};
11use crate::utils::{euclidean_distance, Position};
12
13use maplit::hashset;
14
15#[derive(Debug)]
17pub(super) struct InitialContender {
18 pub(super) max_finger_displacement_in_mm: f32,
21
22 pub(super) max_time_elapsed: zx::MonotonicDuration,
25}
26
27impl InitialContender {
28 #[allow(clippy::boxed_local, reason = "mass allow for https://fxbug.dev/381896734")]
29 fn into_finger_contact_contender(
30 self: Box<Self>,
31 finger_down_event: TouchpadEvent,
32 ) -> Box<dyn gesture_arena::Contender> {
33 Box::new(FingerContactContender {
34 max_finger_displacement_in_mm: self.max_finger_displacement_in_mm,
35 max_time_elapsed: self.max_time_elapsed,
36 finger_down_event,
37 })
38 }
39}
40
41impl gesture_arena::Contender for InitialContender {
42 fn examine_event(self: Box<Self>, event: &TouchpadEvent) -> ExamineEventResult {
43 let num_contacts = event.contacts.len();
44 if num_contacts != 1 {
45 return ExamineEventResult::Mismatch(Reason::DetailedUint(DetailedReasonUint {
46 criterion: "num_contacts",
47 min: Some(1),
48 max: Some(1),
49 actual: num_contacts,
50 }));
51 }
52
53 let num_pressed_buttons = event.pressed_buttons.len();
54 match num_pressed_buttons {
55 0 => ExamineEventResult::Contender(self.into_finger_contact_contender(event.clone())),
56 _ => ExamineEventResult::Mismatch(Reason::DetailedUint(DetailedReasonUint {
57 criterion: "num_pressed_buttons",
58 min: Some(0),
59 max: Some(0),
60 actual: num_pressed_buttons,
61 })),
62 }
63 }
64
65 fn start_from_idle(&self) -> bool {
66 true
67 }
68}
69
70#[derive(Debug)]
72struct FingerContactContender {
73 max_finger_displacement_in_mm: f32,
76
77 max_time_elapsed: zx::MonotonicDuration,
80
81 finger_down_event: TouchpadEvent,
83}
84
85impl FingerContactContender {
86 #[allow(clippy::boxed_local, reason = "mass allow for https://fxbug.dev/381896734")]
87 fn into_matched_contender(
88 self: Box<Self>,
89 finger_up_event: TouchpadEvent,
90 ) -> Box<dyn gesture_arena::MatchedContender> {
91 Box::new(MatchedContender {
92 finger_down_event: self.finger_down_event,
93 finger_up_event,
94 max_time_elapsed: self.max_time_elapsed,
95 })
96 }
97}
98
99impl gesture_arena::Contender for FingerContactContender {
100 fn examine_event(self: Box<Self>, event: &TouchpadEvent) -> ExamineEventResult {
101 let elapsed_time = event.timestamp - self.finger_down_event.timestamp;
102 if elapsed_time >= self.max_time_elapsed {
103 return ExamineEventResult::Mismatch(Reason::DetailedInt(DetailedReasonInt {
104 criterion: "elapsed_time_micros",
105 min: None,
106 max: Some(self.max_time_elapsed.into_micros()),
107 actual: elapsed_time.into_micros(),
108 }));
109 }
110
111 let num_pressed_buttons = event.pressed_buttons.len();
112 if num_pressed_buttons != 0 {
113 return ExamineEventResult::Mismatch(Reason::DetailedUint(DetailedReasonUint {
114 criterion: "num_pressed_buttons",
115 min: Some(0),
116 max: Some(0),
117 actual: num_pressed_buttons,
118 }));
119 }
120
121 let num_contacts = event.contacts.len();
122 match num_contacts {
123 0 => ExamineEventResult::MatchedContender(self.into_matched_contender(event.clone())),
124 1 => {
125 let displacement_mm = euclidean_distance(
126 position_from_event(event),
127 position_from_event(&self.finger_down_event),
128 );
129 if displacement_mm >= self.max_finger_displacement_in_mm {
130 return ExamineEventResult::Mismatch(Reason::DetailedFloat(
131 DetailedReasonFloat {
132 criterion: "displacement_mm",
133 min: None,
134 max: Some(self.max_finger_displacement_in_mm),
135 actual: displacement_mm,
136 },
137 ));
138 }
139 ExamineEventResult::Contender(self)
140 }
141 _ => ExamineEventResult::Mismatch(Reason::DetailedUint(DetailedReasonUint {
142 criterion: "num_contacts",
143 min: Some(0),
144 max: Some(1),
145 actual: num_contacts,
146 })),
147 }
148 }
149}
150
151#[derive(Debug)]
154struct MatchedContender {
155 finger_down_event: TouchpadEvent,
157
158 finger_up_event: TouchpadEvent,
160
161 max_time_elapsed: zx::MonotonicDuration,
164}
165
166impl gesture_arena::MatchedContender for MatchedContender {
167 fn verify_event(self: Box<Self>, event: &TouchpadEvent) -> VerifyEventResult {
168 let elapsed_time = event.timestamp - self.finger_down_event.timestamp;
169 if elapsed_time >= self.max_time_elapsed {
170 return VerifyEventResult::Mismatch(Reason::DetailedInt(DetailedReasonInt {
171 criterion: "elapsed_time_micros",
172 min: None,
173 max: Some(self.max_time_elapsed.into_micros()),
174 actual: elapsed_time.into_micros(),
175 }));
176 }
177
178 let num_contacts = event.contacts.len();
179 if num_contacts != 0 {
180 return VerifyEventResult::Mismatch(Reason::DetailedUint(DetailedReasonUint {
181 criterion: "num_contacts",
182 min: Some(0),
183 max: Some(0),
184 actual: num_contacts,
185 }));
186 }
187
188 let num_pressed_buttons = event.pressed_buttons.len();
189 if num_pressed_buttons != 0 {
190 return VerifyEventResult::Mismatch(Reason::DetailedUint(DetailedReasonUint {
191 criterion: "num_pressed_buttons",
192 min: Some(0),
193 max: Some(0),
194 actual: num_pressed_buttons,
195 }));
196 }
197
198 VerifyEventResult::MatchedContender(self)
199 }
200
201 fn process_buffered_events(
202 self: Box<Self>,
203 _events: Vec<TouchpadEvent>,
204 ) -> ProcessBufferedEventsResult {
205 ProcessBufferedEventsResult {
206 generated_events: vec![
207 gesture_arena::MouseEvent {
208 timestamp: self.finger_down_event.timestamp,
209 mouse_data: MouseEvent {
210 location: MouseLocation::Relative(RelativeLocation {
211 millimeters: Position::zero(),
212 }),
213 wheel_delta_v: None,
214 wheel_delta_h: None,
215 phase: MousePhase::Down,
216 affected_buttons: hashset! {PRIMARY_BUTTON},
217 pressed_buttons: hashset! {PRIMARY_BUTTON},
218 is_precision_scroll: None,
219 },
220 },
221 gesture_arena::MouseEvent {
222 timestamp: self.finger_up_event.timestamp,
223 mouse_data: MouseEvent {
224 location: MouseLocation::Relative(RelativeLocation {
225 millimeters: Position::zero(),
226 }),
227 wheel_delta_v: None,
228 wheel_delta_h: None,
229 phase: MousePhase::Up,
230 affected_buttons: hashset! {PRIMARY_BUTTON},
231 pressed_buttons: hashset! {},
232 is_precision_scroll: None,
233 },
234 },
235 ],
236 winner: None,
237 recognized_gesture: RecognizedGesture::PrimaryTap,
238 }
239 }
240}
241
242fn position_from_event(event: &TouchpadEvent) -> Position {
245 event.contacts[0].position
246}
247
248#[cfg(test)]
249mod tests {
250 use super::*;
251 use crate::gestures::gesture_arena::{Contender, MatchedContender as _};
252 use crate::testing_utilities::create_touch_contact;
253 use assert_matches::assert_matches;
254 use std::any::TypeId;
255
256 const MAX_TIME_ELAPSED: zx::MonotonicDuration = zx::MonotonicDuration::from_nanos(10000);
257 const MAX_FINGER_DISPLACEMENT_IN_MM: f32 = 10.0;
258 const HALF_MOTION: f32 = MAX_FINGER_DISPLACEMENT_IN_MM / 2.0;
259
260 fn assert_finger_down_contender(result: ExamineEventResult) {
261 match result {
262 ExamineEventResult::Contender(boxed) => {
263 assert_eq!((&*boxed).as_any().type_id(), TypeId::of::<FingerContactContender>());
264 }
265 other => panic!("Expected a Contender but found {:?}", other),
266 }
267 }
268
269 fn assert_examined_matched_contender(result: ExamineEventResult) {
270 match result {
271 ExamineEventResult::MatchedContender(boxed) => {
272 assert_eq!((&*boxed).as_any().type_id(), TypeId::of::<MatchedContender>());
273 }
274 other => panic!("Expected a MatchedContender but found {:?}", other),
275 }
276 }
277
278 fn assert_verified_matched_contender(result: VerifyEventResult) {
279 match result {
280 VerifyEventResult::MatchedContender(boxed) => {
281 assert_eq!((&*boxed).as_any().type_id(), TypeId::of::<MatchedContender>());
282 }
283 other => panic!("Expected a MatchedContender but found {:?}", other),
284 }
285 }
286
287 #[fuchsia::test]
290 fn contender_no_touch_contacts() {
291 assert_matches!(
292 Box::new(InitialContender {
293 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
294 max_time_elapsed: MAX_TIME_ELAPSED
295 })
296 .examine_event(&TouchpadEvent {
297 contacts: vec![],
298 timestamp: zx::MonotonicInstant::from_nanos(0),
299 pressed_buttons: vec![],
300 filtered_palm_contacts: vec![],
301 }),
302 ExamineEventResult::Mismatch(_)
303 );
304 }
305
306 #[fuchsia::test]
309 fn contender_many_touch_contacts() {
310 assert_matches!(
311 Box::new(InitialContender {
312 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
313 max_time_elapsed: MAX_TIME_ELAPSED
314 })
315 .examine_event(&TouchpadEvent {
316 contacts: vec![
317 create_touch_contact(0, Position::zero()),
318 create_touch_contact(1, Position::zero())
319 ],
320 timestamp: zx::MonotonicInstant::from_nanos(0),
321 pressed_buttons: vec![],
322 filtered_palm_contacts: vec![],
323 }),
324 ExamineEventResult::Mismatch(_)
325 );
326 }
327
328 #[fuchsia::test]
331 fn contender_single_button() {
332 assert_matches!(
333 Box::new(InitialContender {
334 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
335 max_time_elapsed: MAX_TIME_ELAPSED
336 })
337 .examine_event(&TouchpadEvent {
338 contacts: vec![create_touch_contact(0, Position::zero())],
339 timestamp: zx::MonotonicInstant::from_nanos(0),
340 pressed_buttons: vec![0],
341 filtered_palm_contacts: vec![],
342 },),
343 ExamineEventResult::Mismatch(_)
344 );
345 }
346
347 #[fuchsia::test]
350 fn contender_many_buttons() {
351 assert_matches!(
352 Box::new(InitialContender {
353 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
354 max_time_elapsed: MAX_TIME_ELAPSED
355 })
356 .examine_event(&TouchpadEvent {
357 contacts: vec![create_touch_contact(0, Position::zero())],
358 timestamp: zx::MonotonicInstant::from_nanos(0),
359 pressed_buttons: vec![0, 1],
360 filtered_palm_contacts: vec![],
361 },),
362 ExamineEventResult::Mismatch(_)
363 );
364 }
365
366 #[fuchsia::test]
369 fn contender_no_buttons() {
370 assert_finger_down_contender(
371 Box::new(InitialContender {
372 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
373 max_time_elapsed: MAX_TIME_ELAPSED,
374 })
375 .examine_event(&TouchpadEvent {
376 contacts: vec![create_touch_contact(0, Position::zero())],
377 timestamp: zx::MonotonicInstant::from_nanos(0),
378 pressed_buttons: vec![],
379 filtered_palm_contacts: vec![],
380 }),
381 );
382 }
383
384 #[fuchsia::test]
387 fn finger_down_contender_too_long() {
388 assert_matches!(
389 Box::new(FingerContactContender {
390 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
391 max_time_elapsed: MAX_TIME_ELAPSED,
392 finger_down_event: TouchpadEvent {
393 contacts: vec![create_touch_contact(0, Position::zero())],
394 timestamp: zx::MonotonicInstant::from_nanos(0),
395 pressed_buttons: vec![],
396 filtered_palm_contacts: vec![],
397 },
398 })
399 .examine_event(&TouchpadEvent {
400 contacts: vec![],
401 timestamp: MAX_TIME_ELAPSED + zx::MonotonicInstant::from_nanos(1),
402 pressed_buttons: vec![],
403 filtered_palm_contacts: vec![],
404 }),
405 ExamineEventResult::Mismatch(_)
406 );
407 }
408
409 #[fuchsia::test]
412 fn finger_down_contender_no_touch_contacts() {
413 assert_examined_matched_contender(
414 Box::new(FingerContactContender {
415 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
416 max_time_elapsed: MAX_TIME_ELAPSED,
417 finger_down_event: TouchpadEvent {
418 contacts: vec![create_touch_contact(0, Position::zero())],
419 timestamp: zx::MonotonicInstant::from_nanos(0),
420 pressed_buttons: vec![],
421 filtered_palm_contacts: vec![],
422 },
423 })
424 .examine_event(&TouchpadEvent {
425 contacts: vec![],
426 timestamp: zx::MonotonicInstant::from_nanos(0),
427 pressed_buttons: vec![],
428 filtered_palm_contacts: vec![],
429 }),
430 );
431 }
432
433 #[fuchsia::test]
436 fn finger_down_contender_many_touch_contacts() {
437 assert_matches!(
438 Box::new(FingerContactContender {
439 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
440 max_time_elapsed: MAX_TIME_ELAPSED,
441 finger_down_event: TouchpadEvent {
442 contacts: vec![create_touch_contact(0, Position::zero())],
443 timestamp: zx::MonotonicInstant::from_nanos(0),
444 pressed_buttons: vec![],
445 filtered_palm_contacts: vec![],
446 },
447 })
448 .examine_event(&TouchpadEvent {
449 contacts: vec![
450 create_touch_contact(0, Position::zero()),
451 create_touch_contact(1, Position::zero())
452 ],
453 timestamp: zx::MonotonicInstant::from_nanos(0),
454 pressed_buttons: vec![],
455 filtered_palm_contacts: vec![],
456 }),
457 ExamineEventResult::Mismatch(_)
458 );
459 }
460
461 #[fuchsia::test]
464 fn finger_down_contender_large_displacement() {
465 assert_matches!(
466 Box::new(FingerContactContender {
467 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
468 max_time_elapsed: MAX_TIME_ELAPSED,
469 finger_down_event: TouchpadEvent {
470 contacts: vec![create_touch_contact(0, Position::zero())],
471 timestamp: zx::MonotonicInstant::from_nanos(0),
472 pressed_buttons: vec![],
473 filtered_palm_contacts: vec![],
474 },
475 })
476 .examine_event(&TouchpadEvent {
477 contacts: vec![create_touch_contact(
478 0,
479 Position { x: MAX_FINGER_DISPLACEMENT_IN_MM, y: MAX_FINGER_DISPLACEMENT_IN_MM }
480 )],
481 timestamp: zx::MonotonicInstant::from_nanos(0),
482 pressed_buttons: vec![],
483 filtered_palm_contacts: vec![],
484 }),
485 ExamineEventResult::Mismatch(_)
486 );
487 }
488
489 #[fuchsia::test]
493 fn finger_down_contender_no_buttons_no_displacement() {
494 assert_finger_down_contender(
495 Box::new(FingerContactContender {
496 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
497 max_time_elapsed: MAX_TIME_ELAPSED,
498 finger_down_event: TouchpadEvent {
499 contacts: vec![create_touch_contact(0, Position::zero())],
500 timestamp: zx::MonotonicInstant::from_nanos(0),
501 pressed_buttons: vec![],
502 filtered_palm_contacts: vec![],
503 },
504 })
505 .examine_event(&TouchpadEvent {
506 contacts: vec![create_touch_contact(0, Position::zero())],
507 timestamp: zx::MonotonicInstant::from_nanos(0),
508 pressed_buttons: vec![],
509 filtered_palm_contacts: vec![],
510 }),
511 );
512 }
513
514 #[fuchsia::test]
518 fn finger_down_contender_no_buttons_some_displacement() {
519 assert_finger_down_contender(
520 Box::new(FingerContactContender {
521 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
522 max_time_elapsed: MAX_TIME_ELAPSED,
523 finger_down_event: TouchpadEvent {
524 contacts: vec![create_touch_contact(0, Position::zero())],
525 timestamp: zx::MonotonicInstant::from_nanos(0),
526 pressed_buttons: vec![],
527 filtered_palm_contacts: vec![],
528 },
529 })
530 .examine_event(&TouchpadEvent {
531 contacts: vec![create_touch_contact(
532 0,
533 Position { x: HALF_MOTION, y: HALF_MOTION },
534 )],
535 timestamp: zx::MonotonicInstant::from_nanos(0),
536 pressed_buttons: vec![],
537 filtered_palm_contacts: vec![],
538 }),
539 );
540 }
541
542 #[fuchsia::test]
546 fn finger_down_contender_single_button() {
547 assert_matches!(
548 Box::new(FingerContactContender {
549 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
550 max_time_elapsed: MAX_TIME_ELAPSED,
551 finger_down_event: TouchpadEvent {
552 contacts: vec![create_touch_contact(0, Position::zero())],
553 timestamp: zx::MonotonicInstant::from_nanos(0),
554 pressed_buttons: vec![],
555 filtered_palm_contacts: vec![],
556 },
557 })
558 .examine_event(&TouchpadEvent {
559 contacts: vec![create_touch_contact(
560 0,
561 Position { x: HALF_MOTION, y: HALF_MOTION }
562 )],
563 timestamp: zx::MonotonicInstant::from_nanos(0),
564 pressed_buttons: vec![0],
565 filtered_palm_contacts: vec![],
566 }),
567 ExamineEventResult::Mismatch(_)
568 );
569 }
570
571 #[fuchsia::test]
575 fn finger_down_contender_many_buttons() {
576 assert_matches!(
577 Box::new(FingerContactContender {
578 max_finger_displacement_in_mm: MAX_FINGER_DISPLACEMENT_IN_MM,
579 max_time_elapsed: MAX_TIME_ELAPSED,
580 finger_down_event: TouchpadEvent {
581 contacts: vec![create_touch_contact(0, Position::zero())],
582 timestamp: zx::MonotonicInstant::from_nanos(0),
583 pressed_buttons: vec![],
584 filtered_palm_contacts: vec![],
585 },
586 })
587 .examine_event(&TouchpadEvent {
588 contacts: vec![create_touch_contact(
589 0,
590 Position { x: HALF_MOTION, y: HALF_MOTION }
591 )],
592 timestamp: zx::MonotonicInstant::from_nanos(0),
593 pressed_buttons: vec![0, 1],
594 filtered_palm_contacts: vec![],
595 }),
596 ExamineEventResult::Mismatch(_)
597 );
598 }
599
600 #[fuchsia::test]
602 fn matched_contender_one_button() {
603 assert_matches!(
604 Box::new(MatchedContender {
605 finger_down_event: TouchpadEvent {
606 contacts: vec![create_touch_contact(0, Position::zero())],
607 timestamp: zx::MonotonicInstant::from_nanos(0),
608 pressed_buttons: vec![],
609 filtered_palm_contacts: vec![],
610 },
611 finger_up_event: TouchpadEvent {
612 contacts: vec![],
613 timestamp: zx::MonotonicInstant::from_nanos(0),
614 pressed_buttons: vec![],
615 filtered_palm_contacts: vec![],
616 },
617 max_time_elapsed: MAX_TIME_ELAPSED,
618 })
619 .verify_event(&TouchpadEvent {
620 contacts: vec![],
621 timestamp: zx::MonotonicInstant::from_nanos(0),
622 pressed_buttons: vec![0],
623 filtered_palm_contacts: vec![],
624 }),
625 VerifyEventResult::Mismatch(_)
626 );
627 }
628
629 #[fuchsia::test]
632 fn matched_contender_many_buttons() {
633 assert_matches!(
634 Box::new(MatchedContender {
635 finger_down_event: TouchpadEvent {
636 contacts: vec![create_touch_contact(0, Position::zero())],
637 timestamp: zx::MonotonicInstant::from_nanos(0),
638 pressed_buttons: vec![],
639 filtered_palm_contacts: vec![],
640 },
641 finger_up_event: TouchpadEvent {
642 contacts: vec![],
643 timestamp: zx::MonotonicInstant::from_nanos(0),
644 pressed_buttons: vec![],
645 filtered_palm_contacts: vec![],
646 },
647 max_time_elapsed: MAX_TIME_ELAPSED,
648 })
649 .verify_event(&TouchpadEvent {
650 contacts: vec![],
651 timestamp: zx::MonotonicInstant::from_nanos(0),
652 pressed_buttons: vec![0, 1],
653 filtered_palm_contacts: vec![],
654 }),
655 VerifyEventResult::Mismatch(_)
656 );
657 }
658
659 #[fuchsia::test]
661 fn matched_contender_single_touch_contact() {
662 assert_matches!(
663 Box::new(MatchedContender {
664 finger_down_event: TouchpadEvent {
665 contacts: vec![create_touch_contact(0, Position::zero())],
666 timestamp: zx::MonotonicInstant::from_nanos(0),
667 pressed_buttons: vec![],
668 filtered_palm_contacts: vec![],
669 },
670 finger_up_event: TouchpadEvent {
671 contacts: vec![],
672 timestamp: zx::MonotonicInstant::from_nanos(0),
673 pressed_buttons: vec![],
674 filtered_palm_contacts: vec![],
675 },
676 max_time_elapsed: MAX_TIME_ELAPSED,
677 })
678 .verify_event(&TouchpadEvent {
679 contacts: vec![create_touch_contact(0, Position::zero())],
680 timestamp: zx::MonotonicInstant::from_nanos(0),
681 pressed_buttons: vec![],
682 filtered_palm_contacts: vec![],
683 }),
684 VerifyEventResult::Mismatch(_)
685 );
686 }
687
688 #[fuchsia::test]
691 fn matched_contender_many_touch_contacts() {
692 assert_matches!(
693 Box::new(MatchedContender {
694 finger_down_event: TouchpadEvent {
695 contacts: vec![create_touch_contact(0, Position::zero())],
696 timestamp: zx::MonotonicInstant::from_nanos(0),
697 pressed_buttons: vec![0],
698 filtered_palm_contacts: vec![],
699 },
700 finger_up_event: TouchpadEvent {
701 contacts: vec![],
702 timestamp: zx::MonotonicInstant::from_nanos(0),
703 pressed_buttons: vec![],
704 filtered_palm_contacts: vec![],
705 },
706 max_time_elapsed: MAX_TIME_ELAPSED,
707 })
708 .verify_event(&TouchpadEvent {
709 contacts: vec![
710 create_touch_contact(0, Position::zero()),
711 create_touch_contact(1, Position::zero())
712 ],
713 timestamp: zx::MonotonicInstant::from_nanos(0),
714 pressed_buttons: vec![],
715 filtered_palm_contacts: vec![],
716 }),
717 VerifyEventResult::Mismatch(_)
718 );
719 }
720
721 #[fuchsia::test]
724 fn matched_contender_no_contacts_no_buttons_too_long() {
725 assert_matches!(
726 Box::new(MatchedContender {
727 finger_down_event: TouchpadEvent {
728 contacts: vec![create_touch_contact(0, Position::zero())],
729 timestamp: zx::MonotonicInstant::from_nanos(0),
730 pressed_buttons: vec![],
731 filtered_palm_contacts: vec![],
732 },
733 finger_up_event: TouchpadEvent {
734 contacts: vec![],
735 timestamp: zx::MonotonicInstant::from_nanos(0),
736 pressed_buttons: vec![],
737 filtered_palm_contacts: vec![],
738 },
739 max_time_elapsed: MAX_TIME_ELAPSED,
740 })
741 .verify_event(&TouchpadEvent {
742 contacts: vec![],
743 timestamp: MAX_TIME_ELAPSED + zx::MonotonicInstant::from_nanos(1),
744 pressed_buttons: vec![],
745 filtered_palm_contacts: vec![],
746 }),
747 VerifyEventResult::Mismatch(_)
748 );
749 }
750
751 #[fuchsia::test]
754 fn matched_contender_no_contacts_no_buttons() {
755 assert_verified_matched_contender(
756 Box::new(MatchedContender {
757 finger_down_event: TouchpadEvent {
758 contacts: vec![create_touch_contact(0, Position::zero())],
759 timestamp: zx::MonotonicInstant::from_nanos(0),
760 pressed_buttons: vec![],
761 filtered_palm_contacts: vec![],
762 },
763 finger_up_event: TouchpadEvent {
764 contacts: vec![],
765 timestamp: zx::MonotonicInstant::from_nanos(0),
766 pressed_buttons: vec![],
767 filtered_palm_contacts: vec![],
768 },
769 max_time_elapsed: MAX_TIME_ELAPSED,
770 })
771 .verify_event(&TouchpadEvent {
772 contacts: vec![],
773 timestamp: zx::MonotonicInstant::from_nanos(0),
774 pressed_buttons: vec![],
775 filtered_palm_contacts: vec![],
776 }),
777 );
778 }
779
780 #[fuchsia::test]
783 fn matched_contender_process_buffered_events() {
784 let timestamp = zx::MonotonicInstant::from_nanos(0);
785 let ProcessBufferedEventsResult { generated_events, winner, recognized_gesture } =
786 Box::new(MatchedContender {
787 finger_down_event: TouchpadEvent {
788 contacts: vec![create_touch_contact(0, Position::zero())],
789 timestamp,
790 pressed_buttons: vec![],
791 filtered_palm_contacts: vec![],
792 },
793 finger_up_event: TouchpadEvent {
794 contacts: vec![],
795 timestamp,
796 pressed_buttons: vec![],
797 filtered_palm_contacts: vec![],
798 },
799 max_time_elapsed: MAX_TIME_ELAPSED,
800 })
801 .process_buffered_events(vec![]);
802
803 assert_eq!(
804 generated_events,
805 [
806 gesture_arena::MouseEvent {
807 timestamp: timestamp,
808 mouse_data: MouseEvent {
809 location: MouseLocation::Relative(RelativeLocation {
810 millimeters: Position { x: 0.0, y: 0.0 }
811 }),
812 wheel_delta_v: None,
813 wheel_delta_h: None,
814 phase: MousePhase::Down,
815 affected_buttons: hashset! {PRIMARY_BUTTON},
816 pressed_buttons: hashset! {PRIMARY_BUTTON},
817 is_precision_scroll: None,
818 },
819 },
820 gesture_arena::MouseEvent {
821 timestamp: timestamp,
822 mouse_data: MouseEvent {
823 location: MouseLocation::Relative(RelativeLocation {
824 millimeters: Position { x: 0.0, y: 0.0 }
825 }),
826 wheel_delta_v: None,
827 wheel_delta_h: None,
828 phase: MousePhase::Up,
829 affected_buttons: hashset! {PRIMARY_BUTTON},
830 pressed_buttons: hashset! {},
831 is_precision_scroll: None,
832 },
833 }
834 ]
835 );
836 assert_matches!(winner, None);
837 assert_eq!(recognized_gesture, RecognizedGesture::PrimaryTap);
838 }
839}