1818import io .sentry .SpanDataConvention ;
1919import io .sentry .SpanId ;
2020import io .sentry .SpanStatus ;
21+ import io .sentry .TracesSamplingDecision ;
2122import io .sentry .android .core .internal .util .AndroidThreadChecker ;
23+ import io .sentry .android .core .performance .ActivityLifecycleTimeSpan ;
2224import io .sentry .android .core .performance .AppStartMetrics ;
2325import io .sentry .android .core .performance .TimeSpan ;
2426import io .sentry .protocol .SentryId ;
2830import io .sentry .protocol .TransactionNameSource ;
2931import io .sentry .util .AutoClosableReentrantLock ;
3032import io .sentry .util .IntegrationUtils ;
33+ import io .sentry .util .Objects ;
3134import java .io .Closeable ;
3235import java .io .IOException ;
3336import java .util .Date ;
@@ -52,7 +55,7 @@ public ApplicationStartInfoIntegration(
5255 final @ NotNull Context context , final @ NotNull BuildInfoProvider buildInfoProvider ) {
5356 this .context = ContextUtils .getApplicationContext (context );
5457 this .buildInfoProvider =
55- java . util . Objects .requireNonNull (buildInfoProvider , "BuildInfoProvider is required" );
58+ Objects .requireNonNull (buildInfoProvider , "BuildInfoProvider is required" );
5659 }
5760
5861 @ Override
@@ -70,9 +73,9 @@ private void register(
7073 "ApplicationStartInfoIntegration enabled: %s" ,
7174 options .isEnableApplicationStartInfo ());
7275
73- // if (!options.isEnableApplicationStartInfo()) {
74- // return;
75- // }
76+ if (!options .isEnableApplicationStartInfo ()) {
77+ return ;
78+ }
7679
7780 if (buildInfoProvider .getSdkInfoVersion () < Build .VERSION_CODES .VANILLA_ICE_CREAM ) {
7881 options
@@ -157,9 +160,7 @@ private void onApplicationStartInfoAvailable(
157160 final long unixTimeOffsetMs = currentUnixMs - currentRealtimeMs ;
158161
159162 final Map <String , String > tags = extractTags (startInfo );
160- final String transactionName = "app.start." + getReasonLabel (startInfo .getReason ());
161163 final long startRealtimeMs = getStartTimestampMs (startInfo );
162-
163164 final long ttidRealtimeMs = getFirstFrameTimestampMs (startInfo );
164165 final long ttfdRealtimeMs = getFullyDrawnTimestampMs (startInfo );
165166 final long bindApplicationRealtimeMs = getBindApplicationTimestampMs (startInfo );
@@ -172,36 +173,30 @@ private void onApplicationStartInfoAvailable(
172173 ? dateFromUnixTime (unixTimeOffsetMs + endTimestamp )
173174 : options .getDateProvider ().now ();
174175
175- // Create trace context
176176 final SentryId traceId = new SentryId ();
177177 final SpanId spanId = new SpanId ();
178178 final SpanContext traceContext =
179- new SpanContext (traceId , spanId , "app.startDate.info " , null , null );
179+ new SpanContext (traceId , spanId , "app.start " , null , new TracesSamplingDecision ( true ) );
180180 traceContext .setStatus (SpanStatus .OK );
181181
182- // Convert timestamps to seconds
183182 final double startTimestampSecs = dateToSeconds (startDate );
184183 final double endTimestampSecs = dateToSeconds (endDate );
185184
186- // Create transaction directly
187185 final SentryTransaction transaction =
188186 new SentryTransaction (
189- transactionName ,
187+ "app.start" ,
190188 startTimestampSecs ,
191189 endTimestampSecs ,
192190 new java .util .ArrayList <>(),
193191 new HashMap <>(),
194192 new TransactionInfo (TransactionNameSource .COMPONENT .apiName ()));
195193
196- // Set trace context
197194 transaction .getContexts ().setTrace (traceContext );
198195
199- // Set tags
200196 for (Map .Entry <String , String > entry : tags .entrySet ()) {
201197 transaction .setTag (entry .getKey (), entry .getValue ());
202198 }
203199
204- // Add spans
205200 if (bindApplicationRealtimeMs > 0 ) {
206201 transaction
207202 .getSpans ()
@@ -215,6 +210,12 @@ private void onApplicationStartInfoAvailable(
215210 dateFromUnixTime (unixTimeOffsetMs + bindApplicationRealtimeMs )));
216211 }
217212
213+ if (startInfo .getStartType () == ApplicationStartInfo .START_TYPE_COLD ) {
214+ attachColdStartInstrumentations (transaction , traceId , spanId );
215+ }
216+
217+ attachActivitySpans (transaction , traceId , spanId );
218+
218219 if (ttidRealtimeMs > 0 ) {
219220 transaction
220221 .getSpans ()
@@ -241,26 +242,6 @@ private void onApplicationStartInfoAvailable(
241242 dateFromUnixTime (unixTimeOffsetMs + ttfdRealtimeMs )));
242243 }
243244
244- attachAppStartMetrics (transaction , traceId , spanId , unixTimeOffsetMs );
245-
246- // if application instrumentation was disabled, report app start info data
247- final TimeSpan appOnCreateSpan = AppStartMetrics .getInstance ().getApplicationOnCreateTimeSpan ();
248- if (!appOnCreateSpan .hasStarted () || appOnCreateSpan .hasStopped ()) {
249- final long applicationOnCreateRealtimeMs = getApplicationOnCreateTimestampMs (startInfo );
250- if (applicationOnCreateRealtimeMs > 0 ) {
251- transaction
252- .getSpans ()
253- .add (
254- createSpan (
255- traceId ,
256- spanId ,
257- "application.onCreate" ,
258- null ,
259- startDate ,
260- dateFromUnixTime (unixTimeOffsetMs + applicationOnCreateRealtimeMs )));
261- }
262- }
263-
264245 scopes .captureTransaction (transaction , null , null );
265246 }
266247
@@ -299,11 +280,10 @@ private static double dateToSeconds(final @NotNull SentryDate date) {
299280 }
300281
301282 @ RequiresApi (api = 35 )
302- private void attachAppStartMetrics (
283+ private void attachColdStartInstrumentations (
303284 final @ NotNull SentryTransaction transaction ,
304285 final @ NotNull SentryId traceId ,
305- final @ NotNull SpanId parentSpanId ,
306- final long unixTimeOffsetMs ) {
286+ final @ NotNull SpanId parentSpanId ) {
307287
308288 final @ NotNull AppStartMetrics appStartMetrics = AppStartMetrics .getInstance ();
309289 final @ NotNull List <TimeSpan > contentProviderSpans =
@@ -320,7 +300,7 @@ private void attachAppStartMetrics(
320300 createSpan (
321301 traceId ,
322302 parentSpanId ,
323- "contentprovider.load " ,
303+ "contentprovider.on_create " ,
324304 cpSpan .getDescription (),
325305 cpStartDate ,
326306 cpEndDate ));
@@ -342,13 +322,61 @@ private void attachAppStartMetrics(
342322 createSpan (
343323 traceId ,
344324 parentSpanId ,
345- "application.onCreate " ,
325+ "application.on_create " ,
346326 appOnCreateDescription ,
347327 appOnCreateStart ,
348328 appOnCreateEnd ));
349329 }
350330 }
351331
332+ @ RequiresApi (api = 35 )
333+ private void attachActivitySpans (
334+ final @ NotNull SentryTransaction transaction ,
335+ final @ NotNull SentryId traceId ,
336+ final @ NotNull SpanId parentSpanId ) {
337+
338+ final @ NotNull AppStartMetrics appStartMetrics = AppStartMetrics .getInstance ();
339+ final @ NotNull List <ActivityLifecycleTimeSpan > activityLifecycleTimeSpans =
340+ appStartMetrics .getActivityLifecycleTimeSpans ();
341+
342+ for (final ActivityLifecycleTimeSpan span : activityLifecycleTimeSpans ) {
343+ final TimeSpan onCreate = span .getOnCreate ();
344+ final TimeSpan onStart = span .getOnStart ();
345+
346+ if (onCreate .hasStarted () && onCreate .hasStopped ()) {
347+ final SentryDate start = dateFromUnixTime (onCreate .getStartTimestampMs ());
348+ final SentryDate end = dateFromUnixTime (onCreate .getProjectedStopTimestampMs ());
349+
350+ transaction
351+ .getSpans ()
352+ .add (
353+ createSpan (
354+ traceId ,
355+ parentSpanId ,
356+ "activity.on_create" ,
357+ onCreate .getDescription (),
358+ start ,
359+ end ));
360+ }
361+
362+ if (onStart .hasStarted () && onStart .hasStopped ()) {
363+ final SentryDate start = dateFromUnixTime (onStart .getStartTimestampMs ());
364+ final SentryDate end = dateFromUnixTime (onStart .getProjectedStopTimestampMs ());
365+
366+ transaction
367+ .getSpans ()
368+ .add (
369+ createSpan (
370+ traceId ,
371+ parentSpanId ,
372+ "activity.on_start" ,
373+ onStart .getDescription (),
374+ start ,
375+ end ));
376+ }
377+ }
378+ }
379+
352380 @ RequiresApi (api = 35 )
353381 private @ NotNull Map <String , String > extractTags (
354382 final @ NotNull android .app .ApplicationStartInfo startInfo ) {
@@ -437,15 +465,6 @@ private long getBindApplicationTimestampMs(
437465 return bindTime != null ? TimeUnit .NANOSECONDS .toMillis (bindTime ) : 0 ;
438466 }
439467
440- @ RequiresApi (api = 35 )
441- private long getApplicationOnCreateTimestampMs (
442- final @ NotNull android .app .ApplicationStartInfo startInfo ) {
443- final Map <Integer , Long > timestamps = startInfo .getStartupTimestamps ();
444- final Long onCreateTime =
445- timestamps .get (ApplicationStartInfo .START_TIMESTAMP_APPLICATION_ONCREATE );
446- return onCreateTime != null ? TimeUnit .NANOSECONDS .toMillis (onCreateTime ) : 0 ;
447- }
448-
449468 @ RequiresApi (api = 35 )
450469 private long getFirstFrameTimestampMs (final @ NotNull android .app .ApplicationStartInfo startInfo ) {
451470 final Map <Integer , Long > timestamps = startInfo .getStartupTimestamps ();
0 commit comments