66import android .view .MotionEvent ;
77import androidx .annotation .IntDef ;
88import androidx .annotation .NonNull ;
9- import androidx .annotation .VisibleForTesting ;
109import io .flutter .embedding .engine .renderer .FlutterRenderer ;
1110import java .nio .ByteBuffer ;
1211import java .nio .ByteOrder ;
13- import java .util .HashMap ;
14- import java .util .Map ;
1512
1613/** Sends touch information from Android to Flutter in a format that Flutter understands. */
1714public class AndroidTouchProcessor {
@@ -29,7 +26,7 @@ public class AndroidTouchProcessor {
2926 PointerChange .PAN_ZOOM_UPDATE ,
3027 PointerChange .PAN_ZOOM_END
3128 })
32- public @interface PointerChange {
29+ private @interface PointerChange {
3330 int CANCEL = 0 ;
3431 int ADD = 1 ;
3532 int REMOVE = 2 ;
@@ -51,7 +48,7 @@ public class AndroidTouchProcessor {
5148 PointerDeviceKind .TRACKPAD ,
5249 PointerDeviceKind .UNKNOWN
5350 })
54- public @interface PointerDeviceKind {
51+ private @interface PointerDeviceKind {
5552 int TOUCH = 0 ;
5653 int MOUSE = 1 ;
5754 int STYLUS = 2 ;
@@ -62,15 +59,15 @@ public class AndroidTouchProcessor {
6259
6360 // Must match the PointerSignalKind enum in pointer.dart.
6461 @ IntDef ({PointerSignalKind .NONE , PointerSignalKind .SCROLL , PointerSignalKind .UNKNOWN })
65- public @interface PointerSignalKind {
62+ private @interface PointerSignalKind {
6663 int NONE = 0 ;
6764 int SCROLL = 1 ;
6865 int UNKNOWN = 2 ;
6966 }
7067
7168 // Must match the unpacking code in hooks.dart.
7269 private static final int POINTER_DATA_FIELD_COUNT = 35 ;
73- @ VisibleForTesting static final int BYTES_PER_FIELD = 8 ;
70+ private static final int BYTES_PER_FIELD = 8 ;
7471
7572 // This value must match the value in framework's platform_view.dart.
7673 // This flag indicates whether the original Android pointer events were batched together.
@@ -79,12 +76,12 @@ public class AndroidTouchProcessor {
7976 @ NonNull private final FlutterRenderer renderer ;
8077 @ NonNull private final MotionEventTracker motionEventTracker ;
8178
79+ private static final int _POINTER_BUTTON_PRIMARY = 1 ;
80+
8281 private static final Matrix IDENTITY_TRANSFORM = new Matrix ();
8382
8483 private final boolean trackMotionEvents ;
8584
86- private final Map <Integer , float []> ongoingPans = new HashMap <>();
87-
8885 /**
8986 * Constructs an {@code AndroidTouchProcessor} that will send touch event data to the Flutter
9087 * execution context represented by the given {@link FlutterRenderer}.
@@ -223,28 +220,6 @@ private void addPointerForIndex(
223220 }
224221
225222 int pointerKind = getPointerDeviceTypeForToolType (event .getToolType (pointerIndex ));
226- // We use this in lieu of using event.getRawX and event.getRawY as we wish to support
227- // earlier versions than API level 29.
228- float viewToScreenCoords [] = {event .getX (pointerIndex ), event .getY (pointerIndex )};
229- transformMatrix .mapPoints (viewToScreenCoords );
230- long buttons ;
231- if (pointerKind == PointerDeviceKind .MOUSE ) {
232- buttons = event .getButtonState () & 0x1F ;
233- if (buttons == 0
234- && event .getSource () == InputDevice .SOURCE_MOUSE
235- && pointerChange == PointerChange .DOWN ) {
236- // Some implementations translate trackpad scrolling into a mouse down-move-up event
237- // sequence with buttons: 0, such as ARC on a Chromebook. See #11420, a legacy
238- // implementation that uses the same condition but converts differently.
239- ongoingPans .put (event .getPointerId (pointerIndex ), viewToScreenCoords );
240- }
241- } else if (pointerKind == PointerDeviceKind .STYLUS ) {
242- buttons = (event .getButtonState () >> 4 ) & 0xF ;
243- } else {
244- buttons = 0 ;
245- }
246-
247- boolean isTrackpadPan = ongoingPans .containsKey (event .getPointerId (pointerIndex ));
248223
249224 int signalKind =
250225 event .getActionMasked () == MotionEvent .ACTION_SCROLL
@@ -255,31 +230,39 @@ private void addPointerForIndex(
255230
256231 packet .putLong (motionEventId ); // motionEventId
257232 packet .putLong (timeStamp ); // time_stamp
258- if (isTrackpadPan ) {
259- packet .putLong (getPointerChangeForPanZoom (pointerChange )); // change
260- packet .putLong (PointerDeviceKind .TRACKPAD ); // kind
261- } else {
262- packet .putLong (pointerChange ); // change
263- packet .putLong (pointerKind ); // kind
264- }
233+ packet .putLong (pointerChange ); // change
234+ packet .putLong (pointerKind ); // kind
265235 packet .putLong (signalKind ); // signal_kind
266236 packet .putLong (event .getPointerId (pointerIndex )); // device
267237 packet .putLong (0 ); // pointer_identifier, will be generated in pointer_data_packet_converter.cc.
268238
269- if (isTrackpadPan ) {
270- float [] panStart = ongoingPans .get (event .getPointerId (pointerIndex ));
271- packet .putDouble (panStart [0 ]);
272- packet .putDouble (panStart [1 ]);
273- } else {
274- packet .putDouble (viewToScreenCoords [0 ]); // physical_x
275- packet .putDouble (viewToScreenCoords [1 ]); // physical_y
276- }
239+ // We use this in lieu of using event.getRawX and event.getRawY as we wish to support
240+ // earlier versions than API level 29.
241+ float viewToScreenCoords [] = {event .getX (pointerIndex ), event .getY (pointerIndex )};
242+ transformMatrix .mapPoints (viewToScreenCoords );
243+ packet .putDouble (viewToScreenCoords [0 ]); // physical_x
244+ packet .putDouble (viewToScreenCoords [1 ]); // physical_y
277245
278246 packet .putDouble (
279247 0.0 ); // physical_delta_x, will be generated in pointer_data_packet_converter.cc.
280248 packet .putDouble (
281249 0.0 ); // physical_delta_y, will be generated in pointer_data_packet_converter.cc.
282250
251+ long buttons ;
252+ if (pointerKind == PointerDeviceKind .MOUSE ) {
253+ buttons = event .getButtonState () & 0x1F ;
254+ // TODO(dkwingsmt): Remove this fix after implementing touchpad gestures
255+ // https://github.com/flutter/flutter/issues/23604#issuecomment-524471152
256+ if (buttons == 0
257+ && event .getSource () == InputDevice .SOURCE_MOUSE
258+ && (pointerChange == PointerChange .DOWN || pointerChange == PointerChange .MOVE )) {
259+ buttons = _POINTER_BUTTON_PRIMARY ;
260+ }
261+ } else if (pointerKind == PointerDeviceKind .STYLUS ) {
262+ buttons = (event .getButtonState () >> 4 ) & 0xF ;
263+ } else {
264+ buttons = 0 ;
265+ }
283266 packet .putLong (buttons ); // buttons
284267
285268 packet .putLong (0 ); // obscured
@@ -334,22 +317,12 @@ private void addPointerForIndex(
334317 packet .putDouble (0.0 ); // scroll_delta_x
335318 }
336319
337- if (isTrackpadPan ) {
338- float [] panStart = ongoingPans .get (event .getPointerId (pointerIndex ));
339- packet .putDouble (viewToScreenCoords [0 ] - panStart [0 ]);
340- packet .putDouble (viewToScreenCoords [1 ] - panStart [1 ]);
341- } else {
342- packet .putDouble (0.0 ); // pan_x
343- packet .putDouble (0.0 ); // pan_y
344- }
320+ packet .putDouble (0.0 ); // pan_x
321+ packet .putDouble (0.0 ); // pan_y
345322 packet .putDouble (0.0 ); // pan_delta_x
346323 packet .putDouble (0.0 ); // pan_delta_y
347324 packet .putDouble (1.0 ); // scale
348325 packet .putDouble (0.0 ); // rotation
349-
350- if (isTrackpadPan && getPointerChangeForPanZoom (pointerChange ) == PointerChange .PAN_ZOOM_END ) {
351- ongoingPans .remove (event .getPointerId (pointerIndex ));
352- }
353326 }
354327
355328 @ PointerChange
@@ -384,18 +357,6 @@ private int getPointerChangeForAction(int maskedAction) {
384357 return -1 ;
385358 }
386359
387- @ PointerChange
388- private int getPointerChangeForPanZoom (int pointerChange ) {
389- if (pointerChange == PointerChange .DOWN ) {
390- return PointerChange .PAN_ZOOM_START ;
391- } else if (pointerChange == PointerChange .MOVE ) {
392- return PointerChange .PAN_ZOOM_UPDATE ;
393- } else if (pointerChange == PointerChange .UP || pointerChange == PointerChange .CANCEL ) {
394- return PointerChange .PAN_ZOOM_END ;
395- }
396- return -1 ;
397- }
398-
399360 @ PointerDeviceKind
400361 private int getPointerDeviceTypeForToolType (int toolType ) {
401362 switch (toolType ) {
0 commit comments