Skip to content

Commit a83f2e3

Browse files
authored
Merge e963707 into bc2e9d6
2 parents bc2e9d6 + e963707 commit a83f2e3

File tree

14 files changed

+98
-82
lines changed

14 files changed

+98
-82
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
- Session Replay: Fix memory leak when masking Compose screens ([#3985](https://github.com/getsentry/sentry-java/pull/3985))
99
- Session Replay: Fix potential ANRs in `GestureRecorder` ([#4001](https://github.com/getsentry/sentry-java/pull/4001))
1010

11+
### Internal
12+
13+
- Session Replay: Flutter improvements ([#4007](https://github.com/getsentry/sentry-java/pull/4007))
14+
1115
## 7.19.0
1216

1317
### Fixes

sentry-android-replay/api/sentry-android-replay.api

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ public abstract interface class io/sentry/android/replay/Recorder : java/io/Clos
4343
public final class io/sentry/android/replay/ReplayCache : java/io/Closeable {
4444
public static final field $stable I
4545
public static final field Companion Lio/sentry/android/replay/ReplayCache$Companion;
46-
public fun <init> (Lio/sentry/SentryOptions;Lio/sentry/protocol/SentryId;Lio/sentry/android/replay/ScreenshotRecorderConfig;)V
46+
public fun <init> (Lio/sentry/SentryOptions;Lio/sentry/protocol/SentryId;)V
4747
public final fun addFrame (Ljava/io/File;JLjava/lang/String;)V
4848
public static synthetic fun addFrame$default (Lio/sentry/android/replay/ReplayCache;Ljava/io/File;JLjava/lang/String;ILjava/lang/Object;)V
4949
public fun close ()V
50-
public final fun createVideoOf (JJIIILjava/io/File;)Lio/sentry/android/replay/GeneratedVideo;
51-
public static synthetic fun createVideoOf$default (Lio/sentry/android/replay/ReplayCache;JJIIILjava/io/File;ILjava/lang/Object;)Lio/sentry/android/replay/GeneratedVideo;
50+
public final fun createVideoOf (JJIIIIILjava/io/File;)Lio/sentry/android/replay/GeneratedVideo;
51+
public static synthetic fun createVideoOf$default (Lio/sentry/android/replay/ReplayCache;JJIIIIILjava/io/File;ILjava/lang/Object;)Lio/sentry/android/replay/GeneratedVideo;
5252
public final fun persistSegmentValues (Ljava/lang/String;Ljava/lang/String;)V
5353
public final fun rotate (J)Ljava/lang/String;
5454
}
@@ -60,8 +60,8 @@ public final class io/sentry/android/replay/ReplayCache$Companion {
6060
public final class io/sentry/android/replay/ReplayIntegration : android/content/ComponentCallbacks, io/sentry/IConnectionStatusProvider$IConnectionStatusObserver, io/sentry/Integration, io/sentry/ReplayController, io/sentry/android/replay/ScreenshotRecorderCallback, io/sentry/android/replay/gestures/TouchRecorderCallback, io/sentry/transport/RateLimiter$IRateLimitObserver, java/io/Closeable {
6161
public static final field $stable I
6262
public fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;)V
63-
public fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
64-
public synthetic fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
63+
public fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
64+
public synthetic fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6565
public fun captureReplay (Ljava/lang/Boolean;)V
6666
public fun close ()V
6767
public fun getBreadcrumbConverter ()Lio/sentry/ReplayBreadcrumbConverter;

sentry-android-replay/src/main/java/io/sentry/android/replay/ReplayCache.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ import java.util.concurrent.atomic.AtomicBoolean
3838
*/
3939
public class ReplayCache(
4040
private val options: SentryOptions,
41-
private val replayId: SentryId,
42-
private val recorderConfig: ScreenshotRecorderConfig
41+
private val replayId: SentryId
4342
) : Closeable {
4443

4544
private val isClosed = AtomicBoolean(false)
@@ -133,6 +132,8 @@ public class ReplayCache(
133132
segmentId: Int,
134133
height: Int,
135134
width: Int,
135+
frameRate: Int,
136+
bitRate: Int,
136137
videoFile: File = File(replayCacheDir, "$segmentId.mp4")
137138
): GeneratedVideo? {
138139
if (videoFile.exists() && videoFile.length() > 0) {
@@ -146,21 +147,20 @@ public class ReplayCache(
146147
return null
147148
}
148149

149-
// TODO: reuse instance of encoder and just change file path to create a different muxer
150150
encoder = synchronized(encoderLock) {
151151
SimpleVideoEncoder(
152152
options,
153153
MuxerConfig(
154154
file = videoFile,
155155
recordingHeight = height,
156156
recordingWidth = width,
157-
frameRate = recorderConfig.frameRate,
158-
bitRate = recorderConfig.bitRate
157+
frameRate = frameRate,
158+
bitRate = bitRate
159159
)
160160
).also { it.start() }
161161
}
162162

163-
val step = 1000 / recorderConfig.frameRate.toLong()
163+
val step = 1000 / frameRate.toLong()
164164
var frameCount = 0
165165
var lastFrame: ReplayFrame = frames.first()
166166
for (timestamp in from until (from + (duration)) step step) {
@@ -306,7 +306,7 @@ public class ReplayCache(
306306
}
307307
}
308308

309-
internal fun fromDisk(options: SentryOptions, replayId: SentryId, replayCacheProvider: ((replayId: SentryId, recorderConfig: ScreenshotRecorderConfig) -> ReplayCache)? = null): LastSegmentData? {
309+
internal fun fromDisk(options: SentryOptions, replayId: SentryId, replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null): LastSegmentData? {
310310
val replayCacheDir = makeReplayCacheDir(options, replayId)
311311
val lastSegmentFile = File(replayCacheDir, ONGOING_SEGMENT)
312312
if (!lastSegmentFile.exists()) {
@@ -360,7 +360,7 @@ public class ReplayCache(
360360
scaleFactorY = 1.0f
361361
)
362362

363-
val cache = replayCacheProvider?.invoke(replayId, recorderConfig) ?: ReplayCache(options, replayId, recorderConfig)
363+
val cache = replayCacheProvider?.invoke(replayId) ?: ReplayCache(options, replayId)
364364
cache.replayCacheDir?.listFiles { dir, name ->
365365
if (name.endsWith(".jpg")) {
366366
val file = File(dir, name)

sentry-android-replay/src/main/java/io/sentry/android/replay/ReplayIntegration.kt

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class ReplayIntegration(
5656
private val dateProvider: ICurrentDateProvider,
5757
private val recorderProvider: (() -> Recorder)? = null,
5858
private val recorderConfigProvider: ((configChanged: Boolean) -> ScreenshotRecorderConfig)? = null,
59-
private val replayCacheProvider: ((replayId: SentryId, recorderConfig: ScreenshotRecorderConfig) -> ReplayCache)? = null
59+
private val replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null
6060
) : Integration,
6161
Closeable,
6262
ScreenshotRecorderCallback,
@@ -80,7 +80,7 @@ public class ReplayIntegration(
8080
dateProvider: ICurrentDateProvider,
8181
recorderProvider: (() -> Recorder)?,
8282
recorderConfigProvider: ((configChanged: Boolean) -> ScreenshotRecorderConfig)?,
83-
replayCacheProvider: ((replayId: SentryId, recorderConfig: ScreenshotRecorderConfig) -> ReplayCache)?,
83+
replayCacheProvider: ((replayId: SentryId) -> ReplayCache)?,
8484
replayCaptureStrategyProvider: ((isFullSession: Boolean) -> CaptureStrategy)? = null,
8585
mainLooperHandler: MainLooperHandler? = null,
8686
gestureRecorderProvider: (() -> GestureRecorder)? = null
@@ -110,8 +110,6 @@ public class ReplayIntegration(
110110
private var mainLooperHandler: MainLooperHandler = MainLooperHandler()
111111
private var gestureRecorderProvider: (() -> GestureRecorder)? = null
112112

113-
private lateinit var recorderConfig: ScreenshotRecorderConfig
114-
115113
override fun register(hub: IHub, options: SentryOptions) {
116114
this.options = options
117115

@@ -134,10 +132,16 @@ public class ReplayIntegration(
134132

135133
options.connectionStatusProvider.addConnectionStatusObserver(this)
136134
hub.rateLimiter?.addRateLimitObserver(this)
137-
try {
138-
context.registerComponentCallbacks(this)
139-
} catch (e: Throwable) {
140-
options.logger.log(INFO, "ComponentCallbacks is not available, orientation changes won't be handled by Session replay", e)
135+
if (options.experimental.sessionReplay.isTrackOrientationChange) {
136+
try {
137+
context.registerComponentCallbacks(this)
138+
} catch (e: Throwable) {
139+
options.logger.log(
140+
INFO,
141+
"ComponentCallbacks is not available, orientation changes won't be handled by Session replay",
142+
e
143+
)
144+
}
141145
}
142146

143147
addIntegrationToSdkVersion("Replay")
@@ -169,7 +173,7 @@ public class ReplayIntegration(
169173
return
170174
}
171175

172-
recorderConfig = recorderConfigProvider?.invoke(false) ?: ScreenshotRecorderConfig.from(context, options.experimental.sessionReplay)
176+
val recorderConfig = recorderConfigProvider?.invoke(false) ?: ScreenshotRecorderConfig.from(context, options.experimental.sessionReplay)
173177
captureStrategy = replayCaptureStrategyProvider?.invoke(isFullSession) ?: if (isFullSession) {
174178
SessionCaptureStrategy(options, hub, dateProvider, replayExecutor, replayCacheProvider)
175179
} else {
@@ -260,9 +264,11 @@ public class ReplayIntegration(
260264

261265
options.connectionStatusProvider.removeConnectionStatusObserver(this)
262266
hub?.rateLimiter?.removeRateLimitObserver(this)
263-
try {
264-
context.unregisterComponentCallbacks(this)
265-
} catch (ignored: Throwable) {
267+
if (options.experimental.sessionReplay.isTrackOrientationChange) {
268+
try {
269+
context.unregisterComponentCallbacks(this)
270+
} catch (ignored: Throwable) {
271+
}
266272
}
267273
stop()
268274
recorder?.close()
@@ -279,7 +285,7 @@ public class ReplayIntegration(
279285
recorder?.stop()
280286

281287
// refresh config based on new device configuration
282-
recorderConfig = recorderConfigProvider?.invoke(true) ?: ScreenshotRecorderConfig.from(context, options.experimental.sessionReplay)
288+
val recorderConfig = recorderConfigProvider?.invoke(true) ?: ScreenshotRecorderConfig.from(context, options.experimental.sessionReplay)
283289
captureStrategy?.onConfigurationChanged(recorderConfig)
284290

285291
recorder?.start(recorderConfig)
@@ -392,6 +398,7 @@ public class ReplayIntegration(
392398
height = lastSegment.recorderConfig.recordingHeight,
393399
width = lastSegment.recorderConfig.recordingWidth,
394400
frameRate = lastSegment.recorderConfig.frameRate,
401+
bitRate = lastSegment.recorderConfig.bitRate,
395402
cache = lastSegment.cache,
396403
replayType = lastSegment.replayType,
397404
screenAtStart = lastSegment.screenAtStart,

sentry-android-replay/src/main/java/io/sentry/android/replay/capture/BaseCaptureStrategy.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ internal abstract class BaseCaptureStrategy(
4646
private val hub: IHub?,
4747
private val dateProvider: ICurrentDateProvider,
4848
protected val replayExecutor: ScheduledExecutorService,
49-
private val replayCacheProvider: ((replayId: SentryId, recorderConfig: ScreenshotRecorderConfig) -> ReplayCache)? = null
49+
private val replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null
5050
) : CaptureStrategy {
5151

5252
internal companion object {
@@ -89,7 +89,7 @@ internal abstract class BaseCaptureStrategy(
8989
replayId: SentryId,
9090
replayType: ReplayType?
9191
) {
92-
cache = replayCacheProvider?.invoke(replayId, recorderConfig) ?: ReplayCache(options, replayId, recorderConfig)
92+
cache = replayCacheProvider?.invoke(replayId) ?: ReplayCache(options, replayId)
9393

9494
this.currentReplayId = replayId
9595
this.currentSegment = segmentId
@@ -124,6 +124,7 @@ internal abstract class BaseCaptureStrategy(
124124
replayType: ReplayType = this.replayType,
125125
cache: ReplayCache? = this.cache,
126126
frameRate: Int = recorderConfig.frameRate,
127+
bitRate: Int = recorderConfig.bitRate,
127128
screenAtStart: String? = this.screenAtStart,
128129
breadcrumbs: List<Breadcrumb>? = null,
129130
events: Deque<RRWebEvent> = this.currentEvents
@@ -140,6 +141,7 @@ internal abstract class BaseCaptureStrategy(
140141
replayType,
141142
cache,
142143
frameRate,
144+
bitRate,
143145
screenAtStart,
144146
breadcrumbs,
145147
events

sentry-android-replay/src/main/java/io/sentry/android/replay/capture/BufferCaptureStrategy.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal class BufferCaptureStrategy(
3131
private val dateProvider: ICurrentDateProvider,
3232
private val random: Random,
3333
executor: ScheduledExecutorService,
34-
replayCacheProvider: ((replayId: SentryId, recorderConfig: ScreenshotRecorderConfig) -> ReplayCache)? = null
34+
replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null
3535
) : BaseCaptureStrategy(options, hub, dateProvider, executor, replayCacheProvider = replayCacheProvider) {
3636

3737
// TODO: capture envelopes for buffered segments instead, but don't send them until buffer is triggered

sentry-android-replay/src/main/java/io/sentry/android/replay/capture/CaptureStrategy.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ internal interface CaptureStrategy {
6969
replayType: ReplayType,
7070
cache: ReplayCache?,
7171
frameRate: Int,
72+
bitRate: Int,
7273
screenAtStart: String?,
7374
breadcrumbs: List<Breadcrumb>?,
7475
events: Deque<RRWebEvent>
@@ -78,7 +79,9 @@ internal interface CaptureStrategy {
7879
currentSegmentTimestamp.time,
7980
segmentId,
8081
height,
81-
width
82+
width,
83+
frameRate,
84+
bitRate
8285
) ?: return ReplaySegment.Failed
8386

8487
val (video, frameCount, videoDuration) = generatedVideo

sentry-android-replay/src/main/java/io/sentry/android/replay/capture/SessionCaptureStrategy.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ internal class SessionCaptureStrategy(
2121
private val hub: IHub?,
2222
private val dateProvider: ICurrentDateProvider,
2323
executor: ScheduledExecutorService,
24-
replayCacheProvider: ((replayId: SentryId, recorderConfig: ScreenshotRecorderConfig) -> ReplayCache)? = null
24+
replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null
2525
) : BaseCaptureStrategy(options, hub, dateProvider, executor, replayCacheProvider) {
2626

2727
internal companion object {

0 commit comments

Comments
 (0)