Skip to content

Commit ad80795

Browse files
Session Replay: Recording on Android (#3552)
--------- Co-authored-by: James Crosswell <[email protected]>
1 parent 3bcab16 commit ad80795

File tree

8 files changed

+79
-1
lines changed

8 files changed

+79
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Features
6+
7+
- Limited experimental support for Session Replay Recording on Android ([#3552](https://github.com/getsentry/sentry-dotnet/pull/3552))
8+
59
### Fixes
610

711
- 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))

samples/Sentry.Samples.Maui/MauiProgram.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ public static MauiApp CreateMauiApp()
2525
options.Debug = true;
2626
options.SampleRate = 1.0F;
2727

28+
#if ANDROID
29+
// Currently experimental support is only available on Android
30+
options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate = 1.0;
31+
options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate = 1.0;
32+
options.Native.ExperimentalOptions.SessionReplay.MaskAllImages = false;
33+
options.Native.ExperimentalOptions.SessionReplay.MaskAllText = false;
34+
#endif
35+
2836
options.SetBeforeScreenshotCapture((@event, hint) =>
2937
{
3038
Console.WriteLine("screenshot about to be captured.");
@@ -33,7 +41,6 @@ public static MauiApp CreateMauiApp()
3341
return true;
3442
});
3543
})
36-
3744
.ConfigureFonts(fonts =>
3845
{
3946
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");

src/Sentry.Bindings.Android/Sentry.Bindings.Android.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<AndroidLibrary Include="$(SentryAndroidSdkDirectory)sentry-$(SentryAndroidSdkVersion).jar" />
3030
<AndroidLibrary Include="$(SentryAndroidSdkDirectory)sentry-android-core-$(SentryAndroidSdkVersion).aar" />
3131
<AndroidLibrary Include="$(SentryAndroidSdkDirectory)sentry-android-ndk-$(SentryAndroidSdkVersion).aar" />
32+
<AndroidLibrary Include="$(SentryAndroidSdkDirectory)sentry-android-replay-$(SentryAndroidSdkVersion).aar" />
3233
<AndroidLibrary Include="..\..\lib\sentry-android-supplemental\bin\sentry-android-supplemental.jar" />
3334
<AndroidNativeLibrary Include="..\..\lib\sentrysupplemental\bin\arm64-v8a\libsentrysupplemental.so" Abi="arm64-v8a" />
3435
<AndroidNativeLibrary Include="..\..\lib\sentrysupplemental\bin\armeabi-v7a\libsentrysupplemental.so" Abi="armeabi-v7a" />
@@ -49,6 +50,12 @@
4950
Condition="!Exists('$(SentryAndroidSdkDirectory)sentry-android-ndk-$(SentryAndroidSdkVersion).aar')"
5051
Retries="3"
5152
/>
53+
<DownloadFile
54+
SourceUrl="https://repo1.maven.org/maven2/io/sentry/sentry-android-replay/$(SentryAndroidSdkVersion)/sentry-android-replay-$(SentryAndroidSdkVersion).aar"
55+
DestinationFolder="$(SentryAndroidSdkDirectory)"
56+
Condition="!Exists('$(SentryAndroidSdkDirectory)sentry-android-replay-$(SentryAndroidSdkVersion).aar')"
57+
Retries="3"
58+
/>
5259
<DownloadFile
5360
SourceUrl="https://repo1.maven.org/maven2/io/sentry/sentry/$(SentryAndroidSdkVersion)/sentry-$(SentryAndroidSdkVersion).jar"
5461
DestinationFolder="$(SentryAndroidSdkDirectory)"

src/Sentry.Bindings.Android/Transforms/Metadata.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@
118118
<remove-node path="/api/package[@name='io.sentry.android.core']/class[@name='TempSensorBreadcrumbsIntegration']" />
119119
<remove-node path="/api/package[@name='io.sentry.android.core.internal.gestures']" />
120120
<remove-node path="/api/package[@name='io.sentry.android.core.performance']" />
121+
<remove-node path="/api/package[@name='io.sentry.android.replay.viewhierarchy']" />
122+
<remove-node path="/api/package[@name='io.sentry.android.replay.util']" />
121123

122124
<remove-node path="/api/package[starts-with(@name,'io.sentry')]/*/method[@name='clone' and count(parameter)=0]" />
123125
<remove-node path="/api/package[starts-with(@name,'io.sentry')]/class/implements[@name='io.sentry.JsonDeserializer']" />

src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// ReSharper disable once CheckNamespace
2+
23
namespace Sentry;
34

45
internal partial class BindableSentryOptions
@@ -34,7 +35,20 @@ public class NativeOptions
3435
public TimeSpan? ReadTimeout { get; set; }
3536
public bool? EnableTracing { get; set; }
3637
public bool? EnableBeforeSend { get; set; }
38+
public NativeExperimentalOptions ExperimentalOptions { get; set; } = new();
39+
40+
internal class NativeExperimentalOptions
41+
{
42+
public NativeSentryReplayOptions SessionReplay { get; set; } = new();
43+
}
3744

45+
internal class NativeSentryReplayOptions
46+
{
47+
public double? OnErrorSampleRate { get; set; }
48+
public double? SessionSampleRate { get; set; }
49+
public bool RedactAllImages { get; set; }
50+
public bool RedactAllText { get; set; }
51+
}
3852
public void ApplyTo(SentryOptions.NativeOptions options)
3953
{
4054
options.AnrEnabled = AnrEnabled ?? options.AnrEnabled;
@@ -61,6 +75,21 @@ public void ApplyTo(SentryOptions.NativeOptions options)
6175
options.ReadTimeout = ReadTimeout ?? options.ReadTimeout;
6276
options.EnableTracing = EnableTracing ?? options.EnableTracing;
6377
options.EnableBeforeSend = EnableBeforeSend ?? options.EnableBeforeSend;
78+
79+
if (ExperimentalOptions.SessionReplay.OnErrorSampleRate is { } errorSampleRate)
80+
{
81+
#pragma warning disable CA1422
82+
options.ExperimentalOptions.SessionReplay.OnErrorSampleRate = errorSampleRate;
83+
#pragma warning restore CA1422
84+
}
85+
if (ExperimentalOptions.SessionReplay.SessionSampleRate is { } sessionSampleRate)
86+
{
87+
#pragma warning disable CA1422
88+
options.ExperimentalOptions.SessionReplay.SessionSampleRate = sessionSampleRate;
89+
#pragma warning restore CA1422
90+
}
91+
ExperimentalOptions.SessionReplay.RedactAllText = options.ExperimentalOptions.SessionReplay.MaskAllText;
92+
ExperimentalOptions.SessionReplay.RedactAllImages = options.ExperimentalOptions.SessionReplay.MaskAllImages;
6493
}
6594
}
6695
}

src/Sentry/Platforms/Android/NativeOptions.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// ReSharper disable once CheckNamespace
2+
23
namespace Sentry;
34

45
public partial class SentryOptions
@@ -260,5 +261,21 @@ public void AddInAppInclude(string prefix)
260261
/// be stripped away during the round-tripping between the two SDKs. Use with caution.
261262
/// </remarks>
262263
public bool EnableBeforeSend { get; set; } = false;
264+
public class NativeExperimentalOptions
265+
{
266+
public NativeSentryReplayOptions SessionReplay { get; set; } = new();
267+
}
268+
269+
public class NativeSentryReplayOptions
270+
{
271+
public double? OnErrorSampleRate { get; set; }
272+
public double? SessionSampleRate { get; set; }
273+
public bool MaskAllImages { get; set; } = true;
274+
public bool MaskAllText { get; set; } = true;
275+
}
276+
/// <summary>
277+
/// ExperimentalOptions
278+
/// </summary>
279+
public NativeExperimentalOptions ExperimentalOptions { get; set; } = new();
263280
}
264281
}

src/Sentry/Platforms/Android/SentrySdk.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ private static void InitSentryAndroidSdk(SentryOptions options)
163163
options.Native.InAppExcludes?.ForEach(o.AddInAppExclude);
164164
options.Native.InAppIncludes?.ForEach(o.AddInAppInclude);
165165

166+
o.Experimental.SessionReplay.OnErrorSampleRate =
167+
(JavaDouble?)options.Native.ExperimentalOptions.SessionReplay.OnErrorSampleRate;
168+
o.Experimental.SessionReplay.SessionSampleRate =
169+
(JavaDouble?)options.Native.ExperimentalOptions.SessionReplay.SessionSampleRate;
170+
o.Experimental.SessionReplay.SetMaskAllImages(options.Native.ExperimentalOptions.SessionReplay.MaskAllImages);
171+
o.Experimental.SessionReplay.SetMaskAllText(options.Native.ExperimentalOptions.SessionReplay.MaskAllText);
172+
166173
// These options are intentionally set and not exposed for modification
167174
o.EnableExternalConfiguration = false;
168175
o.EnableDeduplication = false;

test/Sentry.Tests/Platforms/Android/BindableNativeOptionsTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ namespace Sentry.Tests.Platforms.Android;
55

66
public class BindableNativeOptionsTests : BindableTests<SentryOptions.NativeOptions>
77
{
8+
public BindableNativeOptionsTests()
9+
: base(nameof(BindableSentryOptions.NativeOptions.ExperimentalOptions))
10+
{
11+
}
12+
813
[Fact]
914
public void BindableProperties_MatchOptionsProperties()
1015
{

0 commit comments

Comments
 (0)