Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
replace getRawX and getRawY with shims
  • Loading branch information
Kaushik Iska committed Jul 15, 2020
commit 57a8b35ad6721908007479153c768c232bc4d8b3
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.flutter.embedding.android;

import android.graphics.Matrix;
import android.os.Build;
import android.view.InputDevice;
import android.view.MotionEvent;
Expand Down Expand Up @@ -69,6 +70,8 @@ public class AndroidTouchProcessor {

private static final int _POINTER_BUTTON_PRIMARY = 1;

private static final Matrix IDENTITY_TRANSFORM = new Matrix();

private final boolean trackMotionEvents;

/**
Expand All @@ -83,8 +86,12 @@ public AndroidTouchProcessor(@NonNull FlutterRenderer renderer, boolean trackMot
this.trackMotionEvents = trackMotionEvents;
}

/** Sends the given {@link MotionEvent} data to Flutter in a format that Flutter understands. */
public boolean onTouchEvent(@NonNull MotionEvent event) {
return onTouchEvent(event, IDENTITY_TRANSFORM);
}

/** Sends the given {@link MotionEvent} data to Flutter in a format that Flutter understands. */
public boolean onTouchEvent(@NonNull MotionEvent event, Matrix transformMatrix) {
int pointerCount = event.getPointerCount();

// Prepare a data packet of the appropriate size and order.
Expand All @@ -102,26 +109,27 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
|| maskedAction == MotionEvent.ACTION_POINTER_UP);
if (updateForSinglePointer) {
// ACTION_DOWN and ACTION_POINTER_DOWN always apply to a single pointer only.
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, transformMatrix, packet);
} else if (updateForMultiplePointers) {
// 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() && event.getToolType(p) == MotionEvent.TOOL_TYPE_FINGER) {
addPointerForIndex(event, p, PointerChange.MOVE, POINTER_DATA_FLAG_BATCHED, packet);
addPointerForIndex(
event, p, PointerChange.MOVE, POINTER_DATA_FLAG_BATCHED, transformMatrix, 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);
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, transformMatrix, 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, pointerChange, 0, packet);
addPointerForIndex(event, p, pointerChange, 0, transformMatrix, packet);
}
}

Expand Down Expand Up @@ -163,7 +171,7 @@ public boolean onGenericMotionEvent(@NonNull MotionEvent event) {
packet.order(ByteOrder.LITTLE_ENDIAN);

// ACTION_HOVER_MOVE always applies to a single pointer only.
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, IDENTITY_TRANSFORM, packet);
if (packet.position() % (POINTER_DATA_FIELD_COUNT * BYTES_PER_FIELD) != 0) {
throw new AssertionError("Packet position is not on field boundary.");
}
Expand All @@ -174,7 +182,12 @@ public boolean onGenericMotionEvent(@NonNull MotionEvent event) {
// TODO(mattcarroll): consider creating a PointerPacket class instead of using a procedure that
// mutates inputs.
private void addPointerForIndex(
MotionEvent event, int pointerIndex, int pointerChange, int pointerData, ByteBuffer packet) {
MotionEvent event,
int pointerIndex,
int pointerChange,
int pointerData,
Matrix transformMatrix,
ByteBuffer packet) {
if (pointerChange == -1) {
return;
}
Expand All @@ -201,8 +214,14 @@ private void addPointerForIndex(
packet.putLong(signalKind); // signal_kind
packet.putLong(event.getPointerId(pointerIndex)); // device
packet.putLong(0); // pointer_identifier, will be generated in pointer_data_packet_converter.cc.
packet.putDouble(event.getRawX(pointerIndex)); // physical_x
packet.putDouble(event.getRawY(pointerIndex)); // physical_y

// We use this in lieu of using event.getRawX and event.getRawY as we wish to support
// earlier versions than API level 29.
float viewToScreenCoords[] = {event.getX(pointerIndex), event.getY(pointerIndex)};
transformMatrix.mapPoints(viewToScreenCoords);
packet.putDouble(viewToScreenCoords[0]); // physical_x
packet.putDouble(viewToScreenCoords[1]); // physical_y

packet.putDouble(
0.0); // physical_delta_x, will be generated in pointer_data_packet_converter.cc.
packet.putDouble(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.flutter.embedding.engine.mutatorsstack;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
Expand All @@ -26,17 +27,19 @@ public class FlutterMutatorView extends FrameLayout {
* correct the final transform matrix.
*/
public FlutterMutatorView(
@NonNull Context context, float screenDensity, AndroidTouchProcessor androidTouchProcessor) {
@NonNull Context context,
float screenDensity,
@NonNull AndroidTouchProcessor androidTouchProcessor) {
super(context, null);
this.screenDensity = screenDensity;
this.androidTouchProcessor = androidTouchProcessor;
}

/** Initialize the FlutterMutatorView. */
public FlutterMutatorView(@NonNull Context context, AndroidTouchProcessor androidTouchProcessor) {
public FlutterMutatorView(@NonNull Context context) {
super(context, null);
this.screenDensity = 1;
this.androidTouchProcessor = androidTouchProcessor;
this.androidTouchProcessor = null;
}

/**
Expand Down Expand Up @@ -78,7 +81,14 @@ public void dispatchDraw(Canvas canvas) {
// Apply all the transforms on the child canvas.
canvas.save();

canvas.concat(getPlatformViewMatrix());
super.dispatchDraw(canvas);
canvas.restore();
}

private Matrix getPlatformViewMatrix() {
Matrix finalMatrix = new Matrix(mutatorsStack.getFinalMatrix());

// Reverse scale based on screen scale.
//
// The Android frame is set based on the logical resolution instead of physical.
Expand All @@ -87,6 +97,7 @@ public void dispatchDraw(Canvas canvas) {
// 500 points in Android. And until this point, we did all the calculation based on the flow
// resolution. So we need to scale down to match Android's logical resolution.
finalMatrix.preScale(1 / screenDensity, 1 / screenDensity);

// Reverse the current offset.
//
// The frame of this view includes the final offset of the bounding rect.
Expand All @@ -95,19 +106,27 @@ public void dispatchDraw(Canvas canvas) {
// all the clipping paths
finalMatrix.postTranslate(-left, -top);

canvas.concat(finalMatrix);
super.dispatchDraw(canvas);
canvas.restore();
return finalMatrix;
}

/** Intercept the events here and do not propagate them to the child platform views. */
@Override
// Intercept the events here and do not propagate them to the child platform views.
public boolean onInterceptTouchEvent(MotionEvent event) {
return true;
}

@Override
@SuppressLint("ClickableViewAccessibility")
public boolean onTouchEvent(MotionEvent event) {
return androidTouchProcessor.onTouchEvent(event);
if (androidTouchProcessor == null) {
return super.onTouchEvent(event);
}

// Mutator view itself doesn't rotate, scale, skew, etc.
// we only need to account for translation.
Matrix screenMatrix = new Matrix();
screenMatrix.postTranslate(getLeft(), getTop());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you intend to use getPlatformViewMatrix() here or somewhere else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, it is for when we need to support mutations on top of platform views

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mutator view does rotate, translate and scale. right @cyanglaz ?


return androidTouchProcessor.onTouchEvent(event, screenMatrix);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ public void itUsesActionEventTypeFromFrameworkEventForVirtualDisplays() {
assertNotEquals(resolvedEvent.getAction(), original.getAction());
}

@Ignore
@Test
public void itUsesActionEventTypeFromMotionEventForHybridPlatformViews() {
MotionEventTracker motionEventTracker = MotionEventTracker.getInstance();
Expand Down