StrictMode.java revision bfb191998eba2ebc710ff9eb59480b10909ba4c9
1438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/* 2438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Copyright (C) 2010 The Android Open Source Project 3438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 4438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 5438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * you may not use this file except in compliance with the License. 6438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * You may obtain a copy of the License at 7438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 8438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * http://www.apache.org/licenses/LICENSE-2.0 9438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 10438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Unless required by applicable law or agreed to in writing, software 11438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * distributed under the License is distributed on an "AS IS" BASIS, 12438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * See the License for the specific language governing permissions and 14438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * limitations under the License. 15438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 16438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpackage android.os; 17438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 18599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrickimport android.animation.ValueAnimator; 19438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ActivityManagerNative; 20bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.app.ActivityThread; 21438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ApplicationErrorReport; 22bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.content.Intent; 23438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Log; 24cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrickimport android.util.Printer; 25438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 26438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit; 27438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 28438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport dalvik.system.BlockGuard; 29438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.PrintWriter; 315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.StringWriter; 325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.util.ArrayList; 3346d42387464a651268648659e91d022566d4844cBrad Fitzpatrickimport java.util.HashMap; 3446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 35438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/** 3632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>StrictMode is a developer tool which detects things you might be 3732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * doing by accident and brings them to your attention so you can fix 3832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * them. 3915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 4015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or 4115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * network access on the application's main thread, where UI 4215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * operations are received and animations take place. Keeping disk 4315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and network operations off the main thread makes for much smoother, 449fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * more responsive applications. By keeping your application's main thread 459fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * responsive, you also prevent 469fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * <a href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a> 479fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * from being shown to users. 4815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 4915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is 5015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that 5115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * memory with very limited concurrency. It's often the case that 5215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be 5315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background 5415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from other processes. If possible, it's best to assume that such 5515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p> 5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your 5815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or 5915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's 6015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method: 6115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 6215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre> 6315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() { 6415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * if (DEVELOPER_MODE) { 6532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}() 6632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskReads() 6732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskWrites() 6832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectNetwork() // or .detectAll() for all detectable problems 6932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 7032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 7132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}() 7262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * .detectLeakedSqlLiteObjects() 7332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 7432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyDeath() 7532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 7615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 7715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * super.onCreate(); 7815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 7915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * </pre> 8015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 8132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can decide what should happen when a violation is detected. 8232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * For example, using {@link ThreadPolicy.Builder#penaltyLog} you can 8332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * watch the output of <code>adb logcat</code> while you use your 8432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * application to see the violations as they happen. 8515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 8615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are 8715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler}, 8815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc. 8915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds. In particular, 9032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * many cases of disk access are often necessary during the normal activity lifecycle. Use 9132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode to find things you did by accident. Network requests on the UI thread 9215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * are almost always a problem, though. 9315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 9415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not 9515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses. While it does 9615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing 9715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best 9815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * effort mechanism. Notably, disk or network access from JNI calls 9915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * won't necessarily trigger it. Future versions of Android may catch 10015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode 10115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * enabled in shipping applications on the Android Market. 102438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 103438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpublic final class StrictMode { 104438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static final String TAG = "StrictMode"; 1055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static final boolean LOG_V = false; 106438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 10746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 10846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 10946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 11046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 11146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 11246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 113191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // How many offending stacks to keep track of (and time) per loop 114191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // of the Looper. 115191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final int MAX_OFFENSES_PER_LOOP = 10; 116191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 11732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Thread-policy: 118438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 11915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 12032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 12115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 12232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy 12315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 12415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 12532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 12615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 12732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy 12815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 12915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 13032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 13115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 13232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy 133438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 13432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Process-policy: 135438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 136438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 13732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Note, a "VM_" bit, not thread. 13832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 13932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 14032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy 14132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 14232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 14332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 144438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 145438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 146438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 14732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Used for both process and thread policy: 14832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 149438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 15032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 151438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 152438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 153438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 154438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 155b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death on any detected violation. 156b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 15732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 158438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 159438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DEATH = 0x40; 160438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 161438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 162b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death just for detected network usage. 163b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 164b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 165b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 166b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final int PENALTY_DEATH_ON_NETWORK = 0x200; 167b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 168b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 16932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 170438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 171438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DROPBOX = 0x80; 172438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 173727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 174727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 175727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * bits and signals that we're in a Binder call and we should 176727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 177727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 178727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * in the originating process. 179727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 180703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 181703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * 182727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @hide 183727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 184727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 185727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 18632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 18771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * Mask of all the penalty bits. 18871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick */ 18971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick private static final int PENALTY_MASK = 190b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | 191b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_DEATH_ON_NETWORK; 19271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 19371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /** 19432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The current VmPolicy in effect. 19532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 19632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static volatile int sVmPolicyMask = 0; 19732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 19832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private StrictMode() {} 19932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 20032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 20132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to a certain thread. 20232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 20332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy 20432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can be retrieved with {@link #getThreadPolicy}. 20532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 20632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note that multiple penalties may be provided and they're run 20732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * in order from least to most severe (logging before process 20832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * death, for example). There's currently no mechanism to choose 20932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * different penalties for different detected actions. 21032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 21132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class ThreadPolicy { 21232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 21332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 21432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 21532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final ThreadPolicy LAX = new ThreadPolicy(0); 21632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 21732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 21832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 21932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private ThreadPolicy(int mask) { 22032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 22132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 22232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 22332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 22432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 22532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.ThreadPolicy; mask=" + mask + "]"; 22632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 22732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 22832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 22932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates ThreadPolicy instances. Methods whose names start 23032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 23132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 23232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 23332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 23432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 23532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 23632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 23732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 23832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 23932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 24032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 24132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 24232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 24332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 24432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 24532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 24632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 24732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 24832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask = 0; 24932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 25032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 25132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create a Builder that detects nothing and has no 25232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations. (but note that {@link #build} will default 25332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to enabling {@link #penaltyLog} if no other penalties 25432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are specified) 25532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 25632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder() { 25732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = 0; 25832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 25932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 26032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 26132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Initialize a Builder from an existing ThreadPolicy. 26232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 26332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder(ThreadPolicy policy) { 26432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = policy.mask; 26532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 26632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 26732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 26832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 26932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 27032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this includes network and 27132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * disk operations but will likely expand in future releases. 27232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 27332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 27432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 27532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 27732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 27832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable the detection of everything. 27932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 28032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitAll() { 28132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 28232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 28332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 28432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of network operations. 28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 28732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectNetwork() { 28832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_NETWORK); 28932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 29032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of network operations. 29332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitNetwork() { 29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_NETWORK); 29632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk reads. 30032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskReads() { 30232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_READ); 30332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk reads. 30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskReads() { 30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_READ); 31032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk writes. 31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskWrites() { 31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE); 31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk writes. 32132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskWrites() { 32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE); 32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 32532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Show an annoying dialog to the developer on detected 32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations, rate-limited to be only a little annoying. 32932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDialog() { 33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DIALOG); 33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 33532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crash the whole process on violation. This penalty runs at 33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so you'll still get 33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * see logging or other violations before the process dies. 338b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 339b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>Unlike {@link #penaltyDeathOnNetwork}, this applies 340b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * to disk reads, disk writes, and network usage if their 341b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * corresponding detect flags are set. 34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 348b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Crash the whole process on any network usage. Unlike 349b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * {@link #penaltyDeath}, this penalty runs 350b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <em>before</em> anything else. You must still have 351b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * called {@link #detectNetwork} to enable this. 352b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 353b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>In the Honeycomb or later SDKs, this is on by default. 354b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 355b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public Builder penaltyDeathOnNetwork() { 356b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return enable(PENALTY_DEATH_ON_NETWORK); 357b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 358b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 359b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 36032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 36132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 36232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 36332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 36432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 36532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 36632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 36732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 36832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 36932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 37032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 37132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 37232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 37332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 37432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 37832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 37932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder disable(int bit) { 38232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask &= ~bit; 38332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 38432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 38732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the ThreadPolicy instance. 38832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 38932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 39032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 39132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 39232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 39332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ThreadPolicy build() { 39432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 39532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 39632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 39732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 39832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 39932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 40032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 40132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(mMask); 40232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 40332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 40432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 40532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 40632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 40732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to all threads in the virtual machine's process. 40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setVmPolicy}. 41032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 41132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class VmPolicy { 41232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 41332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 41432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 41532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final VmPolicy LAX = new VmPolicy(0); 41632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 41832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private VmPolicy(int mask) { 42032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 42132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 42232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 42332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 42432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 42532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.VmPolicy; mask=" + mask + "]"; 42632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 42732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 42832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 42932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates {@link VmPolicy} instances. Methods whose names start 43032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 43132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 43232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 43332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 43432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 43532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 43632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 44332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 44432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 44532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 44632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 44732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 44832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask; 44932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 45032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 45132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 45232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 45332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this only includes 45432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite cursor leaks but will likely expand in future 45532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * releases. 45632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 45732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 45832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 45932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 46032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 46132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 46232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect when an 46332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link android.database.sqlite.SQLiteCursor} or other 46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite object is finalized without having been closed. 46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 46632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You always want to explicitly close your SQLite 46732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * cursors to avoid unnecessary database contention and 46832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * temporary memory leaks. 46932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 47032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectLeakedSqlLiteObjects() { 47132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 47232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 47332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 47432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 47532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crashes the whole process on violation. This penalty runs at 47632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so yo you'll still get 47732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * your logging or other violations before the process dies. 47832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 47932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 48032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 48132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 48332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 48432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 48532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 48632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 48732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 48832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 49032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 49132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 49232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 49332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 49432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 49532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 49632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 49732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 49832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 49932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 50232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 50632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the VmPolicy instance. 50732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 50932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 51232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public VmPolicy build() { 51332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 51432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 51532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 51632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 51732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 51832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 51932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(mMask); 52132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 524438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 525438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 5265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Log of strict mode violation stack traces that have occurred 5275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * during a Binder call, to be serialized back later to the caller 5285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 5295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * choose how to react. 5305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 531cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 532cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 533cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 534703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 535703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // checking whether there are any violations or not in 536703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // hasGatheredViolations() below. 537703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return null; 5385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick }; 5405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 5415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 54232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions on the current thread should 54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * be detected, as well as the penalty if such actions occur. 54415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 54532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Internally this sets a thread-local variable which is 54615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 54715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * catch violations when a system service or another process 54815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * accesses the disk or network on your behalf. 549438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 55032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 551438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 55232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setThreadPolicy(final ThreadPolicy policy) { 55332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(policy.mask); 55432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 55532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 55632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static void setThreadPolicyMask(final int policyMask) { 557727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // In addition to the Java-level thread-local in Dalvik's 558727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // BlockGuard, we also need to keep a native thread-local in 559727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 560727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // even across native-only processes. The two are kept in 561727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 562727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(policyMask); 563727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 564727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // And set the Android native version... 565727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 566727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 567727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 568727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 569727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 57046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (policyMask == 0) { 57146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 57246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 57346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 574438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 575438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 576438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask)); 577438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 578438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy; 579438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick androidPolicy.setPolicyMask(policyMask); 580438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 581438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 582438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 5835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { 5845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 58532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_NETWORK); 5865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 5895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { 5905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 59132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_READ); 5925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 5955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { 5965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 59732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_WRITE); 5985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 601438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 60215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 603438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 60432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled 60532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 60632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 607438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 60832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static int getThreadPolicyMask() { 609438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 610438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 611438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 6125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 61332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Returns the current thread's policy. 61432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 61532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy getThreadPolicy() { 61632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(getThreadPolicyMask()); 61732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 61832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 61932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 62032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 62132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 62232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit both disk reads & writes, and sets the new policy 62332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 62432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 62597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 62632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to {@link #setThreadPolicy} to 62732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * restore the policy at the end of a block 62897461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 62932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskWrites() { 63032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 63132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ); 63232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 63332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 63497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 63532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 63697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 63797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 63897461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 63932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 64032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 64132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit disk reads, and sets the new policy 64232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 64332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 64497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 64532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to setThreadPolicy to 64697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 64797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 64832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskReads() { 64932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 65032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ); 65132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 65232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 65397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 65432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 65597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 65697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 65797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 65850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * Enable DropBox logging for debug phone builds. 65950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * 66050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * @hide 66150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick */ 66250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 66350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 66450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 66550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick if ("user".equals(Build.TYPE)) { 66650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return false; 66750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 66832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.setThreadPolicyMask( 66932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_DISK_WRITE | 67032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_DISK_READ | 67132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_NETWORK | 67250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.PENALTY_DROPBOX); 67332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | 67432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.PENALTY_DROPBOX | 67532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.PENALTY_LOG; 67650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return true; 67750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 67850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 67950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick /** 680b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Used by the framework to make network usage on the main 681b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * thread a fatal error. 682b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 683b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 684b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 685b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static void enableDeathOnNetwork() { 686b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int oldPolicy = getThreadPolicyMask(); 687b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int newPolicy = oldPolicy | DETECT_NETWORK | PENALTY_DEATH_ON_NETWORK; 688b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick setThreadPolicyMask(newPolicy); 689b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 690b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 691b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 6925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 6935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 6945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 6955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 6965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Input is of form "policy=137 violation=64" 6975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 6985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 6995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 7005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 7015b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 7025b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 7035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 7045b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7065b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 7075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (spaceIndex == -1) { 7085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 7115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 7125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 7135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 7145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 7195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 7205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 7215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 7225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null) { 7235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 7265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (violationIndex == -1) { 7275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String violationString = message.substring(violationIndex + 10); 7305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 7315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 7325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 7335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 737191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 738191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 739191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 740191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return new ArrayList<ViolationInfo>(); 741191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 742191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick }; 743191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 744191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static boolean tooManyViolationsThisLoop() { 745191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; 746191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 747191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 748438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 749438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private int mPolicyMask; 75046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 75146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 75246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // last violation. No locking needed, as this is only 75346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // accessed by the same thread. 75446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); 755438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 756438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 757438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 758438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 759438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 7605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick @Override 7615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public String toString() { 7625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 7635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 765438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 766438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public int getPolicyMask() { 767438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mPolicyMask; 768438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 769438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 770438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 771438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onWriteToDisk() { 77232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { 773438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 774438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 775191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 776191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 777191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 778cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 779cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 780cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 781438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 782438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 783438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 784438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onReadFromDisk() { 78532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_READ) == 0) { 786438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 787438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 788191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 789191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 790191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 791cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 792cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 793cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 794438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 795438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 796438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 797438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onNetwork() { 79832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_NETWORK) == 0) { 799438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 800438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 801b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) { 802b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick throw new NetworkOnMainThreadException(); 803b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 804191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 805191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 806191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 807cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 808cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 809cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 810438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 811438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 812438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void setPolicyMask(int policyMask) { 813438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 814438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 815438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 8165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 8175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 8185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 8195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 8205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 8215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 822cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 823cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 824cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolationWithTimingAttempt(info); 825cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 826438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 827cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 828cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 829cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // to measure with. We measure from the time of violation 830cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // until the time the looper is idle again (right before 831cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // the next epoll_wait) 832cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 833438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Looper looper = Looper.myLooper(); 834cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 835cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Without a Looper, we're unable to time how long the 836cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // violation takes place. This case should be rare, as 837cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // most users will care about timing violations that 838cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // happen on their main UI thread. Note that this case is 839cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // also hit when a violation takes place in a Binder 840cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 841cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // of the violation is computed by the ultimate caller and 842cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // its Looper, if any. 843cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 844cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // go into this immediate mode? 845438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (looper == null) { 846cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 847cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(info); 848cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 849438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 850438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 851cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick MessageQueue queue = Looper.myQueue(); 852cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 853191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() >= MAX_OFFENSES_PER_LOOP) { 854cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 855cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 856cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 857cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.add(info); 858cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() > 1) { 859cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // There's already been a violation this loop, so we've already 860cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // registered an idle handler to process the list of violations 861cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // at the end of this Looper's loop. 862cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 863cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 864cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 865cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick queue.addIdleHandler(new MessageQueue.IdleHandler() { 866cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public boolean queueIdle() { 867cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 868cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 869cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo v = records.get(n); 870cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.violationNumThisLoop = n + 1; 871cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.durationMillis = 872cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 873cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(v); 874cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 875cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.clear(); 876cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return false; // remove this idle handler from the array 877cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 878cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }); 8795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 880438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 8815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Note: It's possible (even quite likely) that the 8825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread-local policy mask has changed from the time the 8835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation fired and now (after the violating code ran) due 8845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to people who push/pop temporary policy in regions of code, 8855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // hence the policy being passed around. 886cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolation(final ViolationInfo info) { 887cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 888cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 8895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 8905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 891438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 892cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 89346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 894cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 895cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 896703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 897cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 898703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(violations); 899703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else if (violations.size() >= 5) { 9005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 9015b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9025b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 903cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 904cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 9055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Duplicate. Don't log. 9065b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 909cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations.add(info); 910727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return; 911727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 912727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 91346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 914cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Integer crashFingerprint = info.crashInfo.stackTrace.hashCode(); 91546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long lastViolationTime = 0; 91646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (mLastViolationTime.containsKey(crashFingerprint)) { 91746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick lastViolationTime = mLastViolationTime.get(crashFingerprint); 91846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 91946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 92046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 92146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 92246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 92346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 924cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 92546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 926cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.durationMillis != -1) { 9275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 928cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 929438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 930cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 931438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 932438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 933438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 93471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // The violationMaskSubset, passed to ActivityManager, is a 93546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 93646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // only the bit violated and penalty bits to be executed 93746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // by the ActivityManagerService remaining set. 938cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 93946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 940cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 94146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 942cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 94346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 94446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 945cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 946cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 94746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 94846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 949cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 950cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 951cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 95271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick final int violationMaskSubsetFinal = violationMaskSubset; 95332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 95471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 95571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick final boolean justDropBox = (info.policy & PENALTY_MASK) == PENALTY_DROPBOX; 95671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick if (justDropBox) { 95771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // If all we're going to ask the activity manager 95871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // to do is dropbox it (the common case during 95971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // platform development), we can avoid doing this 96071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // call synchronously which Binder data suggests 96171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // isn't always super fast, despite the implementation 96271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // in the ActivityManager trying to be mostly async. 96371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick new Thread("callActivityManagerForStrictModeDropbox") { 96471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick public void run() { 96571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 96671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick try { 96771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick ActivityManagerNative.getDefault(). 96871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick handleApplicationStrictModeViolation( 96971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick RuntimeInit.getApplicationObject(), 97071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick violationMaskSubsetFinal, 97171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick info); 97271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } catch (RemoteException e) { 97371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick Log.e(TAG, "RemoteException handling StrictMode violation", e); 97471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 97571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 97671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick }.start(); 97771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick return; 97871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 97971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 98071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // Normal synchronous call to the ActivityManager. 981438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 982727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 983727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 984727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 985727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // We restore the current policy below, in the finally block. 98632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 987727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 988438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 989438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 990cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 991cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 992438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (RemoteException e) { 99346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 994727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } finally { 995727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Restore the policy. 99632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 997438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 998438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 999438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1000cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 1001438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); 1002438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Process.killProcess(Process.myPid()); 1003438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.exit(10); 1004438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1005438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1006438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1007727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1008727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 10095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 10105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 10115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 1012703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return gatheredViolations.get() != null; 1013703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1014703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1015703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1016703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 1017703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 1018703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Binder call on this thread. 1019703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 1020703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 1021703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 10225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 10245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 102532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions in the VM process (on any 102632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * thread) should be detected, as well as the penalty if such 102732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * actions occur. 102832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 102932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 103032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 103132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setVmPolicy(final VmPolicy policy) { 103232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick sVmPolicyMask = policy.mask; 103332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 103432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 103532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 103632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Gets the current VM policy. 103732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 103832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static VmPolicy getVmPolicy() { 103932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(sVmPolicyMask); 104032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 104132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 104232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 104362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * Enable the recommended StrictMode defaults, with violations just being logged. 104462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * 104562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * <p>This catches disk and network access on the main thread, as 104662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * well as leaked SQLite cursors. This is simply a wrapper around 104762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * {@link #setVmPolicy} and {@link #setThreadPolicy}. 104862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick */ 104962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick public static void enableDefaults() { 105062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 105162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectAll() 105262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 105362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 105462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 105562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectLeakedSqlLiteObjects() 105662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 105762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 105862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 105962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick 106062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 106132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 106232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 106332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static boolean vmSqliteObjectLeaksEnabled() { 106432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0; 106532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 106632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 106732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 106832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 106932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 107032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void onSqliteObjectLeaked(String message, Throwable originStack) { 107132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_LOG) != 0) { 107232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, message, originStack); 107332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 107432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 107532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_DROPBOX) != 0) { 107632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); 107732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 107832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 107932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // subset of the original StrictMode policy bitmask, with 108032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // only the bit violated and penalty bits to be executed 108132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // by the ActivityManagerService remaining set. 108232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS; 108332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 108432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick try { 108532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 108632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 108732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 108832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // We restore the current policy below, in the finally block. 108932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 109032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 109132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 109232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick RuntimeInit.getApplicationObject(), 109332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick violationMaskSubset, 109432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick info); 109532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } catch (RemoteException e) { 109632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 109732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } finally { 109832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Restore the policy. 109932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 110032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 110132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 110232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 110332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_DEATH) != 0) { 110432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down."); 110532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Process.killProcess(Process.myPid()); 110632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.exit(10); 110732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 110832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 110932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 111032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 11115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 11125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 11135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 1114cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1115703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1116703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(0); 1117703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else { 1118703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(violations.size()); 1119703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 1120703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 1121703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1122703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 1123703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 11245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1125703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 11265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 11275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class LogStackTrace extends Exception {} 11295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 11315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 11325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * we here read back all the encoded violations. 11335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 11345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 11355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Our own stack trace to append 11365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StringWriter sw = new StringWriter(); 1137cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new LogStackTrace().printStackTrace(new PrintWriter(sw)); 11385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String ourStack = sw.toString(); 11395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 114032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int policyMask = getThreadPolicyMask(); 1141cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 11425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int numViolations = p.readInt(); 11445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 11455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 1146cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 1147cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 11485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 11495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 1150cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 11515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 11525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 11535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 11545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1156727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Called from android_util_Binder.cpp's 1157727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 1158727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 1159727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 1160727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 1161727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * thread-local policy value. 1162727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 1163727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 1164727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 1165727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1166cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1167cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1168cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 1169cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * to report violations that happened during a cross-process call. 1170cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1171cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @hide 1172cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1173cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static class ViolationInfo { 1174cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1175cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Stack and other stuff info. 1176cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1177cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 1178cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1179cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1180cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The strict mode policy mask at the time of violation. 1181cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1182cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final int policy; 1183cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1184cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1185cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 1186cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * not known. 1187cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1188cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int durationMillis = -1; 1189cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1190cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1191599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick * The number of animations currently running. 1192599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick */ 1193599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick public int numAnimationsRunning = 0; 1194599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick 1195599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick /** 1196cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Which violation number this was (1-based) since the last Looper loop, 1197cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 1198cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 1199cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * thread. 1200cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1201cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int violationNumThisLoop; 1202cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1203cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1204cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 1205cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * violation occurred. 1206cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1207cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public long violationUptimeMillis; 1208cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1209cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1210bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * The action of the Intent being broadcast to somebody's onReceive 1211bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * on this thread right now, or null. 1212bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick */ 1213bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick public String broadcastIntentAction; 1214bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick 1215bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick /** 1216cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 1217cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1218cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo() { 1219cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = null; 1220cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = 0; 1221cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1222cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1223cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1224cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 1225cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1226cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 1227cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 1228cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = SystemClock.uptimeMillis(); 1229cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this.policy = policy; 1230599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount(); 1231bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast(); 1232bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntent != null) { 1233bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = broadcastIntent.getAction(); 1234bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1235cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1236cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1237cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1238cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1239cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1240cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in) { 1241cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this(in, false); 1242cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1243cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1244cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1245cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1246cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1247cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @param unsetGatheringBit if true, the caller is the root caller 1248cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * and the gathering penalty should be removed. 1249cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1250cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 1251cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 1252cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int rawPolicy = in.readInt(); 1253cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (unsetGatheringBit) { 1254cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 1255cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } else { 1256cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy; 1257cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1258cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick durationMillis = in.readInt(); 1259cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationNumThisLoop = in.readInt(); 1260599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick numAnimationsRunning = in.readInt(); 1261cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = in.readLong(); 1262bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = in.readString(); 1263cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1264cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1265cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1266cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 1267cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1268cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 1269cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 1270cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(policy); 1271cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(durationMillis); 1272cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 1273599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick dest.writeInt(numAnimationsRunning); 1274cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 1275bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick dest.writeString(broadcastIntentAction); 1276cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1277cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1278cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1279cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1280cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Dump a ViolationInfo instance to a Printer. 1281cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1282cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void dump(Printer pw, String prefix) { 1283cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.dump(pw, prefix); 1284cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 1285cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (durationMillis != -1) { 1286cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "durationMillis: " + durationMillis); 1287cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1288cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationNumThisLoop != 0) { 1289cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 1290cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1291599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick if (numAnimationsRunning != 0) { 1292599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick pw.println(prefix + "numAnimationsRunning: " + numAnimationsRunning); 1293599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick } 1294cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 1295bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntentAction != null) { 1296bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction); 1297bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1298cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1299cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1300cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1301438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick} 1302