diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java index 8206ebd883d..88ab9e9efc0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSPointerDispatcher.java @@ -16,6 +16,7 @@ import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.TouchTargetHelper.ViewTarget; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.PointerEvent; +import com.facebook.react.uimanager.events.PointerEvent.PointerEventState; import com.facebook.react.uimanager.events.PointerEventHelper; import com.facebook.react.uimanager.events.PointerEventHelper.EVENT; import java.util.ArrayList; @@ -35,8 +36,8 @@ public class JSPointerDispatcher { private static final float ONMOVE_EPSILON = 0.1f; private static final String TAG = "POINTER EVENTS"; - private final Map> mLastHitPathByPointerId = new HashMap<>(); - private final Map mLastEventCoodinatesByPointerId = new HashMap<>(); + private Map> mLastHitPathByPointerId; + private Map mLastEventCoordinatesByPointerId; private int mChildHandlingNativeGesture = -1; private int mPrimaryPointerId = UNSET_POINTER_ID; @@ -72,11 +73,14 @@ public class JSPointerDispatcher { int activeTargetTag, PointerEventState eventState, MotionEvent motionEvent, - List hitPath, EventDispatcher eventDispatcher) { + List activeHitPath = + eventState.getHitPathByPointerId().get(eventState.getActivePointerId()); + boolean supportsHover = PointerEventHelper.supportsHover(motionEvent); - boolean listeningForUp = isAnyoneListeningForBubblingEvent(hitPath, EVENT.UP, EVENT.UP_CAPTURE); + boolean listeningForUp = + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.UP, EVENT.UP_CAPTURE); if (listeningForUp) { eventDispatcher.dispatchEvent( PointerEvent.obtain( @@ -85,7 +89,7 @@ public class JSPointerDispatcher { if (!supportsHover) { boolean listeningForOut = - isAnyoneListeningForBubblingEvent(hitPath, EVENT.OUT, EVENT.OUT_CAPTURE); + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.OUT, EVENT.OUT_CAPTURE); if (listeningForOut) { eventDispatcher.dispatchEvent( PointerEvent.obtain( @@ -93,7 +97,7 @@ public class JSPointerDispatcher { } List leaveViewTargets = - filterByShouldDispatch(hitPath, EVENT.LEAVE, EVENT.LEAVE_CAPTURE, false); + filterByShouldDispatch(activeHitPath, EVENT.LEAVE, EVENT.LEAVE_CAPTURE, false); // target -> root dispatchEventForViewTargets( @@ -102,10 +106,6 @@ public class JSPointerDispatcher { motionEvent, leaveViewTargets, eventDispatcher); - - int activePointerId = motionEvent.getPointerId(motionEvent.getActionIndex()); - mLastHitPathByPointerId.remove(activePointerId); - mLastEventCoodinatesByPointerId.remove(activePointerId); } if (motionEvent.getActionMasked() == MotionEvent.ACTION_UP) { @@ -125,15 +125,17 @@ public class JSPointerDispatcher { int activeTargetTag, PointerEventState eventState, MotionEvent motionEvent, - List hitPath, EventDispatcher eventDispatcher) { + List activeHitPath = + eventState.getHitPathByPointerId().get(eventState.getActivePointerId()); + incrementCoalescingKey(); boolean supportsHover = PointerEventHelper.supportsHover(motionEvent); if (!supportsHover) { // Indirect OVER event dispatches before ENTER boolean listeningForOver = - isAnyoneListeningForBubblingEvent(hitPath, EVENT.OVER, EVENT.OVER_CAPTURE); + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.OVER, EVENT.OVER_CAPTURE); if (listeningForOver) { eventDispatcher.dispatchEvent( PointerEvent.obtain( @@ -141,7 +143,7 @@ public class JSPointerDispatcher { } List enterViewTargets = - filterByShouldDispatch(hitPath, EVENT.ENTER, EVENT.ENTER_CAPTURE, false); + filterByShouldDispatch(activeHitPath, EVENT.ENTER, EVENT.ENTER_CAPTURE, false); // Dispatch root -> target, we need to reverse order of enterViewTargets Collections.reverse(enterViewTargets); @@ -154,7 +156,7 @@ public class JSPointerDispatcher { } boolean listeningForDown = - isAnyoneListeningForBubblingEvent(hitPath, EVENT.DOWN, EVENT.DOWN_CAPTURE); + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.DOWN, EVENT.DOWN_CAPTURE); if (listeningForDown) { eventDispatcher.dispatchEvent( PointerEvent.obtain( @@ -162,57 +164,74 @@ public class JSPointerDispatcher { } } + private PointerEventState createEventState(MotionEvent motionEvent) { + int activeIndex = motionEvent.getActionIndex(); + + Map offsetByPointerId = new HashMap(); + Map> hitPathByPointerId = new HashMap>(); + Map eventCoordinatesByPointerId = new HashMap(); + for (int index = 0; index < motionEvent.getPointerCount(); index++) { + float[] offsetCoordinates = new float[2]; + float[] eventCoordinates = new float[] {motionEvent.getX(index), motionEvent.getY(index)}; + List hitPath = + TouchTargetHelper.findTargetPathAndCoordinatesForTouch( + eventCoordinates[0], eventCoordinates[1], mRootViewGroup, offsetCoordinates); + + int pointerId = motionEvent.getPointerId(index); + offsetByPointerId.put(pointerId, offsetCoordinates); + hitPathByPointerId.put(pointerId, hitPath); + eventCoordinatesByPointerId.put(pointerId, eventCoordinates); + } + + int activePointerId = motionEvent.getPointerId(activeIndex); + int surfaceId = UIManagerHelper.getSurfaceId(mRootViewGroup); + + return new PointerEventState( + mPrimaryPointerId, + activePointerId, + mLastButtonState, + surfaceId, + offsetByPointerId, + hitPathByPointerId, + eventCoordinatesByPointerId); + } + public void handleMotionEvent(MotionEvent motionEvent, EventDispatcher eventDispatcher) { // Don't fire any pointer events if child view is handling native gesture if (mChildHandlingNativeGesture != -1) { return; } - // Only relevant for POINTER_UP/POINTER_DOWN actions, otherwise 0 - int actionIndex = motionEvent.getActionIndex(); - float[] targetCoordinates = new float[2]; - List hitPath = - TouchTargetHelper.findTargetPathAndCoordinatesForTouch( - motionEvent.getX(actionIndex), - motionEvent.getY(actionIndex), - mRootViewGroup, - targetCoordinates); - - if (hitPath.isEmpty()) { - return; - } - int action = motionEvent.getActionMasked(); - - 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); + PointerEventState eventState = createEventState(motionEvent); + List activeHitPath = + eventState.getHitPathByPointerId().get(eventState.getActivePointerId()); + + if (activeHitPath == null || activeHitPath.isEmpty()) { + return; + } + + TouchTargetHelper.ViewTarget activeViewTarget = activeHitPath.get(0); + int activeTargetTag = activeViewTarget.getViewId(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: - onDown(activeTargetTag, eventState, motionEvent, hitPath, eventDispatcher); + onDown(activeTargetTag, eventState, motionEvent, 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, eventState, motionEvent, hitPath, eventDispatcher); + onMove(activeTargetTag, eventState, motionEvent, eventDispatcher); break; case MotionEvent.ACTION_MOVE: // TODO(luwe) - converge this with ACTION_HOVER_MOVE boolean listeningForMove = - isAnyoneListeningForBubblingEvent(hitPath, EVENT.MOVE, EVENT.MOVE_CAPTURE); + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.MOVE, EVENT.MOVE_CAPTURE); if (listeningForMove) { eventDispatcher.dispatchEvent( PointerEvent.obtain( @@ -226,10 +245,10 @@ public class JSPointerDispatcher { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: incrementCoalescingKey(); - onUp(activeTargetTag, eventState, motionEvent, hitPath, eventDispatcher); + onUp(activeTargetTag, eventState, motionEvent, eventDispatcher); break; case MotionEvent.ACTION_CANCEL: - dispatchCancelEvent(eventState, hitPath, motionEvent, eventDispatcher); + dispatchCancelEvent(eventState, motionEvent, eventDispatcher); break; default: FLog.w( @@ -238,6 +257,8 @@ public class JSPointerDispatcher { return; } + mLastHitPathByPointerId = eventState.getHitPathByPointerId(); + mLastEventCoordinatesByPointerId = eventState.getEventCoordinatesByPointerId(); mLastButtonState = motionEvent.getButtonState(); } @@ -305,33 +326,28 @@ public class JSPointerDispatcher { int targetTag, PointerEventState eventState, MotionEvent motionEvent, - List hitPath, EventDispatcher eventDispatcher) { - int action = motionEvent.getActionMasked(); - if (action != MotionEvent.ACTION_HOVER_MOVE) { - return; - } + int activePointerId = eventState.getActivePointerId(); + float[] eventCoordinates = eventState.getEventCoordinatesByPointerId().get(activePointerId); + List activeHitPath = eventState.getHitPathByPointerId().get(activePointerId); - int actionIndex = motionEvent.getActionIndex(); - int activePointerId = motionEvent.getPointerId(actionIndex); - float x = motionEvent.getX(); - float y = motionEvent.getY(); List lastHitPath = - mLastHitPathByPointerId.containsKey(activePointerId) + mLastHitPathByPointerId != null && mLastHitPathByPointerId.containsKey(activePointerId) ? mLastHitPathByPointerId.get(activePointerId) : new ArrayList(); float[] lastEventCoordinates = - mLastEventCoodinatesByPointerId.containsKey(activePointerId) - ? mLastEventCoodinatesByPointerId.get(activePointerId) + mLastEventCoordinatesByPointerId != null + && mLastEventCoordinatesByPointerId.containsKey(activePointerId) + ? mLastEventCoordinatesByPointerId.get(activePointerId) : new float[] {0, 0}; boolean qualifiedMove = - (Math.abs(lastEventCoordinates[0] - x) > ONMOVE_EPSILON - || Math.abs(lastEventCoordinates[1] - y) > ONMOVE_EPSILON); + (Math.abs(lastEventCoordinates[0] - eventCoordinates[0]) > ONMOVE_EPSILON + || Math.abs(lastEventCoordinates[1] - eventCoordinates[1]) > ONMOVE_EPSILON); - // Early exit + // Early exit if active pointer has not moved enough if (!qualifiedMove) { return; } @@ -342,14 +358,14 @@ public class JSPointerDispatcher { boolean nonDivergentListeningToEnter = false; boolean nonDivergentListeningToLeave = false; int firstDivergentIndexFromBack = 0; - while (firstDivergentIndexFromBack < Math.min(hitPath.size(), lastHitPath.size()) - && hitPath - .get(hitPath.size() - 1 - firstDivergentIndexFromBack) + while (firstDivergentIndexFromBack < Math.min(activeHitPath.size(), lastHitPath.size()) + && activeHitPath + .get(activeHitPath.size() - 1 - firstDivergentIndexFromBack) .equals(lastHitPath.get(lastHitPath.size() - 1 - firstDivergentIndexFromBack))) { // Track if any non-diverging views are listening to enter/leave View nonDivergentViewTargetView = - hitPath.get(hitPath.size() - 1 - firstDivergentIndexFromBack).getView(); + activeHitPath.get(activeHitPath.size() - 1 - firstDivergentIndexFromBack).getView(); if (!nonDivergentListeningToEnter && PointerEventHelper.isListening(nonDivergentViewTargetView, EVENT.ENTER_CAPTURE)) { nonDivergentListeningToEnter = true; @@ -363,7 +379,7 @@ public class JSPointerDispatcher { } boolean hasDiverged = - firstDivergentIndexFromBack < Math.max(hitPath.size(), lastHitPath.size()); + firstDivergentIndexFromBack < Math.max(activeHitPath.size(), lastHitPath.size()); if (hasDiverged) { // If something has changed in either enter/exit, let's start a new coalescing key @@ -399,7 +415,7 @@ public class JSPointerDispatcher { } boolean listeningForOver = - isAnyoneListeningForBubblingEvent(hitPath, EVENT.OVER, EVENT.OVER_CAPTURE); + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.OVER, EVENT.OVER_CAPTURE); if (listeningForOver) { eventDispatcher.dispatchEvent( PointerEvent.obtain( @@ -409,7 +425,7 @@ public class JSPointerDispatcher { // target -> root List enterViewTargets = filterByShouldDispatch( - hitPath.subList(0, hitPath.size() - firstDivergentIndexFromBack), + activeHitPath.subList(0, activeHitPath.size() - firstDivergentIndexFromBack), EVENT.ENTER, EVENT.ENTER_CAPTURE, nonDivergentListeningToEnter); @@ -427,7 +443,7 @@ public class JSPointerDispatcher { } boolean listeningToMove = - isAnyoneListeningForBubblingEvent(hitPath, EVENT.MOVE, EVENT.MOVE_CAPTURE); + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.MOVE, EVENT.MOVE_CAPTURE); if (listeningToMove) { eventDispatcher.dispatchEvent( PointerEvent.obtain( @@ -437,9 +453,6 @@ public class JSPointerDispatcher { motionEvent, getCoalescingKey())); } - - mLastHitPathByPointerId.put(activePointerId, hitPath); - mLastEventCoodinatesByPointerId.put(activePointerId, new float[] {x, y}); } private void dispatchCancelEvent(MotionEvent motionEvent, EventDispatcher eventDispatcher) { @@ -447,28 +460,12 @@ public class JSPointerDispatcher { mChildHandlingNativeGesture == -1, "Expected to not have already sent a cancel for this gesture"); - float[] targetCoordinates = new float[2]; - List 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); + PointerEventState eventState = createEventState(motionEvent); + dispatchCancelEvent(eventState, motionEvent, eventDispatcher); } private void dispatchCancelEvent( - PointerEventState eventState, - List hitPath, - MotionEvent motionEvent, - EventDispatcher eventDispatcher) { + PointerEventState eventState, MotionEvent motionEvent, 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. @@ -476,11 +473,14 @@ public class JSPointerDispatcher { mChildHandlingNativeGesture == -1, "Expected to not have already sent a cancel for this gesture"); - if (!hitPath.isEmpty()) { + List activeHitPath = + eventState.getHitPathByPointerId().get(eventState.getActivePointerId()); + + if (!activeHitPath.isEmpty()) { boolean listeningForCancel = - isAnyoneListeningForBubblingEvent(hitPath, EVENT.CANCEL, EVENT.CANCEL_CAPTURE); + isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.CANCEL, EVENT.CANCEL_CAPTURE); if (listeningForCancel) { - int targetTag = hitPath.get(0).getViewId(); + int targetTag = activeHitPath.get(0).getViewId(); Assertions.assertNotNull(eventDispatcher) .dispatchEvent( PointerEvent.obtain( @@ -490,7 +490,7 @@ public class JSPointerDispatcher { // TODO(luwe) - Need to fire pointer out here as well: // https://w3c.github.io/pointerevents/#dfn-suppress-a-pointer-event-stream List leaveViewTargets = - filterByShouldDispatch(hitPath, EVENT.LEAVE, EVENT.LEAVE_CAPTURE, false); + filterByShouldDispatch(activeHitPath, EVENT.LEAVE, EVENT.LEAVE_CAPTURE, false); // dispatch from target -> root dispatchEventForViewTargets( diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/PointerEventState.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/PointerEventState.java deleted file mode 100644 index 0a23011d456..00000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/PointerEventState.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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; -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java index d2a3eda421d..67534e698ac 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java @@ -15,10 +15,11 @@ 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 com.facebook.react.uimanager.TouchTargetHelper; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; public class PointerEvent extends Event { private static final String TAG = PointerEvent.class.getSimpleName(); @@ -73,7 +74,7 @@ public class PointerEvent extends Event { MotionEvent motionEventToCopy, short coalescingKey) { - super.init(eventState.surfaceId, targetTag, motionEventToCopy.getEventTime()); + super.init(eventState.getSurfaceId(), targetTag, motionEventToCopy.getEventTime()); mEventName = eventName; mMotionEvent = MotionEvent.obtain(motionEventToCopy); mCoalescingKey = coalescingKey; @@ -137,18 +138,17 @@ public class PointerEvent extends Event { } } - private ArrayList createPointerEvents() { - MotionEvent motionEvent = mMotionEvent; - ArrayList pointerEvents = new ArrayList<>(); + private List createW3CPointerEvents() { - for (int index = 0; index < motionEvent.getPointerCount(); index++) { - pointerEvents.add(this.createPointerEventData(index)); + ArrayList w3cPointerEvents = new ArrayList<>(); + for (int index = 0; index < mMotionEvent.getPointerCount(); index++) { + w3cPointerEvents.add(this.createW3CPointerEvent(index)); } - return pointerEvents; + return w3cPointerEvents; } - private WritableMap createPointerEventData(int index) { + private WritableMap createW3CPointerEvent(int index) { WritableMap pointerEvent = Arguments.createMap(); int pointerId = mMotionEvent.getPointerId(index); @@ -161,13 +161,14 @@ public class PointerEvent extends Event { pointerEvent.putBoolean( "isPrimary", - PointerEventHelper.isPrimary(pointerId, mEventState.primaryPointerId, mMotionEvent)); + PointerEventHelper.isPrimary(pointerId, mEventState.getPrimaryPointerId(), mMotionEvent)); // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent // Client refers to upper left edge of the content area (viewport) // We define the viewport to be ReactRootView - double clientX = PixelUtil.toDIPFromPixel(mMotionEvent.getX(index)); - double clientY = PixelUtil.toDIPFromPixel(mMotionEvent.getY(index)); + float[] eventCoords = mEventState.getEventCoordinatesByPointerId().get(pointerId); + double clientX = PixelUtil.toDIPFromPixel(eventCoords[0]); + double clientY = PixelUtil.toDIPFromPixel(eventCoords[1]); pointerEvent.putDouble("clientX", clientX); pointerEvent.putDouble("clientY", clientY); @@ -180,8 +181,9 @@ public class PointerEvent extends Event { pointerEvent.putDouble("pageY", clientY); // Offset refers to upper left edge of the target view - pointerEvent.putDouble("offsetX", PixelUtil.toDIPFromPixel(mEventState.offsetCoords[0])); - pointerEvent.putDouble("offsetY", PixelUtil.toDIPFromPixel(mEventState.offsetCoords[1])); + float[] offsetCoords = mEventState.getOffsetByPointerId().get(pointerId); + pointerEvent.putDouble("offsetX", PixelUtil.toDIPFromPixel(offsetCoords[0])); + pointerEvent.putDouble("offsetY", PixelUtil.toDIPFromPixel(offsetCoords[1])); pointerEvent.putInt("target", this.getViewTag()); pointerEvent.putDouble("timestamp", this.getTimestampMs()); @@ -193,8 +195,10 @@ public class PointerEvent extends Event { pointerEvent.putDouble("tiltY", 0); } - pointerEvent.putInt("buttons", mEventState.buttons); - pointerEvent.putInt("button", mEventState.button); + int buttons = mMotionEvent.getButtonState(); + pointerEvent.putInt("buttons", buttons); + pointerEvent.putInt( + "button", PointerEventHelper.getButtonChange(mEventState.getLastButtonState(), buttons)); return pointerEvent; } @@ -206,7 +210,7 @@ public class PointerEvent extends Event { // Cases where all pointer info is relevant case PointerEventHelper.POINTER_MOVE: case PointerEventHelper.POINTER_CANCEL: - pointersEventData = createPointerEvents(); + pointersEventData = this.createW3CPointerEvents(); break; // Cases where only the "active" pointer info is relevant case PointerEventHelper.POINTER_ENTER: @@ -215,7 +219,7 @@ public class PointerEvent extends Event { case PointerEventHelper.POINTER_LEAVE: case PointerEventHelper.POINTER_OUT: case PointerEventHelper.POINTER_OVER: - pointersEventData = Arrays.asList(createPointerEventData(activePointerIndex)); + pointersEventData = Arrays.asList(createW3CPointerEvent(activePointerIndex)); break; } @@ -259,4 +263,60 @@ public class PointerEvent extends Event { PointerEventHelper.getEventCategory(mEventName)); } } + + public static class PointerEventState { + private int mPrimaryPointerId; + private int mActivePointerId; + private int mLastButtonState; + private int mSurfaceId; + + private Map mOffsetByPointerId; + private Map> mHitPathByPointerId; + private Map mEventCoordinatesByPointerId; + + public PointerEventState( + int primaryPointerId, + int activePointerId, + int lastButtonState, + int surfaceId, + Map offsetByPointerId, + Map> hitPathByPointerId, + Map eventCoordinatesByPointerId) { + mPrimaryPointerId = primaryPointerId; + mActivePointerId = activePointerId; + mLastButtonState = lastButtonState; + mSurfaceId = surfaceId; + mOffsetByPointerId = offsetByPointerId; + mHitPathByPointerId = hitPathByPointerId; + mEventCoordinatesByPointerId = eventCoordinatesByPointerId; + } + + public int getLastButtonState() { + return mLastButtonState; + } + + public int getPrimaryPointerId() { + return mPrimaryPointerId; + } + + public int getSurfaceId() { + return mSurfaceId; + } + + public int getActivePointerId() { + return mActivePointerId; + } + + public final Map getOffsetByPointerId() { + return mOffsetByPointerId; + } + + public final Map> getHitPathByPointerId() { + return mHitPathByPointerId; + } + + public final Map getEventCoordinatesByPointerId() { + return mEventCoordinatesByPointerId; + } + } }