diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 755f4d8d7a720e..74e7e2df4ea499 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2541,7 +2541,7 @@ public class com/facebook/react/fabric/FabricSoLoader { public static fun staticInit ()V } -public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/UIManager { +public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/UIManager, com/facebook/react/fabric/interop/UIBlockViewResolver { public static final field ENABLE_FABRIC_LOGS Z public static final field ENABLE_FABRIC_PERF_LOGS Z public static final field IS_DEVELOPMENT_ENVIRONMENT Z 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 476dd2318d3bd0..9812b59aad18b6 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 @@ -57,6 +57,7 @@ import com.facebook.react.fabric.events.FabricEventEmitter; import com.facebook.react.fabric.internal.interop.InteropUIBlockListener; import com.facebook.react.fabric.interop.UIBlock; +import com.facebook.react.fabric.interop.UIBlockViewResolver; import com.facebook.react.fabric.mounting.MountItemDispatcher; import com.facebook.react.fabric.mounting.MountingManager; import com.facebook.react.fabric.mounting.SurfaceMountingManager; @@ -99,7 +100,7 @@ */ @SuppressLint("MissingNativeLoadLibrary") @DoNotStripAny -public class FabricUIManager implements UIManager, LifecycleEventListener { +public class FabricUIManager implements UIManager, LifecycleEventListener, UIBlockViewResolver { public static final String TAG = FabricUIManager.class.getSimpleName(); // The IS_DEVELOPMENT_ENVIRONMENT variable is used to log extra data when running fabric in a diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt index a3acebecac68a4..5435a35dbe1346 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt @@ -39,6 +39,9 @@ internal class InteropUIBlockListener : UIManagerListener { } override fun willMountItems(uiManager: UIManager) { + if (beforeUIBlocks.isEmpty()) { + return + } beforeUIBlocks.forEach { if (uiManager is UIBlockViewResolver) { it.execute(uiManager) @@ -48,6 +51,9 @@ internal class InteropUIBlockListener : UIManagerListener { } override fun didMountItems(uiManager: UIManager) { + if (afterUIBlocks.isEmpty()) { + return + } afterUIBlocks.forEach { if (uiManager is UIBlockViewResolver) { it.execute(uiManager) @@ -56,9 +62,9 @@ internal class InteropUIBlockListener : UIManagerListener { afterUIBlocks.clear() } - override fun willDispatchViewUpdates(uiManager: UIManager) = Unit + override fun didDispatchMountItems(uiManager: UIManager) = didMountItems(uiManager) - override fun didDispatchMountItems(uiManager: UIManager) = Unit + override fun willDispatchViewUpdates(uiManager: UIManager) = willMountItems(uiManager) override fun didScheduleMountItems(uiManager: UIManager) = Unit } diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListenerTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListenerTest.kt index e61021c5b2c169..9abeccdb7930cc 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListenerTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListenerTest.kt @@ -45,6 +45,18 @@ class InteropUiBlockListenerTest { assertEquals(1, underTest.afterUIBlocks.size) } + @Test + fun willDispatchViewUpdates_emptiesBeforeUIBlocks() { + val underTest = InteropUIBlockListener() + underTest.prependUIBlock {} + underTest.addUIBlock {} + + underTest.willDispatchViewUpdates(FakeUIManager()) + + assertEquals(0, underTest.beforeUIBlocks.size) + assertEquals(1, underTest.afterUIBlocks.size) + } + @Test fun didMountItems_emptiesAfterUIBlocks() { val underTest = InteropUIBlockListener() @@ -57,6 +69,18 @@ class InteropUiBlockListenerTest { assertEquals(0, underTest.afterUIBlocks.size) } + @Test + fun didDispatchMountItems_emptiesAfterUIBlocks() { + val underTest = InteropUIBlockListener() + underTest.prependUIBlock {} + underTest.addUIBlock {} + + underTest.didDispatchMountItems(FakeUIManager()) + + assertEquals(1, underTest.beforeUIBlocks.size) + assertEquals(0, underTest.afterUIBlocks.size) + } + @Test fun willMountItems_deliversUiManagerCorrectly() { val fakeUIManager = FakeUIManager() @@ -69,6 +93,18 @@ class InteropUiBlockListenerTest { assertEquals(1, fakeUIManager.resolvedViewCount) } + @Test + fun willDispatchViewUpdates_deliversUiManagerCorrectly() { + val fakeUIManager = FakeUIManager() + val underTest = InteropUIBlockListener() + + underTest.prependUIBlock { uiManager -> uiManager.resolveView(0) } + + underTest.willDispatchViewUpdates(fakeUIManager) + + assertEquals(1, fakeUIManager.resolvedViewCount) + } + @Test fun didMountItems_deliversUiManagerCorrectly() { val fakeUIManager = FakeUIManager() @@ -80,4 +116,16 @@ class InteropUiBlockListenerTest { assertEquals(1, fakeUIManager.resolvedViewCount) } + + @Test + fun didDispatchMountItems_deliversUiManagerCorrectly() { + val fakeUIManager = FakeUIManager() + val underTest = InteropUIBlockListener() + + underTest.addUIBlock { uiManager -> uiManager.resolveView(0) } + + underTest.didDispatchMountItems(fakeUIManager) + + assertEquals(1, fakeUIManager.resolvedViewCount) + } }