diff --git a/CHANGELOG.md b/CHANGELOG.md
index eaa4da4d2c..2f828b7790 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### Features
+
+- Limited experimental support for Session Replay Recording on Android ([#3552](https://github.com/getsentry/sentry-dotnet/pull/3552))
+
### Fixes
- When using OTel and ASP.NET Core the SDK could try to process OTel spans after the SDK had been closed ([#3726](https://github.com/getsentry/sentry-dotnet/pull/3726))
diff --git a/samples/Sentry.Samples.Maui/MauiProgram.cs b/samples/Sentry.Samples.Maui/MauiProgram.cs
index 028d98b90c..4d33296512 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.");
@@ -33,7 +41,6 @@ public static MauiApp CreateMauiApp()
return true;
});
})
-
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
diff --git a/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj b/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj
index 963f70b866..a0eb9f33bc 100644
--- a/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj
+++ b/src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj
@@ -29,6 +29,7 @@
+
@@ -49,6 +50,12 @@
Condition="!Exists('$(SentryAndroidSdkDirectory)sentry-android-ndk-$(SentryAndroidSdkVersion).aar')"
Retries="3"
/>
+
+
+
diff --git a/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs b/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs
index 1b12a9e385..f3151f73a5 100644
--- a/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs
+++ b/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs
@@ -1,4 +1,5 @@
// ReSharper disable once CheckNamespace
+
namespace Sentry;
internal partial class BindableSentryOptions
@@ -34,7 +35,20 @@ public class NativeOptions
public TimeSpan? ReadTimeout { get; set; }
public bool? EnableTracing { get; set; }
public bool? EnableBeforeSend { get; set; }
+ public NativeExperimentalOptions ExperimentalOptions { get; set; } = new();
+
+ internal class NativeExperimentalOptions
+ {
+ public NativeSentryReplayOptions SessionReplay { get; set; } = new();
+ }
+ internal class NativeSentryReplayOptions
+ {
+ public double? OnErrorSampleRate { get; set; }
+ public double? SessionSampleRate { get; set; }
+ public bool RedactAllImages { get; set; }
+ public bool RedactAllText { get; set; }
+ }
public void ApplyTo(SentryOptions.NativeOptions options)
{
options.AnrEnabled = AnrEnabled ?? options.AnrEnabled;
@@ -61,6 +75,21 @@ public void ApplyTo(SentryOptions.NativeOptions options)
options.ReadTimeout = ReadTimeout ?? options.ReadTimeout;
options.EnableTracing = EnableTracing ?? options.EnableTracing;
options.EnableBeforeSend = EnableBeforeSend ?? options.EnableBeforeSend;
+
+ if (ExperimentalOptions.SessionReplay.OnErrorSampleRate is { } errorSampleRate)
+ {
+#pragma warning disable CA1422
+ options.ExperimentalOptions.SessionReplay.OnErrorSampleRate = errorSampleRate;
+#pragma warning restore CA1422
+ }
+ if (ExperimentalOptions.SessionReplay.SessionSampleRate is { } sessionSampleRate)
+ {
+#pragma warning disable CA1422
+ options.ExperimentalOptions.SessionReplay.SessionSampleRate = sessionSampleRate;
+#pragma warning restore CA1422
+ }
+ ExperimentalOptions.SessionReplay.RedactAllText = options.ExperimentalOptions.SessionReplay.MaskAllText;
+ ExperimentalOptions.SessionReplay.RedactAllImages = options.ExperimentalOptions.SessionReplay.MaskAllImages;
}
}
}
diff --git a/src/Sentry/Platforms/Android/NativeOptions.cs b/src/Sentry/Platforms/Android/NativeOptions.cs
index fdef25e518..45616fc237 100644
--- a/src/Sentry/Platforms/Android/NativeOptions.cs
+++ b/src/Sentry/Platforms/Android/NativeOptions.cs
@@ -1,4 +1,5 @@
// ReSharper disable once CheckNamespace
+
namespace Sentry;
public partial class SentryOptions
@@ -260,5 +261,21 @@ public void AddInAppInclude(string prefix)
/// be stripped away during the round-tripping between the two SDKs. Use with caution.
///
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 01ffe1dee1..0e073fba9d 100644
--- a/src/Sentry/Platforms/Android/SentrySdk.cs
+++ b/src/Sentry/Platforms/Android/SentrySdk.cs
@@ -163,6 +163,13 @@ private static void InitSentryAndroidSdk(SentryOptions options)
options.Native.InAppExcludes?.ForEach(o.AddInAppExclude);
options.Native.InAppIncludes?.ForEach(o.AddInAppInclude);
+ o.Experimental.SessionReplay.OnErrorSampleRate =
+ (JavaDouble?)options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate;
+ o.Experimental.SessionReplay.SessionSampleRate =
+ (JavaDouble?)options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate;
+ o.Experimental.SessionReplay.SetMaskAllImages(options.Native.ExperimentalOptions.SessionReplay.MaskAllImages);
+ o.Experimental.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()
{