Skip to content

feat(sr): capture Icon widgets as raster images#1018

Open
nottmey wants to merge 2 commits into
DataDog:developfrom
nottmey:feat/dart-based-icon-capture
Open

feat(sr): capture Icon widgets as raster images#1018
nottmey wants to merge 2 commits into
DataDog:developfrom
nottmey:feat/dart-based-icon-capture

Conversation

@nottmey
Copy link
Copy Markdown
Contributor

@nottmey nottmey commented Apr 30, 2026

What and why?

  • Capture Icon widgets as rasterized images with a transparent background and upload them through the same image resource pipeline as Image/RawImage. Icons are rasterized at a configurable logical size (DatadogSessionReplayConfiguration.iconRasterLogicalSize, default 20) × device pixel ratio, cached by glyph + font + color so the same icon is rasterized once per recorder instance regardless of on-screen Icon size. Concurrent raster work for the same icon is deduplicated; additional per-frame capture processing runs in parallel. ImagePrivacyLevel.maskAll shows a placeholder (no upload); maskNone and maskNonAssetsOnly record icons; the inner RichText of Icon is not captured as text.

How?

Review checklist

  • This pull request has appropriate unit and / or integration tests
  • This pull request references a Github or JIRA issue

@nottmey nottmey requested a review from a team as a code owner April 30, 2026 11:37
Copy link
Copy Markdown
Member

@fuzzybinary fuzzybinary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me with some minor nits.

But this needs a Golden test as well.

Comment on lines +141 to +143
final fontFamily = iconData.fontFamily;
if (fontFamily == null || fontFamily.isEmpty) {
return SpecificElement(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to render the Material Icons font without needing to perform a raster. I think these get captured as Text elements, so it might be worth checking for that and sending its corresponding Text element instead of performing the raster.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out this feature has a bug on the player side, so if you weren't seeing Material lcons, that's why. We're working on a fix.

@nottmey
Copy link
Copy Markdown
Contributor Author

nottmey commented May 7, 2026

image (example link: https://app.datadoghq.eu/rum/replay/sessions/6a189644-871a-420c-93b0-aa2e2c1616e3?ts=1778180629349) Note, we are noticing that datadog is dropping uploaded images. Maybe this has to do with your backend bug, maybe it's some kind of upload limit dropping oldest cache entries. @fuzzybinary

@nottmey nottmey force-pushed the feat/dart-based-icon-capture branch 2 times, most recently from f8272b2 to d961dfc Compare May 7, 2026 20:44
@nottmey nottmey requested a review from fuzzybinary May 7, 2026 20:44
@fuzzybinary
Copy link
Copy Markdown
Member

@nottmey The dropped uploaded images should be Android specific and fixed in preview 12. If it's not please let me know.

@nottmey nottmey changed the title feat(session-replay): capture Icon widgets as raster images feat(sr): capture Icon widgets as raster images May 11, 2026
@nottmey
Copy link
Copy Markdown
Contributor Author

nottmey commented May 11, 2026

@fuzzybinary tested it out, images are still dropped with icon rasterization + preview 12
https://app.datadoghq.eu/rum/replay/sessions/5c8460d0-2f3e-4cb1-9f2e-480d5073cbfe
image

Register IconRecorder in the capture pipeline, reuse identical icon
rasters per recorder, and respect image privacy levels. Add example
screen coverage, unit tests, and changelog entry.

Made-with: Cursor

feat(session_replay): add configurable icon raster logical size

Rasterize icons at DatadogSessionReplayConfiguration.iconRasterLogicalSize
(default 20) × DPR, cache by glyph/font/color, and dedupe concurrent work.
Align glyph layout with Flutter Icon for replay; export config on public API.

Made-with: Cursor

feat(session_replay): add phased icon raster timings and outcome type

Introduce _IconRasterOutcome so raster work reports per-phase ms
(toImage, toByteData, save) and defers rich debug logging until after
the shared in-flight future completes.

Made-with: Cursor

chore: revert icon layouting changes

fix(session-replay): dispose TextPainter after icon rasterization

Made-with: Cursor

feat(session_replay): parallel icon processing and raster size

Resolve AdditionalProcessingElement work with Future.wait so icon rasterization is not serialized.

Add DatadogSessionReplayConfiguration.iconRasterLogicalSize (default 20) and plumb it into IconRecorder for canonical glyph bitmaps.

Add golden coverage for Icon image privacy levels and extend icon_recorder tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@nottmey nottmey force-pushed the feat/dart-based-icon-capture branch from d961dfc to c3cf50b Compare May 11, 2026 16:55
@nottmey
Copy link
Copy Markdown
Contributor Author

nottmey commented May 11, 2026

maybe it works for you?

@fuzzybinary
Copy link
Copy Markdown
Member

@gonzalezreal Can you take a look at ☝️ . The android resource id fix should have been pushed in preview 12.

@nottmey Can you open a support request for that? That way we can potentially look at your replays and determine what's going on.

@nottmey
Copy link
Copy Markdown
Contributor Author

nottmey commented May 12, 2026

@fuzzybinary will do, tested on an iOS simulator (fyi)

@nottmey
Copy link
Copy Markdown
Contributor Author

nottmey commented May 13, 2026

support ticket: https://help.datadoghq.com/hc/requests/2894616

@gonzalezreal
Copy link
Copy Markdown
Contributor

gonzalezreal commented May 18, 2026

@fuzzybinary Just to confirm, the Android resource-context fix did land in preview.12 (it's in the changelog).
@nottmey Could you share which platforms you're seeing the dropped images on through the support ticket? You mentioned testing on an iOS simulator. Is that where the screenshots are from, or are you also seeing it on Android? We'll follow up there.

@nottmey
Copy link
Copy Markdown
Contributor Author

nottmey commented May 18, 2026

@gonzalezreal we see dropped images on all sessions; we have the feature running in production (start/stop on a selected set of users) (feel free to check all our session recordings)

yes, the screenshot and example session is done from an ios simulator; Tomorrow, I can also reproduce it on android as well and send you the matching link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants