diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 9c29ee6213de..066dd9d8b29e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -1199,42 +1199,22 @@ public void receiveEvent( return; } - EventEmitterWrapper eventEmitter = mMountingManager.getEventEmitter(surfaceId, reactTag); - if (eventEmitter == null) { - if (mMountingManager.getViewExists(reactTag)) { - // The view is pre-allocated and created. However, it hasn't been mounted yet. We will have - // access to the event emitter later when the view is mounted. For now just save the event - // in the view state and trigger it later. - mMountingManager.enqueuePendingEvent( - surfaceId, - reactTag, - eventName, - canCoalesceEvent, - params, - eventCategory, - eventTimestamp); - } else { - // This can happen if the view has disappeared from the screen (because of async events) - FLog.i(TAG, "Unable to invoke event: " + eventName + " for reactTag: " + reactTag); - } - return; - } - if (experimentalIsSynchronous) { UiThreadUtil.assertOnUiThread(); - // add() returns true only if there are no equivalent events already in the set - boolean firstEventForFrame = - mSynchronousEvents.add(new SynchronousEvent(surfaceId, reactTag, eventName)); - if (firstEventForFrame) { - eventEmitter.dispatchEventSynchronously(eventName, params, eventTimestamp); - } - } else { - if (canCoalesceEvent) { - eventEmitter.dispatchUnique(eventName, params, eventTimestamp); - } else { - eventEmitter.dispatch(eventName, params, eventCategory, eventTimestamp); + EventEmitterWrapper eventEmitter = mMountingManager.getEventEmitter(surfaceId, reactTag); + if (eventEmitter != null) { + // add() returns true only if there are no equivalent events already in the set + boolean firstEventForFrame = + mSynchronousEvents.add(new SynchronousEvent(surfaceId, reactTag, eventName)); + if (firstEventForFrame) { + eventEmitter.dispatchEventSynchronously(eventName, params, eventTimestamp); + } + return; } } + + mMountingManager.dispatchEvent( + surfaceId, reactTag, eventName, canCoalesceEvent, params, eventCategory, eventTimestamp); } @Override diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt index aa0365037ec2..60c11be0be64 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt @@ -327,7 +327,7 @@ internal class MountingManager( attachmentsPositions, ) - fun enqueuePendingEvent( + fun dispatchEvent( surfaceId: Int, reactTag: Int, eventName: String, @@ -338,22 +338,16 @@ internal class MountingManager( ) { val smm = getSurfaceMountingManager(surfaceId, reactTag) if (smm == null) { - FLog.d( + FLog.i( TAG, - "Cannot queue event without valid surface mounting manager for tag: %d, surfaceId: %d", + "Unable to invoke event %s for tag [%d] in surfaceId [%d]", + eventName, reactTag, surfaceId, ) return } - smm.enqueuePendingEvent( - reactTag, - eventName, - canCoalesceEvent, - params, - eventCategory, - eventTimestamp, - ) + smm.dispatchEvent(reactTag, eventName, canCoalesceEvent, params, eventCategory, eventTimestamp) } private fun getSurfaceMountingManager(surfaceId: Int, reactTag: Int): SurfaceMountingManager? = diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt index 9e53dc8c365b..8b2feba623ca 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt @@ -1241,6 +1241,45 @@ internal constructor( } } + @AnyThread + internal fun dispatchEvent( + reactTag: Int, + eventName: String, + canCoalesceEvent: Boolean, + params: WritableMap?, + @EventCategoryDef eventCategory: Int, + eventTimestamp: Long, + ) { + val viewState = registryGet(reactTag) + if (viewState == null) { + // This can happen if the view has disappeared from the screen (because of async events) + FLog.i(TAG, "Unable to invoke event: %s for reactTag: %d", eventName, reactTag) + return + } + + val eventEmitter = viewState.eventEmitter + if (eventEmitter == null) { + // The view is pre-allocated and created. However, it hasn't been mounted yet. We will have + // access to the event emitter later when the view is mounted. For now just save the event + // in the view state and trigger it later. + enqueuePendingEvent( + reactTag, + eventName, + canCoalesceEvent, + params, + eventCategory, + eventTimestamp, + ) + return + } + + if (canCoalesceEvent) { + eventEmitter.dispatchUnique(eventName, params, eventTimestamp) + } else { + eventEmitter.dispatch(eventName, params, eventCategory, eventTimestamp) + } + } + public fun markActiveTouchForTag(reactTag: Int): Unit { viewsWithActiveTouches.add(reactTag) }