Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0795adf

Browse files
authored
Fix unexpected pointer change issue and Add test case (#43949)
Fix issue 129765 and Add test case, see issue Fixes flutter/flutter#129765 - [�] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [�] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [�] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [�] I listed at least one issue that this PR fixes in the description above. - [�] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See [testing the engine] for instructions on writing and running engine tests. - [�] I updated/added relevant documentation (doc comments with `///`). - [�] I signed the [CLA]. - [ �] All existing and new tests are passing. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 69675f6 commit 0795adf

File tree

2 files changed

+72
-9
lines changed

2 files changed

+72
-9
lines changed

shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,6 @@ private void addPointerForIndex(
224224
return;
225225
}
226226

227-
long motionEventId = 0;
228-
if (trackMotionEvents) {
229-
MotionEventTracker.MotionEventId trackedEvent = motionEventTracker.track(event);
230-
motionEventId = trackedEvent.getId();
231-
}
232-
233227
int pointerKind = getPointerDeviceTypeForToolType(event.getToolType(pointerIndex));
234228
// We use this in lieu of using event.getRawX and event.getRawY as we wish to support
235229
// earlier versions than API level 29.
@@ -252,7 +246,20 @@ private void addPointerForIndex(
252246
buttons = 0;
253247
}
254248

249+
int panZoomType = -1;
255250
boolean isTrackpadPan = ongoingPans.containsKey(event.getPointerId(pointerIndex));
251+
if (isTrackpadPan) {
252+
panZoomType = getPointerChangeForPanZoom(pointerChange);
253+
if (panZoomType == -1) {
254+
return;
255+
}
256+
}
257+
258+
long motionEventId = 0;
259+
if (trackMotionEvents) {
260+
MotionEventTracker.MotionEventId trackedEvent = motionEventTracker.track(event);
261+
motionEventId = trackedEvent.getId();
262+
}
256263

257264
int signalKind =
258265
event.getActionMasked() == MotionEvent.ACTION_SCROLL
@@ -264,7 +271,7 @@ private void addPointerForIndex(
264271
packet.putLong(motionEventId); // motionEventId
265272
packet.putLong(timeStamp); // time_stamp
266273
if (isTrackpadPan) {
267-
packet.putLong(getPointerChangeForPanZoom(pointerChange)); // change
274+
packet.putLong(panZoomType); // change
268275
packet.putLong(PointerDeviceKind.TRACKPAD); // kind
269276
} else {
270277
packet.putLong(pointerChange); // change
@@ -355,7 +362,7 @@ private void addPointerForIndex(
355362
packet.putDouble(1.0); // scale
356363
packet.putDouble(0.0); // rotation
357364

358-
if (isTrackpadPan && getPointerChangeForPanZoom(pointerChange) == PointerChange.PAN_ZOOM_END) {
365+
if (isTrackpadPan && (panZoomType == PointerChange.PAN_ZOOM_END)) {
359366
ongoingPans.remove(event.getPointerId(pointerIndex));
360367
}
361368
}
@@ -401,7 +408,7 @@ private int getPointerChangeForPanZoom(int pointerChange) {
401408
} else if (pointerChange == PointerChange.UP || pointerChange == PointerChange.CANCEL) {
402409
return PointerChange.PAN_ZOOM_END;
403410
}
404-
throw new AssertionError("Unexpected pointer change");
411+
return -1;
405412
}
406413

407414
@PointerDeviceKind

shell/platform/android/test/io/flutter/embedding/android/AndroidTouchProcessorTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ MotionEvent mockEvent(int action, float x, float y, int buttonState) {
8989
when(event.getX(0)).thenReturn(x);
9090
when(event.getY(0)).thenReturn(y);
9191
when(event.getToolType(0)).thenReturn(toolType);
92+
when(event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)).thenReturn(true);
9293
return event;
9394
}
9495
}
@@ -218,4 +219,59 @@ public void unexpectedMaskedAction() {
218219
touchProcessor.onTouchEvent(mocker.mockEvent(MotionEvent.ACTION_BUTTON_PRESS, 0.0f, 0.0f, 0));
219220
verify(mockRenderer, never()).dispatchPointerDataPacket(ByteBuffer.allocate(0), 0);
220221
}
222+
223+
@Test
224+
public void unexpectedPointerChange() {
225+
// Regression test for https://github.com/flutter/flutter/issues/129765
226+
227+
MotionEventMocker mocker =
228+
new MotionEventMocker(0, InputDevice.SOURCE_MOUSE, MotionEvent.TOOL_TYPE_MOUSE);
229+
230+
touchProcessor.onTouchEvent(mocker.mockEvent(MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0));
231+
InOrder inOrder = inOrder(mockRenderer);
232+
inOrder
233+
.verify(mockRenderer)
234+
.dispatchPointerDataPacket(packetCaptor.capture(), packetSizeCaptor.capture());
235+
ByteBuffer packet = packetCaptor.getValue();
236+
assertEquals(AndroidTouchProcessor.PointerChange.PAN_ZOOM_START, readPointerChange(packet));
237+
assertEquals(AndroidTouchProcessor.PointerDeviceKind.TRACKPAD, readPointerDeviceKind(packet));
238+
assertEquals(AndroidTouchProcessor.PointerSignalKind.NONE, readPointerSignalKind(packet));
239+
assertEquals(0.0, readPointerPhysicalX(packet));
240+
assertEquals(0.0, readPointerPhysicalY(packet));
241+
242+
touchProcessor.onTouchEvent(mocker.mockEvent(MotionEvent.ACTION_MOVE, 10.0f, 5.0f, 0));
243+
inOrder
244+
.verify(mockRenderer)
245+
.dispatchPointerDataPacket(packetCaptor.capture(), packetSizeCaptor.capture());
246+
packet = packetCaptor.getValue();
247+
assertEquals(AndroidTouchProcessor.PointerChange.PAN_ZOOM_UPDATE, readPointerChange(packet));
248+
assertEquals(AndroidTouchProcessor.PointerDeviceKind.TRACKPAD, readPointerDeviceKind(packet));
249+
assertEquals(AndroidTouchProcessor.PointerSignalKind.NONE, readPointerSignalKind(packet));
250+
assertEquals(0.0, readPointerPhysicalX(packet));
251+
assertEquals(0.0, readPointerPhysicalY(packet));
252+
assertEquals(10.0, readPointerPanX(packet));
253+
assertEquals(5.0, readPointerPanY(packet));
254+
255+
touchProcessor.onGenericMotionEvent(mocker.mockEvent(MotionEvent.ACTION_SCROLL, 0.0f, 0.0f, 0));
256+
inOrder
257+
.verify(mockRenderer)
258+
.dispatchPointerDataPacket(packetCaptor.capture(), packetSizeCaptor.capture());
259+
packet = packetCaptor.getValue();
260+
packet.rewind();
261+
while (packet.hasRemaining()) {
262+
assertEquals(0, packet.get());
263+
}
264+
265+
touchProcessor.onTouchEvent(mocker.mockEvent(MotionEvent.ACTION_UP, 10.0f, 5.0f, 0));
266+
inOrder
267+
.verify(mockRenderer)
268+
.dispatchPointerDataPacket(packetCaptor.capture(), packetSizeCaptor.capture());
269+
packet = packetCaptor.getValue();
270+
assertEquals(AndroidTouchProcessor.PointerChange.PAN_ZOOM_END, readPointerChange(packet));
271+
assertEquals(AndroidTouchProcessor.PointerDeviceKind.TRACKPAD, readPointerDeviceKind(packet));
272+
assertEquals(AndroidTouchProcessor.PointerSignalKind.NONE, readPointerSignalKind(packet));
273+
assertEquals(0.0, readPointerPhysicalX(packet));
274+
assertEquals(0.0, readPointerPhysicalY(packet));
275+
inOrder.verifyNoMoreInteractions();
276+
}
221277
}

0 commit comments

Comments
 (0)