Unverified Commit 0347c533 authored by xubaolin's avatar xubaolin Committed by GitHub

fix a PlatformView gesture bug (#84257)

parent f43a282f
...@@ -540,20 +540,24 @@ class _AndroidMotionEventConverter { ...@@ -540,20 +540,24 @@ class _AndroidMotionEventConverter {
); );
} }
void handlePointerUpEvent(PointerUpEvent event) { void _remove(int pointer) {
pointerPositions.remove(event.pointer); pointerPositions.remove(pointer);
usedAndroidPointerIds.remove(pointerProperties[event.pointer]!.id); usedAndroidPointerIds.remove(pointerProperties[pointer]!.id);
pointerProperties.remove(event.pointer); pointerProperties.remove(pointer);
if (pointerProperties.isEmpty) { if (pointerProperties.isEmpty) {
downTimeMillis = null; downTimeMillis = null;
} }
} }
void handlePointerUpEvent(PointerUpEvent event) {
_remove(event.pointer);
}
void handlePointerCancelEvent(PointerCancelEvent event) { void handlePointerCancelEvent(PointerCancelEvent event) {
pointerPositions.clear(); // The pointer cancel event is handled like pointer up. Normally,
pointerProperties.clear(); // the difference is that pointer cancel doesn't perform any action,
usedAndroidPointerIds.clear(); // but in this case neither up or cancel perform any action.
downTimeMillis = null; _remove(event.pointer);
} }
AndroidMotionEvent? toAndroidMotionEvent(PointerEvent event) { AndroidMotionEvent? toAndroidMotionEvent(PointerEvent event) {
......
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:fake_async/fake_async.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../services/fake_platform_views.dart'; import '../services/fake_platform_views.dart';
import 'rendering_tester.dart'; import 'rendering_tester.dart';
...@@ -98,6 +100,56 @@ void main() { ...@@ -98,6 +100,56 @@ void main() {
}); });
}, skip: isBrowser); // TODO(yjbanov): fails on Web with obscured stack trace: https://github.com/flutter/flutter/issues/42770 }, skip: isBrowser); // TODO(yjbanov): fails on Web with obscured stack trace: https://github.com/flutter/flutter/issues/42770
// Regression test for https://github.com/flutter/flutter/issues/69431
test('multi-finger touch test', () {
renderer; // Initialize bindings.
final FakeAndroidPlatformViewsController viewsController = FakeAndroidPlatformViewsController();
viewsController.registerViewType('webview');
final AndroidViewController viewController =
PlatformViewsService.initAndroidView(id: 0, viewType: 'webview', layoutDirection: TextDirection.rtl);
final PlatformViewRenderBox platformViewRenderBox = PlatformViewRenderBox(
controller: viewController,
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer(),
),
},
);
layout(platformViewRenderBox);
pumpFrame(phase: EnginePhase.flushSemantics);
viewController.pointTransformer = (Offset offset) => platformViewRenderBox.globalToLocal(offset);
FakeAsync().run((FakeAsync async) {
// Put one pointer down.
ui.window.onPointerDataPacket!(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(ui.PointerChange.add, Offset.zero, pointer: 1, kind: PointerDeviceKind.touch),
_pointerData(ui.PointerChange.down, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
_pointerData(ui.PointerChange.remove, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
]));
async.flushMicrotasks();
// Put another pointer down and then cancel it.
ui.window.onPointerDataPacket!(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(ui.PointerChange.add, Offset.zero, pointer: 2, kind: PointerDeviceKind.touch),
_pointerData(ui.PointerChange.down, const Offset(20, 10), pointer: 2, kind: PointerDeviceKind.touch),
_pointerData(ui.PointerChange.cancel, const Offset(20, 10), pointer: 2, kind: PointerDeviceKind.touch),
]));
async.flushMicrotasks();
// The first pointer can still moving without crashing.
ui.window.onPointerDataPacket!(ui.PointerDataPacket(data: <ui.PointerData>[
_pointerData(ui.PointerChange.add, Offset.zero, pointer: 1, kind: PointerDeviceKind.touch),
_pointerData(ui.PointerChange.move, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
_pointerData(ui.PointerChange.remove, const Offset(10, 10), pointer: 1, kind: PointerDeviceKind.touch),
]));
async.flushMicrotasks();
});
// Passes if no crashes.
});
} }
ui.PointerData _pointerData( ui.PointerData _pointerData(
...@@ -105,8 +157,11 @@ ui.PointerData _pointerData( ...@@ -105,8 +157,11 @@ ui.PointerData _pointerData(
Offset logicalPosition, { Offset logicalPosition, {
int device = 0, int device = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse, PointerDeviceKind kind = PointerDeviceKind.mouse,
int pointer = 0,
}) { }) {
return ui.PointerData( return ui.PointerData(
pointerIdentifier: pointer,
embedderId: pointer,
change: change, change: change,
physicalX: logicalPosition.dx * ui.window.devicePixelRatio, physicalX: logicalPosition.dx * ui.window.devicePixelRatio,
physicalY: logicalPosition.dy * ui.window.devicePixelRatio, physicalY: logicalPosition.dy * ui.window.devicePixelRatio,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment