Skip to content

Commit 7c4b39a

Browse files
committed
Move all app start handling to AppStartMetrics
1 parent 8823143 commit 7c4b39a

File tree

7 files changed

+191
-273
lines changed

7 files changed

+191
-273
lines changed

sentry-android-core/api/sentry-android-core.api

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,22 +447,22 @@ public class io/sentry/android/core/performance/AppStartMetrics : io/sentry/andr
447447
public static fun getInstance ()Lio/sentry/android/core/performance/AppStartMetrics;
448448
public fun getSdkInitTimeSpan ()Lio/sentry/android/core/performance/TimeSpan;
449449
public fun isAppLaunchedInForeground ()Z
450-
public fun isColdStartValid ()Z
451450
public fun onActivityCreated (Landroid/app/Activity;Landroid/os/Bundle;)V
451+
public fun onActivityDestroyed (Landroid/app/Activity;)V
452+
public fun onActivityStarted (Landroid/app/Activity;)V
452453
public fun onAppStartSpansSent ()V
453454
public static fun onApplicationCreate (Landroid/app/Application;)V
454455
public static fun onApplicationPostCreate (Landroid/app/Application;)V
455456
public static fun onContentProviderCreate (Landroid/content/ContentProvider;)V
456457
public static fun onContentProviderPostCreate (Landroid/content/ContentProvider;)V
457-
public fun registerApplicationForegroundCheck (Landroid/app/Application;)V
458+
public fun registerLifecycleCallbacks (Landroid/app/Application;)V
458459
public fun restartAppStart (J)V
459460
public fun setAppLaunchedInForeground (Z)V
460461
public fun setAppStartProfiler (Lio/sentry/ITransactionProfiler;)V
461462
public fun setAppStartSamplingDecision (Lio/sentry/TracesSamplingDecision;)V
462463
public fun setAppStartType (Lio/sentry/android/core/performance/AppStartMetrics$AppStartType;)V
463464
public fun setClassLoadedUptimeMs (J)V
464465
public fun shouldSendStartMeasurements ()Z
465-
public fun updateAppStartType (ZJ)V
466466
}
467467

468468
public final class io/sentry/android/core/performance/AppStartMetrics$AppStartType : java/lang/Enum {

sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,6 @@ public synchronized void onActivityCreated(
397397
if (!isAllActivityCallbacksAvailable) {
398398
onActivityPreCreated(activity, savedInstanceState);
399399
}
400-
setColdStart(savedInstanceState != null);
401400
if (hub != null && options != null && options.isEnableScreenTracking()) {
402401
final @Nullable String activityClassName = ClassUtil.getClassName(activity);
403402
hub.configureScope(scope -> scope.setScreen(activityClassName));
@@ -553,17 +552,6 @@ public synchronized void onActivityDestroyed(final @NotNull Activity activity) {
553552
// activity stack still.
554553
// if the activity is opened again and not in memory, transactions will be created normally.
555554
activitiesWithOngoingTransactions.remove(activity);
556-
557-
if (activitiesWithOngoingTransactions.isEmpty()) {
558-
clear();
559-
}
560-
}
561-
562-
private void clear() {
563-
firstActivityCreated = false;
564-
lastPausedTime = new SentryNanotimeDate(new Date(0), 0);
565-
lastPausedUptimeMillis = 0;
566-
activityLifecycleMap.clear();
567555
}
568556

569557
private void finishSpan(final @Nullable ISpan span) {
@@ -705,12 +693,6 @@ WeakHashMap<Activity, ISpan> getTtfdSpanMap() {
705693
return ttfdSpanMap;
706694
}
707695

708-
private void setColdStart(final boolean hasBundle) {
709-
if (!firstActivityCreated) {
710-
AppStartMetrics.getInstance().updateAppStartType(hasBundle, lastPausedUptimeMillis);
711-
}
712-
}
713-
714696
private @NotNull String getTtidDesc(final @NotNull String activityName) {
715697
return activityName + " initial display";
716698
}

sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public static synchronized void init(
152152
}
153153
}
154154
if (context.getApplicationContext() instanceof Application) {
155-
appStartMetrics.registerApplicationForegroundCheck(
155+
appStartMetrics.registerLifecycleCallbacks(
156156
(Application) context.getApplicationContext());
157157
}
158158
final @NotNull TimeSpan sdkInitTimeSpan = appStartMetrics.getSdkInitTimeSpan();

sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java

Lines changed: 4 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,13 @@
33
import static io.sentry.Sentry.APP_START_PROFILING_CONFIG_FILE_NAME;
44

55
import android.annotation.SuppressLint;
6-
import android.app.Activity;
76
import android.app.Application;
87
import android.content.Context;
98
import android.content.pm.ProviderInfo;
109
import android.net.Uri;
1110
import android.os.Build;
12-
import android.os.Bundle;
13-
import android.os.Handler;
14-
import android.os.Looper;
1511
import android.os.Process;
1612
import android.os.SystemClock;
17-
import android.util.Log;
18-
import androidx.annotation.NonNull;
1913
import io.sentry.ILogger;
2014
import io.sentry.ITransactionProfiler;
2115
import io.sentry.JsonSerializer;
@@ -24,9 +18,7 @@
2418
import io.sentry.SentryLevel;
2519
import io.sentry.SentryOptions;
2620
import io.sentry.TracesSamplingDecision;
27-
import io.sentry.android.core.internal.util.FirstDrawDoneListener;
2821
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
29-
import io.sentry.android.core.performance.ActivityLifecycleCallbacksAdapter;
3022
import io.sentry.android.core.performance.AppStartMetrics;
3123
import io.sentry.android.core.performance.TimeSpan;
3224
import java.io.BufferedReader;
@@ -35,8 +27,6 @@
3527
import java.io.FileNotFoundException;
3628
import java.io.InputStreamReader;
3729
import java.io.Reader;
38-
import java.util.concurrent.atomic.AtomicBoolean;
39-
import java.util.concurrent.atomic.AtomicInteger;
4030
import org.jetbrains.annotations.ApiStatus;
4131
import org.jetbrains.annotations.NotNull;
4232
import org.jetbrains.annotations.Nullable;
@@ -54,8 +44,6 @@ public final class SentryPerformanceProvider extends EmptySecureContentProvider
5444

5545
private final @NotNull ILogger logger;
5646
private final @NotNull BuildInfoProvider buildInfoProvider;
57-
private final AtomicInteger activeActivitiesCounter = new AtomicInteger();
58-
private final AtomicBoolean firstDrawDone = new AtomicBoolean(false);
5947

6048
@TestOnly
6149
SentryPerformanceProvider(
@@ -190,8 +178,9 @@ private void onAppLaunched(
190178

191179
// performance v2: Uses Process.getStartUptimeMillis()
192180
// requires API level 24+
193-
if (buildInfoProvider.getSdkInfoVersion() < android.os.Build.VERSION_CODES.N) {
194-
return;
181+
if (buildInfoProvider.getSdkInfoVersion() >= android.os.Build.VERSION_CODES.N) {
182+
final @NotNull TimeSpan appStartTimespan = appStartMetrics.getAppStartTimeSpan();
183+
appStartTimespan.setStartedAt(Process.getStartUptimeMillis());
195184
}
196185

197186
if (context instanceof Application) {
@@ -201,61 +190,6 @@ private void onAppLaunched(
201190
return;
202191
}
203192

204-
final @NotNull TimeSpan appStartTimespan = appStartMetrics.getAppStartTimeSpan();
205-
appStartTimespan.setStartedAt(Process.getStartUptimeMillis());
206-
appStartMetrics.registerApplicationForegroundCheck(app);
207-
208-
activityCallback =
209-
new ActivityLifecycleCallbacksAdapter() {
210-
211-
@Override
212-
public void onActivityCreated(
213-
@NotNull Activity activity, @Nullable Bundle savedInstanceState) {
214-
Log.d("TAG", "onActivityCreated");
215-
activeActivitiesCounter.incrementAndGet();
216-
217-
// In case the SDK gets initialized async or the
218-
// ActivityLifecycleIntegration is not enabled (e.g on RN due to Context not being
219-
// instanceof Application)
220-
// the app start type never gets set
221-
if (!firstDrawDone.get()) {
222-
final long now = SystemClock.uptimeMillis();
223-
AppStartMetrics.getInstance().updateAppStartType(savedInstanceState != null, now);
224-
}
225-
}
226-
227-
@Override
228-
public void onActivityStarted(@NotNull Activity activity) {
229-
if (firstDrawDone.get()) {
230-
return;
231-
}
232-
if (activity.getWindow() != null) {
233-
FirstDrawDoneListener.registerForNextDraw(
234-
activity, () -> onAppStartDone(), buildInfoProvider);
235-
} else {
236-
new Handler(Looper.getMainLooper()).post(() -> onAppStartDone());
237-
}
238-
}
239-
240-
@Override
241-
public void onActivityDestroyed(@NonNull Activity activity) {
242-
final int remainingActivities = activeActivitiesCounter.decrementAndGet();
243-
// if the app is moving into background, reset firstDrawDone
244-
// as the next Activity is considered like a new app start
245-
if (remainingActivities == 0 && !activity.isChangingConfigurations()) {
246-
firstDrawDone.set(false);
247-
}
248-
}
249-
};
250-
251-
app.registerActivityLifecycleCallbacks(activityCallback);
252-
}
253-
254-
synchronized void onAppStartDone() {
255-
if (!firstDrawDone.getAndSet(true)) {
256-
final @NotNull AppStartMetrics appStartMetrics = AppStartMetrics.getInstance();
257-
appStartMetrics.getSdkInitTimeSpan().stop();
258-
appStartMetrics.getAppStartTimeSpan().stop();
259-
}
193+
appStartMetrics.registerLifecycleCallbacks(app);
260194
}
261195
}

0 commit comments

Comments
 (0)