Skip to content
Open
Changes from 1 commit
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
Prev Previous commit
fix: force software layer recursively before snapping screenshots
view.draw(canvas) skips Fabric child views that have hardware display
lists, leaving only the root container's white background. Walking the
entire view tree and setting LAYER_TYPE_SOFTWARE on every node ensures
all content is visible to the software canvas used by Screenshot.snap().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
  • Loading branch information
EmilioBejasa and claude committed Mar 30, 2026
commit c573f4107aac77dbd115afe8fd50a71d440c2bdb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import android.util.Log
import android.view.Choreographer
import android.view.ContextThemeWrapper
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import com.facebook.react.ReactApplication
import com.facebook.react.ReactRootView
import com.facebook.testing.screenshot.Screenshot
import com.facebook.testing.screenshot.ViewHelpers
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
Expand Down Expand Up @@ -107,10 +107,7 @@ abstract class BaseStoryScreenshotTest {
waitTwoFrames()
val screenshotName = storyId.replace("--", "_")
instrumentation.runOnMainSync {
ViewHelpers.setupView(view)
.setExactWidthPx(SCREEN_WIDTH_PX)
.setExactHeightPx(SCREEN_HEIGHT_PX)
.layout()
setLayerTypeSoftwareRecursively(view)
Screenshot.snap(view).setName(screenshotName).record()
}
Log.d(TAG, "Screenshot captured: $screenshotName")
Expand Down Expand Up @@ -214,6 +211,23 @@ abstract class BaseStoryScreenshotTest {
}
}

/**
* Recursively sets LAYER_TYPE_SOFTWARE on a view and all its descendants.
*
* view.draw(canvas) cannot capture children that have hardware display lists.
* Fabric child views in a hardware-accelerated WindowManager window get hardware
* display lists by default, so they render blank into a software canvas.
* Walking the tree and forcing software layers ensures draw() sees all content.
*/
private fun setLayerTypeSoftwareRecursively(view: View) {
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
if (view is ViewGroup) {
for (i in 0 until view.childCount) {
setLayerTypeSoftwareRecursively(view.getChildAt(i))
}
}
}

/**
* Waits for two Choreographer frames on the main thread.
*
Expand Down
Loading