Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Add support for setting in-app-includes/in-app-excludes via AndroidManifest.xml ([#4240](https://github.com/getsentry/sentry-java/pull/4240))
- Modifications to OkHttp requests are now properly propagated to the affected span / breadcrumbs ([#4238](https://github.com/getsentry/sentry-java/pull/4238))
- Please ensure the SentryOkHttpInterceptor is added last to your OkHttpClient, as otherwise changes to the `Request` by subsequent interceptors won't be considered
- Ensure app start type is set, even when ActivityLifecycleIntegration is not running ([#4250](https://github.com/getsentry/sentry-java/pull/4250))

### Features

Expand Down
6 changes: 3 additions & 3 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 +471,15 @@ public class io/sentry/android/core/performance/AppStartMetrics : io/sentry/andr
public static fun getInstance ()Lio/sentry/android/core/performance/AppStartMetrics;
public fun getSdkInitTimeSpan ()Lio/sentry/android/core/performance/TimeSpan;
public fun isAppLaunchedInForeground ()Z
public fun isColdStartValid ()Z
public fun onActivityCreated (Landroid/app/Activity;Landroid/os/Bundle;)V
public fun onActivityDestroyed (Landroid/app/Activity;)V
public fun onActivityStarted (Landroid/app/Activity;)V
public fun onAppStartSpansSent ()V
public static fun onApplicationCreate (Landroid/app/Application;)V
public static fun onApplicationPostCreate (Landroid/app/Application;)V
public static fun onContentProviderCreate (Landroid/content/ContentProvider;)V
public static fun onContentProviderPostCreate (Landroid/content/ContentProvider;)V
public fun registerApplicationForegroundCheck (Landroid/app/Application;)V
public fun restartAppStart (J)V
public fun registerLifecycleCallbacks (Landroid/app/Application;)V
public fun setAppLaunchedInForeground (Z)V
public fun setAppStartProfiler (Lio/sentry/ITransactionProfiler;)V
public fun setAppStartSamplingDecision (Lio/sentry/TracesSamplingDecision;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import io.sentry.FullyDisplayedReporter;
import io.sentry.IScope;
import io.sentry.IScopes;
Expand Down Expand Up @@ -83,7 +82,6 @@ public final class ActivityLifecycleIntegration
private final @NotNull WeakHashMap<Activity, ActivityLifecycleSpanHelper> activitySpanHelpers =
new WeakHashMap<>();
private @NotNull SentryDate lastPausedTime = new SentryNanotimeDate(new Date(0), 0);
private long lastPausedUptimeMillis = 0;
private @Nullable Future<?> ttfdAutoCloseFuture = null;

// WeakHashMap isn't thread safe but ActivityLifecycleCallbacks is only called from the
Expand Down Expand Up @@ -400,7 +398,6 @@ public void onActivityPreCreated(
scopes != null
? scopes.getOptions().getDateProvider().now()
: AndroidDateUtils.getCurrentSentryDateTime();
lastPausedUptimeMillis = SystemClock.uptimeMillis();
helper.setOnCreateStartTimestamp(lastPausedTime);
}

Expand All @@ -411,7 +408,6 @@ public void onActivityCreated(
onActivityPreCreated(activity, savedInstanceState);
}
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
setColdStart(savedInstanceState);
if (scopes != null && options != null && options.isEnableScreenTracking()) {
final @Nullable String activityClassName = ClassUtil.getClassName(activity);
scopes.configureScope(scope -> scope.setScreen(activityClassName));
Expand Down Expand Up @@ -516,7 +512,6 @@ public void onActivityPrePaused(@NotNull Activity activity) {
scopes != null
? scopes.getOptions().getDateProvider().now()
: AndroidDateUtils.getCurrentSentryDateTime();
lastPausedUptimeMillis = SystemClock.uptimeMillis();
}

@Override
Expand Down Expand Up @@ -577,7 +572,7 @@ public void onActivityDestroyed(final @NotNull Activity activity) {
// if the activity is opened again and not in memory, transactions will be created normally.
activitiesWithOngoingTransactions.remove(activity);

if (activitiesWithOngoingTransactions.isEmpty()) {
if (activitiesWithOngoingTransactions.isEmpty() && !activity.isChangingConfigurations()) {
clear();
}
}
Expand All @@ -586,7 +581,6 @@ public void onActivityDestroyed(final @NotNull Activity activity) {
private void clear() {
firstActivityCreated = false;
lastPausedTime = new SentryNanotimeDate(new Date(0), 0);
lastPausedUptimeMillis = 0;
activitySpanHelpers.clear();
}

Expand Down Expand Up @@ -728,27 +722,6 @@ WeakHashMap<Activity, ISpan> getTtfdSpanMap() {
return ttfdSpanMap;
}

private void setColdStart(final @Nullable Bundle savedInstanceState) {
if (!firstActivityCreated) {
final @NotNull TimeSpan appStartSpan = AppStartMetrics.getInstance().getAppStartTimeSpan();
// If the app start span already started and stopped, it means the app restarted without
// killing the process, so we are in a warm start
// If the app has an invalid cold start, it means it was started in the background, like
// via BroadcastReceiver, so we consider it a warm start
if ((appStartSpan.hasStarted() && appStartSpan.hasStopped())
|| (!AppStartMetrics.getInstance().isColdStartValid())) {
AppStartMetrics.getInstance().restartAppStart(lastPausedUptimeMillis);
AppStartMetrics.getInstance().setAppStartType(AppStartMetrics.AppStartType.WARM);
} else {
AppStartMetrics.getInstance()
.setAppStartType(
savedInstanceState == null
? AppStartMetrics.AppStartType.COLD
: AppStartMetrics.AppStartType.WARM);
}
}
}

private @NotNull String getTtidDesc(final @NotNull String activityName) {
return activityName + " initial display";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public static void init(
}
}
if (context.getApplicationContext() instanceof Application) {
appStartMetrics.registerApplicationForegroundCheck(
appStartMetrics.registerLifecycleCallbacks(
(Application) context.getApplicationContext());
}
final @NotNull TimeSpan sdkInitTimeSpan = appStartMetrics.getSdkInitTimeSpan();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,9 @@ private void onAppLaunched(

// performance v2: Uses Process.getStartUptimeMillis()
// requires API level 24+
if (buildInfoProvider.getSdkInfoVersion() < android.os.Build.VERSION_CODES.N) {
return;
if (buildInfoProvider.getSdkInfoVersion() >= android.os.Build.VERSION_CODES.N) {
final @NotNull TimeSpan appStartTimespan = appStartMetrics.getAppStartTimeSpan();
appStartTimespan.setStartedAt(Process.getStartUptimeMillis());
}

if (context instanceof Application) {
Expand All @@ -185,8 +186,6 @@ private void onAppLaunched(
return;
}

final @NotNull TimeSpan appStartTimespan = appStartMetrics.getAppStartTimeSpan();
appStartTimespan.setStartedAt(Process.getStartUptimeMillis());
appStartMetrics.registerApplicationForegroundCheck(app);
appStartMetrics.registerLifecycleCallbacks(app);
}
}
Loading