From 4167c4f2a678bca983d9a0e59ff50fdafacb88c6 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Wed, 13 Jul 2022 15:45:45 -0700 Subject: [PATCH] Support legacy event emitter Summary: Changelog: [Internal] - Add support for legacy event emitter for PointerEvents because it's used by natively driven Animated events It works by * [NativeAnimatedNodesManager being a listener on every event dispatched](https://www.internalfb.com/code/fbsource/[b8fc8603f8d84003bcb73ec84e8490c136df290c]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java?lines=115-117) * NativeAnimatedNodesManager [re-dispatching the event onto an EventAnimationDriver to update the animated value.](https://www.internalfb.com/code/fbsource/[d5403bc1fa55a68d9346ac693378551b734c565b]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java?lines=597) As such, we need to make sure to implement the legacy event dispatch function. Reviewed By: vincentriemer Differential Revision: D37769785 fbshipit-source-id: c570896afc624193fdb636a302e9613ca6fee14d --- .../react/uimanager/events/PointerEvent.java | 73 +++++++++++++------ 1 file changed, 51 insertions(+), 22 deletions(-) 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 d577163b56a..e5ca07139b9 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 @@ -72,6 +72,7 @@ public class PointerEvent extends Event { private int mCoalescingKey = UNSET_COALESCING_KEY; private float mOffsetX; private float mOffsetY; + private @Nullable List mPointersEventData; private void init( String eventName, @@ -98,12 +99,33 @@ public class PointerEvent extends Event { @Override public void dispatch(RCTEventEmitter rctEventEmitter) { - // Skip legacy stuff for now? + if (mMotionEvent == null) { + ReactSoftExceptionLogger.logSoftException( + TAG, + new IllegalStateException( + "Cannot dispatch a Pointer that has no MotionEvent; the PointerEvehas been recycled")); + return; + } + if (mPointersEventData == null) { + mPointersEventData = createPointersEventData(); + } + + if (mPointersEventData == null) { + // No relevant MotionEvent to dispatch + return; + } + + boolean shouldCopy = mPointersEventData.size() > 1; + for (WritableMap pointerEventData : mPointersEventData) { + WritableMap eventData = shouldCopy ? pointerEventData.copy() : pointerEventData; + rctEventEmitter.receiveEvent(this.getViewTag(), mEventName, eventData); + } return; } @Override public void onDispose() { + mPointersEventData = null; MotionEvent motionEvent = mMotionEvent; mMotionEvent = null; if (motionEvent != null) { @@ -130,13 +152,13 @@ public class PointerEvent extends Event { ArrayList pointerEvents = new ArrayList<>(); for (int index = 0; index < motionEvent.getPointerCount(); index++) { - pointerEvents.add(this.createPointerEvent(index)); + pointerEvents.add(this.createPointerEventData(index)); } return pointerEvents; } - private WritableMap createPointerEvent(int index) { + private WritableMap createPointerEventData(int index) { WritableMap pointerEvent = Arguments.createMap(); pointerEvent.putDouble("pointerId", mMotionEvent.getPointerId(index)); @@ -158,6 +180,27 @@ public class PointerEvent extends Event { return pointerEvent; } + private List createPointersEventData() { + int activePointerIndex = mMotionEvent.getActionIndex(); + List pointersEventData = null; + switch (mEventName) { + // Cases where all pointer info is relevant + case PointerEventHelper.POINTER_MOVE: + case PointerEventHelper.POINTER_CANCEL: + pointersEventData = createPointerEvents(); + break; + // Cases where only the "active" pointer info is relevant + case PointerEventHelper.POINTER_ENTER: + case PointerEventHelper.POINTER_DOWN: + case PointerEventHelper.POINTER_UP: + case PointerEventHelper.POINTER_LEAVE: + pointersEventData = Arrays.asList(createPointerEventData(activePointerIndex)); + break; + } + + return pointersEventData; + } + @Override public void dispatchModern(RCTModernEventEmitter rctEventEmitter) { if (mMotionEvent == null) { @@ -168,31 +211,17 @@ public class PointerEvent extends Event { return; } - List relevantPointerEventData = null; - - int activePointerIndex = mMotionEvent.getActionIndex(); - switch (mEventName) { - // Cases where all pointer info is relevant - case PointerEventHelper.POINTER_MOVE: - case PointerEventHelper.POINTER_CANCEL: - relevantPointerEventData = createPointerEvents(); - break; - // Cases where only the "active" pointer info is relevant - case PointerEventHelper.POINTER_ENTER: - case PointerEventHelper.POINTER_DOWN: - case PointerEventHelper.POINTER_UP: - case PointerEventHelper.POINTER_LEAVE: - relevantPointerEventData = Arrays.asList(createPointerEvent(activePointerIndex)); - break; + if (mPointersEventData == null) { + mPointersEventData = createPointersEventData(); } - if (relevantPointerEventData == null) { + if (mPointersEventData == null) { // No relevant MotionEvent to dispatch return; } - boolean shouldCopy = relevantPointerEventData.size() > 1; - for (WritableMap pointerEventData : relevantPointerEventData) { + boolean shouldCopy = mPointersEventData.size() > 1; + for (WritableMap pointerEventData : mPointersEventData) { WritableMap eventData = shouldCopy ? pointerEventData.copy() : pointerEventData; rctEventEmitter.receiveEvent( this.getSurfaceId(),