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

Commit a171c59c authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Introduce utilities to log listener callbacks

+ traceSection with a lambda param to avoid creating the string when not needed.

Flag: None
Bug: 312894757
Test: perfetto traces
Change-Id: I9961d3dc67d8b556908469c5bd72721666f1a3da
parent d63cb1b2
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.app.tracing

/** Utilities to trace automatically computations happening for each element of a list. */
object ListenersTracing {

    /**
     * Like [forEach], but outputs a trace for each element.
     *
     * The ideal usage of this is to debug what's taking long in a list of Listeners. For example:
     * ```
     * listeners.forEach { it.dispatch(state) }
     * ```
     *
     * often it's tricky to udnerstand which listener is causing delays. This can be used instead to
     * log how much each listener is taking:
     * ```
     * listeners.forEachTraced(TAG) { it.dispatch(state) }
     * ```
     */
    inline fun <T : Any> List<T>.forEachTraced(tag: String = "", f: (T) -> Unit) {
        forEach { traceSection({ "$tag#${it::javaClass.get().name}" }) { f(it) } }
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -51,6 +51,22 @@ inline fun <T> traceSection(tag: String, block: () -> T): T =
        block()
    }

/**
 * Same as [traceSection], but the tag is provided as a lambda to help avoiding creating expensive
 * strings when not needed.
 */
inline fun <T> traceSection(tag: () -> String, block: () -> T): T =
    if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
        Trace.traceBegin(Trace.TRACE_TAG_APP, tag())
        try {
            block()
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_APP)
        }
    } else {
        block()
    }

class TraceUtils {
    companion object {
        const val TAG = "TraceUtils"
@@ -69,6 +85,7 @@ class TraceUtils {
        inline fun namedRunnable(tag: String, crossinline block: () -> Unit): Runnable {
            return object : Runnable, TraceNameSupplier {
                override fun getTraceName(): String = tag

                override fun run() = block()
            }
        }