1 /* 2 * Copyright 2025 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.tracing.driver 18 19 internal const val TRACE_EVENT_TYPE_UNDEFINED: Int = 0 20 internal const val TRACE_EVENT_TYPE_BEGIN: Int = 1 21 internal const val TRACE_EVENT_TYPE_END: Int = 2 22 internal const val TRACE_EVENT_TYPE_INSTANT: Int = 3 23 internal const val TRACE_EVENT_TYPE_COUNTER: Int = 4 24 25 /** 26 * Mutable in-memory only representation a trace event, such as a slice start, slice end, or counter 27 * update. 28 * 29 * This structure is optimized for performance, with the expectation that these are created by a 30 * trace event, and passed to a background thread to be serialized. Mutability (and thus reuse) is 31 * an important component of this. 32 * 33 * Code outside of tracing-driver implementation should only ever consume these objects, not produce 34 * them. 35 */ 36 @Suppress("NOTHING_TO_INLINE") 37 public class TraceEvent 38 internal constructor( 39 /** 40 * Must be one of [TRACE_EVENT_TYPE_UNDEFINED], [TRACE_EVENT_TYPE_INSTANT], 41 * [TRACE_EVENT_TYPE_BEGIN], [TRACE_EVENT_TYPE_END], [TRACE_EVENT_TYPE_COUNTER] 42 */ 43 @field:Suppress("MutableBareField") // public / mutable to minimize overhead 44 @JvmField 45 public var type: Int, 46 /** Set to the value of the containing [Track]'s [Track.uuid]. */ 47 @field:Suppress("MutableBareField") // public / mutable to minimize overhead 48 @JvmField 49 public var trackUuid: Long, 50 51 /** Timestamp in nanoseconds of the trace event. */ 52 @field:Suppress("MutableBareField") // public / mutable to minimize overhead 53 @JvmField 54 public var timestamp: Long, 55 56 /** Name of the trace event - null if the event [type] is [TRACE_EVENT_TYPE_COUNTER]. */ 57 @field:Suppress("MutableBareField") // public / mutable to minimize overhead 58 @JvmField 59 public var name: String?, 60 @field:Suppress( 61 "MutableBareField", // public / mutable to minimize overhead 62 "AutoBoxing", // temporary 63 ) 64 65 /** 66 * Value of the trace event if the event [type] is [TRACE_EVENT_TYPE_COUNTER]. 67 * 68 * Note that only one of [counterDoubleValue] and [counterLongValue] may be set. 69 */ 70 @JvmField 71 public var counterDoubleValue: Double?, 72 73 /** 74 * Value of the trace event if the event [type] is [TRACE_EVENT_TYPE_COUNTER]. 75 * 76 * Note that only one of [counterDoubleValue] and [counterLongValue] may be set. 77 */ 78 @field:Suppress( 79 "MutableBareField", // public / mutable to minimize overhead 80 "AutoBoxing", // temporary 81 ) 82 @JvmField 83 public var counterLongValue: Long?, 84 85 /** List of trace flows associated with this event. */ 86 // ideally this would be a array to avoid boxing, but proto libs consume longs anyway :| 87 @field:Suppress("MutableBareField") // public / mutable to minimize overhead 88 @JvmField 89 public var flowIds: List<Long>, 90 91 /** 92 * If not null, this TraceEvent initializes a track, and the [TrackDescriptor] defines its 93 * properties. 94 */ 95 @field:Suppress("MutableBareField") // public / mutable to minimize overhead 96 @JvmField 97 public var trackDescriptor: TrackDescriptor?, 98 ) { 99 public constructor() : 100 this( 101 type = INVALID_INT, 102 trackUuid = INVALID_LONG, 103 timestamp = INVALID_LONG, 104 name = null, 105 counterDoubleValue = null, 106 counterLongValue = null, 107 flowIds = emptyList(), 108 trackDescriptor = null 109 ) 110 setPreamblenull111 internal inline fun setPreamble(trackDescriptor: TrackDescriptor) { 112 this.trackDescriptor = trackDescriptor 113 this.timestamp = nanoTime() 114 } 115 setBeginSectionnull116 internal inline fun setBeginSection(trackUuid: Long, name: String) { 117 type = TRACE_EVENT_TYPE_BEGIN 118 this.trackUuid = trackUuid 119 timestamp = nanoTime() 120 this.name = name 121 } 122 setBeginSectionWithFlowsnull123 internal inline fun setBeginSectionWithFlows( 124 trackUuid: Long, 125 name: String, 126 flowIds: List<Long> 127 ) { 128 type = TRACE_EVENT_TYPE_BEGIN 129 this.trackUuid = trackUuid 130 timestamp = nanoTime() 131 this.flowIds = flowIds 132 this.name = name 133 } 134 setEndSectionnull135 internal inline fun setEndSection(trackUuid: Long) { 136 type = TRACE_EVENT_TYPE_END 137 this.trackUuid = trackUuid 138 timestamp = nanoTime() 139 } 140 setInstantnull141 internal inline fun setInstant( 142 trackUuid: Long, 143 name: String, 144 ) { 145 type = TRACE_EVENT_TYPE_END 146 this.trackUuid = trackUuid 147 timestamp = nanoTime() 148 this.name = name 149 } 150 setCounterLongnull151 internal inline fun setCounterLong(trackUuid: Long, value: Long) { 152 type = TRACE_EVENT_TYPE_COUNTER 153 this.trackUuid = trackUuid 154 timestamp = nanoTime() 155 counterLongValue = value 156 } 157 setCounterDoublenull158 internal inline fun setCounterDouble(trackUuid: Long, value: Double) { 159 type = TRACE_EVENT_TYPE_COUNTER 160 this.trackUuid = trackUuid 161 timestamp = nanoTime() 162 counterDoubleValue = value 163 } 164 resetnull165 public fun reset() { 166 type = INVALID_INT 167 trackUuid = INVALID_LONG 168 timestamp = INVALID_LONG 169 name = null 170 counterDoubleValue = null 171 counterLongValue = null 172 flowIds = emptyList() 173 trackDescriptor = null 174 } 175 } 176