Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -971,9 +971,15 @@ private void scheduleMountItem(
if (shouldSchedule) {
Assertions.assertNotNull(mountItem, "MountItem is null");
if (synchronous) {
// Pull model: we are already on the UI thread, inside the dispatcher's loop executing
// a PullTransactionMountItem. We don't schedule the item, we execute it directly.
mountItem.execute(mMountingManager);
if (mMountingManager.isWaitingForViewAttach(mountItem.getSurfaceId())) {
// Regular mount items are still being deferred into the surface's attach queue.
// Executing this batch inline would run it ahead of the preallocations queued there.
mMountItemDispatcher.addMountItem(mountItem);
} else {
// Pull model: we are already on the UI thread, inside the dispatcher's loop executing
// a PullTransactionMountItem. We don't schedule the item, we execute it directly.
mountItem.execute(mMountingManager);
}
} else {
mMountItemDispatcher.addMountItem(mountItem);
if (UiThreadUtil.isOnUiThread()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,30 @@

package com.facebook.react.fabric

import com.facebook.react.ReactRootView
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactTestHelper
import com.facebook.react.fabric.mounting.MountingManager
import com.facebook.react.fabric.mounting.mountitems.MountItem
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsDefaults
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewManagerRegistry
import com.facebook.testutils.fakes.FakeBatchEventDispatchedListener
import com.facebook.testutils.shadows.ShadowFabricUIManagerBinding
import com.facebook.testutils.shadows.ShadowNativeLoader
import com.facebook.testutils.shadows.ShadowPerformanceTracer
import com.facebook.testutils.shadows.ShadowSoLoader
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.shadow.api.Shadow
import org.robolectric.util.ReflectionHelpers

/**
* Tests for the pull-model notification path: [FabricUIManager.onTransactionAvailable] enqueues a
Expand Down Expand Up @@ -55,6 +63,11 @@ class FabricUIManagerPullModelTest {
@Before
fun setup() {
ReactNativeFeatureFlagsForTests.setUp()
ReactNativeFeatureFlags.override(
object : ReactNativeFeatureFlagsDefaults() {
override fun enableMountingCoordinatorPullModelAndroid(): Boolean = true
},
)
reactContext = ReactTestHelper.createCatalystContextForTest()
underTest =
FabricUIManager(
Expand All @@ -67,6 +80,11 @@ class FabricUIManagerPullModelTest {
underTest.setBinding(binding)
}

@After
fun tearDown() {
ReactNativeFeatureFlags.dangerouslyReset()
}

private fun runOnBackgroundThread(block: () -> Unit) {
var error: Throwable? = null
val thread = Thread {
Expand All @@ -81,6 +99,28 @@ class FabricUIManagerPullModelTest {
error?.let { throw it }
}

private fun scheduleSynchronously(mountItem: MountItem) {
val method =
FabricUIManager::class
.java
.getDeclaredMethod(
"scheduleMountItem",
MountItem::class.java,
Integer.TYPE,
java.lang.Long.TYPE,
java.lang.Long.TYPE,
java.lang.Long.TYPE,
java.lang.Long.TYPE,
java.lang.Long.TYPE,
java.lang.Long.TYPE,
java.lang.Long.TYPE,
Integer.TYPE,
java.lang.Boolean.TYPE,
)
method.isAccessible = true
method.invoke(underTest, mountItem, 0, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0, true)
}

@Test
fun onTransactionAvailable_onUiThread_pullsSynchronously() {
underTest.onTransactionAvailable(1)
Expand All @@ -105,4 +145,31 @@ class FabricUIManagerPullModelTest {

assertThat(shadowBinding.pulledSurfaceIds).containsExactly(1, 2, 1, 3)
}

@Test
fun synchronousBatch_waitingForRootAttach_isDeferred() {
val surfaceId = 12
val themedReactContext = ThemedReactContext(reactContext, reactContext, "TestModule", surfaceId)
val mountingManager = ReflectionHelpers.getField<MountingManager>(underTest, "mMountingManager")
mountingManager.startSurface(surfaceId, themedReactContext, null)

var executionCount = 0
val mountItem =
object : MountItem {
override fun execute(mountingManager: MountingManager) {
executionCount++
}

override fun getSurfaceId(): Int = surfaceId
}

scheduleSynchronously(mountItem)

assertThat(executionCount).isZero()

mountingManager.attachRootView(surfaceId, ReactRootView(reactContext), themedReactContext)
underTest.onTransactionAvailable(surfaceId)

assertThat(executionCount).isEqualTo(1)
}
}
Loading