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

Commit f9c7d6bc authored by Jamie Gennis's avatar Jamie Gennis
Browse files

Add APIs for application-generated systrace events

This change adds new APIs to enable applications to generate custom Systrace
begin/end events.  Application-generated events use the ATRACE_APP_TAG tag,
which is enabled only if either the application has declared itself debuggable
in its manifest or ro.debuggable is set to 1 on the device.

Change-Id: I311d09e2e6ed1a30f5ffa84907f250e11cc0d48d
parent b4c13c4b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4322,6 +4322,10 @@ public final class ActivityThread {
            GLUtils.setTracingLevel(1);
        }

        // Allow application-generated systrace messages if we're debuggable.
        boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        Trace.setAppTracingAllowed(appTracingAllowed);

        /**
         * Initialize the default http proxy in this process for the reasons we set the time zone.
         */
+87 −13
Original line number Diff line number Diff line
@@ -19,41 +19,55 @@ package android.os;
import android.util.Log;

/**
 * Writes trace events to the kernel trace buffer.  These trace events can be
 * collected using the "atrace" program for offline analysis.
 * Writes trace events to the system trace buffer.  These trace events can be
 * collected and visualized using the Systrace tool.
 *
 * This tracing mechanism is independent of the method tracing mechanism
 * offered by {@link Debug#startMethodTracing}.  In particular, it enables
 * tracing of events that occur across processes.
 * tracing of events that occur across multiple processes.
 *
 * @hide
 */
public final class Trace {
    /*
     * Writes trace events to the kernel trace buffer.  These trace events can be
     * collected using the "atrace" program for offline analysis.
     */

    private static final String TAG = "Trace";

    // These tags must be kept in sync with system/core/include/cutils/trace.h.
    /** @hide */
    public static final long TRACE_TAG_NEVER = 0;
    /** @hide */
    public static final long TRACE_TAG_ALWAYS = 1L << 0;
    /** @hide */
    public static final long TRACE_TAG_GRAPHICS = 1L << 1;
    /** @hide */
    public static final long TRACE_TAG_INPUT = 1L << 2;
    /** @hide */
    public static final long TRACE_TAG_VIEW = 1L << 3;
    /** @hide */
    public static final long TRACE_TAG_WEBVIEW = 1L << 4;
    /** @hide */
    public static final long TRACE_TAG_WINDOW_MANAGER = 1L << 5;
    /** @hide */
    public static final long TRACE_TAG_ACTIVITY_MANAGER = 1L << 6;
    /** @hide */
    public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7;
    /** @hide */
    public static final long TRACE_TAG_AUDIO = 1L << 8;
    /** @hide */
    public static final long TRACE_TAG_VIDEO = 1L << 9;
    /** @hide */
    public static final long TRACE_TAG_CAMERA = 1L << 10;
    /** @hide */
    public static final long TRACE_TAG_HAL = 1L << 11;
    private static final long TRACE_TAG_NOT_READY = 1L << 63;

    public static final int TRACE_FLAGS_START_BIT = 1;
    public static final String[] TRACE_TAGS = {
        "Graphics", "Input", "View", "WebView", "Window Manager",
        "Activity Manager", "Sync Manager", "Audio", "Video", "Camera", "HAL",
    };
    /** @hide */
    public static final long TRACE_TAG_APP = 1L << 12;

    public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
    private static final long TRACE_TAG_NOT_READY = 1L << 63;
    private static final int MAX_SECTION_NAME_LEN = 127;

    // Must be volatile to avoid word tearing.
    private static volatile long sEnabledTags = TRACE_TAG_NOT_READY;
@@ -62,6 +76,7 @@ public final class Trace {
    private static native void nativeTraceCounter(long tag, String name, int value);
    private static native void nativeTraceBegin(long tag, String name);
    private static native void nativeTraceEnd(long tag);
    private static native void nativeSetAppTracingAllowed(boolean allowed);

    static {
        // We configure two separate change callbacks, one in Trace.cpp and one here.  The
@@ -111,6 +126,8 @@ public final class Trace {
     *
     * @param traceTag The trace tag to check.
     * @return True if the trace tag is valid.
     *
     * @hide
     */
    public static boolean isTagEnabled(long traceTag) {
        long tags = sEnabledTags;
@@ -126,6 +143,8 @@ public final class Trace {
     * @param traceTag The trace tag.
     * @param counterName The counter name to appear in the trace.
     * @param counterValue The counter value.
     *
     * @hide
     */
    public static void traceCounter(long traceTag, String counterName, int counterValue) {
        if (isTagEnabled(traceTag)) {
@@ -134,11 +153,28 @@ public final class Trace {
    }

    /**
     * Writes a trace message to indicate that a given method has begun.
     * Must be followed by a call to {@link #traceEnd} using the same tag.
     * Set whether application tracing is allowed for this process.  This is intended to be set
     * once at application start-up time based on whether the application is debuggable.
     *
     * @hide
     */
    public static void setAppTracingAllowed(boolean allowed) {
        nativeSetAppTracingAllowed(allowed);

        // Setting whether app tracing is allowed may change the tags, so we update the cached
        // tags here.
        cacheEnabledTags();
    }

    /**
     * Writes a trace message to indicate that a given section of code has
     * begun. Must be followed by a call to {@link #traceEnd} using the same
     * tag.
     *
     * @param traceTag The trace tag.
     * @param methodName The method name to appear in the trace.
     *
     * @hide
     */
    public static void traceBegin(long traceTag, String methodName) {
        if (isTagEnabled(traceTag)) {
@@ -151,10 +187,48 @@ public final class Trace {
     * Must be called exactly once for each call to {@link #traceBegin} using the same tag.
     *
     * @param traceTag The trace tag.
     *
     * @hide
     */
    public static void traceEnd(long traceTag) {
        if (isTagEnabled(traceTag)) {
            nativeTraceEnd(traceTag);
        }
    }

    /**
     * Writes a trace message to indicate that a given section of code has begun. This call must
     * be followed by a corresponding call to {@link #traceEnd()} on the same thread.
     *
     * <p class="note"> At this time the vertical bar character '|', newline character '\n', and
     * null character '\0' are used internally by the tracing mechanism.  If sectionName contains
     * these characters they will be replaced with a space character in the trace.
     *
     * @param sectionName The name of the code section to appear in the trace.  This may be at
     * most 127 Unicode code units long.
     *
     * @hide
     */
    public static void traceBegin(String sectionName) {
        if (isTagEnabled(TRACE_TAG_APP)) {
            if (sectionName.length() > MAX_SECTION_NAME_LEN) {
                throw new IllegalArgumentException("sectionName is too long");
            }
            nativeTraceBegin(TRACE_TAG_APP, sectionName);
        }
    }

    /**
     * Writes a trace message to indicate that a given section of code has ended. This call must
     * be preceeded by a corresponding call to {@link #traceBegin(String)}. Calling this method
     * will mark the end of the most recently begun section of code, so care must be taken to
     * ensure that traceBegin / traceEnd pairs are properly nested and called from the same thread.
     *
     * @hide
     */
    public static void traceEnd() {
        if (isTagEnabled(TRACE_TAG_APP)) {
            nativeTraceEnd(TRACE_TAG_APP);
        }
    }
}
+25 −2
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@

#include <JNIHelp.h>
#include <ScopedUtfChars.h>
#include <ScopedStringChars.h>

#include <utils/String8.h>

#include <cutils/trace.h>
#include <cutils/log.h>
@@ -36,8 +39,20 @@ static void android_os_Trace_nativeTraceCounter(JNIEnv* env, jclass clazz,

static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass clazz,
        jlong tag, jstring nameStr) {
    ScopedUtfChars name(env, nameStr);
    atrace_begin(tag, name.c_str());
    const size_t MAX_SECTION_NAME_LEN = 127;
    ScopedStringChars jchars(env, nameStr);
    String8 utf8Chars(reinterpret_cast<const char16_t*>(jchars.get()),
            jchars.size());
    size_t size = utf8Chars.size();
    char* str = utf8Chars.lockBuffer(size);
    for (size_t i = 0; i < size; i++) {
        char c = str[i];
        if (c == '\0' || c == '\n' || c == '|') {
            str[i] = ' ';
        }
    }
    utf8Chars.unlockBuffer();
    atrace_begin(tag, utf8Chars.string());
}

static void android_os_Trace_nativeTraceEnd(JNIEnv* env, jclass clazz,
@@ -45,6 +60,11 @@ static void android_os_Trace_nativeTraceEnd(JNIEnv* env, jclass clazz,
    atrace_end(tag);
}

static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv* env,
        jclass clazz, jboolean allowed) {
    atrace_set_debuggable(allowed);
}

static JNINativeMethod gTraceMethods[] = {
    /* name, signature, funcPtr */
    { "nativeGetEnabledTags",
@@ -59,6 +79,9 @@ static JNINativeMethod gTraceMethods[] = {
    { "nativeTraceEnd",
            "(J)V",
            (void*)android_os_Trace_nativeTraceEnd },
    { "nativeSetAppTracingAllowed",
            "(Z)V",
            (void*)android_os_Trace_nativeSetAppTracingAllowed },
};

int register_android_os_Trace(JNIEnv* env) {