diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3a46a5f694..cc49ac0676 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### Features
+
+- Reintroduced experimental support for Session Replay on Android ([#4097](https://github.com/getsentry/sentry-dotnet/pull/4097))
+
### Fixes
- Prevent users from disabling AndroidEnableAssemblyCompression which leads to untrappable crash ([#4089](https://github.com/getsentry/sentry-dotnet/pull/4089))
diff --git a/samples/Sentry.Samples.Android/MainActivity.cs b/samples/Sentry.Samples.Android/MainActivity.cs
index 7ec70a4f9b..e098254833 100644
--- a/samples/Sentry.Samples.Android/MainActivity.cs
+++ b/samples/Sentry.Samples.Android/MainActivity.cs
@@ -21,6 +21,12 @@ protected override void OnCreate(Bundle? savedInstanceState)
// Enable Native Android SDK ANR detection
options.Native.AnrEnabled = true;
+ // Currently experimental support is only available on Android
+ options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate = 1.0;
+ options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate = 1.0;
+ options.Native.ExperimentalOptions.SessionReplay.MaskAllImages = false;
+ options.Native.ExperimentalOptions.SessionReplay.MaskAllText = false;
+
options.SetBeforeSend(evt =>
{
if (evt.Exception?.Message.Contains("Something you don't care want logged?") ?? false)
diff --git a/samples/Sentry.Samples.Maui/MauiProgram.cs b/samples/Sentry.Samples.Maui/MauiProgram.cs
index 028d98b90c..b3f6df76b0 100644
--- a/samples/Sentry.Samples.Maui/MauiProgram.cs
+++ b/samples/Sentry.Samples.Maui/MauiProgram.cs
@@ -25,6 +25,14 @@ public static MauiApp CreateMauiApp()
options.Debug = true;
options.SampleRate = 1.0F;
+#if ANDROID
+ // Currently experimental support is only available on Android
+ options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate = 1.0;
+ options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate = 1.0;
+ options.Native.ExperimentalOptions.SessionReplay.MaskAllImages = false;
+ options.Native.ExperimentalOptions.SessionReplay.MaskAllText = false;
+#endif
+
options.SetBeforeScreenshotCapture((@event, hint) =>
{
Console.WriteLine("screenshot about to be captured.");
diff --git a/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj b/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj
index 5893bf65c8..d3cc4f44cc 100644
--- a/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj
+++ b/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj
@@ -38,6 +38,8 @@
+
+
+
+
+
@@ -66,6 +71,7 @@
/>
+
@@ -89,6 +95,12 @@
Condition="!Exists('$(SentryAndroidSdkDirectory)sentry-android-ndk-$(SentryAndroidSdkVersion).aar') And $(TargetFramework.StartsWith('net8'))"
Retries="3"
/>
+
public bool EnableBeforeSend { get; set; } = false;
+
+ public class NativeExperimentalOptions
+ {
+ public NativeSentryReplayOptions SessionReplay { get; set; } = new();
+ }
+
+ public class NativeSentryReplayOptions
+ {
+ public double? OnErrorSampleRate { get; set; }
+ public double? SessionSampleRate { get; set; }
+ public bool MaskAllImages { get; set; } = true;
+ public bool MaskAllText { get; set; } = true;
+ }
+
+ ///
+ /// ExperimentalOptions
+ ///
+ public NativeExperimentalOptions ExperimentalOptions { get; set; } = new();
}
}
diff --git a/src/Sentry/Platforms/Android/SentrySdk.cs b/src/Sentry/Platforms/Android/SentrySdk.cs
index f0db0a1fef..ed54760d68 100644
--- a/src/Sentry/Platforms/Android/SentrySdk.cs
+++ b/src/Sentry/Platforms/Android/SentrySdk.cs
@@ -135,6 +135,13 @@ private static void InitSentryAndroidSdk(SentryOptions options)
options.Native.InAppExcludes?.ForEach(o.AddInAppExclude);
options.Native.InAppIncludes?.ForEach(o.AddInAppInclude);
+ o.SessionReplay.OnErrorSampleRate =
+ (JavaDouble?)options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate;
+ o.SessionReplay.SessionSampleRate =
+ (JavaDouble?)options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate;
+ o.SessionReplay.SetMaskAllImages(options.Native.ExperimentalOptions.SessionReplay.MaskAllImages);
+ o.SessionReplay.SetMaskAllText(options.Native.ExperimentalOptions.SessionReplay.MaskAllText);
+
// These options are intentionally set and not exposed for modification
o.EnableExternalConfiguration = false;
o.EnableDeduplication = false;
diff --git a/test/Sentry.Tests/Platforms/Android/BindableNativeOptionsTests.cs b/test/Sentry.Tests/Platforms/Android/BindableNativeOptionsTests.cs
index c70a9cb565..136ac43629 100644
--- a/test/Sentry.Tests/Platforms/Android/BindableNativeOptionsTests.cs
+++ b/test/Sentry.Tests/Platforms/Android/BindableNativeOptionsTests.cs
@@ -5,6 +5,11 @@ namespace Sentry.Tests.Platforms.Android;
public class BindableNativeOptionsTests : BindableTests
{
+ public BindableNativeOptionsTests()
+ : base(nameof(BindableSentryOptions.NativeOptions.ExperimentalOptions))
+ {
+ }
+
[Fact]
public void BindableProperties_MatchOptionsProperties()
{