Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR] Add buffer mode and link replays with events/transactions #3291

Merged
merged 15 commits into from
Apr 4, 2024
4 changes: 0 additions & 4 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,6 @@ public final class io/sentry/android/core/SentryAndroid {
public static fun init (Landroid/content/Context;Lio/sentry/ILogger;)V
public static fun init (Landroid/content/Context;Lio/sentry/ILogger;Lio/sentry/Sentry$OptionsConfiguration;)V
public static fun init (Landroid/content/Context;Lio/sentry/Sentry$OptionsConfiguration;)V
public static fun pauseReplay ()V
public static fun resumeReplay ()V
public static fun startReplay ()V
public static fun stopReplay ()V
}

public final class io/sentry/android/core/SentryAndroidDateProvider : io/sentry/SentryDateProvider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,10 @@ static void installDefaultIntegrations(
options.addIntegration(new TempSensorBreadcrumbsIntegration(context));
options.addIntegration(new PhoneStateBreadcrumbsIntegration(context));
if (isReplayAvailable) {
options.addIntegration(new ReplayIntegration(context, CurrentDateProvider.getInstance()));
final ReplayIntegration replay =
new ReplayIntegration(context, CurrentDateProvider.getInstance());
options.addIntegration(replay);
options.setReplayController(replay);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ private void startSession() {
addSessionBreadcrumb("start");
hub.startSession();
}
SentryAndroid.startReplay();
hub.getOptions().getReplayController().start();
} else if (!isFreshSession.getAndSet(false)) {
// only resume if it's not a fresh session, which has been started in SentryAndroid.init
SentryAndroid.resumeReplay();
hub.getOptions().getReplayController().resume();
}
this.lastUpdatedSession.set(currentTimeMillis);
}
Expand All @@ -108,7 +108,7 @@ public void onStop(final @NotNull LifecycleOwner owner) {
final long currentTimeMillis = currentDateProvider.getCurrentTimeMillis();
this.lastUpdatedSession.set(currentTimeMillis);

SentryAndroid.pauseReplay();
hub.getOptions().getReplayController().pause();
scheduleEndSession();

AppState.getInstance().setInBackground(true);
Expand All @@ -127,7 +127,7 @@ public void run() {
addSessionBreadcrumb("end");
hub.endSession();
}
SentryAndroid.stopReplay();
hub.getOptions().getReplayController().stop();
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
import io.sentry.android.core.performance.AppStartMetrics;
import io.sentry.android.core.performance.TimeSpan;
import io.sentry.android.fragment.FragmentLifecycleIntegration;
import io.sentry.android.replay.ReplayIntegration;
import io.sentry.android.replay.ReplayIntegrationKt;
import io.sentry.android.timber.SentryTimberIntegration;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
Expand Down Expand Up @@ -160,7 +158,7 @@ public static synchronized void init(
hub.addBreadcrumb(BreadcrumbFactory.forSession("session.start"));
hub.startSession();
}
startReplay();
hub.getOptions().getReplayController().start();
}
} catch (IllegalAccessException e) {
logger.log(SentryLevel.FATAL, "Fatal error during SentryAndroid.init(...)", e);
Expand Down Expand Up @@ -225,59 +223,4 @@ private static void deduplicateIntegrations(
}
}
}

public static synchronized void startReplay() {
if (!ensureReplayIntegration("starting")) {
return;
}
final @NotNull IHub hub = Sentry.getCurrentHub();
ReplayIntegrationKt.getReplayIntegration(hub).start();
}

public static synchronized void stopReplay() {
if (!ensureReplayIntegration("stopping")) {
return;
}
final @NotNull IHub hub = Sentry.getCurrentHub();
ReplayIntegrationKt.getReplayIntegration(hub).stop();
}

public static synchronized void resumeReplay() {
if (!ensureReplayIntegration("resuming")) {
return;
}
final @NotNull IHub hub = Sentry.getCurrentHub();
ReplayIntegrationKt.getReplayIntegration(hub).resume();
}

public static synchronized void pauseReplay() {
if (!ensureReplayIntegration("pausing")) {
return;
}
final @NotNull IHub hub = Sentry.getCurrentHub();
ReplayIntegrationKt.getReplayIntegration(hub).pause();
}

private static boolean ensureReplayIntegration(final @NotNull String actionName) {
final @NotNull IHub hub = Sentry.getCurrentHub();
if (isReplayAvailable) {
final ReplayIntegration replay = ReplayIntegrationKt.getReplayIntegration(hub);
if (replay != null) {
return true;
} else {
hub.getOptions()
.getLogger()
.log(
SentryLevel.INFO,
"Session Replay wasn't registered yet, not " + actionName + " the replay");
}
} else {
hub.getOptions()
.getLogger()
.log(
SentryLevel.INFO,
"Session Replay wasn't found on classpath, not " + actionName + " the replay");
}
return false;
}
}
17 changes: 6 additions & 11 deletions sentry-android-replay/api/sentry-android-replay.api
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,17 @@ public final class io/sentry/android/replay/BuildConfig {
public fun <init> ()V
}

public final class io/sentry/android/replay/ReplayIntegration : io/sentry/Integration, io/sentry/android/replay/ScreenshotRecorderCallback, java/io/Closeable {
public static final field Companion Lio/sentry/android/replay/ReplayIntegration$Companion;
public static final field VIDEO_BUFFER_DURATION J
public static final field VIDEO_SEGMENT_DURATION J
public final class io/sentry/android/replay/ReplayIntegration : io/sentry/Integration, io/sentry/ReplayController, io/sentry/android/replay/ScreenshotRecorderCallback, java/io/Closeable {
public fun <init> (Landroid/content/Context;Lio/sentry/transport/ICurrentDateProvider;)V
public fun close ()V
public final fun isRecording ()Z
public fun onScreenshotRecorded (Landroid/graphics/Bitmap;)V
public final fun pause ()V
public fun pause ()V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public final fun resume ()V
public final fun start ()V
public final fun stop ()V
}

public final class io/sentry/android/replay/ReplayIntegration$Companion {
public fun resume ()V
public fun sendReplayForEvent (Lio/sentry/SentryEvent;Lio/sentry/Hint;)V
public fun start ()V
public fun stop ()V
}

public final class io/sentry/android/replay/ReplayIntegrationKt {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,7 @@ internal class ReplayCache(
encoder = null
}

frames.removeAll {
if (it.timestamp < (from + duration)) {
deleteFile(it.screenshot)
return@removeAll true
}
return@removeAll false
}
rotate(until = (from + duration))

return GeneratedVideo(videoFile, frameCount, videoDuration)
}
Expand All @@ -142,6 +136,16 @@ internal class ReplayCache(
}
}

fun rotate(until: Long) {
frames.removeAll {
if (it.timestamp < until) {
deleteFile(it.screenshot)
return@removeAll true
}
return@removeAll false
}
}

override fun close() {
synchronized(encoderLock) {
encoder?.release()
Expand Down
Loading
Loading