From 8ba4a2f127ee5fd862f2bb573ded50abce70c048 Mon Sep 17 00:00:00 2001 From: Andrei Shikov Date: Wed, 13 Oct 2021 08:21:38 -0700 Subject: [PATCH] Define event category in Event class Summary: Propagate event category definition to every event that is using `dispatchModernV2` (gated in production), providing opportunity to override categories of some events if needed. No events are meaningfully affected by this change, as coalesced events (e.g. scroll) are always dispatched as continuous and touch events are handled separately. Changelog: [Internal] Expose event category in Event class Reviewed By: cortinico Differential Revision: D31276249 fbshipit-source-id: f9a756b3a5cf5897e17209f3d0aed6a1c16cbd2e --- .../react/fabric/FabricUIManager.java | 2 +- .../fabric/events/EventEmitterWrapper.java | 1 + .../fabric/events/FabricEventEmitter.java | 33 ++++++++++++------- .../react/uimanager/events/Event.java | 8 ++++- .../events/EventCategoryDef.java | 12 +++---- .../events/RCTModernEventEmitter.java | 3 +- .../uimanager/events/ReactEventEmitter.java | 13 ++++++-- 7 files changed, 48 insertions(+), 24 deletions(-) rename ReactAndroid/src/main/java/com/facebook/react/{fabric => uimanager}/events/EventCategoryDef.java (71%) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 44a81cd0310..270b9466b0d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -54,7 +54,6 @@ import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.react.common.mapbuffer.ReadableMapBuffer; import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.fabric.events.EventBeatManager; -import com.facebook.react.fabric.events.EventCategoryDef; import com.facebook.react.fabric.events.EventEmitterWrapper; import com.facebook.react.fabric.events.FabricEventEmitter; import com.facebook.react.fabric.mounting.MountItemDispatcher; @@ -78,6 +77,7 @@ import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.ViewManagerPropertyUpdater; import com.facebook.react.uimanager.ViewManagerRegistry; +import com.facebook.react.uimanager.events.EventCategoryDef; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.EventDispatcherImpl; import com.facebook.react.uimanager.events.LockFreeEventDispatcherImpl; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java index dc875cea1dc..24d33be42f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java @@ -16,6 +16,7 @@ import com.facebook.react.bridge.NativeMap; import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeMap; import com.facebook.react.fabric.FabricSoLoader; +import com.facebook.react.uimanager.events.EventCategoryDef; /** * This class holds reference to the C++ EventEmitter object. Instances of this class are created on diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java index 71cafaabd3c..983466ab382 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java @@ -22,6 +22,7 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeArray; import com.facebook.react.bridge.WritableNativeMap; import com.facebook.react.fabric.FabricUIManager; +import com.facebook.react.uimanager.events.EventCategoryDef; import com.facebook.react.uimanager.events.RCTModernEventEmitter; import com.facebook.react.uimanager.events.TouchEventType; import com.facebook.systrace.Systrace; @@ -46,7 +47,7 @@ public class FabricEventEmitter implements RCTModernEventEmitter { @Override public void receiveEvent( int surfaceId, int reactTag, String eventName, @Nullable WritableMap params) { - receiveEvent(surfaceId, reactTag, eventName, false, 0, params); + receiveEvent(surfaceId, reactTag, eventName, false, 0, params, EventCategoryDef.UNSPECIFIED); } @Override @@ -56,37 +57,46 @@ public class FabricEventEmitter implements RCTModernEventEmitter { String eventName, boolean canCoalesceEvent, int customCoalesceKey, - @Nullable WritableMap params) { + @Nullable WritableMap params, + @EventCategoryDef int category) { Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricEventEmitter.receiveEvent('" + eventName + "')"); mUIManager.receiveEvent( - surfaceId, reactTag, eventName, canCoalesceEvent, customCoalesceKey, params); + surfaceId, reactTag, eventName, canCoalesceEvent, customCoalesceKey, params, category); Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); } + /** + * Processes touches in a JS compatible way and send it to Fabric core + * + * @param eventName the event name (see {@link TouchEventType}) + * @param touches all the touch data extracted from MotionEvent + * @param changedIndices the indices of the pointers that changed (MOVE/CANCEL includes all + * touches, START/END only the one that was added/removed) + */ @Override public void receiveTouches( - @NonNull String eventTopLevelType, + @NonNull String eventName, @NonNull WritableArray touches, @NonNull WritableArray changedIndices) { Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricEventEmitter.receiveTouches('" + eventTopLevelType + "')"); + "FabricEventEmitter.receiveTouches('" + eventName + "')"); - boolean isPointerEndEvent = - TouchEventType.END.getJsName().equalsIgnoreCase(eventTopLevelType) - || TouchEventType.CANCEL.getJsName().equalsIgnoreCase(eventTopLevelType); + boolean isFinalEvent = + TouchEventType.END.getJsName().equalsIgnoreCase(eventName) + || TouchEventType.CANCEL.getJsName().equalsIgnoreCase(eventName); Pair result = - isPointerEndEvent + isFinalEvent ? removeTouchesAtIndices(touches, changedIndices) : touchSubsequence(touches, changedIndices); WritableArray changedTouches = result.first; touches = result.second; - int eventCategory = getTouchCategory(eventTopLevelType); + int eventCategory = getTouchCategory(eventName); for (int jj = 0; jj < changedTouches.size(); jj++) { WritableMap touch = getWritableMap(changedTouches.getMap(jj)); // Touch objects can fulfill the role of `DOM` `Event` objects if we set @@ -104,8 +114,7 @@ public class FabricEventEmitter implements RCTModernEventEmitter { rootNodeID = targetReactTag; } - mUIManager.receiveEvent( - targetSurfaceId, rootNodeID, eventTopLevelType, false, 0, touch, eventCategory); + receiveEvent(targetSurfaceId, rootNodeID, eventName, false, 0, touch, eventCategory); } Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java index 22ba9149955..2ffb063c966 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java @@ -182,6 +182,11 @@ public abstract class Event { return null; } + @EventCategoryDef + protected int getEventCategory() { + return EventCategoryDef.UNSPECIFIED; + } + /** * Dispatch this event to JS using a V2 EventEmitter. If surfaceId is not -1 and `getEventData` is * non-null, this will use the RCTModernEventEmitter API. Otherwise, it falls back to the @@ -215,7 +220,8 @@ public abstract class Event { getEventName(), canCoalesce(), getCoalescingKey(), - eventData); + eventData, + getEventCategory()); return; } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventCategoryDef.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventCategoryDef.java similarity index 71% rename from ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventCategoryDef.java rename to ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventCategoryDef.java index f55fa701c02..60c5a50df78 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventCategoryDef.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventCategoryDef.java @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -package com.facebook.react.fabric.events; +package com.facebook.react.uimanager.events; -import static com.facebook.react.fabric.events.EventCategoryDef.CONTINUOUS; -import static com.facebook.react.fabric.events.EventCategoryDef.CONTINUOUS_END; -import static com.facebook.react.fabric.events.EventCategoryDef.CONTINUOUS_START; -import static com.facebook.react.fabric.events.EventCategoryDef.DISCRETE; -import static com.facebook.react.fabric.events.EventCategoryDef.UNSPECIFIED; +import static com.facebook.react.uimanager.events.EventCategoryDef.CONTINUOUS; +import static com.facebook.react.uimanager.events.EventCategoryDef.CONTINUOUS_END; +import static com.facebook.react.uimanager.events.EventCategoryDef.CONTINUOUS_START; +import static com.facebook.react.uimanager.events.EventCategoryDef.DISCRETE; +import static com.facebook.react.uimanager.events.EventCategoryDef.UNSPECIFIED; import androidx.annotation.IntDef; diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java index 47fbd764165..4466e07b11c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.java @@ -28,5 +28,6 @@ public interface RCTModernEventEmitter extends RCTEventEmitter { String eventName, boolean canCoalesceEvent, int customCoalesceKey, - @Nullable WritableMap event); + @Nullable WritableMap event, + @EventCategoryDef int category); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java index c99cb277ba9..1ab5400106e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java @@ -64,7 +64,7 @@ public class ReactEventEmitter implements RCTModernEventEmitter { int surfaceId, int targetTag, String eventName, @Nullable WritableMap event) { // The two additional params here, `canCoalesceEvent` and `customCoalesceKey`, have no // meaning outside of Fabric. - receiveEvent(surfaceId, targetTag, eventName, false, 0, event); + receiveEvent(surfaceId, targetTag, eventName, false, 0, event, EventCategoryDef.UNSPECIFIED); } @Override @@ -120,11 +120,18 @@ public class ReactEventEmitter implements RCTModernEventEmitter { String eventName, boolean canCoalesceEvent, int customCoalesceKey, - @Nullable WritableMap event) { + @Nullable WritableMap event, + @EventCategoryDef int category) { @UIManagerType int uiManagerType = ViewUtil.getUIManagerType(targetReactTag); if (uiManagerType == UIManagerType.FABRIC && mFabricEventEmitter != null) { mFabricEventEmitter.receiveEvent( - surfaceId, targetReactTag, eventName, canCoalesceEvent, customCoalesceKey, event); + surfaceId, + targetReactTag, + eventName, + canCoalesceEvent, + customCoalesceKey, + event, + category); } else if (uiManagerType == UIManagerType.DEFAULT && getEventEmitter(targetReactTag) != null) { mRCTEventEmitter.receiveEvent(targetReactTag, eventName, event); } else {