Skip to content

Commit 75ebe50

Browse files
authored
[SR] Allow overriding SdkVersion only for replay events (#4014)
1 parent 45a4343 commit 75ebe50

File tree

9 files changed

+74
-15
lines changed

9 files changed

+74
-15
lines changed

CHANGELOG.md

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

77
- Fix warm start detection ([#3937](https://github.com/getsentry/sentry-java/pull/3937))
88

9+
### Internal
10+
11+
- Session Replay: Allow overriding `SdkVersion` for replay events ([#4014](https://github.com/getsentry/sentry-java/pull/4014))
12+
913
## 7.19.1
1014

1115
### Fixes

sentry/api/sentry.api

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ public abstract interface class io/sentry/EventProcessor {
315315
}
316316

317317
public final class io/sentry/ExperimentalOptions {
318-
public fun <init> (Z)V
318+
public fun <init> (ZLio/sentry/protocol/SdkVersion;)V
319319
public fun getSessionReplay ()Lio/sentry/SentryReplayOptions;
320320
public fun setSessionReplay (Lio/sentry/SentryReplayOptions;)V
321321
}
@@ -2724,8 +2724,8 @@ public final class io/sentry/SentryReplayOptions {
27242724
public static final field TEXT_VIEW_CLASS_NAME Ljava/lang/String;
27252725
public static final field VIDEO_VIEW_CLASS_NAME Ljava/lang/String;
27262726
public static final field WEB_VIEW_CLASS_NAME Ljava/lang/String;
2727-
public fun <init> (Ljava/lang/Double;Ljava/lang/Double;)V
2728-
public fun <init> (Z)V
2727+
public fun <init> (Ljava/lang/Double;Ljava/lang/Double;Lio/sentry/protocol/SdkVersion;)V
2728+
public fun <init> (ZLio/sentry/protocol/SdkVersion;)V
27292729
public fun addMaskViewClass (Ljava/lang/String;)V
27302730
public fun addUnmaskViewClass (Ljava/lang/String;)V
27312731
public fun getErrorReplayDuration ()J
@@ -2734,6 +2734,7 @@ public final class io/sentry/SentryReplayOptions {
27342734
public fun getMaskViewContainerClass ()Ljava/lang/String;
27352735
public fun getOnErrorSampleRate ()Ljava/lang/Double;
27362736
public fun getQuality ()Lio/sentry/SentryReplayOptions$SentryReplayQuality;
2737+
public fun getSdkVersion ()Lio/sentry/protocol/SdkVersion;
27372738
public fun getSessionDuration ()J
27382739
public fun getSessionSampleRate ()Ljava/lang/Double;
27392740
public fun getSessionSegmentDuration ()J
@@ -2747,6 +2748,7 @@ public final class io/sentry/SentryReplayOptions {
27472748
public fun setMaskViewContainerClass (Ljava/lang/String;)V
27482749
public fun setOnErrorSampleRate (Ljava/lang/Double;)V
27492750
public fun setQuality (Lio/sentry/SentryReplayOptions$SentryReplayQuality;)V
2751+
public fun setSdkVersion (Lio/sentry/protocol/SdkVersion;)V
27502752
public fun setSessionSampleRate (Ljava/lang/Double;)V
27512753
public fun setTrackOrientationChange (Z)V
27522754
public fun setUnmaskViewContainerClass (Ljava/lang/String;)V

sentry/src/main/java/io/sentry/ExperimentalOptions.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.sentry;
22

3+
import io.sentry.protocol.SdkVersion;
34
import org.jetbrains.annotations.NotNull;
5+
import org.jetbrains.annotations.Nullable;
46

57
/**
68
* Experimental options for new features, these options are going to be promoted to SentryOptions
@@ -11,8 +13,8 @@
1113
public final class ExperimentalOptions {
1214
private @NotNull SentryReplayOptions sessionReplay;
1315

14-
public ExperimentalOptions(final boolean empty) {
15-
this.sessionReplay = new SentryReplayOptions(empty);
16+
public ExperimentalOptions(final boolean empty, final @Nullable SdkVersion sdkVersion) {
17+
this.sessionReplay = new SentryReplayOptions(empty, sdkVersion);
1618
}
1719

1820
@NotNull

sentry/src/main/java/io/sentry/MainEventProcessor.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.sentry.hints.Cached;
55
import io.sentry.protocol.DebugImage;
66
import io.sentry.protocol.DebugMeta;
7+
import io.sentry.protocol.SdkVersion;
78
import io.sentry.protocol.SentryException;
89
import io.sentry.protocol.SentryTransaction;
910
import io.sentry.protocol.User;
@@ -159,6 +160,12 @@ private void processNonCachedEvent(final @NotNull SentryBaseEvent event) {
159160

160161
if (shouldApplyScopeData(event, hint)) {
161162
processNonCachedEvent(event);
163+
final @Nullable SdkVersion replaySdkVersion =
164+
options.getExperimental().getSessionReplay().getSdkVersion();
165+
if (replaySdkVersion != null) {
166+
// we override the SdkVersion only for replay events as those may come from Hybrid SDKs
167+
event.setSdk(replaySdkVersion);
168+
}
162169
}
163170
return event;
164171
}

sentry/src/main/java/io/sentry/SentryClient.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,11 @@ public void captureUserFeedback(final @NotNull UserFeedback userFeedback) {
640640
envelopeItems.add(replayItem);
641641
final SentryId sentryId = event.getEventId();
642642

643+
// SdkVersion from ReplayOptions defaults to SdkVersion from SentryOptions and can be
644+
// overwritten by the hybrid SDKs
643645
final SentryEnvelopeHeader envelopeHeader =
644-
new SentryEnvelopeHeader(sentryId, options.getSdkVersion(), traceContext);
646+
new SentryEnvelopeHeader(
647+
sentryId, options.getExperimental().getSessionReplay().getSdkVersion(), traceContext);
645648

646649
return new SentryEnvelope(envelopeHeader, envelopeItems);
647650
}

sentry/src/main/java/io/sentry/SentryOptions.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,13 @@ public void setSslSocketFactory(final @Nullable SSLSocketFactory sslSocketFactor
14211421
*/
14221422
@ApiStatus.Internal
14231423
public void setSdkVersion(final @Nullable SdkVersion sdkVersion) {
1424+
final @Nullable SdkVersion replaySdkVersion = experimental.getSessionReplay().getSdkVersion();
1425+
if (this.sdkVersion != null
1426+
&& replaySdkVersion != null
1427+
&& this.sdkVersion.equals(replaySdkVersion)) {
1428+
// if sdkVersion = sessionReplay.sdkVersion we override it, as it means no one else set it
1429+
experimental.getSessionReplay().setSdkVersion(sdkVersion);
1430+
}
14241431
this.sdkVersion = sdkVersion;
14251432
}
14261433

@@ -2626,7 +2633,8 @@ public SentryOptions() {
26262633
* @param empty if options should be empty.
26272634
*/
26282635
private SentryOptions(final boolean empty) {
2629-
experimental = new ExperimentalOptions(empty);
2636+
final @NotNull SdkVersion sdkVersion = createSdkVersion();
2637+
experimental = new ExperimentalOptions(empty, sdkVersion);
26302638
if (!empty) {
26312639
// SentryExecutorService should be initialized before any
26322640
// SendCachedEventFireAndForgetIntegration
@@ -2647,7 +2655,7 @@ private SentryOptions(final boolean empty) {
26472655
}
26482656

26492657
setSentryClientName(BuildConfig.SENTRY_JAVA_SDK_NAME + "/" + BuildConfig.VERSION_NAME);
2650-
setSdkVersion(createSdkVersion());
2658+
setSdkVersion(sdkVersion);
26512659
addPackageInfo();
26522660
}
26532661
}

sentry/src/main/java/io/sentry/SentryReplayOptions.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry;
22

3+
import io.sentry.protocol.SdkVersion;
34
import io.sentry.util.SampleRateUtils;
45
import java.util.Set;
56
import java.util.concurrent.CopyOnWriteArraySet;
@@ -114,7 +115,13 @@ public enum SentryReplayQuality {
114115
*/
115116
private boolean trackOrientationChange = true;
116117

117-
public SentryReplayOptions(final boolean empty) {
118+
/**
119+
* SdkVersion object that contains the Sentry Client Name and its version. This object is only
120+
* applied to {@link SentryReplayEvent}s.
121+
*/
122+
private @Nullable SdkVersion sdkVersion;
123+
124+
public SentryReplayOptions(final boolean empty, final @Nullable SdkVersion sdkVersion) {
118125
if (!empty) {
119126
setMaskAllText(true);
120127
setMaskAllImages(true);
@@ -123,14 +130,18 @@ public SentryReplayOptions(final boolean empty) {
123130
maskViewClasses.add(ANDROIDX_MEDIA_VIEW_CLASS_NAME);
124131
maskViewClasses.add(EXOPLAYER_CLASS_NAME);
125132
maskViewClasses.add(EXOPLAYER_STYLED_CLASS_NAME);
133+
this.sdkVersion = sdkVersion;
126134
}
127135
}
128136

129137
public SentryReplayOptions(
130-
final @Nullable Double sessionSampleRate, final @Nullable Double onErrorSampleRate) {
131-
this(false);
138+
final @Nullable Double sessionSampleRate,
139+
final @Nullable Double onErrorSampleRate,
140+
final @Nullable SdkVersion sdkVersion) {
141+
this(false, sdkVersion);
132142
this.sessionSampleRate = sessionSampleRate;
133143
this.onErrorSampleRate = onErrorSampleRate;
144+
this.sdkVersion = sdkVersion;
134145
}
135146

136147
@Nullable
@@ -282,4 +293,14 @@ public boolean isTrackOrientationChange() {
282293
public void setTrackOrientationChange(final boolean trackOrientationChange) {
283294
this.trackOrientationChange = trackOrientationChange;
284295
}
296+
297+
@ApiStatus.Internal
298+
public @Nullable SdkVersion getSdkVersion() {
299+
return sdkVersion;
300+
}
301+
302+
@ApiStatus.Internal
303+
public void setSdkVersion(final @Nullable SdkVersion sdkVersion) {
304+
this.sdkVersion = sdkVersion;
305+
}
285306
}

sentry/src/test/java/io/sentry/MainEventProcessorTest.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import kotlin.test.assertTrue
2727

2828
class MainEventProcessorTest {
2929
class Fixture {
30-
private val sentryOptions: SentryOptions = SentryOptions().apply {
30+
val sentryOptions: SentryOptions = SentryOptions().apply {
3131
dsn = dsnString
3232
release = "release"
3333
dist = "dist"
@@ -619,6 +619,18 @@ class MainEventProcessorTest {
619619
assertEquals("value1", replayEvent.tags!!["tag1"])
620620
}
621621

622+
@Test
623+
fun `uses SdkVersion from replay options for replay events`() {
624+
val sut = fixture.getSut(tags = mapOf("tag1" to "value1"))
625+
626+
fixture.sentryOptions.experimental.sessionReplay.sdkVersion = SdkVersion("dart", "3.2.1")
627+
var replayEvent = SentryReplayEvent()
628+
replayEvent = sut.process(replayEvent, Hint())
629+
630+
assertEquals("3.2.1", replayEvent.sdk!!.version)
631+
assertEquals("dart", replayEvent.sdk!!.name)
632+
}
633+
622634
private fun generateCrashedEvent(crashedThread: Thread = Thread.currentThread()) =
623635
SentryEvent().apply {
624636
val mockThrowable = mock<Throwable>()

sentry/src/test/java/io/sentry/SentryReplayOptionsTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class SentryReplayOptionsTest {
77

88
@Test
99
fun `uses medium quality as default`() {
10-
val replayOptions = SentryReplayOptions(true)
10+
val replayOptions = SentryReplayOptions(true, null)
1111

1212
assertEquals(SentryReplayOptions.SentryReplayQuality.MEDIUM, replayOptions.quality)
1313
assertEquals(75_000, replayOptions.quality.bitRate)
@@ -16,15 +16,15 @@ class SentryReplayOptionsTest {
1616

1717
@Test
1818
fun `low quality`() {
19-
val replayOptions = SentryReplayOptions(true).apply { quality = SentryReplayOptions.SentryReplayQuality.LOW }
19+
val replayOptions = SentryReplayOptions(true, null).apply { quality = SentryReplayOptions.SentryReplayQuality.LOW }
2020

2121
assertEquals(50_000, replayOptions.quality.bitRate)
2222
assertEquals(0.8f, replayOptions.quality.sizeScale)
2323
}
2424

2525
@Test
2626
fun `high quality`() {
27-
val replayOptions = SentryReplayOptions(true).apply { quality = SentryReplayOptions.SentryReplayQuality.HIGH }
27+
val replayOptions = SentryReplayOptions(true, null).apply { quality = SentryReplayOptions.SentryReplayQuality.HIGH }
2828

2929
assertEquals(100_000, replayOptions.quality.bitRate)
3030
assertEquals(1.0f, replayOptions.quality.sizeScale)

0 commit comments

Comments
 (0)