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() {