diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java index 9ed40b823..c80266335 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java @@ -11,7 +11,6 @@ package com.facebook.react.animated; import android.util.SparseArray; -import com.facebook.infer.annotation.Assertions; import com.facebook.common.logging.FLog; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; @@ -59,7 +58,7 @@ import javax.annotation.Nullable; // Mapping of a view tag and an event name to a list of event animation drivers. 99% of the time // there will be only one driver per mapping so all code code should be optimized around that. private final Map> mEventDrivers = new HashMap<>(); - private final Map> mCustomEventTypes; + private final UIManagerModule.CustomEventNamesResolver mCustomEventNamesResolver; private final UIImplementation mUIImplementation; private int mAnimatedGraphBFSColor = 0; // Used to avoid allocating a new array on every frame in `runUpdates` and `onEventDispatch`. @@ -68,8 +67,7 @@ import javax.annotation.Nullable; public NativeAnimatedNodesManager(UIManagerModule uiManager) { mUIImplementation = uiManager.getUIImplementation(); uiManager.getEventDispatcher().addListener(this); - Object customEventTypes = Assertions.assertNotNull(uiManager.getConstants()).get("customDirectEventTypes"); - mCustomEventTypes = (Map>) customEventTypes; + mCustomEventNamesResolver = uiManager.getDirectEventNamesResolver(); } /*package*/ @Nullable AnimatedNode getNodeById(int id) { @@ -371,12 +369,7 @@ import javax.annotation.Nullable; if (!mEventDrivers.isEmpty()) { // If the event has a different name in native convert it to it's JS name. - String eventName = event.getEventName(); - Map customEventType = mCustomEventTypes.get(eventName); - if (customEventType != null) { - eventName = customEventType.get("registrationName"); - } - + String eventName = mCustomEventNamesResolver.resolveCustomEventName(event.getEventName()); List driversForKey = mEventDrivers.get(event.getViewTag() + eventName); if (driversForKey != null) { for (EventAnimationDriver driver : driversForKey) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 7fc14a632..15aa06bf9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -70,6 +70,17 @@ import javax.annotation.Nullable; public class UIManagerModule extends ReactContextBaseJavaModule implements OnBatchCompleteListener, LifecycleEventListener, PerformanceCounter { + + /** + * Resolves a name coming from native side to a name of the event that is exposed to JS. + */ + public interface CustomEventNamesResolver { + /** + * Returns custom event name by the provided event name. + */ + @Nullable String resolveCustomEventName(String eventName); + } + protected static final String NAME = "UIManager"; private static final boolean DEBUG = false; @@ -164,6 +175,27 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements } } + /** + * Resolves Direct Event name exposed to JS from the one known to the Native side. + */ + public CustomEventNamesResolver getDirectEventNamesResolver() { + return new CustomEventNamesResolver() { + @Override + public @Nullable String resolveCustomEventName(String eventName) { + Map directEventTypes = + (Map) getConstants().get( + UIManagerModuleConstantsHelper.CUSTOM_DIRECT_EVENT_TYPES_KEY); + if (directEventTypes != null) { + Map customEventType = (Map) directEventTypes.get(eventName); + if (customEventType != null) { + return customEventType.get("registrationName"); + } + } + return eventName; + } + }; + } + @Override public Map getPerformanceCounters() { return mUIImplementation.getProfiledBatchPerfCounters(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java index d90842f0f..905b3f669 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java @@ -12,7 +12,6 @@ package com.facebook.react.uimanager; import java.util.List; import java.util.Map; -import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.common.MapBuilder; import com.facebook.systrace.Systrace; import com.facebook.systrace.SystraceMessage; @@ -25,8 +24,8 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE; */ /* package */ class UIManagerModuleConstantsHelper { - private static final String CUSTOM_BUBBLING_EVENT_TYPES_KEY = "customBubblingEventTypes"; - private static final String CUSTOM_DIRECT_EVENT_TYPES_KEY = "customDirectEventTypes"; + /* package */ static final String CUSTOM_BUBBLING_EVENT_TYPES_KEY = "customBubblingEventTypes"; + /* package */ static final String CUSTOM_DIRECT_EVENT_TYPES_KEY = "customDirectEventTypes"; /** * Generates map of constants that is then exposed by {@link UIManagerModule}. @@ -41,8 +40,7 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE; * TODO(6845124): Create a test for this */ /* package */ static Map createConstants( - List viewManagers, - boolean lazyViewManagersEnabled) { + List viewManagers, boolean lazyViewManagersEnabled) { Map constants = UIManagerModuleConstants.getConstants(); // Generic/default event types: @@ -69,18 +67,20 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE; if (viewManagerBubblingEvents != null) { recursiveMerge(allBubblingEventTypes, viewManagerBubblingEvents); recursiveMerge(viewManagerBubblingEvents, genericBubblingEventTypes); - viewManagerConstants.put("bubblingEventTypes", viewManagerBubblingEvents); } else { - viewManagerConstants.put("bubblingEventTypes", genericBubblingEventTypes); + viewManagerBubblingEvents = genericBubblingEventTypes; } + viewManagerConstants.put("bubblingEventTypes", viewManagerBubblingEvents); + Map viewManagerDirectEvents = viewManager.getExportedCustomDirectEventTypeConstants(); if (viewManagerDirectEvents != null) { recursiveMerge(allDirectEventTypes, viewManagerDirectEvents); recursiveMerge(viewManagerDirectEvents, genericDirectEventTypes); - viewManagerConstants.put("directEventTypes", viewManagerDirectEvents); } else { - viewManagerConstants.put("directEventTypes", genericDirectEventTypes); + viewManagerDirectEvents = genericDirectEventTypes; } + viewManagerConstants.put("directEventTypes", viewManagerDirectEvents); + Map customViewConstants = viewManager.getExportedViewConstants(); if (customViewConstants != null) { viewManagerConstants.put("Constants", customViewConstants); diff --git a/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java b/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java index ced79811c..0a172d193 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.java @@ -22,6 +22,8 @@ import com.facebook.react.uimanager.events.Event; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.RCTEventEmitter; +import java.util.Map; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -108,6 +110,27 @@ public class NativeAnimatedNodeTraversalTest { return MapBuilder.of("customDirectEventTypes", MapBuilder.newHashMap()); } }); + PowerMockito + .when(mUIManagerMock.getDirectEventNamesResolver()) + .thenAnswer(new Answer() { + @Override + public UIManagerModule.CustomEventNamesResolver answer(InvocationOnMock invocation) throws Throwable { + return new UIManagerModule.CustomEventNamesResolver() { + @Override + public String resolveCustomEventName(String eventName) { + Map directEventTypes = + (Map) mUIManagerMock.getConstants().get("customDirectEventTypes"); + if (directEventTypes != null) { + Map customEventType = (Map) directEventTypes.get(eventName); + if (customEventType != null) { + return customEventType.get("registrationName"); + } + } + return eventName; + } + }; + } + }); mNativeAnimatedNodesManager = new NativeAnimatedNodesManager(mUIManagerMock); }