Skip to content

Session Replay: support Unity (SurfaceView/OpenGL) rendering #5257

@sentry-junior

Description

@sentry-junior

Summary

Session Replay on Android shows a black screen when the app uses Unity for rendering. Unity renders via a SurfaceView backed by OpenGL in a separate process. The current PixelCopy-based screenshot mechanism does not capture SurfaceView content, resulting in a fully black frame. This blocks replay utility for apps that embed Unity scenes (e.g. for game-like or interactive lesson surfaces).

Current behavior

  • Android replay capture uses PixelCopy to screenshot the window hierarchy.
  • PixelCopy does not capture SurfaceView contents because SurfaceView renders to a separate hardware-composited layer.
  • Unity games/scenes embedded in an Android app use SurfaceView + OpenGL, so they appear black in any captured replay frame.
  • Attempting capture via screenshotty (an alternative screenshot library) produces the same result.
  • The Sentry SDK is not initialized inside the Unity process; the Java/Android SDK captures the host app side only.

Gap

Any Android app that embeds Unity content — increasingly common for interactive or game-adjacent product surfaces — gets unusable replays. The black region can cover most or all of the viewport, making the replay meaningless for debugging UX issues in Unity-rendered screens.

This is the same underlying constraint as #4862 (maps rendered via native OpenGL), but Unity is a distinct integration path with higher prevalence in consumer apps.

Options

  1. MediaProjection-based capture — use Android's MediaProjection API to capture the composited screen output. This includes SurfaceView content and would solve Unity, maps, and other native-render cases. Requires a runtime permission prompt (FOREGROUND_SERVICE_MEDIA_PROJECTION) and is more invasive/complex to implement safely. Privacy implications need careful handling.

  2. VirtualDisplay + SurfaceView mirror — create a VirtualDisplay that mirrors the target surface. Technically complex; not guaranteed to work across Unity's multi-process setup.

  3. Placeholder/redaction overlay — when a SurfaceView is detected in the view hierarchy, render a labeled placeholder block in the replay frame (similar to how we mask sensitive content). This doesn't capture Unity content but makes replays honest about what's missing instead of just showing black.

  4. SDK-side Unity integration — coordinate with the Unity SDK (getsentry/sentry-unity) to have Unity emit its own frame snapshots or DOM-equivalent events that can be stitched into the replay. High effort; requires cross-SDK protocol work.

Recommendation

Option 3 (placeholder overlay) is the lowest-risk near-term improvement — it converts a confusing black-screen replay into an honest, annotated gap. Option 1 (MediaProjection) is the right long-term fix for full capture fidelity, but carries permission/privacy tradeoffs that need product alignment before implementing.

Related: #4862 (maps / native OpenGL rendering same root cause)

Action taken on behalf of Simon Zhong.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions