Debug.java revision e17b445b6c813f6f9bc93a5e3811128a197ef50b
1/*
2 * Copyright (C) 2007 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
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.app.AppGlobals;
22import android.content.Context;
23import android.util.Log;
24
25import com.android.internal.util.FastPrintWriter;
26import com.android.internal.util.Preconditions;
27import com.android.internal.util.TypedProperties;
28
29import dalvik.system.VMDebug;
30
31import org.apache.harmony.dalvik.ddmc.Chunk;
32import org.apache.harmony.dalvik.ddmc.ChunkHandler;
33import org.apache.harmony.dalvik.ddmc.DdmServer;
34
35import java.io.File;
36import java.io.FileDescriptor;
37import java.io.FileNotFoundException;
38import java.io.FileOutputStream;
39import java.io.FileReader;
40import java.io.IOException;
41import java.io.PrintWriter;
42import java.io.Reader;
43import java.lang.annotation.ElementType;
44import java.lang.annotation.Retention;
45import java.lang.annotation.RetentionPolicy;
46import java.lang.annotation.Target;
47import java.lang.reflect.Field;
48import java.lang.reflect.Modifier;
49import java.util.HashMap;
50import java.util.Map;
51
52
53/**
54 * Provides various debugging methods for Android applications, including
55 * tracing and allocation counts.
56 * <p><strong>Logging Trace Files</strong></p>
57 * <p>Debug can create log files that give details about an application, such as
58 * a call stack and start/stop times for any running methods. See <a
59href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
60 * information about reading trace files. To start logging trace files, call one
61 * of the startMethodTracing() methods. To stop tracing, call
62 * {@link #stopMethodTracing()}.
63 */
64public final class Debug
65{
66    private static final String TAG = "Debug";
67
68    /**
69     * Flags for startMethodTracing().  These can be ORed together.
70     *
71     * TRACE_COUNT_ALLOCS adds the results from startAllocCounting to the
72     * trace key file.
73     *
74     * @deprecated Accurate counting is a burden on the runtime and may be removed.
75     */
76    @Deprecated
77    public static final int TRACE_COUNT_ALLOCS  = VMDebug.TRACE_COUNT_ALLOCS;
78
79    /**
80     * Flags for printLoadedClasses().  Default behavior is to only show
81     * the class name.
82     */
83    public static final int SHOW_FULL_DETAIL    = 1;
84    public static final int SHOW_CLASSLOADER    = (1 << 1);
85    public static final int SHOW_INITIALIZED    = (1 << 2);
86
87    // set/cleared by waitForDebugger()
88    private static volatile boolean mWaiting = false;
89
90    private Debug() {}
91
92    /*
93     * How long to wait for the debugger to finish sending requests.  I've
94     * seen this hit 800msec on the device while waiting for a response
95     * to travel over USB and get processed, so we take that and add
96     * half a second.
97     */
98    private static final int MIN_DEBUGGER_IDLE = 1300;      // msec
99
100    /* how long to sleep when polling for activity */
101    private static final int SPIN_DELAY = 200;              // msec
102
103    /**
104     * Default trace file path and file
105     */
106    private static final String DEFAULT_TRACE_BODY = "dmtrace";
107    private static final String DEFAULT_TRACE_EXTENSION = ".trace";
108
109    /**
110     * This class is used to retrieved various statistics about the memory mappings for this
111     * process. The returned info is broken down by dalvik, native, and other. All results are in kB.
112     */
113    public static class MemoryInfo implements Parcelable {
114        /** The proportional set size for dalvik heap.  (Doesn't include other Dalvik overhead.) */
115        public int dalvikPss;
116        /** The proportional set size that is swappable for dalvik heap. */
117        /** @hide We may want to expose this, eventually. */
118        public int dalvikSwappablePss;
119        /** @hide The resident set size for dalvik heap.  (Without other Dalvik overhead.) */
120        public int dalvikRss;
121        /** The private dirty pages used by dalvik heap. */
122        public int dalvikPrivateDirty;
123        /** The shared dirty pages used by dalvik heap. */
124        public int dalvikSharedDirty;
125        /** The private clean pages used by dalvik heap. */
126        /** @hide We may want to expose this, eventually. */
127        public int dalvikPrivateClean;
128        /** The shared clean pages used by dalvik heap. */
129        /** @hide We may want to expose this, eventually. */
130        public int dalvikSharedClean;
131        /** The dirty dalvik pages that have been swapped out. */
132        /** @hide We may want to expose this, eventually. */
133        public int dalvikSwappedOut;
134        /** The dirty dalvik pages that have been swapped out, proportional. */
135        /** @hide We may want to expose this, eventually. */
136        public int dalvikSwappedOutPss;
137
138        /** The proportional set size for the native heap. */
139        public int nativePss;
140        /** The proportional set size that is swappable for the native heap. */
141        /** @hide We may want to expose this, eventually. */
142        public int nativeSwappablePss;
143        /** @hide The resident set size for the native heap. */
144        public int nativeRss;
145        /** The private dirty pages used by the native heap. */
146        public int nativePrivateDirty;
147        /** The shared dirty pages used by the native heap. */
148        public int nativeSharedDirty;
149        /** The private clean pages used by the native heap. */
150        /** @hide We may want to expose this, eventually. */
151        public int nativePrivateClean;
152        /** The shared clean pages used by the native heap. */
153        /** @hide We may want to expose this, eventually. */
154        public int nativeSharedClean;
155        /** The dirty native pages that have been swapped out. */
156        /** @hide We may want to expose this, eventually. */
157        public int nativeSwappedOut;
158        /** The dirty native pages that have been swapped out, proportional. */
159        /** @hide We may want to expose this, eventually. */
160        public int nativeSwappedOutPss;
161
162        /** The proportional set size for everything else. */
163        public int otherPss;
164        /** The proportional set size that is swappable for everything else. */
165        /** @hide We may want to expose this, eventually. */
166        public int otherSwappablePss;
167        /** @hide The resident set size for everything else. */
168        public int otherRss;
169        /** The private dirty pages used by everything else. */
170        public int otherPrivateDirty;
171        /** The shared dirty pages used by everything else. */
172        public int otherSharedDirty;
173        /** The private clean pages used by everything else. */
174        /** @hide We may want to expose this, eventually. */
175        public int otherPrivateClean;
176        /** The shared clean pages used by everything else. */
177        /** @hide We may want to expose this, eventually. */
178        public int otherSharedClean;
179        /** The dirty pages used by anyting else that have been swapped out. */
180        /** @hide We may want to expose this, eventually. */
181        public int otherSwappedOut;
182        /** The dirty pages used by anyting else that have been swapped out, proportional. */
183        /** @hide We may want to expose this, eventually. */
184        public int otherSwappedOutPss;
185
186        /** Whether the kernel reports proportional swap usage */
187        /** @hide */
188        public boolean hasSwappedOutPss;
189
190        /** @hide */
191        public static final int HEAP_UNKNOWN = 0;
192        /** @hide */
193        public static final int HEAP_DALVIK = 1;
194        /** @hide */
195        public static final int HEAP_NATIVE = 2;
196
197        /** @hide */
198        public static final int OTHER_DALVIK_OTHER = 0;
199        /** @hide */
200        public static final int OTHER_STACK = 1;
201        /** @hide */
202        public static final int OTHER_CURSOR = 2;
203        /** @hide */
204        public static final int OTHER_ASHMEM = 3;
205        /** @hide */
206        public static final int OTHER_GL_DEV = 4;
207        /** @hide */
208        public static final int OTHER_UNKNOWN_DEV = 5;
209        /** @hide */
210        public static final int OTHER_SO = 6;
211        /** @hide */
212        public static final int OTHER_JAR = 7;
213        /** @hide */
214        public static final int OTHER_APK = 8;
215        /** @hide */
216        public static final int OTHER_TTF = 9;
217        /** @hide */
218        public static final int OTHER_DEX = 10;
219        /** @hide */
220        public static final int OTHER_OAT = 11;
221        /** @hide */
222        public static final int OTHER_ART = 12;
223        /** @hide */
224        public static final int OTHER_UNKNOWN_MAP = 13;
225        /** @hide */
226        public static final int OTHER_GRAPHICS = 14;
227        /** @hide */
228        public static final int OTHER_GL = 15;
229        /** @hide */
230        public static final int OTHER_OTHER_MEMTRACK = 16;
231
232        // Needs to be declared here for the DVK_STAT ranges below.
233        /** @hide */
234        public static final int NUM_OTHER_STATS = 17;
235
236        // Dalvik subsections.
237        /** @hide */
238        public static final int OTHER_DALVIK_NORMAL = 17;
239        /** @hide */
240        public static final int OTHER_DALVIK_LARGE = 18;
241        /** @hide */
242        public static final int OTHER_DALVIK_ZYGOTE = 19;
243        /** @hide */
244        public static final int OTHER_DALVIK_NON_MOVING = 20;
245        // Section begins and ends for dumpsys, relative to the DALVIK categories.
246        /** @hide */
247        public static final int OTHER_DVK_STAT_DALVIK_START =
248                OTHER_DALVIK_NORMAL - NUM_OTHER_STATS;
249        /** @hide */
250        public static final int OTHER_DVK_STAT_DALVIK_END =
251                OTHER_DALVIK_NON_MOVING - NUM_OTHER_STATS;
252
253        // Dalvik Other subsections.
254        /** @hide */
255        public static final int OTHER_DALVIK_OTHER_LINEARALLOC = 21;
256        /** @hide */
257        public static final int OTHER_DALVIK_OTHER_ACCOUNTING = 22;
258        /** @hide */
259        public static final int OTHER_DALVIK_OTHER_CODE_CACHE = 23;
260        /** @hide */
261        public static final int OTHER_DALVIK_OTHER_COMPILER_METADATA = 24;
262        /** @hide */
263        public static final int OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE = 25;
264        /** @hide */
265        public static final int OTHER_DVK_STAT_DALVIK_OTHER_START =
266                OTHER_DALVIK_OTHER_LINEARALLOC - NUM_OTHER_STATS;
267        /** @hide */
268        public static final int OTHER_DVK_STAT_DALVIK_OTHER_END =
269                OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE - NUM_OTHER_STATS;
270
271        // Dex subsections (Boot vdex, App dex, and App vdex).
272        /** @hide */
273        public static final int OTHER_DEX_BOOT_VDEX = 26;
274        /** @hide */
275        public static final int OTHER_DEX_APP_DEX = 27;
276        /** @hide */
277        public static final int OTHER_DEX_APP_VDEX = 28;
278        /** @hide */
279        public static final int OTHER_DVK_STAT_DEX_START = OTHER_DEX_BOOT_VDEX - NUM_OTHER_STATS;
280        /** @hide */
281        public static final int OTHER_DVK_STAT_DEX_END = OTHER_DEX_APP_VDEX - NUM_OTHER_STATS;
282
283        // Art subsections (App image, boot image).
284        /** @hide */
285        public static final int OTHER_ART_APP = 29;
286        /** @hide */
287        public static final int OTHER_ART_BOOT = 30;
288        /** @hide */
289        public static final int OTHER_DVK_STAT_ART_START = OTHER_ART_APP - NUM_OTHER_STATS;
290        /** @hide */
291        public static final int OTHER_DVK_STAT_ART_END = OTHER_ART_BOOT - NUM_OTHER_STATS;
292
293        /** @hide */
294        public static final int NUM_DVK_STATS = 14;
295
296        /** @hide */
297        public static final int NUM_CATEGORIES = 9;
298
299        /** @hide */
300        public static final int OFFSET_PSS = 0;
301        /** @hide */
302        public static final int OFFSET_SWAPPABLE_PSS = 1;
303        /** @hide */
304        public static final int OFFSET_RSS = 2;
305        /** @hide */
306        public static final int OFFSET_PRIVATE_DIRTY = 3;
307        /** @hide */
308        public static final int OFFSET_SHARED_DIRTY = 4;
309        /** @hide */
310        public static final int OFFSET_PRIVATE_CLEAN = 5;
311        /** @hide */
312        public static final int OFFSET_SHARED_CLEAN = 6;
313        /** @hide */
314        public static final int OFFSET_SWAPPED_OUT = 7;
315        /** @hide */
316        public static final int OFFSET_SWAPPED_OUT_PSS = 8;
317
318        private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
319
320        public MemoryInfo() {
321        }
322
323        /**
324         * Return total PSS memory usage in kB.
325         */
326        public int getTotalPss() {
327            return dalvikPss + nativePss + otherPss + getTotalSwappedOutPss();
328        }
329
330        /**
331         * @hide Return total PSS memory usage in kB.
332         */
333        public int getTotalUss() {
334            return dalvikPrivateClean + dalvikPrivateDirty
335                    + nativePrivateClean + nativePrivateDirty
336                    + otherPrivateClean + otherPrivateDirty;
337        }
338
339        /**
340         * Return total PSS memory usage in kB mapping a file of one of the following extension:
341         * .so, .jar, .apk, .ttf, .dex, .odex, .oat, .art .
342         */
343        public int getTotalSwappablePss() {
344            return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss;
345        }
346
347        /**
348         * @hide Return total RSS memory usage in kB.
349         */
350        public int getTotalRss() {
351            return dalvikRss + nativeRss + otherRss;
352        }
353
354        /**
355         * Return total private dirty memory usage in kB.
356         */
357        public int getTotalPrivateDirty() {
358            return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
359        }
360
361        /**
362         * Return total shared dirty memory usage in kB.
363         */
364        public int getTotalSharedDirty() {
365            return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
366        }
367
368        /**
369         * Return total shared clean memory usage in kB.
370         */
371        public int getTotalPrivateClean() {
372            return dalvikPrivateClean + nativePrivateClean + otherPrivateClean;
373        }
374
375        /**
376         * Return total shared clean memory usage in kB.
377         */
378        public int getTotalSharedClean() {
379            return dalvikSharedClean + nativeSharedClean + otherSharedClean;
380        }
381
382        /**
383         * Return total swapped out memory in kB.
384         * @hide
385         */
386        public int getTotalSwappedOut() {
387            return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut;
388        }
389
390        /**
391         * Return total swapped out memory in kB, proportional.
392         * @hide
393         */
394        public int getTotalSwappedOutPss() {
395            return dalvikSwappedOutPss + nativeSwappedOutPss + otherSwappedOutPss;
396        }
397
398        /** @hide */
399        public int getOtherPss(int which) {
400            return otherStats[which * NUM_CATEGORIES + OFFSET_PSS];
401        }
402
403        /** @hide */
404        public int getOtherSwappablePss(int which) {
405            return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPABLE_PSS];
406        }
407
408        /** @hide */
409        public int getOtherRss(int which) {
410            return otherStats[which * NUM_CATEGORIES + OFFSET_RSS];
411        }
412
413        /** @hide */
414        public int getOtherPrivateDirty(int which) {
415            return otherStats[which * NUM_CATEGORIES + OFFSET_PRIVATE_DIRTY];
416        }
417
418        /** @hide */
419        public int getOtherSharedDirty(int which) {
420            return otherStats[which * NUM_CATEGORIES + OFFSET_SHARED_DIRTY];
421        }
422
423        /** @hide */
424        public int getOtherPrivateClean(int which) {
425            return otherStats[which * NUM_CATEGORIES + OFFSET_PRIVATE_CLEAN];
426        }
427
428        /** @hide */
429        public int getOtherPrivate(int which) {
430          return getOtherPrivateClean(which) + getOtherPrivateDirty(which);
431        }
432
433        /** @hide */
434        public int getOtherSharedClean(int which) {
435            return otherStats[which * NUM_CATEGORIES + OFFSET_SHARED_CLEAN];
436        }
437
438        /** @hide */
439        public int getOtherSwappedOut(int which) {
440            return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPED_OUT];
441        }
442
443        /** @hide */
444        public int getOtherSwappedOutPss(int which) {
445            return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPED_OUT_PSS];
446        }
447
448        /** @hide */
449        public static String getOtherLabel(int which) {
450            switch (which) {
451                case OTHER_DALVIK_OTHER: return "Dalvik Other";
452                case OTHER_STACK: return "Stack";
453                case OTHER_CURSOR: return "Cursor";
454                case OTHER_ASHMEM: return "Ashmem";
455                case OTHER_GL_DEV: return "Gfx dev";
456                case OTHER_UNKNOWN_DEV: return "Other dev";
457                case OTHER_SO: return ".so mmap";
458                case OTHER_JAR: return ".jar mmap";
459                case OTHER_APK: return ".apk mmap";
460                case OTHER_TTF: return ".ttf mmap";
461                case OTHER_DEX: return ".dex mmap";
462                case OTHER_OAT: return ".oat mmap";
463                case OTHER_ART: return ".art mmap";
464                case OTHER_UNKNOWN_MAP: return "Other mmap";
465                case OTHER_GRAPHICS: return "EGL mtrack";
466                case OTHER_GL: return "GL mtrack";
467                case OTHER_OTHER_MEMTRACK: return "Other mtrack";
468                case OTHER_DALVIK_NORMAL: return ".Heap";
469                case OTHER_DALVIK_LARGE: return ".LOS";
470                case OTHER_DALVIK_ZYGOTE: return ".Zygote";
471                case OTHER_DALVIK_NON_MOVING: return ".NonMoving";
472                case OTHER_DALVIK_OTHER_LINEARALLOC: return ".LinearAlloc";
473                case OTHER_DALVIK_OTHER_ACCOUNTING: return ".GC";
474                case OTHER_DALVIK_OTHER_CODE_CACHE: return ".JITCache";
475                case OTHER_DALVIK_OTHER_COMPILER_METADATA: return ".CompilerMetadata";
476                case OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE: return ".IndirectRef";
477                case OTHER_DEX_BOOT_VDEX: return ".Boot vdex";
478                case OTHER_DEX_APP_DEX: return ".App dex";
479                case OTHER_DEX_APP_VDEX: return ".App vdex";
480                case OTHER_ART_APP: return ".App art";
481                case OTHER_ART_BOOT: return ".Boot art";
482                default: return "????";
483            }
484        }
485
486      /**
487       * Returns the value of a particular memory statistic or {@code null} if no
488       * such memory statistic exists.
489       *
490       * <p>The following table lists the memory statistics that are supported.
491       * Note that memory statistics may be added or removed in a future API level.</p>
492       *
493       * <table>
494       *     <thead>
495       *         <tr>
496       *             <th>Memory statistic name</th>
497       *             <th>Meaning</th>
498       *             <th>Example</th>
499       *             <th>Supported (API Levels)</th>
500       *         </tr>
501       *     </thead>
502       *     <tbody>
503       *         <tr>
504       *             <td>summary.java-heap</td>
505       *             <td>The private Java Heap usage in kB. This corresponds to the Java Heap field
506       *                 in the App Summary section output by dumpsys meminfo.</td>
507       *             <td>{@code 1442}</td>
508       *             <td>23</td>
509       *         </tr>
510       *         <tr>
511       *             <td>summary.native-heap</td>
512       *             <td>The private Native Heap usage in kB. This corresponds to the Native Heap
513       *                 field in the App Summary section output by dumpsys meminfo.</td>
514       *             <td>{@code 1442}</td>
515       *             <td>23</td>
516       *         </tr>
517       *         <tr>
518       *             <td>summary.code</td>
519       *             <td>The memory usage for static code and resources in kB. This corresponds to
520       *                 the Code field in the App Summary section output by dumpsys meminfo.</td>
521       *             <td>{@code 1442}</td>
522       *             <td>23</td>
523       *         </tr>
524       *         <tr>
525       *             <td>summary.stack</td>
526       *             <td>The stack usage in kB. This corresponds to the Stack field in the
527       *                 App Summary section output by dumpsys meminfo.</td>
528       *             <td>{@code 1442}</td>
529       *             <td>23</td>
530       *         </tr>
531       *         <tr>
532       *             <td>summary.graphics</td>
533       *             <td>The graphics usage in kB. This corresponds to the Graphics field in the
534       *                 App Summary section output by dumpsys meminfo.</td>
535       *             <td>{@code 1442}</td>
536       *             <td>23</td>
537       *         </tr>
538       *         <tr>
539       *             <td>summary.private-other</td>
540       *             <td>Other private memory usage in kB. This corresponds to the Private Other
541       *                 field output in the App Summary section by dumpsys meminfo.</td>
542       *             <td>{@code 1442}</td>
543       *             <td>23</td>
544       *         </tr>
545       *         <tr>
546       *             <td>summary.system</td>
547       *             <td>Shared and system memory usage in kB. This corresponds to the System
548       *                 field output in the App Summary section by dumpsys meminfo.</td>
549       *             <td>{@code 1442}</td>
550       *             <td>23</td>
551       *         </tr>
552       *         <tr>
553       *             <td>summary.total-pss</td>
554       *             <td>Total PPS memory usage in kB.</td>
555       *             <td>{@code 1442}</td>
556       *             <td>23</td>
557       *         </tr>
558       *         <tr>
559       *             <td>summary.total-swap</td>
560       *             <td>Total swap usage in kB.</td>
561       *             <td>{@code 1442}</td>
562       *             <td>23</td>
563       *         </tr>
564       *     </tbody>
565       * </table>
566       */
567       public String getMemoryStat(String statName) {
568            switch(statName) {
569                case "summary.java-heap":
570                    return Integer.toString(getSummaryJavaHeap());
571                case "summary.native-heap":
572                    return Integer.toString(getSummaryNativeHeap());
573                case "summary.code":
574                    return Integer.toString(getSummaryCode());
575                case "summary.stack":
576                    return Integer.toString(getSummaryStack());
577                case "summary.graphics":
578                    return Integer.toString(getSummaryGraphics());
579                case "summary.private-other":
580                    return Integer.toString(getSummaryPrivateOther());
581                case "summary.system":
582                    return Integer.toString(getSummarySystem());
583                case "summary.total-pss":
584                    return Integer.toString(getSummaryTotalPss());
585                case "summary.total-swap":
586                    return Integer.toString(getSummaryTotalSwap());
587                default:
588                    return null;
589            }
590        }
591
592        /**
593         * Returns a map of the names/values of the memory statistics
594         * that {@link #getMemoryStat(String)} supports.
595         *
596         * @return a map of the names/values of the supported memory statistics.
597         */
598        public Map<String, String> getMemoryStats() {
599            Map<String, String> stats = new HashMap<String, String>();
600            stats.put("summary.java-heap", Integer.toString(getSummaryJavaHeap()));
601            stats.put("summary.native-heap", Integer.toString(getSummaryNativeHeap()));
602            stats.put("summary.code", Integer.toString(getSummaryCode()));
603            stats.put("summary.stack", Integer.toString(getSummaryStack()));
604            stats.put("summary.graphics", Integer.toString(getSummaryGraphics()));
605            stats.put("summary.private-other", Integer.toString(getSummaryPrivateOther()));
606            stats.put("summary.system", Integer.toString(getSummarySystem()));
607            stats.put("summary.total-pss", Integer.toString(getSummaryTotalPss()));
608            stats.put("summary.total-swap", Integer.toString(getSummaryTotalSwap()));
609            return stats;
610        }
611
612        /**
613         * Pss of Java Heap bytes in KB due to the application.
614         * Notes:
615         *  * OTHER_ART is the boot image. Anything private here is blamed on
616         *    the application, not the system.
617         *  * dalvikPrivateDirty includes private zygote, which means the
618         *    application dirtied something allocated by the zygote. We blame
619         *    the application for that memory, not the system.
620         *  * Does not include OTHER_DALVIK_OTHER, which is considered VM
621         *    Overhead and lumped into Private Other.
622         *  * We don't include dalvikPrivateClean, because there should be no
623         *    such thing as private clean for the Java Heap.
624         * @hide
625         */
626        public int getSummaryJavaHeap() {
627            return dalvikPrivateDirty + getOtherPrivate(OTHER_ART);
628        }
629
630        /**
631         * Pss of Native Heap bytes in KB due to the application.
632         * Notes:
633         *  * Includes private dirty malloc space.
634         *  * We don't include nativePrivateClean, because there should be no
635         *    such thing as private clean for the Native Heap.
636         * @hide
637         */
638        public int getSummaryNativeHeap() {
639            return nativePrivateDirty;
640        }
641
642        /**
643         * Pss of code and other static resource bytes in KB due to
644         * the application.
645         * @hide
646         */
647        public int getSummaryCode() {
648            return getOtherPrivate(OTHER_SO)
649              + getOtherPrivate(OTHER_JAR)
650              + getOtherPrivate(OTHER_APK)
651              + getOtherPrivate(OTHER_TTF)
652              + getOtherPrivate(OTHER_DEX)
653              + getOtherPrivate(OTHER_OAT);
654        }
655
656        /**
657         * Pss in KB of the stack due to the application.
658         * Notes:
659         *  * Includes private dirty stack, which includes both Java and Native
660         *    stack.
661         *  * Does not include private clean stack, because there should be no
662         *    such thing as private clean for the stack.
663         * @hide
664         */
665        public int getSummaryStack() {
666            return getOtherPrivateDirty(OTHER_STACK);
667        }
668
669        /**
670         * Pss in KB of graphics due to the application.
671         * Notes:
672         *  * Includes private Gfx, EGL, and GL.
673         *  * Warning: These numbers can be misreported by the graphics drivers.
674         *  * We don't include shared graphics. It may make sense to, because
675         *    shared graphics are likely buffers due to the application
676         *    anyway, but it's simpler to implement to just group all shared
677         *    memory into the System category.
678         * @hide
679         */
680        public int getSummaryGraphics() {
681            return getOtherPrivate(OTHER_GL_DEV)
682              + getOtherPrivate(OTHER_GRAPHICS)
683              + getOtherPrivate(OTHER_GL);
684        }
685
686        /**
687         * Pss in KB due to the application that haven't otherwise been
688         * accounted for.
689         * @hide
690         */
691        public int getSummaryPrivateOther() {
692            return getTotalPrivateClean()
693              + getTotalPrivateDirty()
694              - getSummaryJavaHeap()
695              - getSummaryNativeHeap()
696              - getSummaryCode()
697              - getSummaryStack()
698              - getSummaryGraphics();
699        }
700
701        /**
702         * Pss in KB due to the system.
703         * Notes:
704         *  * Includes all shared memory.
705         * @hide
706         */
707        public int getSummarySystem() {
708            return getTotalPss()
709              - getTotalPrivateClean()
710              - getTotalPrivateDirty();
711        }
712
713        /**
714         * Total Pss in KB.
715         * @hide
716         */
717        public int getSummaryTotalPss() {
718            return getTotalPss();
719        }
720
721        /**
722         * Total Swap in KB.
723         * Notes:
724         *  * Some of this memory belongs in other categories, but we don't
725         *    know if the Swap memory is shared or private, so we don't know
726         *    what to blame on the application and what on the system.
727         *    For now, just lump all the Swap in one place.
728         *    For kernels reporting SwapPss {@link #getSummaryTotalSwapPss()}
729         *    will report the application proportional Swap.
730         * @hide
731         */
732        public int getSummaryTotalSwap() {
733            return getTotalSwappedOut();
734        }
735
736        /**
737         * Total proportional Swap in KB.
738         * Notes:
739         *  * Always 0 if {@link #hasSwappedOutPss} is false.
740         * @hide
741         */
742        public int getSummaryTotalSwapPss() {
743            return getTotalSwappedOutPss();
744        }
745
746        /**
747         * Return true if the kernel is reporting pss swapped out...  that is, if
748         * {@link #getSummaryTotalSwapPss()} will return non-0 values.
749         * @hide
750         */
751        public boolean hasSwappedOutPss() {
752            return hasSwappedOutPss;
753        }
754
755        public int describeContents() {
756            return 0;
757        }
758
759        public void writeToParcel(Parcel dest, int flags) {
760            dest.writeInt(dalvikPss);
761            dest.writeInt(dalvikSwappablePss);
762            dest.writeInt(dalvikRss);
763            dest.writeInt(dalvikPrivateDirty);
764            dest.writeInt(dalvikSharedDirty);
765            dest.writeInt(dalvikPrivateClean);
766            dest.writeInt(dalvikSharedClean);
767            dest.writeInt(dalvikSwappedOut);
768            dest.writeInt(dalvikSwappedOutPss);
769            dest.writeInt(nativePss);
770            dest.writeInt(nativeSwappablePss);
771            dest.writeInt(nativeRss);
772            dest.writeInt(nativePrivateDirty);
773            dest.writeInt(nativeSharedDirty);
774            dest.writeInt(nativePrivateClean);
775            dest.writeInt(nativeSharedClean);
776            dest.writeInt(nativeSwappedOut);
777            dest.writeInt(nativeSwappedOutPss);
778            dest.writeInt(otherPss);
779            dest.writeInt(otherSwappablePss);
780            dest.writeInt(otherRss);
781            dest.writeInt(otherPrivateDirty);
782            dest.writeInt(otherSharedDirty);
783            dest.writeInt(otherPrivateClean);
784            dest.writeInt(otherSharedClean);
785            dest.writeInt(otherSwappedOut);
786            dest.writeInt(hasSwappedOutPss ? 1 : 0);
787            dest.writeInt(otherSwappedOutPss);
788            dest.writeIntArray(otherStats);
789        }
790
791        public void readFromParcel(Parcel source) {
792            dalvikPss = source.readInt();
793            dalvikSwappablePss = source.readInt();
794            dalvikRss = source.readInt();
795            dalvikPrivateDirty = source.readInt();
796            dalvikSharedDirty = source.readInt();
797            dalvikPrivateClean = source.readInt();
798            dalvikSharedClean = source.readInt();
799            dalvikSwappedOut = source.readInt();
800            dalvikSwappedOutPss = source.readInt();
801            nativePss = source.readInt();
802            nativeSwappablePss = source.readInt();
803            nativeRss = source.readInt();
804            nativePrivateDirty = source.readInt();
805            nativeSharedDirty = source.readInt();
806            nativePrivateClean = source.readInt();
807            nativeSharedClean = source.readInt();
808            nativeSwappedOut = source.readInt();
809            nativeSwappedOutPss = source.readInt();
810            otherPss = source.readInt();
811            otherSwappablePss = source.readInt();
812            otherRss = source.readInt();
813            otherPrivateDirty = source.readInt();
814            otherSharedDirty = source.readInt();
815            otherPrivateClean = source.readInt();
816            otherSharedClean = source.readInt();
817            otherSwappedOut = source.readInt();
818            hasSwappedOutPss = source.readInt() != 0;
819            otherSwappedOutPss = source.readInt();
820            otherStats = source.createIntArray();
821        }
822
823        public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
824            public MemoryInfo createFromParcel(Parcel source) {
825                return new MemoryInfo(source);
826            }
827            public MemoryInfo[] newArray(int size) {
828                return new MemoryInfo[size];
829            }
830        };
831
832        private MemoryInfo(Parcel source) {
833            readFromParcel(source);
834        }
835    }
836
837
838    /**
839     * Wait until a debugger attaches.  As soon as the debugger attaches,
840     * this returns, so you will need to place a breakpoint after the
841     * waitForDebugger() call if you want to start tracing immediately.
842     */
843    public static void waitForDebugger() {
844        if (!VMDebug.isDebuggingEnabled()) {
845            //System.out.println("debugging not enabled, not waiting");
846            return;
847        }
848        if (isDebuggerConnected())
849            return;
850
851        // if DDMS is listening, inform them of our plight
852        System.out.println("Sending WAIT chunk");
853        byte[] data = new byte[] { 0 };     // 0 == "waiting for debugger"
854        Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1);
855        DdmServer.sendChunk(waitChunk);
856
857        mWaiting = true;
858        while (!isDebuggerConnected()) {
859            try { Thread.sleep(SPIN_DELAY); }
860            catch (InterruptedException ie) {}
861        }
862        mWaiting = false;
863
864        System.out.println("Debugger has connected");
865
866        /*
867         * There is no "ready to go" signal from the debugger, and we're
868         * not allowed to suspend ourselves -- the debugger expects us to
869         * be running happily, and gets confused if we aren't.  We need to
870         * allow the debugger a chance to set breakpoints before we start
871         * running again.
872         *
873         * Sit and spin until the debugger has been idle for a short while.
874         */
875        while (true) {
876            long delta = VMDebug.lastDebuggerActivity();
877            if (delta < 0) {
878                System.out.println("debugger detached?");
879                break;
880            }
881
882            if (delta < MIN_DEBUGGER_IDLE) {
883                System.out.println("waiting for debugger to settle...");
884                try { Thread.sleep(SPIN_DELAY); }
885                catch (InterruptedException ie) {}
886            } else {
887                System.out.println("debugger has settled (" + delta + ")");
888                break;
889            }
890        }
891    }
892
893    /**
894     * Returns "true" if one or more threads is waiting for a debugger
895     * to attach.
896     */
897    public static boolean waitingForDebugger() {
898        return mWaiting;
899    }
900
901    /**
902     * Determine if a debugger is currently attached.
903     */
904    public static boolean isDebuggerConnected() {
905        return VMDebug.isDebuggerConnected();
906    }
907
908    /**
909     * Returns an array of strings that identify VM features.  This is
910     * used by DDMS to determine what sorts of operations the VM can
911     * perform.
912     *
913     * @hide
914     */
915    public static String[] getVmFeatureList() {
916        return VMDebug.getVmFeatureList();
917    }
918
919    /**
920     * Change the JDWP port.
921     *
922     * @deprecated no longer needed or useful
923     */
924    @Deprecated
925    public static void changeDebugPort(int port) {}
926
927    /**
928     * This is the pathname to the sysfs file that enables and disables
929     * tracing on the qemu emulator.
930     */
931    private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state";
932
933    /**
934     * Enable qemu tracing. For this to work requires running everything inside
935     * the qemu emulator; otherwise, this method will have no effect. The trace
936     * file is specified on the command line when the emulator is started. For
937     * example, the following command line <br />
938     * <code>emulator -trace foo</code><br />
939     * will start running the emulator and create a trace file named "foo". This
940     * method simply enables writing the trace records to the trace file.
941     *
942     * <p>
943     * The main differences between this and {@link #startMethodTracing()} are
944     * that tracing in the qemu emulator traces every cpu instruction of every
945     * process, including kernel code, so we have more complete information,
946     * including all context switches. We can also get more detailed information
947     * such as cache misses. The sequence of calls is determined by
948     * post-processing the instruction trace. The qemu tracing is also done
949     * without modifying the application or perturbing the timing of calls
950     * because no instrumentation is added to the application being traced.
951     * </p>
952     *
953     * <p>
954     * One limitation of using this method compared to using
955     * {@link #startMethodTracing()} on the real device is that the emulator
956     * does not model all of the real hardware effects such as memory and
957     * bus contention.  The emulator also has a simple cache model and cannot
958     * capture all the complexities of a real cache.
959     * </p>
960     */
961    public static void startNativeTracing() {
962        // Open the sysfs file for writing and write "1" to it.
963        PrintWriter outStream = null;
964        try {
965            FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
966            outStream = new FastPrintWriter(fos);
967            outStream.println("1");
968        } catch (Exception e) {
969        } finally {
970            if (outStream != null)
971                outStream.close();
972        }
973
974        VMDebug.startEmulatorTracing();
975    }
976
977    /**
978     * Stop qemu tracing.  See {@link #startNativeTracing()} to start tracing.
979     *
980     * <p>Tracing can be started and stopped as many times as desired.  When
981     * the qemu emulator itself is stopped then the buffered trace records
982     * are flushed and written to the trace file.  In fact, it is not necessary
983     * to call this method at all; simply killing qemu is sufficient.  But
984     * starting and stopping a trace is useful for examining a specific
985     * region of code.</p>
986     */
987    public static void stopNativeTracing() {
988        VMDebug.stopEmulatorTracing();
989
990        // Open the sysfs file for writing and write "0" to it.
991        PrintWriter outStream = null;
992        try {
993            FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
994            outStream = new FastPrintWriter(fos);
995            outStream.println("0");
996        } catch (Exception e) {
997            // We could print an error message here but we probably want
998            // to quietly ignore errors if we are not running in the emulator.
999        } finally {
1000            if (outStream != null)
1001                outStream.close();
1002        }
1003    }
1004
1005    /**
1006     * Enable "emulator traces", in which information about the current
1007     * method is made available to the "emulator -trace" feature.  There
1008     * is no corresponding "disable" call -- this is intended for use by
1009     * the framework when tracing should be turned on and left that way, so
1010     * that traces captured with F9/F10 will include the necessary data.
1011     *
1012     * This puts the VM into "profile" mode, which has performance
1013     * consequences.
1014     *
1015     * To temporarily enable tracing, use {@link #startNativeTracing()}.
1016     */
1017    public static void enableEmulatorTraceOutput() {
1018        VMDebug.startEmulatorTracing();
1019    }
1020
1021    /**
1022     * Start method tracing with default log name and buffer size.
1023     * <p>
1024     * By default, the trace file is called "dmtrace.trace" and it's placed
1025     * under your package-specific directory on primary shared/external storage,
1026     * as returned by {@link Context#getExternalFilesDir(String)}.
1027     * <p>
1028     * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview:
1029     * A Graphical Log Viewer</a> for information about reading trace files.
1030     * <p class="note">
1031     * When method tracing is enabled, the VM will run more slowly than usual,
1032     * so the timings from the trace files should only be considered in relative
1033     * terms (e.g. was run #1 faster than run #2). The times for native methods
1034     * will not change, so don't try to use this to compare the performance of
1035     * interpreted and native implementations of the same method. As an
1036     * alternative, consider using sampling-based method tracing via
1037     * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing
1038     * in the emulator via {@link #startNativeTracing()}.
1039     * </p>
1040     */
1041    public static void startMethodTracing() {
1042        VMDebug.startMethodTracing(fixTracePath(null), 0, 0, false, 0);
1043    }
1044
1045    /**
1046     * Start method tracing, specifying the trace log file path.
1047     * <p>
1048     * When a relative file path is given, the trace file will be placed under
1049     * your package-specific directory on primary shared/external storage, as
1050     * returned by {@link Context#getExternalFilesDir(String)}.
1051     * <p>
1052     * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview:
1053     * A Graphical Log Viewer</a> for information about reading trace files.
1054     * <p class="note">
1055     * When method tracing is enabled, the VM will run more slowly than usual,
1056     * so the timings from the trace files should only be considered in relative
1057     * terms (e.g. was run #1 faster than run #2). The times for native methods
1058     * will not change, so don't try to use this to compare the performance of
1059     * interpreted and native implementations of the same method. As an
1060     * alternative, consider using sampling-based method tracing via
1061     * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing
1062     * in the emulator via {@link #startNativeTracing()}.
1063     * </p>
1064     *
1065     * @param tracePath Path to the trace log file to create. If {@code null},
1066     *            this will default to "dmtrace.trace". If the file already
1067     *            exists, it will be truncated. If the path given does not end
1068     *            in ".trace", it will be appended for you.
1069     */
1070    public static void startMethodTracing(String tracePath) {
1071        startMethodTracing(tracePath, 0, 0);
1072    }
1073
1074    /**
1075     * Start method tracing, specifying the trace log file name and the buffer
1076     * size.
1077     * <p>
1078     * When a relative file path is given, the trace file will be placed under
1079     * your package-specific directory on primary shared/external storage, as
1080     * returned by {@link Context#getExternalFilesDir(String)}.
1081     * <p>
1082     * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview:
1083     * A Graphical Log Viewer</a> for information about reading trace files.
1084     * <p class="note">
1085     * When method tracing is enabled, the VM will run more slowly than usual,
1086     * so the timings from the trace files should only be considered in relative
1087     * terms (e.g. was run #1 faster than run #2). The times for native methods
1088     * will not change, so don't try to use this to compare the performance of
1089     * interpreted and native implementations of the same method. As an
1090     * alternative, consider using sampling-based method tracing via
1091     * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing
1092     * in the emulator via {@link #startNativeTracing()}.
1093     * </p>
1094     *
1095     * @param tracePath Path to the trace log file to create. If {@code null},
1096     *            this will default to "dmtrace.trace". If the file already
1097     *            exists, it will be truncated. If the path given does not end
1098     *            in ".trace", it will be appended for you.
1099     * @param bufferSize The maximum amount of trace data we gather. If not
1100     *            given, it defaults to 8MB.
1101     */
1102    public static void startMethodTracing(String tracePath, int bufferSize) {
1103        startMethodTracing(tracePath, bufferSize, 0);
1104    }
1105
1106    /**
1107     * Start method tracing, specifying the trace log file name, the buffer
1108     * size, and flags.
1109     * <p>
1110     * When a relative file path is given, the trace file will be placed under
1111     * your package-specific directory on primary shared/external storage, as
1112     * returned by {@link Context#getExternalFilesDir(String)}.
1113     * <p>
1114     * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview:
1115     * A Graphical Log Viewer</a> for information about reading trace files.
1116     * <p class="note">
1117     * When method tracing is enabled, the VM will run more slowly than usual,
1118     * so the timings from the trace files should only be considered in relative
1119     * terms (e.g. was run #1 faster than run #2). The times for native methods
1120     * will not change, so don't try to use this to compare the performance of
1121     * interpreted and native implementations of the same method. As an
1122     * alternative, consider using sampling-based method tracing via
1123     * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing
1124     * in the emulator via {@link #startNativeTracing()}.
1125     * </p>
1126     *
1127     * @param tracePath Path to the trace log file to create. If {@code null},
1128     *            this will default to "dmtrace.trace". If the file already
1129     *            exists, it will be truncated. If the path given does not end
1130     *            in ".trace", it will be appended for you.
1131     * @param bufferSize The maximum amount of trace data we gather. If not
1132     *            given, it defaults to 8MB.
1133     * @param flags Flags to control method tracing. The only one that is
1134     *            currently defined is {@link #TRACE_COUNT_ALLOCS}.
1135     */
1136    public static void startMethodTracing(String tracePath, int bufferSize, int flags) {
1137        VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, flags, false, 0);
1138    }
1139
1140    /**
1141     * Start sampling-based method tracing, specifying the trace log file name,
1142     * the buffer size, and the sampling interval.
1143     * <p>
1144     * When a relative file path is given, the trace file will be placed under
1145     * your package-specific directory on primary shared/external storage, as
1146     * returned by {@link Context#getExternalFilesDir(String)}.
1147     * <p>
1148     * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview:
1149     * A Graphical Log Viewer</a> for information about reading trace files.
1150     *
1151     * @param tracePath Path to the trace log file to create. If {@code null},
1152     *            this will default to "dmtrace.trace". If the file already
1153     *            exists, it will be truncated. If the path given does not end
1154     *            in ".trace", it will be appended for you.
1155     * @param bufferSize The maximum amount of trace data we gather. If not
1156     *            given, it defaults to 8MB.
1157     * @param intervalUs The amount of time between each sample in microseconds.
1158     */
1159    public static void startMethodTracingSampling(String tracePath, int bufferSize,
1160            int intervalUs) {
1161        VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, 0, true, intervalUs);
1162    }
1163
1164    /**
1165     * Formats name of trace log file for method tracing.
1166     */
1167    private static String fixTracePath(String tracePath) {
1168        if (tracePath == null || tracePath.charAt(0) != '/') {
1169            final Context context = AppGlobals.getInitialApplication();
1170            final File dir;
1171            if (context != null) {
1172                dir = context.getExternalFilesDir(null);
1173            } else {
1174                dir = Environment.getExternalStorageDirectory();
1175            }
1176
1177            if (tracePath == null) {
1178                tracePath = new File(dir, DEFAULT_TRACE_BODY).getAbsolutePath();
1179            } else {
1180                tracePath = new File(dir, tracePath).getAbsolutePath();
1181            }
1182        }
1183        if (!tracePath.endsWith(DEFAULT_TRACE_EXTENSION)) {
1184            tracePath += DEFAULT_TRACE_EXTENSION;
1185        }
1186        return tracePath;
1187    }
1188
1189    /**
1190     * Like startMethodTracing(String, int, int), but taking an already-opened
1191     * FileDescriptor in which the trace is written.  The file name is also
1192     * supplied simply for logging.  Makes a dup of the file descriptor.
1193     *
1194     * Not exposed in the SDK unless we are really comfortable with supporting
1195     * this and find it would be useful.
1196     * @hide
1197     */
1198    public static void startMethodTracing(String traceName, FileDescriptor fd,
1199        int bufferSize, int flags, boolean streamOutput) {
1200        VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0, streamOutput);
1201    }
1202
1203    /**
1204     * Starts method tracing without a backing file.  When stopMethodTracing
1205     * is called, the result is sent directly to DDMS.  (If DDMS is not
1206     * attached when tracing ends, the profiling data will be discarded.)
1207     *
1208     * @hide
1209     */
1210    public static void startMethodTracingDdms(int bufferSize, int flags,
1211        boolean samplingEnabled, int intervalUs) {
1212        VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs);
1213    }
1214
1215    /**
1216     * Determine whether method tracing is currently active and what type is
1217     * active.
1218     *
1219     * @hide
1220     */
1221    public static int getMethodTracingMode() {
1222        return VMDebug.getMethodTracingMode();
1223    }
1224
1225    /**
1226     * Stop method tracing.
1227     */
1228    public static void stopMethodTracing() {
1229        VMDebug.stopMethodTracing();
1230    }
1231
1232    /**
1233     * Get an indication of thread CPU usage.  The value returned
1234     * indicates the amount of time that the current thread has spent
1235     * executing code or waiting for certain types of I/O.
1236     *
1237     * The time is expressed in nanoseconds, and is only meaningful
1238     * when compared to the result from an earlier call.  Note that
1239     * nanosecond resolution does not imply nanosecond accuracy.
1240     *
1241     * On system which don't support this operation, the call returns -1.
1242     */
1243    public static long threadCpuTimeNanos() {
1244        return VMDebug.threadCpuTimeNanos();
1245    }
1246
1247    /**
1248     * Start counting the number and aggregate size of memory allocations.
1249     *
1250     * <p>The {@link #startAllocCounting() start} method resets the counts and enables counting.
1251     * The {@link #stopAllocCounting() stop} method disables the counting so that the analysis
1252     * code doesn't cause additional allocations.  The various <code>get</code> methods return
1253     * the specified value. And the various <code>reset</code> methods reset the specified
1254     * count.</p>
1255     *
1256     * <p>Counts are kept for the system as a whole (global) and for each thread.
1257     * The per-thread counts for threads other than the current thread
1258     * are not cleared by the "reset" or "start" calls.</p>
1259     *
1260     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1261     */
1262    @Deprecated
1263    public static void startAllocCounting() {
1264        VMDebug.startAllocCounting();
1265    }
1266
1267    /**
1268     * Stop counting the number and aggregate size of memory allocations.
1269     *
1270     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1271     */
1272    @Deprecated
1273    public static void stopAllocCounting() {
1274        VMDebug.stopAllocCounting();
1275    }
1276
1277    /**
1278     * Returns the global count of objects allocated by the runtime between a
1279     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1280     *
1281     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1282     */
1283    @Deprecated
1284    public static int getGlobalAllocCount() {
1285        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
1286    }
1287
1288    /**
1289     * Clears the global count of objects allocated.
1290     * @see #getGlobalAllocCount()
1291     *
1292     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1293     */
1294    @Deprecated
1295    public static void resetGlobalAllocCount() {
1296        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
1297    }
1298
1299    /**
1300     * Returns the global size, in bytes, of objects allocated by the runtime between a
1301     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1302     *
1303     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1304     */
1305    @Deprecated
1306    public static int getGlobalAllocSize() {
1307        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
1308    }
1309
1310    /**
1311     * Clears the global size of objects allocated.
1312     * @see #getGlobalAllocSize()
1313     *
1314     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1315     */
1316    @Deprecated
1317    public static void resetGlobalAllocSize() {
1318        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
1319    }
1320
1321    /**
1322     * Returns the global count of objects freed by the runtime between a
1323     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1324     *
1325     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1326     */
1327    @Deprecated
1328    public static int getGlobalFreedCount() {
1329        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
1330    }
1331
1332    /**
1333     * Clears the global count of objects freed.
1334     * @see #getGlobalFreedCount()
1335     *
1336     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1337     */
1338    @Deprecated
1339    public static void resetGlobalFreedCount() {
1340        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
1341    }
1342
1343    /**
1344     * Returns the global size, in bytes, of objects freed by the runtime between a
1345     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1346     *
1347     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1348     */
1349    @Deprecated
1350    public static int getGlobalFreedSize() {
1351        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
1352    }
1353
1354    /**
1355     * Clears the global size of objects freed.
1356     * @see #getGlobalFreedSize()
1357     *
1358     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1359     */
1360    @Deprecated
1361    public static void resetGlobalFreedSize() {
1362        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
1363    }
1364
1365    /**
1366     * Returns the number of non-concurrent GC invocations between a
1367     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1368     *
1369     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1370     */
1371    @Deprecated
1372    public static int getGlobalGcInvocationCount() {
1373        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
1374    }
1375
1376    /**
1377     * Clears the count of non-concurrent GC invocations.
1378     * @see #getGlobalGcInvocationCount()
1379     *
1380     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1381     */
1382    @Deprecated
1383    public static void resetGlobalGcInvocationCount() {
1384        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
1385    }
1386
1387    /**
1388     * Returns the number of classes successfully initialized (ie those that executed without
1389     * throwing an exception) between a {@link #startAllocCounting() start} and
1390     * {@link #stopAllocCounting() stop}.
1391     *
1392     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1393     */
1394    @Deprecated
1395    public static int getGlobalClassInitCount() {
1396        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
1397    }
1398
1399    /**
1400     * Clears the count of classes initialized.
1401     * @see #getGlobalClassInitCount()
1402     *
1403     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1404     */
1405    @Deprecated
1406    public static void resetGlobalClassInitCount() {
1407        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
1408    }
1409
1410    /**
1411     * Returns the time spent successfully initializing classes between a
1412     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1413     *
1414     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1415     */
1416    @Deprecated
1417    public static int getGlobalClassInitTime() {
1418        /* cumulative elapsed time for class initialization, in usec */
1419        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
1420    }
1421
1422    /**
1423     * Clears the count of time spent initializing classes.
1424     * @see #getGlobalClassInitTime()
1425     *
1426     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1427     */
1428    @Deprecated
1429    public static void resetGlobalClassInitTime() {
1430        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
1431    }
1432
1433    /**
1434     * This method exists for compatibility and always returns 0.
1435     * @deprecated This method is now obsolete.
1436     */
1437    @Deprecated
1438    public static int getGlobalExternalAllocCount() {
1439        return 0;
1440    }
1441
1442    /**
1443     * This method exists for compatibility and has no effect.
1444     * @deprecated This method is now obsolete.
1445     */
1446    @Deprecated
1447    public static void resetGlobalExternalAllocSize() {}
1448
1449    /**
1450     * This method exists for compatibility and has no effect.
1451     * @deprecated This method is now obsolete.
1452     */
1453    @Deprecated
1454    public static void resetGlobalExternalAllocCount() {}
1455
1456    /**
1457     * This method exists for compatibility and always returns 0.
1458     * @deprecated This method is now obsolete.
1459     */
1460    @Deprecated
1461    public static int getGlobalExternalAllocSize() {
1462        return 0;
1463    }
1464
1465    /**
1466     * This method exists for compatibility and always returns 0.
1467     * @deprecated This method is now obsolete.
1468     */
1469    @Deprecated
1470    public static int getGlobalExternalFreedCount() {
1471        return 0;
1472    }
1473
1474    /**
1475     * This method exists for compatibility and has no effect.
1476     * @deprecated This method is now obsolete.
1477     */
1478    @Deprecated
1479    public static void resetGlobalExternalFreedCount() {}
1480
1481    /**
1482     * This method exists for compatibility and has no effect.
1483     * @deprecated This method is now obsolete.
1484     */
1485    @Deprecated
1486    public static int getGlobalExternalFreedSize() {
1487        return 0;
1488    }
1489
1490    /**
1491     * This method exists for compatibility and has no effect.
1492     * @deprecated This method is now obsolete.
1493     */
1494    @Deprecated
1495    public static void resetGlobalExternalFreedSize() {}
1496
1497    /**
1498     * Returns the thread-local count of objects allocated by the runtime between a
1499     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1500     *
1501     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1502     */
1503    @Deprecated
1504    public static int getThreadAllocCount() {
1505        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
1506    }
1507
1508    /**
1509     * Clears the thread-local count of objects allocated.
1510     * @see #getThreadAllocCount()
1511     *
1512     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1513     */
1514    @Deprecated
1515    public static void resetThreadAllocCount() {
1516        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
1517    }
1518
1519    /**
1520     * Returns the thread-local size of objects allocated by the runtime between a
1521     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1522     * @return The allocated size in bytes.
1523     *
1524     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1525     */
1526    @Deprecated
1527    public static int getThreadAllocSize() {
1528        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
1529    }
1530
1531    /**
1532     * Clears the thread-local count of objects allocated.
1533     * @see #getThreadAllocSize()
1534     *
1535     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1536     */
1537    @Deprecated
1538    public static void resetThreadAllocSize() {
1539        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
1540    }
1541
1542    /**
1543     * This method exists for compatibility and has no effect.
1544     * @deprecated This method is now obsolete.
1545     */
1546    @Deprecated
1547    public static int getThreadExternalAllocCount() {
1548        return 0;
1549    }
1550
1551    /**
1552     * This method exists for compatibility and has no effect.
1553     * @deprecated This method is now obsolete.
1554     */
1555    @Deprecated
1556    public static void resetThreadExternalAllocCount() {}
1557
1558    /**
1559     * This method exists for compatibility and has no effect.
1560     * @deprecated This method is now obsolete.
1561     */
1562    @Deprecated
1563    public static int getThreadExternalAllocSize() {
1564        return 0;
1565    }
1566
1567    /**
1568     * This method exists for compatibility and has no effect.
1569     * @deprecated This method is now obsolete.
1570     */
1571    @Deprecated
1572    public static void resetThreadExternalAllocSize() {}
1573
1574    /**
1575     * Returns the number of thread-local non-concurrent GC invocations between a
1576     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1577     *
1578     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1579     */
1580    @Deprecated
1581    public static int getThreadGcInvocationCount() {
1582        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1583    }
1584
1585    /**
1586     * Clears the thread-local count of non-concurrent GC invocations.
1587     * @see #getThreadGcInvocationCount()
1588     *
1589     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1590     */
1591    @Deprecated
1592    public static void resetThreadGcInvocationCount() {
1593        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1594    }
1595
1596    /**
1597     * Clears all the global and thread-local memory allocation counters.
1598     * @see #startAllocCounting()
1599     *
1600     * @deprecated Accurate counting is a burden on the runtime and may be removed.
1601     */
1602    @Deprecated
1603    public static void resetAllCounts() {
1604        VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS);
1605    }
1606
1607    /**
1608     * Returns the value of a particular runtime statistic or {@code null} if no
1609     * such runtime statistic exists.
1610     *
1611     * <p>The following table lists the runtime statistics that the runtime supports.
1612     * Note runtime statistics may be added or removed in a future API level.</p>
1613     *
1614     * <table>
1615     *     <thead>
1616     *         <tr>
1617     *             <th>Runtime statistic name</th>
1618     *             <th>Meaning</th>
1619     *             <th>Example</th>
1620     *             <th>Supported (API Levels)</th>
1621     *         </tr>
1622     *     </thead>
1623     *     <tbody>
1624     *         <tr>
1625     *             <td>art.gc.gc-count</td>
1626     *             <td>The number of garbage collection runs.</td>
1627     *             <td>{@code 164}</td>
1628     *             <td>23</td>
1629     *         </tr>
1630     *         <tr>
1631     *             <td>art.gc.gc-time</td>
1632     *             <td>The total duration of garbage collection runs in ms.</td>
1633     *             <td>{@code 62364}</td>
1634     *             <td>23</td>
1635     *         </tr>
1636     *         <tr>
1637     *             <td>art.gc.bytes-allocated</td>
1638     *             <td>The total number of bytes that the application allocated.</td>
1639     *             <td>{@code 1463948408}</td>
1640     *             <td>23</td>
1641     *         </tr>
1642     *         <tr>
1643     *             <td>art.gc.bytes-freed</td>
1644     *             <td>The total number of bytes that garbage collection reclaimed.</td>
1645     *             <td>{@code 1313493084}</td>
1646     *             <td>23</td>
1647     *         </tr>
1648     *         <tr>
1649     *             <td>art.gc.blocking-gc-count</td>
1650     *             <td>The number of blocking garbage collection runs.</td>
1651     *             <td>{@code 2}</td>
1652     *             <td>23</td>
1653     *         </tr>
1654     *         <tr>
1655     *             <td>art.gc.blocking-gc-time</td>
1656     *             <td>The total duration of blocking garbage collection runs in ms.</td>
1657     *             <td>{@code 804}</td>
1658     *             <td>23</td>
1659     *         </tr>
1660     *         <tr>
1661     *             <td>art.gc.gc-count-rate-histogram</td>
1662     *             <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage
1663     *                 collection runs that have occurred over the last 10
1664     *                 seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate
1665     *                 samples taken since the process began. The histogram can be used to identify
1666     *                 instances of high rates of garbage collection runs. For example, a histogram
1667     *                 of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time
1668     *                 there are between 0 and 2 garbage collection runs every 10 seconds, but there
1669     *                 were 8 distinct 10-second intervals in which 5 garbage collection runs
1670     *                 occurred.</td>
1671     *             <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td>
1672     *             <td>23</td>
1673     *         </tr>
1674     *         <tr>
1675     *             <td>art.gc.blocking-gc-count-rate-histogram</td>
1676     *             <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of
1677     *                 blocking garbage collection runs that have occurred over the last 10
1678     *                 seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the
1679     *                 blocking-gc-count-rate samples taken since the process began. The histogram
1680     *                 can be used to identify instances of high rates of blocking garbage
1681     *                 collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that
1682     *                 most of the time there are zero blocking garbage collection runs every 10
1683     *                 seconds, but there was one 10-second interval in which one blocking garbage
1684     *                 collection run occurred, and there was one interval in which two blocking
1685     *                 garbage collection runs occurred.</td>
1686     *             <td>{@code 0:99269,1:1,2:1}</td>
1687     *             <td>23</td>
1688     *         </tr>
1689     *     </tbody>
1690     * </table>
1691     *
1692     * @param statName
1693     *            the name of the runtime statistic to look up.
1694     * @return the value of the specified runtime statistic or {@code null} if the
1695     *         runtime statistic doesn't exist.
1696     */
1697    public static String getRuntimeStat(String statName) {
1698        return VMDebug.getRuntimeStat(statName);
1699    }
1700
1701    /**
1702     * Returns a map of the names/values of the runtime statistics
1703     * that {@link #getRuntimeStat(String)} supports.
1704     *
1705     * @return a map of the names/values of the supported runtime statistics.
1706     */
1707    public static Map<String, String> getRuntimeStats() {
1708        return VMDebug.getRuntimeStats();
1709    }
1710
1711    /**
1712     * Returns the size of the native heap.
1713     * @return The size of the native heap in bytes.
1714     */
1715    public static native long getNativeHeapSize();
1716
1717    /**
1718     * Returns the amount of allocated memory in the native heap.
1719     * @return The allocated size in bytes.
1720     */
1721    public static native long getNativeHeapAllocatedSize();
1722
1723    /**
1724     * Returns the amount of free memory in the native heap.
1725     * @return The freed size in bytes.
1726     */
1727    public static native long getNativeHeapFreeSize();
1728
1729    /**
1730     * Retrieves information about this processes memory usages. This information is broken down by
1731     * how much is in use by dalvik, the native heap, and everything else.
1732     *
1733     * <p><b>Note:</b> this method directly retrieves memory information for the given process
1734     * from low-level data available to it.  It may not be able to retrieve information about
1735     * some protected allocations, such as graphics.  If you want to be sure you can see
1736     * all information about allocations by the process, use
1737     * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])} instead.</p>
1738     */
1739    public static native void getMemoryInfo(MemoryInfo memoryInfo);
1740
1741    /**
1742     * Note: currently only works when the requested pid has the same UID
1743     * as the caller.
1744     * @hide
1745     */
1746    public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
1747
1748    /**
1749     * Retrieves the PSS memory used by the process as given by the
1750     * smaps.
1751     */
1752    public static native long getPss();
1753
1754    /**
1755     * Retrieves the PSS memory used by the process as given by the
1756     * smaps.  Optionally supply a long array of 2 entries to also
1757     * receive the Uss and SwapPss of the process, and another array to also
1758     * retrieve the separate memtrack size.
1759     * @hide
1760     */
1761    public static native long getPss(int pid, long[] outUssSwapPss, long[] outMemtrack);
1762
1763    /** @hide */
1764    public static final int MEMINFO_TOTAL = 0;
1765    /** @hide */
1766    public static final int MEMINFO_FREE = 1;
1767    /** @hide */
1768    public static final int MEMINFO_BUFFERS = 2;
1769    /** @hide */
1770    public static final int MEMINFO_CACHED = 3;
1771    /** @hide */
1772    public static final int MEMINFO_SHMEM = 4;
1773    /** @hide */
1774    public static final int MEMINFO_SLAB = 5;
1775     /** @hide */
1776    public static final int MEMINFO_SLAB_RECLAIMABLE = 6;
1777     /** @hide */
1778    public static final int MEMINFO_SLAB_UNRECLAIMABLE = 7;
1779    /** @hide */
1780    public static final int MEMINFO_SWAP_TOTAL = 8;
1781    /** @hide */
1782    public static final int MEMINFO_SWAP_FREE = 9;
1783    /** @hide */
1784    public static final int MEMINFO_ZRAM_TOTAL = 10;
1785    /** @hide */
1786    public static final int MEMINFO_MAPPED = 11;
1787    /** @hide */
1788    public static final int MEMINFO_VM_ALLOC_USED = 12;
1789    /** @hide */
1790    public static final int MEMINFO_PAGE_TABLES = 13;
1791    /** @hide */
1792    public static final int MEMINFO_KERNEL_STACK = 14;
1793    /** @hide */
1794    public static final int MEMINFO_COUNT = 15;
1795
1796    /**
1797     * Retrieves /proc/meminfo.  outSizes is filled with fields
1798     * as defined by MEMINFO_* offsets.
1799     * @hide
1800     */
1801    public static native void getMemInfo(long[] outSizes);
1802
1803    /**
1804     * Establish an object allocation limit in the current thread.
1805     * This feature was never enabled in release builds.  The
1806     * allocation limits feature was removed in Honeycomb.  This
1807     * method exists for compatibility and always returns -1 and has
1808     * no effect.
1809     *
1810     * @deprecated This method is now obsolete.
1811     */
1812    @Deprecated
1813    public static int setAllocationLimit(int limit) {
1814        return -1;
1815    }
1816
1817    /**
1818     * Establish a global object allocation limit.  This feature was
1819     * never enabled in release builds.  The allocation limits feature
1820     * was removed in Honeycomb.  This method exists for compatibility
1821     * and always returns -1 and has no effect.
1822     *
1823     * @deprecated This method is now obsolete.
1824     */
1825    @Deprecated
1826    public static int setGlobalAllocationLimit(int limit) {
1827        return -1;
1828    }
1829
1830    /**
1831     * Dump a list of all currently loaded class to the log file.
1832     *
1833     * @param flags See constants above.
1834     */
1835    public static void printLoadedClasses(int flags) {
1836        VMDebug.printLoadedClasses(flags);
1837    }
1838
1839    /**
1840     * Get the number of loaded classes.
1841     * @return the number of loaded classes.
1842     */
1843    public static int getLoadedClassCount() {
1844        return VMDebug.getLoadedClassCount();
1845    }
1846
1847    /**
1848     * Dump "hprof" data to the specified file.  This may cause a GC.
1849     *
1850     * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
1851     * @throws UnsupportedOperationException if the VM was built without
1852     *         HPROF support.
1853     * @throws IOException if an error occurs while opening or writing files.
1854     */
1855    public static void dumpHprofData(String fileName) throws IOException {
1856        VMDebug.dumpHprofData(fileName);
1857    }
1858
1859    /**
1860     * Like dumpHprofData(String), but takes an already-opened
1861     * FileDescriptor to which the trace is written.  The file name is also
1862     * supplied simply for logging.  Makes a dup of the file descriptor.
1863     *
1864     * Primarily for use by the "am" shell command.
1865     *
1866     * @hide
1867     */
1868    public static void dumpHprofData(String fileName, FileDescriptor fd)
1869            throws IOException {
1870        VMDebug.dumpHprofData(fileName, fd);
1871    }
1872
1873    /**
1874     * Collect "hprof" and send it to DDMS.  This may cause a GC.
1875     *
1876     * @throws UnsupportedOperationException if the VM was built without
1877     *         HPROF support.
1878     * @hide
1879     */
1880    public static void dumpHprofDataDdms() {
1881        VMDebug.dumpHprofDataDdms();
1882    }
1883
1884    /**
1885     * Writes native heap data to the specified file descriptor.
1886     *
1887     * @hide
1888     */
1889    public static native void dumpNativeHeap(FileDescriptor fd);
1890
1891    /**
1892     * Writes malloc info data to the specified file descriptor.
1893     *
1894     * @hide
1895     */
1896    public static native void dumpNativeMallocInfo(FileDescriptor fd);
1897
1898    /**
1899      * Returns a count of the extant instances of a class.
1900     *
1901     * @hide
1902     */
1903    public static long countInstancesOfClass(Class cls) {
1904        return VMDebug.countInstancesOfClass(cls, true);
1905    }
1906
1907    /**
1908     * Returns the number of sent transactions from this process.
1909     * @return The number of sent transactions or -1 if it could not read t.
1910     */
1911    public static native int getBinderSentTransactions();
1912
1913    /**
1914     * Returns the number of received transactions from the binder driver.
1915     * @return The number of received transactions or -1 if it could not read the stats.
1916     */
1917    public static native int getBinderReceivedTransactions();
1918
1919    /**
1920     * Returns the number of active local Binder objects that exist in the
1921     * current process.
1922     */
1923    public static final native int getBinderLocalObjectCount();
1924
1925    /**
1926     * Returns the number of references to remote proxy Binder objects that
1927     * exist in the current process.
1928     */
1929    public static final native int getBinderProxyObjectCount();
1930
1931    /**
1932     * Returns the number of death notification links to Binder objects that
1933     * exist in the current process.
1934     */
1935    public static final native int getBinderDeathObjectCount();
1936
1937    /**
1938     * Primes the register map cache.
1939     *
1940     * Only works for classes in the bootstrap class loader.  Does not
1941     * cause classes to be loaded if they're not already present.
1942     *
1943     * The classAndMethodDesc argument is a concatentation of the VM-internal
1944     * class descriptor, method name, and method descriptor.  Examples:
1945     *     Landroid/os/Looper;.loop:()V
1946     *     Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V
1947     *
1948     * @param classAndMethodDesc the method to prepare
1949     *
1950     * @hide
1951     */
1952    public static final boolean cacheRegisterMap(String classAndMethodDesc) {
1953        return VMDebug.cacheRegisterMap(classAndMethodDesc);
1954    }
1955
1956    /**
1957     * Dumps the contents of VM reference tables (e.g. JNI locals and
1958     * globals) to the log file.
1959     *
1960     * @hide
1961     */
1962    public static final void dumpReferenceTables() {
1963        VMDebug.dumpReferenceTables();
1964    }
1965
1966    /**
1967     * API for gathering and querying instruction counts.
1968     *
1969     * Example usage:
1970     * <pre>
1971     *   Debug.InstructionCount icount = new Debug.InstructionCount();
1972     *   icount.resetAndStart();
1973     *    [... do lots of stuff ...]
1974     *   if (icount.collect()) {
1975     *       System.out.println("Total instructions executed: "
1976     *           + icount.globalTotal());
1977     *       System.out.println("Method invocations: "
1978     *           + icount.globalMethodInvocations());
1979     *   }
1980     * </pre>
1981     *
1982     * @deprecated Instruction counting is no longer supported.
1983     */
1984    @Deprecated
1985    public static class InstructionCount {
1986        public InstructionCount() {
1987        }
1988
1989        /**
1990         * Reset counters and ensure counts are running.  Counts may
1991         * have already been running.
1992         *
1993         * @return true if counting was started
1994         */
1995        public boolean resetAndStart() {
1996            return false;
1997        }
1998
1999        /**
2000         * Collect instruction counts.  May or may not stop the
2001         * counting process.
2002         */
2003        public boolean collect() {
2004            return false;
2005        }
2006
2007        /**
2008         * Return the total number of instructions executed globally (i.e. in
2009         * all threads).
2010         */
2011        public int globalTotal() {
2012            return 0;
2013        }
2014
2015        /**
2016         * Return the total number of method-invocation instructions
2017         * executed globally.
2018         */
2019        public int globalMethodInvocations() {
2020            return 0;
2021        }
2022    }
2023
2024    /**
2025     * A Map of typed debug properties.
2026     */
2027    private static final TypedProperties debugProperties;
2028
2029    /*
2030     * Load the debug properties from the standard files into debugProperties.
2031     */
2032    static {
2033        if (false) {
2034            final String TAG = "DebugProperties";
2035            final String[] files = { "/system/debug.prop", "/debug.prop", "/data/debug.prop" };
2036            final TypedProperties tp = new TypedProperties();
2037
2038            // Read the properties from each of the files, if present.
2039            for (String file : files) {
2040                Reader r;
2041                try {
2042                    r = new FileReader(file);
2043                } catch (FileNotFoundException ex) {
2044                    // It's ok if a file is missing.
2045                    continue;
2046                }
2047
2048                try {
2049                    tp.load(r);
2050                } catch (Exception ex) {
2051                    throw new RuntimeException("Problem loading " + file, ex);
2052                } finally {
2053                    try {
2054                        r.close();
2055                    } catch (IOException ex) {
2056                        // Ignore this error.
2057                    }
2058                }
2059            }
2060
2061            debugProperties = tp.isEmpty() ? null : tp;
2062        } else {
2063            debugProperties = null;
2064        }
2065    }
2066
2067
2068    /**
2069     * Returns true if the type of the field matches the specified class.
2070     * Handles the case where the class is, e.g., java.lang.Boolean, but
2071     * the field is of the primitive "boolean" type.  Also handles all of
2072     * the java.lang.Number subclasses.
2073     */
2074    private static boolean fieldTypeMatches(Field field, Class<?> cl) {
2075        Class<?> fieldClass = field.getType();
2076        if (fieldClass == cl) {
2077            return true;
2078        }
2079        Field primitiveTypeField;
2080        try {
2081            /* All of the classes we care about (Boolean, Integer, etc.)
2082             * have a Class field called "TYPE" that points to the corresponding
2083             * primitive class.
2084             */
2085            primitiveTypeField = cl.getField("TYPE");
2086        } catch (NoSuchFieldException ex) {
2087            return false;
2088        }
2089        try {
2090            return fieldClass == (Class<?>) primitiveTypeField.get(null);
2091        } catch (IllegalAccessException ex) {
2092            return false;
2093        }
2094    }
2095
2096
2097    /**
2098     * Looks up the property that corresponds to the field, and sets the field's value
2099     * if the types match.
2100     */
2101    private static void modifyFieldIfSet(final Field field, final TypedProperties properties,
2102                                         final String propertyName) {
2103        if (field.getType() == java.lang.String.class) {
2104            int stringInfo = properties.getStringInfo(propertyName);
2105            switch (stringInfo) {
2106                case TypedProperties.STRING_SET:
2107                    // Handle as usual below.
2108                    break;
2109                case TypedProperties.STRING_NULL:
2110                    try {
2111                        field.set(null, null);  // null object for static fields; null string
2112                    } catch (IllegalAccessException ex) {
2113                        throw new IllegalArgumentException(
2114                            "Cannot set field for " + propertyName, ex);
2115                    }
2116                    return;
2117                case TypedProperties.STRING_NOT_SET:
2118                    return;
2119                case TypedProperties.STRING_TYPE_MISMATCH:
2120                    throw new IllegalArgumentException(
2121                        "Type of " + propertyName + " " +
2122                        " does not match field type (" + field.getType() + ")");
2123                default:
2124                    throw new IllegalStateException(
2125                        "Unexpected getStringInfo(" + propertyName + ") return value " +
2126                        stringInfo);
2127            }
2128        }
2129        Object value = properties.get(propertyName);
2130        if (value != null) {
2131            if (!fieldTypeMatches(field, value.getClass())) {
2132                throw new IllegalArgumentException(
2133                    "Type of " + propertyName + " (" + value.getClass() + ") " +
2134                    " does not match field type (" + field.getType() + ")");
2135            }
2136            try {
2137                field.set(null, value);  // null object for static fields
2138            } catch (IllegalAccessException ex) {
2139                throw new IllegalArgumentException(
2140                    "Cannot set field for " + propertyName, ex);
2141            }
2142        }
2143    }
2144
2145
2146    /**
2147     * Equivalent to <code>setFieldsOn(cl, false)</code>.
2148     *
2149     * @see #setFieldsOn(Class, boolean)
2150     *
2151     * @hide
2152     */
2153    public static void setFieldsOn(Class<?> cl) {
2154        setFieldsOn(cl, false);
2155    }
2156
2157    /**
2158     * Reflectively sets static fields of a class based on internal debugging
2159     * properties.  This method is a no-op if false is
2160     * false.
2161     * <p>
2162     * <strong>NOTE TO APPLICATION DEVELOPERS</strong>: false will
2163     * always be false in release builds.  This API is typically only useful
2164     * for platform developers.
2165     * </p>
2166     * Class setup: define a class whose only fields are non-final, static
2167     * primitive types (except for "char") or Strings.  In a static block
2168     * after the field definitions/initializations, pass the class to
2169     * this method, Debug.setFieldsOn(). Example:
2170     * <pre>
2171     * package com.example;
2172     *
2173     * import android.os.Debug;
2174     *
2175     * public class MyDebugVars {
2176     *    public static String s = "a string";
2177     *    public static String s2 = "second string";
2178     *    public static String ns = null;
2179     *    public static boolean b = false;
2180     *    public static int i = 5;
2181     *    @Debug.DebugProperty
2182     *    public static float f = 0.1f;
2183     *    @@Debug.DebugProperty
2184     *    public static double d = 0.5d;
2185     *
2186     *    // This MUST appear AFTER all fields are defined and initialized!
2187     *    static {
2188     *        // Sets all the fields
2189     *        Debug.setFieldsOn(MyDebugVars.class);
2190     *
2191     *        // Sets only the fields annotated with @Debug.DebugProperty
2192     *        // Debug.setFieldsOn(MyDebugVars.class, true);
2193     *    }
2194     * }
2195     * </pre>
2196     * setFieldsOn() may override the value of any field in the class based
2197     * on internal properties that are fixed at boot time.
2198     * <p>
2199     * These properties are only set during platform debugging, and are not
2200     * meant to be used as a general-purpose properties store.
2201     *
2202     * {@hide}
2203     *
2204     * @param cl The class to (possibly) modify
2205     * @param partial If false, sets all static fields, otherwise, only set
2206     *        fields with the {@link android.os.Debug.DebugProperty}
2207     *        annotation
2208     * @throws IllegalArgumentException if any fields are final or non-static,
2209     *         or if the type of the field does not match the type of
2210     *         the internal debugging property value.
2211     */
2212    public static void setFieldsOn(Class<?> cl, boolean partial) {
2213        if (false) {
2214            if (debugProperties != null) {
2215                /* Only look for fields declared directly by the class,
2216                 * so we don't mysteriously change static fields in superclasses.
2217                 */
2218                for (Field field : cl.getDeclaredFields()) {
2219                    if (!partial || field.getAnnotation(DebugProperty.class) != null) {
2220                        final String propertyName = cl.getName() + "." + field.getName();
2221                        boolean isStatic = Modifier.isStatic(field.getModifiers());
2222                        boolean isFinal = Modifier.isFinal(field.getModifiers());
2223
2224                        if (!isStatic || isFinal) {
2225                            throw new IllegalArgumentException(propertyName +
2226                                " must be static and non-final");
2227                        }
2228                        modifyFieldIfSet(field, debugProperties, propertyName);
2229                    }
2230                }
2231            }
2232        } else {
2233            Log.wtf(TAG,
2234                  "setFieldsOn(" + (cl == null ? "null" : cl.getName()) +
2235                  ") called in non-DEBUG build");
2236        }
2237    }
2238
2239    /**
2240     * Annotation to put on fields you want to set with
2241     * {@link Debug#setFieldsOn(Class, boolean)}.
2242     *
2243     * @hide
2244     */
2245    @Target({ ElementType.FIELD })
2246    @Retention(RetentionPolicy.RUNTIME)
2247    public @interface DebugProperty {
2248    }
2249
2250    /**
2251     * Get a debugging dump of a system service by name.
2252     *
2253     * <p>Most services require the caller to hold android.permission.DUMP.
2254     *
2255     * @param name of the service to dump
2256     * @param fd to write dump output to (usually an output log file)
2257     * @param args to pass to the service's dump method, may be null
2258     * @return true if the service was dumped successfully, false if
2259     *     the service could not be found or had an error while dumping
2260     */
2261    public static boolean dumpService(String name, FileDescriptor fd, String[] args) {
2262        IBinder service = ServiceManager.getService(name);
2263        if (service == null) {
2264            Log.e(TAG, "Can't find service to dump: " + name);
2265            return false;
2266        }
2267
2268        try {
2269            service.dump(fd, args);
2270            return true;
2271        } catch (RemoteException e) {
2272            Log.e(TAG, "Can't dump service: " + name, e);
2273            return false;
2274        }
2275    }
2276
2277    /**
2278     * Append the Java stack traces of a given native process to a specified file.
2279     *
2280     * @param pid pid to dump.
2281     * @param file path of file to append dump to.
2282     * @param timeoutSecs time to wait in seconds, or 0 to wait forever.
2283     * @hide
2284     */
2285    public static native boolean dumpJavaBacktraceToFileTimeout(int pid, String file,
2286                                                                int timeoutSecs);
2287
2288    /**
2289     * Append the native stack traces of a given process to a specified file.
2290     *
2291     * @param pid pid to dump.
2292     * @param file path of file to append dump to.
2293     * @param timeoutSecs time to wait in seconds, or 0 to wait forever.
2294     * @hide
2295     */
2296    public static native boolean dumpNativeBacktraceToFileTimeout(int pid, String file,
2297                                                                  int timeoutSecs);
2298
2299    /**
2300     * Get description of unreachable native memory.
2301     * @param limit the number of leaks to provide info on, 0 to only get a summary.
2302     * @param contents true to include a hex dump of the contents of unreachable memory.
2303     * @return the String containing a description of unreachable memory.
2304     * @hide */
2305    public static native String getUnreachableMemory(int limit, boolean contents);
2306
2307    /**
2308     * Return a String describing the calling method and location at a particular stack depth.
2309     * @param callStack the Thread stack
2310     * @param depth the depth of stack to return information for.
2311     * @return the String describing the caller at that depth.
2312     */
2313    private static String getCaller(StackTraceElement callStack[], int depth) {
2314        // callStack[4] is the caller of the method that called getCallers()
2315        if (4 + depth >= callStack.length) {
2316            return "<bottom of call stack>";
2317        }
2318        StackTraceElement caller = callStack[4 + depth];
2319        return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
2320    }
2321
2322    /**
2323     * Return a string consisting of methods and locations at multiple call stack levels.
2324     * @param depth the number of levels to return, starting with the immediate caller.
2325     * @return a string describing the call stack.
2326     * {@hide}
2327     */
2328    public static String getCallers(final int depth) {
2329        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
2330        StringBuffer sb = new StringBuffer();
2331        for (int i = 0; i < depth; i++) {
2332            sb.append(getCaller(callStack, i)).append(" ");
2333        }
2334        return sb.toString();
2335    }
2336
2337    /**
2338     * Return a string consisting of methods and locations at multiple call stack levels.
2339     * @param depth the number of levels to return, starting with the immediate caller.
2340     * @return a string describing the call stack.
2341     * {@hide}
2342     */
2343    public static String getCallers(final int start, int depth) {
2344        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
2345        StringBuffer sb = new StringBuffer();
2346        depth += start;
2347        for (int i = start; i < depth; i++) {
2348            sb.append(getCaller(callStack, i)).append(" ");
2349        }
2350        return sb.toString();
2351    }
2352
2353    /**
2354     * Like {@link #getCallers(int)}, but each location is append to the string
2355     * as a new line with <var>linePrefix</var> in front of it.
2356     * @param depth the number of levels to return, starting with the immediate caller.
2357     * @param linePrefix prefix to put in front of each location.
2358     * @return a string describing the call stack.
2359     * {@hide}
2360     */
2361    public static String getCallers(final int depth, String linePrefix) {
2362        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
2363        StringBuffer sb = new StringBuffer();
2364        for (int i = 0; i < depth; i++) {
2365            sb.append(linePrefix).append(getCaller(callStack, i)).append("\n");
2366        }
2367        return sb.toString();
2368    }
2369
2370    /**
2371     * @return a String describing the immediate caller of the calling method.
2372     * {@hide}
2373     */
2374    public static String getCaller() {
2375        return getCaller(Thread.currentThread().getStackTrace(), 0);
2376    }
2377
2378    /**
2379     * Attach a library as a jvmti agent to the current runtime, with the given classloader
2380     * determining the library search path.
2381     * <p>
2382     * Note: agents may only be attached to debuggable apps. Otherwise, this function will
2383     * throw a SecurityException.
2384     *
2385     * @param library the library containing the agent.
2386     * @param options the options passed to the agent.
2387     * @param classLoader the classloader determining the library search path.
2388     *
2389     * @throws IOException if the agent could not be attached.
2390     * @throws SecurityException if the app is not debuggable.
2391     */
2392    public static void attachJvmtiAgent(@NonNull String library, @Nullable String options,
2393            @Nullable ClassLoader classLoader) throws IOException {
2394        Preconditions.checkNotNull(library);
2395        Preconditions.checkArgument(!library.contains("="));
2396
2397        if (options == null) {
2398            VMDebug.attachAgent(library, classLoader);
2399        } else {
2400            VMDebug.attachAgent(library + "=" + options, classLoader);
2401        }
2402    }
2403}
2404