1 /* 2 * Copyright (C) 2012 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 android.os; 18 19 import android.util.Log; 20 21 /** 22 * Writes trace events to the kernel trace buffer. These trace events can be 23 * collected using the "atrace" program for offline analysis. 24 * 25 * This tracing mechanism is independent of the method tracing mechanism 26 * offered by {@link Debug#startMethodTracing}. In particular, it enables 27 * tracing of events that occur across processes. 28 * 29 * @hide 30 */ 31 public final class Trace { 32 private static final String TAG = "Trace"; 33 34 // These tags must be kept in sync with frameworks/native/include/utils/Trace.h. 35 public static final long TRACE_TAG_NEVER = 0; 36 public static final long TRACE_TAG_ALWAYS = 1L << 0; 37 public static final long TRACE_TAG_GRAPHICS = 1L << 1; 38 public static final long TRACE_TAG_INPUT = 1L << 2; 39 public static final long TRACE_TAG_VIEW = 1L << 3; 40 public static final long TRACE_TAG_WEBVIEW = 1L << 4; 41 public static final long TRACE_TAG_WINDOW_MANAGER = 1L << 5; 42 public static final long TRACE_TAG_ACTIVITY_MANAGER = 1L << 6; 43 public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7; 44 public static final long TRACE_TAG_AUDIO = 1L << 8; 45 public static final long TRACE_TAG_VIDEO = 1L << 9; 46 public static final long TRACE_TAG_CAMERA = 1L << 10; 47 private static final long TRACE_TAG_NOT_READY = 1L << 63; 48 49 public static final int TRACE_FLAGS_START_BIT = 1; 50 public static final String[] TRACE_TAGS = { 51 "Graphics", "Input", "View", "WebView", "Window Manager", 52 "Activity Manager", "Sync Manager", "Audio", "Video", "Camera", 53 }; 54 55 public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags"; 56 57 // Must be volatile to avoid word tearing. 58 private static volatile long sEnabledTags = TRACE_TAG_NOT_READY; 59 nativeGetEnabledTags()60 private static native long nativeGetEnabledTags(); nativeTraceCounter(long tag, String name, int value)61 private static native void nativeTraceCounter(long tag, String name, int value); nativeTraceBegin(long tag, String name)62 private static native void nativeTraceBegin(long tag, String name); nativeTraceEnd(long tag)63 private static native void nativeTraceEnd(long tag); 64 65 static { 66 // We configure two separate change callbacks, one in Trace.cpp and one here. The 67 // native callback reads the tags from the system property, and this callback 68 // reads the value that the native code retrieved. It's essential that the native 69 // callback executes first. 70 // 71 // The system provides ordering through a priority level. Callbacks made through 72 // SystemProperties.addChangeCallback currently have a negative priority, while 73 // our native code is using a priority of zero. SystemProperties.addChangeCallback(new Runnable() { @Override public void run() { cacheEnabledTags(); } })74 SystemProperties.addChangeCallback(new Runnable() { 75 @Override public void run() { 76 cacheEnabledTags(); 77 } 78 }); 79 } 80 Trace()81 private Trace() { 82 } 83 84 /** 85 * Caches a copy of the enabled-tag bits. The "master" copy is held by the native code, 86 * and comes from the PROPERTY_TRACE_TAG_ENABLEFLAGS property. 87 * <p> 88 * If the native code hasn't yet read the property, we will cause it to do one-time 89 * initialization. We don't want to do this during class init, because this class is 90 * preloaded, so all apps would be stuck with whatever the zygote saw. (The zygote 91 * doesn't see the system-property update broadcasts.) 92 * <p> 93 * We want to defer initialization until the first use by an app, post-zygote. 94 * <p> 95 * We're okay if multiple threads call here simultaneously -- the native state is 96 * synchronized, and sEnabledTags is volatile (prevents word tearing). 97 */ cacheEnabledTags()98 private static long cacheEnabledTags() { 99 long tags = nativeGetEnabledTags(); 100 if (tags == TRACE_TAG_NOT_READY) { 101 Log.w(TAG, "Unexpected value from nativeGetEnabledTags: " + tags); 102 // keep going 103 } 104 sEnabledTags = tags; 105 return tags; 106 } 107 108 /** 109 * Returns true if a trace tag is enabled. 110 * 111 * @param traceTag The trace tag to check. 112 * @return True if the trace tag is valid. 113 */ isTagEnabled(long traceTag)114 public static boolean isTagEnabled(long traceTag) { 115 long tags = sEnabledTags; 116 if (tags == TRACE_TAG_NOT_READY) { 117 tags = cacheEnabledTags(); 118 } 119 return (tags & traceTag) != 0; 120 } 121 122 /** 123 * Writes trace message to indicate the value of a given counter. 124 * 125 * @param traceTag The trace tag. 126 * @param counterName The counter name to appear in the trace. 127 * @param counterValue The counter value. 128 */ traceCounter(long traceTag, String counterName, int counterValue)129 public static void traceCounter(long traceTag, String counterName, int counterValue) { 130 if (isTagEnabled(traceTag)) { 131 nativeTraceCounter(traceTag, counterName, counterValue); 132 } 133 } 134 135 /** 136 * Writes a trace message to indicate that a given method has begun. 137 * Must be followed by a call to {@link #traceEnd} using the same tag. 138 * 139 * @param traceTag The trace tag. 140 * @param methodName The method name to appear in the trace. 141 */ traceBegin(long traceTag, String methodName)142 public static void traceBegin(long traceTag, String methodName) { 143 if (isTagEnabled(traceTag)) { 144 nativeTraceBegin(traceTag, methodName); 145 } 146 } 147 148 /** 149 * Writes a trace message to indicate that the current method has ended. 150 * Must be called exactly once for each call to {@link #traceBegin} using the same tag. 151 * 152 * @param traceTag The trace tag. 153 */ traceEnd(long traceTag)154 public static void traceEnd(long traceTag) { 155 if (isTagEnabled(traceTag)) { 156 nativeTraceEnd(traceTag); 157 } 158 } 159 } 160