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