Skip to content

Commit 24a3dad

Browse files
cortinicofacebook-github-bot
authored andcommitted
Fix InteropUIBlockListener to support react-native-view-shot on Bridgeless (#43594)
Summary: Pull Request resolved: #43594 I've been migrating `react-native-view-shot` to Fabric by using the `InteropUiBlockListener` and I've realized that the interop layer doesn't work well. 1. FabricUIManager needs to implement `UIBlockViewResolver` in order for the interop layer to work correctly. 2. We need to hook `addUIBlock` to the `didDispatchMountItems` callback otherwise the UIBlocks won't be executed at all. Changelog: [Android] [Fixed] - Fix InteropUIBlockListener to support react-native-view-shot on Bridgeless Reviewed By: javache Differential Revision: D55187939 fbshipit-source-id: d048b4b5eed77fa856fdfac17c0df5f23fd44844
1 parent 9d79f05 commit 24a3dad

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

+1-1
Original file line numberDiff line numberDiff line change
@@ -2541,7 +2541,7 @@ public class com/facebook/react/fabric/FabricSoLoader {
25412541
public static fun staticInit ()V
25422542
}
25432543

2544-
public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/UIManager {
2544+
public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/UIManager, com/facebook/react/fabric/interop/UIBlockViewResolver {
25452545
public static final field ENABLE_FABRIC_LOGS Z
25462546
public static final field ENABLE_FABRIC_PERF_LOGS Z
25472547
public static final field IS_DEVELOPMENT_ENVIRONMENT Z

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.facebook.react.fabric.events.FabricEventEmitter;
5858
import com.facebook.react.fabric.internal.interop.InteropUIBlockListener;
5959
import com.facebook.react.fabric.interop.UIBlock;
60+
import com.facebook.react.fabric.interop.UIBlockViewResolver;
6061
import com.facebook.react.fabric.mounting.MountItemDispatcher;
6162
import com.facebook.react.fabric.mounting.MountingManager;
6263
import com.facebook.react.fabric.mounting.SurfaceMountingManager;
@@ -99,7 +100,7 @@
99100
*/
100101
@SuppressLint("MissingNativeLoadLibrary")
101102
@DoNotStripAny
102-
public class FabricUIManager implements UIManager, LifecycleEventListener {
103+
public class FabricUIManager implements UIManager, LifecycleEventListener, UIBlockViewResolver {
103104
public static final String TAG = FabricUIManager.class.getSimpleName();
104105

105106
// The IS_DEVELOPMENT_ENVIRONMENT variable is used to log extra data when running fabric in a

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt

+8-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ internal class InteropUIBlockListener : UIManagerListener {
3939
}
4040

4141
override fun willMountItems(uiManager: UIManager) {
42+
if (beforeUIBlocks.isEmpty()) {
43+
return
44+
}
4245
beforeUIBlocks.forEach {
4346
if (uiManager is UIBlockViewResolver) {
4447
it.execute(uiManager)
@@ -48,6 +51,9 @@ internal class InteropUIBlockListener : UIManagerListener {
4851
}
4952

5053
override fun didMountItems(uiManager: UIManager) {
54+
if (afterUIBlocks.isEmpty()) {
55+
return
56+
}
5157
afterUIBlocks.forEach {
5258
if (uiManager is UIBlockViewResolver) {
5359
it.execute(uiManager)
@@ -56,9 +62,9 @@ internal class InteropUIBlockListener : UIManagerListener {
5662
afterUIBlocks.clear()
5763
}
5864

59-
override fun willDispatchViewUpdates(uiManager: UIManager) = Unit
65+
override fun didDispatchMountItems(uiManager: UIManager) = didMountItems(uiManager)
6066

61-
override fun didDispatchMountItems(uiManager: UIManager) = Unit
67+
override fun willDispatchViewUpdates(uiManager: UIManager) = willMountItems(uiManager)
6268

6369
override fun didScheduleMountItems(uiManager: UIManager) = Unit
6470
}

packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListenerTest.kt

+48
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ class InteropUiBlockListenerTest {
4545
assertEquals(1, underTest.afterUIBlocks.size)
4646
}
4747

48+
@Test
49+
fun willDispatchViewUpdates_emptiesBeforeUIBlocks() {
50+
val underTest = InteropUIBlockListener()
51+
underTest.prependUIBlock {}
52+
underTest.addUIBlock {}
53+
54+
underTest.willDispatchViewUpdates(FakeUIManager())
55+
56+
assertEquals(0, underTest.beforeUIBlocks.size)
57+
assertEquals(1, underTest.afterUIBlocks.size)
58+
}
59+
4860
@Test
4961
fun didMountItems_emptiesAfterUIBlocks() {
5062
val underTest = InteropUIBlockListener()
@@ -57,6 +69,18 @@ class InteropUiBlockListenerTest {
5769
assertEquals(0, underTest.afterUIBlocks.size)
5870
}
5971

72+
@Test
73+
fun didDispatchMountItems_emptiesAfterUIBlocks() {
74+
val underTest = InteropUIBlockListener()
75+
underTest.prependUIBlock {}
76+
underTest.addUIBlock {}
77+
78+
underTest.didDispatchMountItems(FakeUIManager())
79+
80+
assertEquals(1, underTest.beforeUIBlocks.size)
81+
assertEquals(0, underTest.afterUIBlocks.size)
82+
}
83+
6084
@Test
6185
fun willMountItems_deliversUiManagerCorrectly() {
6286
val fakeUIManager = FakeUIManager()
@@ -69,6 +93,18 @@ class InteropUiBlockListenerTest {
6993
assertEquals(1, fakeUIManager.resolvedViewCount)
7094
}
7195

96+
@Test
97+
fun willDispatchViewUpdates_deliversUiManagerCorrectly() {
98+
val fakeUIManager = FakeUIManager()
99+
val underTest = InteropUIBlockListener()
100+
101+
underTest.prependUIBlock { uiManager -> uiManager.resolveView(0) }
102+
103+
underTest.willDispatchViewUpdates(fakeUIManager)
104+
105+
assertEquals(1, fakeUIManager.resolvedViewCount)
106+
}
107+
72108
@Test
73109
fun didMountItems_deliversUiManagerCorrectly() {
74110
val fakeUIManager = FakeUIManager()
@@ -80,4 +116,16 @@ class InteropUiBlockListenerTest {
80116

81117
assertEquals(1, fakeUIManager.resolvedViewCount)
82118
}
119+
120+
@Test
121+
fun didDispatchMountItems_deliversUiManagerCorrectly() {
122+
val fakeUIManager = FakeUIManager()
123+
val underTest = InteropUIBlockListener()
124+
125+
underTest.addUIBlock { uiManager -> uiManager.resolveView(0) }
126+
127+
underTest.didDispatchMountItems(fakeUIManager)
128+
129+
assertEquals(1, fakeUIManager.resolvedViewCount)
130+
}
83131
}

0 commit comments

Comments
 (0)