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