Fix null event crash in TapGestureRecognizer (#45943)

This commit is contained in:
Tong Mu 2019-12-05 19:33:01 -08:00 committed by Flutter GitHub Bot
parent a2005eaf9a
commit ad20d368ff
2 changed files with 52 additions and 1 deletions

View File

@ -398,6 +398,9 @@ abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecogni
/// If non-null, the recognizer will call [didExceedDeadline] after this
/// amount of time has elapsed since starting to track the primary pointer.
///
/// The [didExceedDeadline] will not be called if the primary pointer is
/// accepted, rejected, or all pointers are up or canceled before [deadline].
final Duration deadline;
/// The maximum distance in logical pixels the gesture is allowed to drift
@ -495,8 +498,11 @@ abstract class PrimaryPointerGestureRecognizer extends OneSequenceGestureRecogni
@override
void acceptGesture(int pointer) {
if (pointer == primaryPointer) {
_stopTimer();
_gestureAccepted = true;
}
}
@override
void rejectGesture(int pointer) {

View File

@ -582,6 +582,51 @@ void main() {
drag.dispose();
});
testGesture('non-primary pointers does not trigger timeout', (GestureTester tester) {
// Regression test for https://github.com/flutter/flutter/issues/43310
// Pointer1 down, pointer2 down, then pointer 1 up, all within the timeout.
// In this way, `BaseTapGestureRecognizer.didExceedDeadline` can be triggered
// after its `_reset`.
final TapGestureRecognizer tap = TapGestureRecognizer();
final List<String> recognized = <String>[];
tap.onTapDown = (_) {
recognized.add('down');
};
tap.onTapUp = (_) {
recognized.add('up');
};
tap.onTap = () {
recognized.add('tap');
};
tap.onTapCancel = () {
recognized.add('cancel');
};
tap.addPointer(down1);
tester.closeArena(down1.pointer);
tap.addPointer(down2);
tester.closeArena(down2.pointer);
expect(recognized, isEmpty);
tester.route(up1);
GestureBinding.instance.gestureArena.sweep(down1.pointer);
expect(recognized, <String>['down', 'up', 'tap']);
recognized.clear();
// If regression happens, the following step will throw error
tester.async.elapse(const Duration(milliseconds: 200));
expect(recognized, isEmpty);
tester.route(up2);
GestureBinding.instance.gestureArena.sweep(down2.pointer);
expect(recognized, isEmpty);
tap.dispose();
});
group('Enforce consistent-button restriction:', () {
// Change buttons during down-up sequence 1
const PointerMoveEvent move1lr = PointerMoveEvent(