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

Commit 0a72a6db authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Add traceAsync to TraceUtils

This utility is useful to trace coroutine code, as the beginning and the
end of the event might end up in different threads.

Note that stacks are maintained as long as the same trackName is used.

When no stackName is used, "AsyncTraces" default is used.

Test: New track appearing in a perfetto trace
Bug: 289353932
Change-Id: I0fbf745d058e6a329d6b2229178a52af21e84033
parent 1748418e
Loading
Loading
Loading
Loading
+44 −10
Original line number Diff line number Diff line
@@ -18,10 +18,11 @@ package com.android.systemui.util

import android.os.Trace
import android.os.TraceNameSupplier
import java.util.concurrent.atomic.AtomicInteger

/**
 * Run a block within a [Trace] section.
 * Calls [Trace.beginSection] before and [Trace.endSection] after the passed block.
 * Run a block within a [Trace] section. Calls [Trace.beginSection] before and [Trace.endSection]
 * after the passed block.
 */
inline fun <T> traceSection(tag: String, block: () -> T): T =
    if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
@@ -43,6 +44,7 @@ class TraceUtils {

        /**
         * Helper function for creating a Runnable object that implements TraceNameSupplier.
         *
         * This is useful for posting Runnables to Handlers with meaningful names.
         */
        inline fun namedRunnable(tag: String, crossinline block: () -> Unit): Runnable {
@@ -51,5 +53,37 @@ class TraceUtils {
                override fun run() = block()
            }
        }

        /**
         * Cookie used for async traces. Shouldn't be public, but to use it inside inline methods
         * there is no other way around.
         */
        val lastCookie = AtomicInteger(0)

        /**
         * Creates an async slice in a track called "AsyncTraces".
         *
         * This can be used to trace coroutine code. Note that all usages of this method will appear
         * under a single track.
         */
        inline fun <T> traceAsync(method: String, block: () -> T): T =
            traceAsync(method, "AsyncTraces", block)

        /**
         * Creates an async slice in a track with [trackName] while [block] runs.
         *
         * This can be used to trace coroutine code. [method] will be the name of the slice,
         * [trackName] of the track. The track is one of the rows visible in a perfetto trace inside
         * SystemUI process.
         */
        inline fun <T> traceAsync(method: String, trackName: String, block: () -> T): T {
            val cookie = lastCookie.incrementAndGet()
            Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, trackName, method, cookie)
            try {
                return block()
            } finally {
                Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, trackName, cookie)
            }
        }
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.TraceUtils.Companion.traceAsync
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -442,9 +443,11 @@ constructor(
    }

    private suspend fun isFeatureDisabledByDevicePolicy(): Boolean =
        traceAsync("isFeatureDisabledByDevicePolicy", TAG) {
            withContext(backgroundDispatcher) {
                devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
            }
        }

    companion object {
        private const val TAG = "KeyguardQuickAffordanceInteractor"