Skip to content

Commit

Permalink
Propagate positions of secondary pointers in UP events on Android (fl…
Browse files Browse the repository at this point in the history
  • Loading branch information
sbaranov authored Nov 2, 2018
1 parent 57c21d4 commit b5758d0
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
5 changes: 3 additions & 2 deletions lib/ui/hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ void _invoke3<A1, A2, A3>(void callback(A1 a1, A2 a2, A3 a3), Zone zone, A1 arg1
//
// * pointer_data.cc
// * FlutterView.java
const int _kPointerDataFieldCount = 20;
const int _kPointerDataFieldCount = 21;

PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
const int kStride = Int64List.bytesPerElement;
Expand Down Expand Up @@ -226,7 +226,8 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
radiusMin: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
radiusMax: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
orientation: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian)
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
platformData: packet.getInt64(kStride * offset++, _kFakeHostEndian),
);
assert(offset == (i + 1) * _kPointerDataFieldCount);
}
Expand Down
9 changes: 7 additions & 2 deletions lib/ui/pointer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ class PointerData {
this.radiusMin: 0.0,
this.radiusMax: 0.0,
this.orientation: 0.0,
this.tilt: 0.0
this.tilt: 0.0,
this.platformData: 0,
});

/// Time of event dispatch, relative to an arbitrary timeline.
Expand Down Expand Up @@ -199,6 +200,9 @@ class PointerData {
/// the stylus is flat on that surface).
final double tilt;

/// Opaque platform-specific data associated with the event.
final int platformData;

@override
String toString() => '$runtimeType(x: $physicalX, y: $physicalY)';

Expand All @@ -223,7 +227,8 @@ class PointerData {
'radiusMin: $radiusMin, '
'radiusMax: $radiusMax, '
'orientation: $orientation, '
'tilt: $tilt'
'tilt: $tilt, '
'platformData: $platformData'
')';
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/window/pointer_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace blink {

// If this value changes, update the pointer data unpacking code in hooks.dart.
static constexpr int kPointerDataFieldCount = 20;
static constexpr int kPointerDataFieldCount = 21;

static_assert(sizeof(PointerData) == sizeof(int64_t) * kPointerDataFieldCount,
"PointerData has the wrong size");
Expand Down
1 change: 1 addition & 0 deletions lib/ui/window/pointer_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct alignas(8) PointerData {
double radius_max;
double orientation;
double tilt;
int64_t platformData;

void Clear();
};
Expand Down
38 changes: 29 additions & 9 deletions shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,8 @@ private int getPointerDeviceTypeForToolType(int toolType) {
}
}

private void addPointerForIndex(MotionEvent event, int pointerIndex, ByteBuffer packet) {
int pointerChange = getPointerChangeForAction(event.getActionMasked());
private void addPointerForIndex(MotionEvent event, int pointerIndex, int pointerChange,
int pointerData, ByteBuffer packet) {
if (pointerChange == -1) {
return;
}
Expand Down Expand Up @@ -503,6 +503,8 @@ private void addPointerForIndex(MotionEvent event, int pointerIndex, ByteBuffer
} else {
packet.putDouble(0.0); // tilt
}

packet.putLong(pointerData); // platformData
}

@Override
Expand All @@ -521,26 +523,44 @@ public boolean onTouchEvent(MotionEvent event) {
}

// These values must match the unpacking code in hooks.dart.
final int kPointerDataFieldCount = 20;
final int kPointerDataFieldCount = 21;
final int kBytePerField = 8;

// This value must match the value in framework's platform_view.dart.
// This flag indicates whether the original Android pointer events were batched together.
final int kPointerDataFlagBatched = 1;

int pointerCount = event.getPointerCount();

ByteBuffer packet = ByteBuffer.allocateDirect(pointerCount * kPointerDataFieldCount * kBytePerField);
packet.order(ByteOrder.LITTLE_ENDIAN);

int maskedAction = event.getActionMasked();
// ACTION_UP, ACTION_POINTER_UP, ACTION_DOWN, and ACTION_POINTER_DOWN
// only apply to a single pointer, other events apply to all pointers.
if (maskedAction == MotionEvent.ACTION_UP || maskedAction == MotionEvent.ACTION_POINTER_UP
|| maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN) {
addPointerForIndex(event, event.getActionIndex(), packet);
int pointerChange = getPointerChangeForAction(event.getActionMasked());
if (maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN) {
// ACTION_DOWN and ACTION_POINTER_DOWN always apply to a single pointer only.
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
} else if (maskedAction == MotionEvent.ACTION_UP || maskedAction == MotionEvent.ACTION_POINTER_UP) {
// ACTION_UP and ACTION_POINTER_UP may contain position updates for other pointers.
// We are converting these updates to move events here in order to preserve this data.
// We also mark these events with a flag in order to help the framework reassemble
// the original Android event later, should it need to forward it to a PlatformView.
for (int p = 0; p < pointerCount; p++) {
if (p != event.getActionIndex()) {
if (event.getToolType(p) == MotionEvent.TOOL_TYPE_FINGER) {
addPointerForIndex(event, p, kPointerChangeMove, kPointerDataFlagBatched, packet);
}
}
}
// It's important that we're sending the UP event last. This allows PlatformView
// to correctly batch everything back into the original Android event if needed.
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
} else {
// ACTION_MOVE may not actually mean all pointers have moved
// but it's the responsibility of a later part of the system to
// ignore 0-deltas if desired.
for (int p = 0; p < pointerCount; p++) {
addPointerForIndex(event, p, packet);
addPointerForIndex(event, p, pointerChange, 0, packet);
}
}

Expand Down

0 comments on commit b5758d0

Please sign in to comment.