@@ -16,7 +16,6 @@ import io.embrace.android.embracesdk.spans.ErrorCode
1616import io.opentelemetry.sdk.common.Clock
1717import java.util.concurrent.ConcurrentHashMap
1818import java.util.concurrent.ConcurrentLinkedQueue
19- import java.util.concurrent.atomic.AtomicBoolean
2019import java.util.concurrent.atomic.AtomicReference
2120
2221/* *
@@ -51,6 +50,8 @@ internal class AppStartupTraceEmitter(
5150 private val processCreatedMs: Long?
5251 private val additionalTrackedIntervals = ConcurrentLinkedQueue <TrackedInterval >()
5352 private val customAttributes: MutableMap <String , String > = ConcurrentHashMap ()
53+ private val endWithFrameDraw: Boolean = startupHasRenderEvent(versionChecker)
54+ private val appStartupRootSpan = AtomicReference <PersistableEmbraceSpan ?>(null )
5455
5556 init {
5657 val timestampAtDeviceStart = nowMs() - clock.nanoTime().nanosToMillis()
@@ -97,12 +98,10 @@ internal class AppStartupTraceEmitter(
9798 private var firstFrameRenderedMs: Long? = null
9899
99100 @Volatile
100- private var recordColdStart = true
101+ private var dataCollectionComplete = false
101102
102- private val appStartupRootSpan = AtomicReference <PersistableEmbraceSpan ?>(null )
103- private val startupRecorded = AtomicBoolean (false )
104- private val dataCollectionComplete = AtomicBoolean (false )
105- private val endWithFrameDraw: Boolean = startupHasRenderEvent(versionChecker)
103+ @Volatile
104+ private var recordColdStart = true
106105
107106 override fun applicationInitStart (timestampMs : Long? ) {
108107 applicationInitStartMs = timestampMs ? : nowMs()
@@ -202,22 +201,18 @@ internal class AppStartupTraceEmitter(
202201 * Called when app startup is considered complete, i.e. the data can be used and any additional updates can be ignored
203202 */
204203 private fun dataCollectionComplete (callback : (() -> Unit )? ) {
205- if (! dataCollectionComplete.get()) {
206- synchronized(dataCollectionComplete) {
207- if (! dataCollectionComplete.get()) {
208- backgroundWorker.submit {
209- recordStartup()
210- if (! startupRecorded.get()) {
211- logger.trackInternalError(
212- type = InternalErrorType .APP_LAUNCH_TRACE_FAIL ,
213- throwable = IllegalStateException (" App startup trace recording attempted but did not succeed" )
214- )
215- }
216- }
217- callback?.invoke()
218- dataCollectionComplete.set(true )
204+ if (! dataCollectionComplete) {
205+ backgroundWorker.submit {
206+ recordStartup()
207+ if (appStartupRootSpan.get()?.isRecording != false ) {
208+ logger.trackInternalError(
209+ type = InternalErrorType .APP_LAUNCH_TRACE_FAIL ,
210+ throwable = IllegalStateException (" App startup trace recording attempted but did not succeed" )
211+ )
219212 }
220213 }
214+ callback?.invoke()
215+ dataCollectionComplete = true
221216 }
222217 }
223218
@@ -296,7 +291,6 @@ internal class AppStartupTraceEmitter(
296291 } while (additionalTrackedIntervals.isNotEmpty())
297292 }
298293
299- @Suppress(" CyclomaticComplexMethod" , " ComplexMethod" )
300294 private fun recordTtid (
301295 applicationInitEndMs : Long? ,
302296 sdkInitStartMs : Long? ,
@@ -305,69 +299,63 @@ internal class AppStartupTraceEmitter(
305299 activityInitStartMs : Long? ,
306300 activityInitEndMs : Long? ,
307301 traceEndTimeMs : Long ,
308- ): EmbraceSpan ? {
309- return if (! startupRecorded.get()) {
310- appStartupRootSpan.get()?.apply {
311- addTraceMetadata()
312-
313- if (stop(endTimeMs = traceEndTimeMs)) {
314- startupRecorded.set(true )
315- }
302+ ) {
303+ appStartupRootSpan.get()?.takeIf { it.isRecording }?.apply {
304+ addTraceMetadata()
316305
317- getStartTimeMs()?.let { traceStartTimeMs ->
318- if (applicationInitEndMs != null ) {
319- spanService.recordCompletedSpan(
320- name = " process-init" ,
321- parent = this ,
322- startTimeMs = traceStartTimeMs,
323- endTimeMs = applicationInitEndMs,
324- )
325- }
326- }
306+ stop(endTimeMs = traceEndTimeMs)
327307
328- if (sdkInitStartMs != null && sdkInitEndMs != null ) {
308+ getStartTimeMs()?.let { traceStartTimeMs ->
309+ if (applicationInitEndMs != null ) {
329310 spanService.recordCompletedSpan(
330- name = " embrace -init" ,
311+ name = " process -init" ,
331312 parent = this ,
332- startTimeMs = sdkInitStartMs ,
333- endTimeMs = sdkInitEndMs ,
313+ startTimeMs = traceStartTimeMs ,
314+ endTimeMs = applicationInitEndMs ,
334315 )
335316 }
317+ }
336318
337- val lastEventBeforeActivityInit = applicationInitEndMs ? : sdkInitEndMs
338- if (lastEventBeforeActivityInit != null && firstActivityInitMs != null ) {
339- spanService.recordCompletedSpan(
340- name = " activity-init-gap" ,
341- parent = this ,
342- startTimeMs = lastEventBeforeActivityInit,
343- endTimeMs = firstActivityInitMs,
344- )
345- }
319+ if (sdkInitStartMs != null && sdkInitEndMs != null ) {
320+ spanService.recordCompletedSpan(
321+ name = " embrace-init" ,
322+ parent = this ,
323+ startTimeMs = sdkInitStartMs,
324+ endTimeMs = sdkInitEndMs,
325+ )
326+ }
346327
347- if (activityInitStartMs != null && activityInitEndMs != null ) {
348- spanService.recordCompletedSpan(
349- name = " activity-create" ,
350- parent = this ,
351- startTimeMs = activityInitStartMs,
352- endTimeMs = activityInitEndMs,
353- )
354- }
355- if (activityInitEndMs != null ) {
356- val uiLoadSpanName = if (endWithFrameDraw) {
357- " first-frame-render"
358- } else {
359- " activity-resume"
360- }
361- spanService.recordCompletedSpan(
362- name = uiLoadSpanName,
363- parent = this ,
364- startTimeMs = activityInitEndMs,
365- endTimeMs = traceEndTimeMs,
366- )
328+ val lastEventBeforeActivityInit = applicationInitEndMs ? : sdkInitEndMs
329+ if (lastEventBeforeActivityInit != null && firstActivityInitMs != null ) {
330+ spanService.recordCompletedSpan(
331+ name = " activity-init-gap" ,
332+ parent = this ,
333+ startTimeMs = lastEventBeforeActivityInit,
334+ endTimeMs = firstActivityInitMs,
335+ )
336+ }
337+
338+ if (activityInitStartMs != null && activityInitEndMs != null ) {
339+ spanService.recordCompletedSpan(
340+ name = " activity-create" ,
341+ parent = this ,
342+ startTimeMs = activityInitStartMs,
343+ endTimeMs = activityInitEndMs,
344+ )
345+ }
346+ if (activityInitEndMs != null ) {
347+ val uiLoadSpanName = if (endWithFrameDraw) {
348+ " first-frame-render"
349+ } else {
350+ " activity-resume"
367351 }
352+ spanService.recordCompletedSpan(
353+ name = uiLoadSpanName,
354+ parent = this ,
355+ startTimeMs = activityInitEndMs,
356+ endTimeMs = traceEndTimeMs,
357+ )
368358 }
369- } else {
370- null
371359 }
372360 }
373361
0 commit comments