feat: Android Incremental Image Diff compression#390
Merged
abelonogov-ld merged 24 commits intomainfrom Feb 27, 2026
Merged
Conversation
Updated the class name from SessionReplayEventGenerator to RRWebEventGenerator for improved clarity and consistency. Adjusted the instantiation in SessionReplayExporter accordingly.
Updated the RRWebEventGenerator to improve the generation of incremental events. Introduced new constants for DOM elements and refined the state management for image nodes. The event generation now utilizes a more structured approach for adding and removing nodes, enhancing clarity and maintainability.
Modified the RRWebEventGenerator to use a constant for the image MIME type, ensuring consistency in data URL generation for incremental events. This change enhances maintainability and clarity in the codebase.
…natureManager Updated the observability module to replace instances of CaptureEvent with the new ExportFrame class, enhancing the structure of exported frames. Introduced TileSignatureManager for improved tile-based signature computation. Adjusted related tests and export logic to accommodate these changes, ensuring consistency across the codebase.
Added CaptureManager class to facilitate capturing frames from the lowest visible window. This implementation includes functionality for emitting captured frames as ExportFrame objects, integrating session management, and applying masks for privacy. The new class enhances the observability module by providing a structured approach to frame capture, with future optimizations planned for capture quality and memory management.
Modified ExportDiffManager to accept ImageCaptureService.RawFrame instead of the previously defined RawFrame data class. This change streamlines the frame capture process and enhances integration with the ImageCaptureService, improving overall code clarity and maintainability. Additionally, removed the RawFrame data class from ExportDiffManager to reduce redundancy.
…ions Modified the TileSignatureManager to accept separate width and height parameters for tile size during signature computation. This change enhances flexibility in tile processing and improves the accuracy of tile-based signatures. Additionally, updated the ExportDiffManager to utilize the new signature computation method, ensuring consistency across the observability module.
…roved state management Updated the SessionReplayExporter to include a condition for forcing full captures based on canvas size and keyframe status. Refined the RRWebEventGenerator to manage node IDs and image handling more effectively, including the introduction of a new tile-based signature system. Adjusted the ExportFrame structure to utilize IntSize for original dimensions, enhancing clarity and consistency across the observability module.
…hashing and signature computation Modified the TileSignature data class to include separate hashLo and hashHi values, enhancing the hashing mechanism. Updated the TileSignatureManager to support multiple compute methods with preferred tile dimensions and added convenience overloads for square tiles. Adjusted internal hashing logic to reduce collision probability and improved test cases to reflect changes in tile signature handling.
(cherry picked from commit 49e4fb9)
Vadman97
approved these changes
Feb 24, 2026
* main: chore: release main (#396) fix: Android span e2e tests (#397) fix: improve network response capture (#379) feat: initial upload of mobile-dotnet (#393) chore: release main (#394) fix: Fix event sorting in session replay export (#392) fix: Touch move event buffering using wrong clock and mismatched constants (#391)
## Summary Fixes and removes ignore on span e2e tests. Flag Eval on the launch was intervening with tests <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to the Android E2E test harness and test annotations, with no impact on production SDK logic beyond skipping a test-only span trigger during tests. > > **Overview** > Fixes flaky Android span E2E tests by preventing `BaseApplication` from running `flagEvaluation()` during test runs (gated on `testUrl == null`), avoiding extra spans that interfered with assertions. > > Re-enables previously ignored span-related E2E coverage by removing `@Ignore` from several trace/export and sampling tests in `DisablingConfigOptionsE2ETest` and `SamplingE2ETest`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 618e2b1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ervability-sdk into andrey/tile-compression * 'andrey/tile-compression' of github.com:launchdarkly/observability-sdk: chore: add CLAUDE.md (#398)
Merged
abelonogov-ld
added a commit
that referenced
this pull request
Feb 27, 2026
* main: feat: Android Incremental Image Diff compression (#390)
abelonogov-ld
added a commit
that referenced
this pull request
Feb 28, 2026
* main: feat: Optional Jet Compose (#402) feat: Android Incremental Image Diff compression (#390) chore: add CLAUDE.md (#398) chore: release main (#400) fix: correct react native session replay build step (#399) chore: release main (#396) fix: Android span e2e tests (#397) fix: improve network response capture (#379) # Conflicts: # sdk/@launchdarkly/mobile-dotnet/.vscode/tasks.json
abelonogov-ld
pushed a commit
that referenced
this pull request
Feb 28, 2026
🤖 I have created a release *beep* *boop* --- <details><summary>launchdarkly-observability-android: 0.27.0</summary> ## [0.27.0](launchdarkly-observability-android-0.26.1...launchdarkly-observability-android-0.27.0) (2026-02-28) ### Features * Android Incremental Image Diff compression ([#390](#390)) ([5ff93f6](5ff93f6)) * Optional Jet Compose ([#402](#402)) ([8f3a671](8f3a671)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is generating a summary for commit bd91847. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Incremental Image Diff compression, layers = 15, backtracking = true
Note
Medium Risk
Touches the core session replay capture/export pipeline (frame encoding, diffing, and rrweb event generation), so regressions could break replay rendering or increase memory/CPU usage. No auth or sensitive data handling logic is introduced beyond existing screenshot capture/masking.
Overview
Implements incremental image diff compression for Android session replay by switching capture output from a single full-screen base64 image to an
ExportFramemodel that can add/remove tiled image layers, with configurableReplayOptions.compression(defaultOverlayTiles(layers=15, backtracking=true)).Refactors capture into
ImageCaptureService(raw bitmap capture + masking) plusExportDiffManager/TileDiffManager(tile signatures, diff rectangle cropping, keyframe layering, and optional backtracking rollbacks), and updates instrumentation/exporter flow to useCaptureManagerand the new frame format.Replaces the previous string-templated rrweb canvas events with
RRWebEventGenerator, generating DOM mutation adds/removes of positionedimgnodes (and related rrweb type enums), and updates exporter logic/tests to decide full vs incremental snapshots based on session/dimension changes and canvas buffer limits.Written by Cursor Bugbot for commit 91087e4. This will update automatically on new commits. Configure here.