blob: 25584f15608444eaf147b22c9613d524c15f4a14 [file] [log] [blame]
Jeff Brown481c1572012-03-09 14:41:15 -08001/*
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
17package android.os;
18
John Reck13f08e62019-01-09 11:16:28 -080019import android.annotation.NonNull;
Artur Satayevafdb23a2019-12-10 17:47:53 +000020import android.compat.annotation.UnsupportedAppUsage;
John Reck62cc1192017-05-12 15:39:51 -070021
Florian Mayer9fd21022019-12-09 17:16:01 +000022import dalvik.annotation.optimization.CriticalNative;
John Reck6be2cab2016-10-03 14:38:06 -070023import dalvik.annotation.optimization.FastNative;
24
Jeff Brown481c1572012-03-09 14:41:15 -080025/**
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070026 * Writes trace events to the system trace buffer. These trace events can be
27 * collected and visualized using the Systrace tool.
Jeff Brown481c1572012-03-09 14:41:15 -080028 *
Scott Mainc4682402013-06-13 12:38:55 -070029 * <p>This tracing mechanism is independent of the method tracing mechanism
Jeff Brown481c1572012-03-09 14:41:15 -080030 * offered by {@link Debug#startMethodTracing}. In particular, it enables
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070031 * tracing of events that occur across multiple processes.
Scott Mainc4682402013-06-13 12:38:55 -070032 * <p>For information about using the Systrace tool, read <a
33 * href="{@docRoot}tools/debugging/systrace.html">Analyzing Display and Performance
34 * with Systrace</a>.
Jeff Brown481c1572012-03-09 14:41:15 -080035 */
36public final class Trace {
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070037 /*
38 * Writes trace events to the kernel trace buffer. These trace events can be
39 * collected using the "atrace" program for offline analysis.
40 */
41
Andy McFaddend11ca4d2012-10-22 16:16:06 -070042 private static final String TAG = "Trace";
43
Alex Ray8a6787b2012-11-14 18:08:49 -080044 // These tags must be kept in sync with system/core/include/cutils/trace.h.
Jeff Brown3edf5272014-08-14 19:25:14 -070045 // They should also be added to frameworks/native/cmds/atrace/atrace.cpp.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070046 /** @hide */
Jeff Brown481c1572012-03-09 14:41:15 -080047 public static final long TRACE_TAG_NEVER = 0;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070048 /** @hide */
Jeff Brown481c1572012-03-09 14:41:15 -080049 public static final long TRACE_TAG_ALWAYS = 1L << 0;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070050 /** @hide */
Jeff Brown481c1572012-03-09 14:41:15 -080051 public static final long TRACE_TAG_GRAPHICS = 1L << 1;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070052 /** @hide */
Jeff Brown481c1572012-03-09 14:41:15 -080053 public static final long TRACE_TAG_INPUT = 1L << 2;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070054 /** @hide */
Andrei Onea24ec3212019-03-15 17:35:05 +000055 @UnsupportedAppUsage
Jeff Brown481c1572012-03-09 14:41:15 -080056 public static final long TRACE_TAG_VIEW = 1L << 3;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070057 /** @hide */
Chris Craik192a65e2012-04-16 16:08:40 -070058 public static final long TRACE_TAG_WEBVIEW = 1L << 4;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070059 /** @hide */
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070060 public static final long TRACE_TAG_WINDOW_MANAGER = 1L << 5;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070061 /** @hide */
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070062 public static final long TRACE_TAG_ACTIVITY_MANAGER = 1L << 6;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070063 /** @hide */
Andy Stadler09b45a32012-05-03 15:00:49 -070064 public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070065 /** @hide */
Glenn Kastened853fc2012-05-07 11:05:55 -070066 public static final long TRACE_TAG_AUDIO = 1L << 8;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070067 /** @hide */
Jamie Gennis24dae6c2012-05-11 04:43:35 -070068 public static final long TRACE_TAG_VIDEO = 1L << 9;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070069 /** @hide */
Eino-Ville Talvala9c0d9cf2012-05-31 15:49:31 -070070 public static final long TRACE_TAG_CAMERA = 1L << 10;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070071 /** @hide */
Alex Ray8a6787b2012-11-14 18:08:49 -080072 public static final long TRACE_TAG_HAL = 1L << 11;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070073 /** @hide */
Andrei Onea24ec3212019-03-15 17:35:05 +000074 @UnsupportedAppUsage
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -070075 public static final long TRACE_TAG_APP = 1L << 12;
Dianne Hackbornf7be4802013-04-12 14:52:58 -070076 /** @hide */
77 public static final long TRACE_TAG_RESOURCES = 1L << 13;
Jamie Gennis0cc84ce2013-05-07 15:22:31 -070078 /** @hide */
79 public static final long TRACE_TAG_DALVIK = 1L << 14;
Tim Murray6d7a53c2013-05-23 16:59:23 -070080 /** @hide */
81 public static final long TRACE_TAG_RS = 1L << 15;
Brigid Smith461ac242014-05-28 14:13:41 -070082 /** @hide */
83 public static final long TRACE_TAG_BIONIC = 1L << 16;
Jeff Brown3edf5272014-08-14 19:25:14 -070084 /** @hide */
85 public static final long TRACE_TAG_POWER = 1L << 17;
Todd Kennedy114beb22015-08-03 09:56:07 -070086 /** @hide */
87 public static final long TRACE_TAG_PACKAGE_MANAGER = 1L << 18;
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +090088 /** @hide */
89 public static final long TRACE_TAG_SYSTEM_SERVER = 1L << 19;
Greg Hackmanne12350f2014-12-01 14:31:21 -080090 /** @hide */
91 public static final long TRACE_TAG_DATABASE = 1L << 20;
Felipe Leme873a83a2016-09-07 11:34:10 -070092 /** @hide */
93 public static final long TRACE_TAG_NETWORK = 1L << 21;
Josh Gao552d86b52016-11-29 10:57:01 -080094 /** @hide */
95 public static final long TRACE_TAG_ADB = 1L << 22;
Alexey Kuzmine59145a2018-02-10 15:19:03 +000096 /** @hide */
97 public static final long TRACE_TAG_VIBRATOR = 1L << 23;
Martijn Coenenafbfb172018-03-09 09:26:54 +010098 /** @hide */
99 public static final long TRACE_TAG_AIDL = 1L << 24;
Mika Raento6a30ff82018-04-23 22:08:57 +0100100 /** @hide */
101 public static final long TRACE_TAG_NNAPI = 1L << 25;
MÃ¥rten Kongstad56685892018-12-03 12:59:19 +0100102 /** @hide */
103 public static final long TRACE_TAG_RRO = 1L << 26;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700104
Andy McFadden325be8a2012-10-29 16:42:41 -0700105 private static final long TRACE_TAG_NOT_READY = 1L << 63;
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700106 private static final int MAX_SECTION_NAME_LEN = 127;
Dianne Hackborn83e6eb12012-05-08 14:53:24 -0700107
Andy McFaddend11ca4d2012-10-22 16:16:06 -0700108 // Must be volatile to avoid word tearing.
Florian Mayer9fd21022019-12-09 17:16:01 +0000109 // This is only kept in case any apps get this by reflection but do not
110 // check the return value for null.
Andrei Onea24ec3212019-03-15 17:35:05 +0000111 @UnsupportedAppUsage
Andy McFadden325be8a2012-10-29 16:42:41 -0700112 private static volatile long sEnabledTags = TRACE_TAG_NOT_READY;
Jeff Brown481c1572012-03-09 14:41:15 -0800113
John Reck62cc1192017-05-12 15:39:51 -0700114 private static int sZygoteDebugFlags = 0;
115
Andrei Onea24ec3212019-03-15 17:35:05 +0000116 @UnsupportedAppUsage
Florian Mayer9fd21022019-12-09 17:16:01 +0000117 @CriticalNative
Jeff Brown481c1572012-03-09 14:41:15 -0800118 private static native long nativeGetEnabledTags();
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700119 private static native void nativeSetAppTracingAllowed(boolean allowed);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700120 private static native void nativeSetTracingEnabled(boolean allowed);
Jeff Brown481c1572012-03-09 14:41:15 -0800121
John Reck6be2cab2016-10-03 14:38:06 -0700122 @FastNative
John Reck77b31a52018-12-05 18:16:39 -0800123 private static native void nativeTraceCounter(long tag, String name, long value);
John Reck6be2cab2016-10-03 14:38:06 -0700124 @FastNative
125 private static native void nativeTraceBegin(long tag, String name);
126 @FastNative
127 private static native void nativeTraceEnd(long tag);
128 @FastNative
129 private static native void nativeAsyncTraceBegin(long tag, String name, int cookie);
130 @FastNative
131 private static native void nativeAsyncTraceEnd(long tag, String name, int cookie);
132
Jeff Brown481c1572012-03-09 14:41:15 -0800133 private Trace() {
134 }
135
136 /**
137 * Returns true if a trace tag is enabled.
138 *
139 * @param traceTag The trace tag to check.
140 * @return True if the trace tag is valid.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700141 *
142 * @hide
Jeff Brown481c1572012-03-09 14:41:15 -0800143 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000144 @UnsupportedAppUsage
Jeff Brown481c1572012-03-09 14:41:15 -0800145 public static boolean isTagEnabled(long traceTag) {
Florian Mayer9fd21022019-12-09 17:16:01 +0000146 long tags = nativeGetEnabledTags();
Andy McFaddend11ca4d2012-10-22 16:16:06 -0700147 return (tags & traceTag) != 0;
Jeff Brown481c1572012-03-09 14:41:15 -0800148 }
149
150 /**
151 * Writes trace message to indicate the value of a given counter.
152 *
153 * @param traceTag The trace tag.
154 * @param counterName The counter name to appear in the trace.
155 * @param counterValue The counter value.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700156 *
157 * @hide
Jeff Brown481c1572012-03-09 14:41:15 -0800158 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000159 @UnsupportedAppUsage
Jeff Brown481c1572012-03-09 14:41:15 -0800160 public static void traceCounter(long traceTag, String counterName, int counterValue) {
Andy McFaddend11ca4d2012-10-22 16:16:06 -0700161 if (isTagEnabled(traceTag)) {
Jeff Brown481c1572012-03-09 14:41:15 -0800162 nativeTraceCounter(traceTag, counterName, counterValue);
163 }
164 }
165
166 /**
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700167 * Set whether application tracing is allowed for this process. This is intended to be set
168 * once at application start-up time based on whether the application is debuggable.
169 *
170 * @hide
171 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000172 @UnsupportedAppUsage
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700173 public static void setAppTracingAllowed(boolean allowed) {
174 nativeSetAppTracingAllowed(allowed);
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700175 }
176
177 /**
Jamie Gennis6ad04522013-04-15 18:53:24 -0700178 * Set whether tracing is enabled in this process. Tracing is disabled shortly after Zygote
179 * initializes and re-enabled after processes fork from Zygote. This is done because Zygote
180 * has no way to be notified about changes to the tracing tags, and if Zygote ever reads and
181 * caches the tracing tags, forked processes will inherit those stale tags.
182 *
183 * @hide
184 */
John Reck62cc1192017-05-12 15:39:51 -0700185 public static void setTracingEnabled(boolean enabled, int debugFlags) {
Jamie Gennis6ad04522013-04-15 18:53:24 -0700186 nativeSetTracingEnabled(enabled);
John Reck62cc1192017-05-12 15:39:51 -0700187 sZygoteDebugFlags = debugFlags;
Jamie Gennis6ad04522013-04-15 18:53:24 -0700188 }
189
190 /**
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700191 * Writes a trace message to indicate that a given section of code has
192 * begun. Must be followed by a call to {@link #traceEnd} using the same
193 * tag.
Jeff Brown481c1572012-03-09 14:41:15 -0800194 *
195 * @param traceTag The trace tag.
196 * @param methodName The method name to appear in the trace.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700197 *
198 * @hide
Jeff Brown481c1572012-03-09 14:41:15 -0800199 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000200 @UnsupportedAppUsage
Jeff Brown481c1572012-03-09 14:41:15 -0800201 public static void traceBegin(long traceTag, String methodName) {
Andy McFaddend11ca4d2012-10-22 16:16:06 -0700202 if (isTagEnabled(traceTag)) {
Jeff Brown481c1572012-03-09 14:41:15 -0800203 nativeTraceBegin(traceTag, methodName);
204 }
205 }
206
207 /**
208 * Writes a trace message to indicate that the current method has ended.
209 * Must be called exactly once for each call to {@link #traceBegin} using the same tag.
210 *
211 * @param traceTag The trace tag.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700212 *
213 * @hide
Jeff Brown481c1572012-03-09 14:41:15 -0800214 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000215 @UnsupportedAppUsage
Jeff Brown481c1572012-03-09 14:41:15 -0800216 public static void traceEnd(long traceTag) {
Andy McFaddend11ca4d2012-10-22 16:16:06 -0700217 if (isTagEnabled(traceTag)) {
Jeff Brown481c1572012-03-09 14:41:15 -0800218 nativeTraceEnd(traceTag);
219 }
220 }
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700221
222 /**
Romain Guy9425f922013-04-10 16:35:48 -0700223 * Writes a trace message to indicate that a given section of code has
224 * begun. Must be followed by a call to {@link #asyncTraceEnd} using the same
225 * tag. Unlike {@link #traceBegin(long, String)} and {@link #traceEnd(long)},
226 * asynchronous events do not need to be nested. The name and cookie used to
227 * begin an event must be used to end it.
228 *
229 * @param traceTag The trace tag.
230 * @param methodName The method name to appear in the trace.
231 * @param cookie Unique identifier for distinguishing simultaneous events
232 *
233 * @hide
234 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000235 @UnsupportedAppUsage
Romain Guy9425f922013-04-10 16:35:48 -0700236 public static void asyncTraceBegin(long traceTag, String methodName, int cookie) {
237 if (isTagEnabled(traceTag)) {
238 nativeAsyncTraceBegin(traceTag, methodName, cookie);
239 }
240 }
241
242 /**
243 * Writes a trace message to indicate that the current method has ended.
244 * Must be called exactly once for each call to {@link #asyncTraceBegin(long, String, int)}
245 * using the same tag, name and cookie.
246 *
247 * @param traceTag The trace tag.
248 * @param methodName The method name to appear in the trace.
249 * @param cookie Unique identifier for distinguishing simultaneous events
250 *
251 * @hide
252 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000253 @UnsupportedAppUsage
Romain Guy9425f922013-04-10 16:35:48 -0700254 public static void asyncTraceEnd(long traceTag, String methodName, int cookie) {
255 if (isTagEnabled(traceTag)) {
256 nativeAsyncTraceEnd(traceTag, methodName, cookie);
257 }
258 }
259
260 /**
John Reckd5a9dc02018-07-16 10:42:35 -0700261 * Checks whether or not tracing is currently enabled. This is useful to avoid intermediate
262 * string creation for trace sections that require formatting. It is not necessary
263 * to guard all Trace method calls as they internally already check this. However it is
264 * recommended to use this to prevent creating any temporary objects that would then be
265 * passed to those methods to reduce runtime cost when tracing isn't enabled.
266 *
267 * @return true if tracing is currently enabled, false otherwise
268 */
269 public static boolean isEnabled() {
270 return isTagEnabled(TRACE_TAG_APP);
271 }
272
273 /**
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700274 * Writes a trace message to indicate that a given section of code has begun. This call must
Jamie Gennis5800fc82013-04-09 18:37:22 -0700275 * be followed by a corresponding call to {@link #endSection()} on the same thread.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700276 *
277 * <p class="note"> At this time the vertical bar character '|', newline character '\n', and
278 * null character '\0' are used internally by the tracing mechanism. If sectionName contains
279 * these characters they will be replaced with a space character in the trace.
280 *
281 * @param sectionName The name of the code section to appear in the trace. This may be at
282 * most 127 Unicode code units long.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700283 */
John Reck13f08e62019-01-09 11:16:28 -0800284 public static void beginSection(@NonNull String sectionName) {
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700285 if (isTagEnabled(TRACE_TAG_APP)) {
286 if (sectionName.length() > MAX_SECTION_NAME_LEN) {
287 throw new IllegalArgumentException("sectionName is too long");
288 }
289 nativeTraceBegin(TRACE_TAG_APP, sectionName);
290 }
291 }
292
293 /**
294 * Writes a trace message to indicate that a given section of code has ended. This call must
Jamie Gennis5800fc82013-04-09 18:37:22 -0700295 * be preceeded by a corresponding call to {@link #beginSection(String)}. Calling this method
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700296 * will mark the end of the most recently begun section of code, so care must be taken to
Jamie Gennis5800fc82013-04-09 18:37:22 -0700297 * ensure that beginSection / endSection pairs are properly nested and called from the same
298 * thread.
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700299 */
Jamie Gennis5800fc82013-04-09 18:37:22 -0700300 public static void endSection() {
Jamie Gennisf9c7d6b2013-03-25 14:18:25 -0700301 if (isTagEnabled(TRACE_TAG_APP)) {
302 nativeTraceEnd(TRACE_TAG_APP);
303 }
304 }
John Reckd5a9dc02018-07-16 10:42:35 -0700305
306 /**
307 * Writes a trace message to indicate that a given section of code has
308 * begun. Must be followed by a call to {@link #endAsyncSection(String, int)} with the same
309 * methodName and cookie. Unlike {@link #beginSection(String)} and {@link #endSection()},
310 * asynchronous events do not need to be nested. The name and cookie used to
311 * begin an event must be used to end it.
312 *
313 * @param methodName The method name to appear in the trace.
314 * @param cookie Unique identifier for distinguishing simultaneous events
315 */
John Reck13f08e62019-01-09 11:16:28 -0800316 public static void beginAsyncSection(@NonNull String methodName, int cookie) {
John Reckd5a9dc02018-07-16 10:42:35 -0700317 asyncTraceBegin(TRACE_TAG_APP, methodName, cookie);
318 }
319
320 /**
321 * Writes a trace message to indicate that the current method has ended.
322 * Must be called exactly once for each call to {@link #beginAsyncSection(String, int)}
323 * using the same name and cookie.
324 *
325 * @param methodName The method name to appear in the trace.
326 * @param cookie Unique identifier for distinguishing simultaneous events
327 */
John Reck13f08e62019-01-09 11:16:28 -0800328 public static void endAsyncSection(@NonNull String methodName, int cookie) {
John Reckd5a9dc02018-07-16 10:42:35 -0700329 asyncTraceEnd(TRACE_TAG_APP, methodName, cookie);
330 }
331
332 /**
333 * Writes trace message to indicate the value of a given counter.
334 *
335 * @param counterName The counter name to appear in the trace.
336 * @param counterValue The counter value.
337 */
John Reck13f08e62019-01-09 11:16:28 -0800338 public static void setCounter(@NonNull String counterName, long counterValue) {
John Reckd5a9dc02018-07-16 10:42:35 -0700339 if (isTagEnabled(TRACE_TAG_APP)) {
340 nativeTraceCounter(TRACE_TAG_APP, counterName, counterValue);
341 }
342 }
Jeff Brown481c1572012-03-09 14:41:15 -0800343}