Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfeea14a authored by Peter Kalauskas's avatar Peter Kalauskas Committed by Android Build Cherrypicker Worker
Browse files

Ensure coroutine tracing is disabled in edge-cases

Additional tests and checks to ensure coroutine tracing is disabled on
user builds.

Bug: 348488027
Test: Inspect odex of user build
Flag: com.android.systemui.coroutine_tracing
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:da66907d9c67464797395d945e6e1ca9fc6eae4d)
Merged-In: Ia53c704ee642568c999606f818b6f9ecb07152e7
Change-Id: Ia53c704ee642568c999606f818b6f9ecb07152e7
parent 9fe13e49
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.app.tracing.coroutines
import com.android.app.tracing.asyncTraceForTrackBegin
import com.android.app.tracing.asyncTraceForTrackEnd
import com.android.app.tracing.isEnabled
import com.android.systemui.util.Compile
import java.util.concurrent.ThreadLocalRandom
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
@@ -176,10 +177,9 @@ inline fun <T> traceCoroutine(spanName: () -> String, block: () -> T): T {
    // For coroutine tracing to work, trace spans must be added and removed even when
    // tracing is not active (i.e. when TRACE_TAG_APP is disabled). Otherwise, when the
    // coroutine resumes when tracing is active, we won't know its name.
    val traceData = traceThreadLocal.get()
    val traceData = if (Compile.IS_DEBUG) traceThreadLocal.get() else null
    val asyncTracingEnabled = isEnabled()
    val spanString = if (traceData != null || asyncTracingEnabled) spanName() else "<none>"

    traceData?.beginSpan(spanString)

    // Also trace to the "Coroutines" async track. This makes it easy to see the duration of
+8 −2
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ private inline fun debug(message: () -> String) {
 */
fun createCoroutineTracingContext(): CoroutineContext =
    if (Compile.IS_DEBUG && coroutineTracing()) {
        TraceContextElement(TraceData())
        TraceContextElement()
    } else {
        EmptyCoroutineContext
    }
@@ -63,11 +63,13 @@ fun createCoroutineTracingContext(): CoroutineContext =
 *
 * @see traceCoroutine
 */
internal class TraceContextElement(internal val traceData: TraceData? = TraceData()) :
internal class TraceContextElement private constructor(internal val traceData: TraceData?) :
    CopyableThreadContextElement<TraceData?> {

    internal companion object Key : CoroutineContext.Key<TraceContextElement>

    internal constructor() : this(if (Compile.IS_DEBUG) TraceData() else null)

    override val key: CoroutineContext.Key<*>
        get() = Key

@@ -91,6 +93,7 @@ internal class TraceContextElement(internal val traceData: TraceData? = TraceDat
     * `^` is a suspension point)
     */
    override fun updateThreadContext(context: CoroutineContext): TraceData? {
        if (!Compile.IS_DEBUG) return null
        val oldState = traceThreadLocal.get()
        debug { "$this #updateThreadContext oldState=$oldState" }
        if (oldState !== traceData) {
@@ -132,6 +135,7 @@ internal class TraceContextElement(internal val traceData: TraceData? = TraceDat
     * ```
     */
    override fun restoreThreadContext(context: CoroutineContext, oldState: TraceData?) {
        if (!Compile.IS_DEBUG) return
        debug { "$this#restoreThreadContext restoring=$oldState" }
        // We not use the `TraceData` object here because it may have been modified on another
        // thread after the last suspension point. This is why we use a [TraceStateHolder]:
@@ -144,11 +148,13 @@ internal class TraceContextElement(internal val traceData: TraceData? = TraceDat
    }

    override fun copyForChild(): CopyableThreadContextElement<TraceData?> {
        if (!Compile.IS_DEBUG) return TraceContextElement(null)
        debug { "$this #copyForChild" }
        return TraceContextElement(traceData?.clone())
    }

    override fun mergeForChild(overwritingElement: CoroutineContext.Element): CoroutineContext {
        if (!Compile.IS_DEBUG) return EmptyCoroutineContext
        debug { "$this #mergeForChild" }
        // For our use-case, we always give precedence to the parent trace context, and the
        // child context (overwritingElement) is ignored
+8 −2
Original line number Diff line number Diff line
@@ -16,7 +16,13 @@

package com.android.systemui.util

@Suppress("UNUSED_PARAMETER")
object Compile {
    const val IS_DEBUG = true
    private var _isDebug = true

    val IS_DEBUG: Boolean
        get() = _isDebug

    fun setIsDebug(isDebug: Boolean) {
        _isDebug = isDebug
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -16,12 +16,13 @@

package com.android.systemui

object Flags {

    private var isCoroutineTracingFlagEnabledForTests = true

object Flags {
    fun coroutineTracing() = isCoroutineTracingFlagEnabledForTests

    fun disableCoroutineTracing() {
        isCoroutineTracingFlagEnabledForTests = false
    fun setCoroutineTracingEnabled(enabled: Boolean) {
        isCoroutineTracingFlagEnabledForTests = enabled
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -25,9 +25,15 @@ private fun debug(message: String) {
    if (DEBUG) println("Thread #${Thread.currentThread().id}: $message")
}

private var isTracingEnabled = true

internal fun setAndroidSystemTracingEnabled(enabled: Boolean) {
    isTracingEnabled = enabled
}

@PublishedApi
internal actual fun isEnabled(): Boolean {
    return true
    return isTracingEnabled
}

val traceCounters = mutableMapOf<String, Int>()
Loading