Create PointerEventState

Summary: Changelog: [Internal] - A refactor to pass the object PointerEventState containing relevant state / and also properties for pointerEvent objects

Reviewed By: vincentriemer

Differential Revision: D39626285

fbshipit-source-id: e2ff5313ef03d7d2d36c35ca459950ec07650df2
This commit is contained in:
Luna Wei
2022-09-20 12:01:07 -07:00
committed by Facebook GitHub Bot
parent 4ca089f94c
commit bcb58089c4
3 changed files with 121 additions and 171 deletions
@@ -59,11 +59,7 @@ public class JSPointerDispatcher {
return;
}
float[] targetCoordinates = new float[2];
List<ViewTarget> hitPath =
TouchTargetHelper.findTargetPathAndCoordinatesForTouch(
motionEvent.getX(), motionEvent.getY(), mRootViewGroup, targetCoordinates);
dispatchCancelEvent(hitPath, motionEvent, eventDispatcher, targetCoordinates);
dispatchCancelEvent(motionEvent, eventDispatcher);
mChildHandlingNativeGesture = childView.getId();
}
@@ -74,24 +70,17 @@ public class JSPointerDispatcher {
private void onUp(
int activeTargetTag,
List<ViewTarget> hitPath,
int surfaceId,
PointerEventState eventState,
MotionEvent motionEvent,
EventDispatcher eventDispatcher,
float[] targetCoordinates) {
List<ViewTarget> hitPath,
EventDispatcher eventDispatcher) {
boolean supportsHover = PointerEventHelper.supportsHover(motionEvent);
boolean listeningForUp = isAnyoneListeningForBubblingEvent(hitPath, EVENT.UP, EVENT.UP_CAPTURE);
if (listeningForUp) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_UP,
surfaceId,
activeTargetTag,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
PointerEventHelper.POINTER_UP, activeTargetTag, eventState, motionEvent));
}
if (!supportsHover) {
@@ -100,13 +89,7 @@ public class JSPointerDispatcher {
if (listeningForOut) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_OUT,
surfaceId,
activeTargetTag,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
PointerEventHelper.POINTER_OUT, activeTargetTag, eventState, motionEvent));
}
List<ViewTarget> leaveViewTargets =
@@ -115,11 +98,10 @@ public class JSPointerDispatcher {
// target -> root
dispatchEventForViewTargets(
PointerEventHelper.POINTER_LEAVE,
leaveViewTargets,
eventDispatcher,
surfaceId,
eventState,
motionEvent,
targetCoordinates);
leaveViewTargets,
eventDispatcher);
int activePointerId = motionEvent.getPointerId(motionEvent.getActionIndex());
mLastHitPathByPointerId.remove(activePointerId);
@@ -141,11 +123,10 @@ public class JSPointerDispatcher {
private void onDown(
int activeTargetTag,
List<ViewTarget> hitPath,
int surfaceId,
PointerEventState eventState,
MotionEvent motionEvent,
EventDispatcher eventDispatcher,
float[] targetCoordinates) {
List<ViewTarget> hitPath,
EventDispatcher eventDispatcher) {
incrementCoalescingKey();
boolean supportsHover = PointerEventHelper.supportsHover(motionEvent);
@@ -156,13 +137,7 @@ public class JSPointerDispatcher {
if (listeningForOver) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_OVER,
surfaceId,
activeTargetTag,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
PointerEventHelper.POINTER_OVER, activeTargetTag, eventState, motionEvent));
}
List<ViewTarget> enterViewTargets =
@@ -172,11 +147,10 @@ public class JSPointerDispatcher {
Collections.reverse(enterViewTargets);
dispatchEventForViewTargets(
PointerEventHelper.POINTER_ENTER,
enterViewTargets,
eventDispatcher,
surfaceId,
eventState,
motionEvent,
targetCoordinates);
enterViewTargets,
eventDispatcher);
}
boolean listeningForDown =
@@ -184,13 +158,7 @@ public class JSPointerDispatcher {
if (listeningForDown) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_DOWN,
surfaceId,
activeTargetTag,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
PointerEventHelper.POINTER_DOWN, activeTargetTag, eventState, motionEvent));
}
}
@@ -215,26 +183,31 @@ public class JSPointerDispatcher {
}
int action = motionEvent.getActionMasked();
int surfaceId = UIManagerHelper.getSurfaceId(mRootViewGroup);
TouchTargetHelper.ViewTarget activeViewTarget = hitPath.get(0);
int activeTargetTag = activeViewTarget.getViewId();
if (action == MotionEvent.ACTION_DOWN) {
mPrimaryPointerId = motionEvent.getPointerId(0);
}
PointerEventState eventState = new PointerEventState();
eventState.primaryPointerId = mPrimaryPointerId;
eventState.buttons = motionEvent.getButtonState();
eventState.button =
PointerEventHelper.getButtonChange(mLastButtonState, motionEvent.getButtonState());
eventState.offsetCoords = targetCoordinates;
eventState.surfaceId = UIManagerHelper.getSurfaceId(mRootViewGroup);
switch (action) {
case MotionEvent.ACTION_DOWN:
mPrimaryPointerId = motionEvent.getPointerId(0);
onDown(
activeTargetTag, hitPath, surfaceId, motionEvent, eventDispatcher, targetCoordinates);
break;
case MotionEvent.ACTION_POINTER_DOWN:
onDown(
activeTargetTag, hitPath, surfaceId, motionEvent, eventDispatcher, targetCoordinates);
onDown(activeTargetTag, eventState, motionEvent, hitPath, eventDispatcher);
break;
case MotionEvent.ACTION_HOVER_MOVE:
// TODO(luwe) - converge this with ACTION_MOVE
// HOVER_MOVE may occur before DOWN. Add its downTime as a coalescing key
onMove(
activeTargetTag, motionEvent, eventDispatcher, surfaceId, hitPath, targetCoordinates);
onMove(activeTargetTag, eventState, motionEvent, hitPath, eventDispatcher);
break;
case MotionEvent.ACTION_MOVE:
// TODO(luwe) - converge this with ACTION_HOVER_MOVE
@@ -244,22 +217,19 @@ public class JSPointerDispatcher {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_MOVE,
surfaceId,
activeTargetTag,
eventState,
motionEvent,
targetCoordinates,
getCoalescingKey(),
mPrimaryPointerId,
mLastButtonState));
getCoalescingKey()));
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
incrementCoalescingKey();
onUp(activeTargetTag, hitPath, surfaceId, motionEvent, eventDispatcher, targetCoordinates);
onUp(activeTargetTag, eventState, motionEvent, hitPath, eventDispatcher);
break;
case MotionEvent.ACTION_CANCEL:
dispatchCancelEvent(hitPath, motionEvent, eventDispatcher, targetCoordinates);
dispatchCancelEvent(eventState, hitPath, motionEvent, eventDispatcher);
break;
default:
FLog.w(
@@ -319,34 +289,24 @@ public class JSPointerDispatcher {
private void dispatchEventForViewTargets(
String eventName,
List<ViewTarget> viewTargets,
EventDispatcher dispatcher,
int surfaceId,
PointerEventState eventState,
MotionEvent motionEvent,
float[] targetCoordinates) {
List<ViewTarget> viewTargets,
EventDispatcher dispatcher) {
for (ViewTarget viewTarget : viewTargets) {
int viewId = viewTarget.getViewId();
dispatcher.dispatchEvent(
PointerEvent.obtain(
eventName,
surfaceId,
viewId,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
dispatcher.dispatchEvent(PointerEvent.obtain(eventName, viewId, eventState, motionEvent));
}
}
// called on hover_move motion events only
private void onMove(
int targetTag,
PointerEventState eventState,
MotionEvent motionEvent,
EventDispatcher eventDispatcher,
int surfaceId,
List<ViewTarget> hitPath,
float[] targetCoordinates) {
EventDispatcher eventDispatcher) {
int action = motionEvent.getActionMasked();
if (action != MotionEvent.ACTION_HOVER_MOVE) {
@@ -417,13 +377,7 @@ public class JSPointerDispatcher {
if (listeningForOut) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_OUT,
surfaceId,
lastTargetTag,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
PointerEventHelper.POINTER_OUT, lastTargetTag, eventState, motionEvent));
}
// target -> root
@@ -437,11 +391,10 @@ public class JSPointerDispatcher {
// We want to dispatch from target -> root, so no need to reverse
dispatchEventForViewTargets(
PointerEventHelper.POINTER_LEAVE,
leaveViewTargets,
eventDispatcher,
surfaceId,
eventState,
motionEvent,
targetCoordinates);
leaveViewTargets,
eventDispatcher);
}
}
@@ -450,13 +403,7 @@ public class JSPointerDispatcher {
if (listeningForOver) {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_OVER,
surfaceId,
targetTag,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
PointerEventHelper.POINTER_OVER, targetTag, eventState, motionEvent));
}
// target -> root
@@ -472,11 +419,10 @@ public class JSPointerDispatcher {
Collections.reverse(enterViewTargets);
dispatchEventForViewTargets(
PointerEventHelper.POINTER_ENTER,
enterViewTargets,
eventDispatcher,
surfaceId,
eventState,
motionEvent,
targetCoordinates);
enterViewTargets,
eventDispatcher);
}
}
@@ -486,32 +432,49 @@ public class JSPointerDispatcher {
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_MOVE,
surfaceId,
targetTag,
eventState,
motionEvent,
targetCoordinates,
getCoalescingKey(),
mPrimaryPointerId,
mLastButtonState));
getCoalescingKey()));
}
mLastHitPathByPointerId.put(activePointerId, hitPath);
mLastEventCoodinatesByPointerId.put(activePointerId, new float[] {x, y});
}
private void dispatchCancelEvent(MotionEvent motionEvent, EventDispatcher eventDispatcher) {
Assertions.assertCondition(
mChildHandlingNativeGesture == -1,
"Expected to not have already sent a cancel for this gesture");
float[] targetCoordinates = new float[2];
List<ViewTarget> hitPath =
TouchTargetHelper.findTargetPathAndCoordinatesForTouch(
motionEvent.getX(), motionEvent.getY(), mRootViewGroup, targetCoordinates);
PointerEventState eventState = new PointerEventState();
eventState.primaryPointerId = mPrimaryPointerId;
eventState.buttons = motionEvent.getButtonState();
eventState.button =
PointerEventHelper.getButtonChange(mLastButtonState, motionEvent.getButtonState());
eventState.offsetCoords = targetCoordinates;
eventState.surfaceId = UIManagerHelper.getSurfaceId(mRootViewGroup);
dispatchCancelEvent(eventState, hitPath, motionEvent, eventDispatcher);
}
private void dispatchCancelEvent(
PointerEventState eventState,
List<ViewTarget> hitPath,
MotionEvent motionEvent,
EventDispatcher eventDispatcher,
float[] targetCoordinates) {
EventDispatcher eventDispatcher) {
// This means the gesture has already ended, via some other CANCEL or UP event. This is not
// expected to happen very often as it would mean some child View has decided to intercept the
// touch stream and start a native gesture only upon receiving the UP/CANCEL event.
Assertions.assertCondition(
mChildHandlingNativeGesture == -1,
"Expected to not have already sent a cancel for this gesture");
int surfaceId = UIManagerHelper.getSurfaceId(mRootViewGroup);
if (!hitPath.isEmpty()) {
boolean listeningForCancel =
@@ -521,13 +484,7 @@ public class JSPointerDispatcher {
Assertions.assertNotNull(eventDispatcher)
.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.POINTER_CANCEL,
surfaceId,
targetTag,
motionEvent,
targetCoordinates,
mPrimaryPointerId,
mLastButtonState));
PointerEventHelper.POINTER_CANCEL, targetTag, eventState, motionEvent));
}
// TODO(luwe) - Need to fire pointer out here as well:
@@ -538,11 +495,10 @@ public class JSPointerDispatcher {
// dispatch from target -> root
dispatchEventForViewTargets(
PointerEventHelper.POINTER_LEAVE,
leaveViewTargets,
eventDispatcher,
surfaceId,
eventState,
motionEvent,
targetCoordinates);
leaveViewTargets,
eventDispatcher);
incrementCoalescingKey();
mPrimaryPointerId = UNSET_POINTER_ID;
@@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager;
public class PointerEventState {
public PointerEventState() {}
public int primaryPointerId;
public int buttons;
public int button;
public float[] offsetCoords;
public int surfaceId;
}
@@ -15,6 +15,7 @@ import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.PointerEventState;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -28,80 +29,55 @@ public class PointerEvent extends Event<PointerEvent> {
public static PointerEvent obtain(
String eventName,
int surfaceId,
int viewTag,
MotionEvent motionEventToCopy,
float[] offsetCoords,
int primaryPointerId,
int lastButtonState) {
int targetTag,
PointerEventState eventState,
MotionEvent motionEventToCopy) {
PointerEvent event = EVENTS_POOL.acquire();
if (event == null) {
event = new PointerEvent();
}
event.init(
eventName,
surfaceId,
viewTag,
Assertions.assertNotNull(motionEventToCopy),
offsetCoords,
(short) 0,
primaryPointerId,
lastButtonState);
eventName, targetTag, eventState, Assertions.assertNotNull(motionEventToCopy), (short) 0);
return event;
}
public static PointerEvent obtain(
String eventName,
int surfaceId,
int viewTag,
int targetTag,
PointerEventState eventState,
MotionEvent motionEventToCopy,
float[] offsetCoords,
short coalescingKey,
int primaryPointerId,
int lastButtonState) {
short coalescingKey) {
PointerEvent event = EVENTS_POOL.acquire();
if (event == null) {
event = new PointerEvent();
}
event.init(
eventName,
surfaceId,
viewTag,
targetTag,
eventState,
Assertions.assertNotNull(motionEventToCopy),
offsetCoords,
coalescingKey,
primaryPointerId,
lastButtonState);
coalescingKey);
return event;
}
private @Nullable MotionEvent mMotionEvent;
private @Nullable String mEventName;
private short mCoalescingKey = UNSET_COALESCING_KEY;
private float mOffsetX;
private float mOffsetY;
private @Nullable List<WritableMap> mPointersEventData;
private int mPrimaryPointerId;
private int mLastButtonState;
private PointerEventState mEventState;
private void init(
String eventName,
int surfaceId,
int viewTag,
int targetTag,
PointerEventState eventState,
MotionEvent motionEventToCopy,
float[] offsetCoords,
short coalescingKey,
int primaryPointerId,
int lastButtonState) {
short coalescingKey) {
super.init(surfaceId, viewTag, motionEventToCopy.getEventTime());
super.init(eventState.surfaceId, targetTag, motionEventToCopy.getEventTime());
mEventName = eventName;
mMotionEvent = MotionEvent.obtain(motionEventToCopy);
mCoalescingKey = coalescingKey;
mOffsetX = offsetCoords[0];
mOffsetY = offsetCoords[1];
mPrimaryPointerId = primaryPointerId;
mLastButtonState = lastButtonState;
mEventState = eventState;
}
private PointerEvent() {}
@@ -184,7 +160,8 @@ public class PointerEvent extends Event<PointerEvent> {
pointerEvent.putString("pointerType", pointerType);
pointerEvent.putBoolean(
"isPrimary", PointerEventHelper.isPrimary(pointerId, mPrimaryPointerId, mMotionEvent));
"isPrimary",
PointerEventHelper.isPrimary(pointerId, mEventState.primaryPointerId, mMotionEvent));
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
// Client refers to upper left edge of the content area (viewport)
@@ -203,8 +180,8 @@ public class PointerEvent extends Event<PointerEvent> {
pointerEvent.putDouble("pageY", clientY);
// Offset refers to upper left edge of the target view
pointerEvent.putDouble("offsetX", PixelUtil.toDIPFromPixel(mOffsetX));
pointerEvent.putDouble("offsetY", PixelUtil.toDIPFromPixel(mOffsetY));
pointerEvent.putDouble("offsetX", PixelUtil.toDIPFromPixel(mEventState.offsetCoords[0]));
pointerEvent.putDouble("offsetY", PixelUtil.toDIPFromPixel(mEventState.offsetCoords[1]));
pointerEvent.putInt("target", this.getViewTag());
pointerEvent.putDouble("timestamp", this.getTimestampMs());
@@ -216,10 +193,8 @@ public class PointerEvent extends Event<PointerEvent> {
pointerEvent.putDouble("tiltY", 0);
}
int buttonState = mMotionEvent.getButtonState();
pointerEvent.putInt("buttons", buttonState);
pointerEvent.putInt(
"button", PointerEventHelper.getButtonChange(mLastButtonState, buttonState));
pointerEvent.putInt("buttons", mEventState.buttons);
pointerEvent.putInt("button", mEventState.button);
return pointerEvent;
}