StrictMode.java revision 320274c5f17057a3a823fed50b7027cbd46fc025
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.app.ActivityManagerNative; 19438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ApplicationErrorReport; 20bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.util.Log; 21438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Printer; 22bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick 23438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit; 24cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 25cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrickimport dalvik.system.BlockGuard; 266804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 27438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport java.io.PrintWriter; 28438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport java.io.StringWriter; 29438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport java.util.ArrayList; 30438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport java.util.HashMap; 31fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 32438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/** 335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * <p>StrictMode is a developer tool which detects things you might be 345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * doing by accident and brings them to your attention so you can fix 355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * them. 3646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick * 37bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or 3846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick * network access on the application's main thread, where UI 39438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * operations are received and animations take place. Keeping disk 4032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * and network operations off the main thread makes for much smoother, 4132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * more responsive applications. By keeping your application's main thread 4232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * responsive, you also prevent 4315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <a href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a> 4415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from being shown to users. 4515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 4615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is 4715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that 489fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * memory with very limited concurrency. It's often the case that 499fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be 509fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background 519fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * from other processes. If possible, it's best to assume that such 5215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p> 5315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your 5515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or 5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's 5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method: 5815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre> 6015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() { 6115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * if (DEVELOPER_MODE) { 6215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}() 6315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * .detectDiskReads() 6415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * .detectDiskWrites() 6515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * .detectNetwork() // or .detectAll() for all detectable problems 6615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * .penaltyLog() 6715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * .build()); 6815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}() 6932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectLeakedSqlLiteObjects() 7032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 7132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyDeath() 7232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 7332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * } 7432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * super.onCreate(); 7532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * } 7662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * </pre> 77fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * 7832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can decide what should happen when a violation is detected. 7932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * For example, using {@link ThreadPolicy.Builder#penaltyLog} you can 8032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * watch the output of <code>adb logcat</code> while you use your 8115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * application to see the violations as they happen. 8215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 8315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are 8415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler}, 8515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc. 8632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds. In particular, 8732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * many cases of disk access are often necessary during the normal activity lifecycle. Use 8832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode to find things you did by accident. Network requests on the UI thread 8932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are almost always a problem, though. 9015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 9115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not 9215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses. While it does 9315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing 9415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best 9532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * effort mechanism. Notably, disk or network access from JNI calls 9632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * won't necessarily trigger it. Future versions of Android may catch 9715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode 9815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * enabled in shipping applications on the Android Market. 9915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 10015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrickpublic final class StrictMode { 10115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick private static final String TAG = "StrictMode"; 10215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick private static final boolean LOG_V = false; 10315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 10415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 10515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 10615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 107438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 108438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 109438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 11082829ef3b7c72bee36d8c17b36ac565f1856a310Brad Fitzpatrick // How many offending stacks to keep track of (and time) per loop 111438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // of the Looper. 1121181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final int MAX_OFFENSES_PER_LOOP = 10; 1136804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 1141181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Thread-policy: 11546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 11646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick /** 11746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick * @hide 11846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick */ 11946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy 12046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 121e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 122e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 123e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 124191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy 125191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 126191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick /** 127191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick * @hide 12832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 129438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy 13015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 13132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Process-policy: 13215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 13332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 13415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Note, a "VM_" bit, not thread. 13515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * @hide 13632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 13715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy 13832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 13915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 14015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * @hide 14132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 14215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 14332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 144438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Used for both process and thread policy: 14532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 146438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 147438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * @hide 14832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 14932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 15032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 15132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 15232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 15332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 154fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static final int PENALTY_DEATH = 0x40; 155fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 156fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 157fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 158fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 159fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static final int PENALTY_DROPBOX = 0x80; 16032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 161438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 162438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 163438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * bits and signals that we're in a Binder call and we should 16432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 16532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 166438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * in the originating process. 16732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 168438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 169438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 170438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * @hide 171438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 172b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 173b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 17432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 175438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * The current VmPolicy in effect. 176438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 177438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static volatile int sVmPolicyMask = 0; 178438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 179b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick private StrictMode() {} 180b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 181b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 182b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * {@link StrictMode} policy applied to a certain thread. 183b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 184b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy 185b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * can be retrieved with {@link #getThreadPolicy}. 1866804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * 1876804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * <p>Note that multiple penalties may be provided and they're run 1886804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * in order from least to most severe (logging before process 1896804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * death, for example). There's currently no mechanism to choose 1906804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * different penalties for different detected actions. 1916804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 1926804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick public static final class ThreadPolicy { 19332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 194438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * The default, lax policy which doesn't catch anything. 195438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 196438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final ThreadPolicy LAX = new ThreadPolicy(0); 197727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 198727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick final int mask; 199727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 200727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private ThreadPolicy(int mask) { 201727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick this.mask = mask; 202727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 203727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 204703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick @Override 205703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick public String toString() { 206727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return "[StrictMode.ThreadPolicy; mask=" + mask + "]"; 207727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 208727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 209727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 21032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates {@link ThreadPolicy} instances. Methods whose names start 21171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * with {@code detect} specify what problems we should look 21271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 21371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * we should do when we detect a problem. 214b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 2156804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 21671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * methods as you like. Currently order is insignificant: all 21771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * penalties apply to all detected problems. 21832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 21932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 22032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 22132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 222bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * .detectAll() 223bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * .penaltyLog() 224bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * .build(); 225bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * StrictMode.setThreadPolicy(policy); 226bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * </pre> 227bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 22832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 22932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask = 0; 23032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 23132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 23232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create a Builder that detects nothing and has no 23332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations. (but note that {@link #build} will default 23432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to enabling {@link #penaltyLog} if no other penalties 23532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are specified) 23632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 23732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder() { 23832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = 0; 23932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 24032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 24132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 24232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Initialize a Builder from an existing ThreadPolicy. 24332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 24432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder(ThreadPolicy policy) { 24532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = policy.mask; 24632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 24732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 24832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 24932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 25032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 25132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this includes network and 25232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * disk operations but will likely expand in future releases. 25332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 25432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 25532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 25632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 25732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 25832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 25932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable the detection of everything. 26032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 26132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitAll() { 26232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 26332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 26432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 26532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 26632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of network operations. 26732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 26832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectNetwork() { 26932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_NETWORK); 27032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 27232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 27332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of network operations. 27432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 27532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitNetwork() { 27632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_NETWORK); 27732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 27932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 28032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk reads. 28132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 28232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskReads() { 28332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_READ); 28432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 28732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk reads. 28832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 28932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskReads() { 29032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_READ); 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 29232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk writes. 29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskWrites() { 29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE); 29832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 29932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk writes. 30232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskWrites() { 30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE); 30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Show an annoying dialog to the developer on detected 30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations, rate-limited to be only a little annoying. 31032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDialog() { 31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DIALOG); 31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crash the whole process on violation. This penalty runs at 31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so you'll still get 31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * see logging or other violations before the process dies. 31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 32132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 32232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 32532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 32932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 33532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 33832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 33932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder disable(int bit) { 34732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask &= ~bit; 34832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 34932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 35032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 35132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 35232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the ThreadPolicy instance. 35332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 35432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 35532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 35632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 35732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 35832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ThreadPolicy build() { 35932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 36032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 36132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 36232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 36332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 36432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 36532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 36632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(mMask); 36732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 368b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 369b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 370b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 371b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 37232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to all threads in the virtual machine's process. 37332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 37432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setVmPolicy}. 37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class VmPolicy { 37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 378b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * The default, lax policy which doesn't catch anything. 379b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 380b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final VmPolicy LAX = new VmPolicy(0); 381b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 382b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick final int mask; 383b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 384b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick private VmPolicy(int mask) { 385b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick this.mask = mask; 386b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 387b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 388b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick @Override 389b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public String toString() { 3906804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick return "[StrictMode.VmPolicy; mask=" + mask + "]"; 3916804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 3926804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 3936804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 3946804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Creates {@link VmPolicy} instances. Methods whose names start 3956804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * with {@code detect} specify what problems we should look 3966804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 39732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 39832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 39932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 40032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 40132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 40232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 40332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 40432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 40532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 40632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 40732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 41032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 41132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 41232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 41332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask; 41432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 41632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 41732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 41832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this only includes 41932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite cursor leaks but will likely expand in future 42032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * releases. 42132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 42232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 42332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 42432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 42532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 42632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 42732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect when an 42832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link android.database.sqlite.SQLiteCursor} or other 42932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite object is finalized without having been closed. 43032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 43132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You always want to explicitly close your SQLite 43232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * cursors to avoid unnecessary database contention and 43332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * temporary memory leaks. 43432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 43532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectLeakedSqlLiteObjects() { 43632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crashes the whole process on violation. This penalty runs at 44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so yo you'll still get 44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * your logging or other violations before the process dies. 44332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 44432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 44532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 44632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 44732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 44832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 44932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 45032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 45132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 45232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 45332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 45432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 45532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 45632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 45732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 45832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 45932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 46032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 46132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 46232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 46332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 46632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 46732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 46832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 46932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 47032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 47132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the VmPolicy instance. 47232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 47332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 47432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 47532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 47632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 47732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public VmPolicy build() { 47832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 47932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 48032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 48132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 48232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 48332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 48432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(mMask); 48632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 490fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 491fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Log of strict mode violation stack traces that have occurred 492fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * during a Binder call, to be serialized back later to the caller 49332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 49432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * choose how to react. 495fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 49632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 49732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 49832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 49932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // checking whether there are any violations or not in 50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // hasGatheredViolations() below. 50232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return null; 50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick }; 50532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 50732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions on the current thread should 50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * be detected, as well as the penalty if such actions occur. 50932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Internally this sets a thread-local variable which is 51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 512fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * catch violations when a system service or another process 513fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * accesses the disk or network on your behalf. 514fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * 515fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @param policy the policy to put into place 516fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 517fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static void setThreadPolicy(final ThreadPolicy policy) { 518fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom setThreadPolicyMask(policy.mask); 519fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 520fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 521fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom private static void setThreadPolicyMask(final int policyMask) { 522fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom // In addition to the Java-level thread-local in Dalvik's 523fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom // BlockGuard, we also need to keep a native thread-local in 52432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 52532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // even across native-only processes. The two are kept in 52632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 52732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setBlockGuardPolicy(policyMask); 52832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 52932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // And set the Android native version... 53032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 53132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 53232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 53332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 53432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 53532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (policyMask == 0) { 53632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 53732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return; 53832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 53932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 54032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 54132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask)); 54232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } else { 54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy; 54432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick androidPolicy.setPolicyMask(policyMask); 54532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 54832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { 54932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 55032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_NETWORK); 55132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 55232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 55332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 55432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { 55532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 55632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_READ); 55732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 55832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 55932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 56032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { 56132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 56232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_WRITE); 56332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 56432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 56532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 56632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 56732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 56832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 56932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled 57032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 57132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 57232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 573438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static int getThreadPolicyMask() { 574438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 5755b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 5775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 5785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns the current thread's policy. 5795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 580cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static ThreadPolicy getThreadPolicy() { 581cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return new ThreadPolicy(getThreadPolicyMask()); 582cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 583703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 584703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 585703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * A convenience wrapper that takes the current 586703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 5875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * to permit both disk reads & writes, and sets the new policy 5885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 5895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * can restore it at the end of a block. 5905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 59132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to {@link #setThreadPolicy} to 59232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * restore the policy at the end of a block 59315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 59432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskWrites() { 59515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 59615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ); 59715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 598438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick setThreadPolicyMask(newPolicyMask); 59932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 600438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 60132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 60232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 60332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 60432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 60532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 606727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * to permit disk reads, and sets the new policy 607727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 608727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * can restore it at the end of a block. 609727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 610727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @return the old policy, to be passed to setThreadPolicy to 611727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * restore the policy. 612727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 613727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static ThreadPolicy allowThreadDiskReads() { 614727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 615727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ); 616727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 617727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 618727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 61946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 62046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 62146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 62246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick /** 623438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Enable DropBox logging for debug phone builds. 624438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 625438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * @hide 626438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 627438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 628438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 629438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 630438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if ("user".equals(Build.TYPE)) { 631438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return false; 6324b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 6334b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom StrictMode.setThreadPolicyMask( 6347c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick StrictMode.DETECT_DISK_WRITE | 6354b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom StrictMode.DETECT_DISK_READ | 6364b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom StrictMode.DETECT_NETWORK | 6374b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom StrictMode.PENALTY_DROPBOX); 6384b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | 6394b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom StrictMode.PENALTY_DROPBOX | 6405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StrictMode.PENALTY_LOG; 6415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return true; 64232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 6435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 6455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 6465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 6475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 64832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 6495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Input is of form "policy=137 violation=64" 6505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 6515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 6525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 6535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 65432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 6555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 6565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 6575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 658438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 65915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 660438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (spaceIndex == -1) { 66132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return 0; 66232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 66332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 664438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 66532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 666438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (NumberFormatException e) { 667438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return 0; 668438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 6695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 67032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 67132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 67232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 67332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 67432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 67532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (message == null) { 67632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return 0; 67732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 67832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 67932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (violationIndex == -1) { 68032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return 0; 68132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 68297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick String violationString = message.substring(violationIndex + 10); 68332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick try { 68432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 68597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } catch (NumberFormatException e) { 68632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return 0; 68732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 68832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 68932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 69032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 69197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 69232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 69397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick return new ArrayList<ViolationInfo>(); 69497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 69597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick }; 69632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 69732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static boolean tooManyViolationsThisLoop() { 69832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; 69932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 70032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 70197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 70232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mPolicyMask; 70397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 70497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 70532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // last violation. No locking needed, as this is only 70632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // accessed by the same thread. 70732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); 70832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 70932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 71097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick mPolicyMask = policyMask; 71132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 71297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 71397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick @Override 71497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick public String toString() { 71550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 71650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 71750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 71850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Part of BlockGuard.Policy interface: 71950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public int getPolicyMask() { 72050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return mPolicyMask; 72150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 7221181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 7237c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick // Part of BlockGuard.Policy interface: 72450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public void onWriteToDisk() { 72550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { 72632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return; 72732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 72832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (tooManyViolationsThisLoop()) { 72932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return; 7306804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 7316804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 7326804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick e.fillInStackTrace(); 73332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick startHandlingViolationException(e); 734fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 735d188ededa6f61dbe5a700e81db22c02478ce60ccBrad Fitzpatrick 7367c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick // Part of BlockGuard.Policy interface: 73750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public void onReadFromDisk() { 73850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_READ) == 0) { 73950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return; 74050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 741b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 742b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return; 743b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 744b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 745b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick e.fillInStackTrace(); 746b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick startHandlingViolationException(e); 747b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 748b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 749b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick // Part of BlockGuard.Policy interface: 750b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public void onNetwork() { 751b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if ((mPolicyMask & DETECT_NETWORK) == 0) { 752b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return; 7535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (tooManyViolationsThisLoop()) { 7555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 7565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 7585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick e.fillInStackTrace(); 7595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick startHandlingViolationException(e); 7605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public void setPolicyMask(int policyMask) { 7635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick mPolicyMask = policyMask; 7645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 7675b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 7685b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 7695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 7705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 7715b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 7725b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 7735b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 7745b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick handleViolationWithTimingAttempt(info); 7755b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 7785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 7795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to measure with. We measure from the time of violation 7805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // until the time the looper is idle again (right before 7815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // the next epoll_wait) 7825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 7835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Looper looper = Looper.myLooper(); 7845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Without a Looper, we're unable to time how long the 7865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation takes place. This case should be rare, as 7875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // most users will care about timing violations that 7885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // happen on their main UI thread. Note that this case is 7895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // also hit when a violation takes place in a Binder 7905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 7915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // of the violation is computed by the ultimate caller and 7925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // its Looper, if any. 7935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 7945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // go into this immediate mode? 7955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (looper == null) { 7965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 7975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick handleViolation(info); 798191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 799191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 800191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 801191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick MessageQueue queue = Looper.myQueue(); 802191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 803191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() >= MAX_OFFENSES_PER_LOOP) { 804191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 805191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 806191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 807191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick records.add(info); 808191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() > 1) { 809438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // There's already been a violation this loop, so we've already 810438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // registered an idle handler to process the list of violations 81146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // at the end of this Looper's loop. 81246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 81346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 81446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 81546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick queue.addIdleHandler(new MessageQueue.IdleHandler() { 816438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public boolean queueIdle() { 817438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 818438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 819438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ViolationInfo v = records.get(n); 820438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick v.violationNumThisLoop = n + 1; 8215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick v.durationMillis = 8225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 8235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick handleViolation(v); 8245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick records.clear(); 826438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return false; // remove this idle handler from the array 827438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 828438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick }); 829438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 830438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 831438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Note: It's possible (even quite likely) that the 832438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // thread-local policy mask has changed from the time the 83332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // violation fired and now (after the violating code ran) due 834438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // to people who push/pop temporary policy in regions of code, 835438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // hence the policy being passed around. 836191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick void handleViolation(final ViolationInfo info) { 837191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 838191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 839cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 840cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 841cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 842438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 843438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 844438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 845438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 84632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (violations == null) { 847438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 848438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick gatheredViolations.set(violations); 849191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } else if (violations.size() >= 5) { 850191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 851191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 852cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 853cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 854cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 855438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Duplicate. Don't log. 856438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 857438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 858438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 85932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick violations.add(info); 860438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 861438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 862b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 863b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 864b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick Integer crashFingerprint = info.crashInfo.stackTrace.hashCode(); 865191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick long lastViolationTime = 0; 866191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (mLastViolationTime.containsKey(crashFingerprint)) { 867191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick lastViolationTime = mLastViolationTime.get(crashFingerprint); 868cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 869cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long now = SystemClock.uptimeMillis(); 870cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 871438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 872438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 873438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 874438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 875438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 876438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (info.durationMillis != -1) { 8775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 8785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 8795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } else { 8805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 8815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 883cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 884cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 885cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // subset of the original StrictMode policy bitmask, with 886cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // only the bit violated and penalty bits to be executed 887438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // by the ActivityManagerService remaining set. 888cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 889cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 890cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 891cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 892cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 893cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 894438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 895cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 896cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 897cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 898cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 899cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 900cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 901cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 902cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 903cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick try { 904cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 905cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 906438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 907cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // We restore the current policy below, in the finally block. 908cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick setThreadPolicyMask(0); 909cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 910438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 911438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 912cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 913cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 914191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } catch (RemoteException e) { 915cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 916cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } finally { 917cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Restore the policy. 918cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 919cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 920cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 921cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 922cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 923cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); 924cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Process.killProcess(Process.myPid()); 925cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick System.exit(10); 9266804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 927cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick } 9286804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 9296804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 9306804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 9316804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Called from Parcel.writeNoException() 9326804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 9336804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 9346804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick return gatheredViolations.get() != null; 935cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 936cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 937cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 938cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 939cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 940cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Binder call on this thread. 941cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 942cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 943cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick gatheredViolations.set(null); 944cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 945cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 9466804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 9476804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Sets the policy for what actions in the VM process (on any 9486804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * thread) should be detected, as well as the penalty if such 9496804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * actions occur. 9506804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * 9516804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * @param policy the policy to put into place 952cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 953cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static void setVmPolicy(final VmPolicy policy) { 954cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick sVmPolicyMask = policy.mask; 9555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 956438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 9575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 9585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Gets the current VM policy. 9595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 9605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public static VmPolicy getVmPolicy() { 9615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return new VmPolicy(sVmPolicyMask); 962cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 963cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 964cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 9655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Enable the recommended StrictMode defaults, with violations just being logged. 9665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 967438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * <p>This catches disk and network access on the main thread, as 968cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * well as leaked SQLite cursors. This is simply a wrapper around 96946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick * {@link #setVmPolicy} and {@link #setThreadPolicy}. 970cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 971cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static void enableDefaults() { 972703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 973cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick .detectAll() 974703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick .penaltyLog() 975703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick .build()); 9765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 9775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick .detectLeakedSqlLiteObjects() 9785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick .penaltyLog() 979cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick .build()); 980cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 9815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 9825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 9835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * @hide 9845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 985cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static boolean vmSqliteObjectLeaksEnabled() { 986727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0; 987727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 988727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 98946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick /** 990f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick * @hide 99146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick */ 99246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick public static void onSqliteObjectLeaked(String message, Throwable originStack) { 99346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if ((sVmPolicyMask & PENALTY_LOG) != 0) { 99446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, message, originStack); 99546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 99646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 99746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if ((sVmPolicyMask & PENALTY_DROPBOX) != 0) { 99846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); 99946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1000cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 100146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 1002cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // only the bit violated and penalty bits to be executed 10035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // by the ActivityManagerService remaining set. 1004cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS; 1005438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 1006cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick try { 1007438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 1008438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 1009438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 101071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // We restore the current policy below, in the finally block. 101146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick setThreadPolicyMask(0); 101246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 101346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 1014cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick RuntimeInit.getApplicationObject(), 101546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick violationMaskSubset, 1016cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 101746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } catch (RemoteException e) { 1018cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 101946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } finally { 102046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Restore the policy. 1021cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 1022cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 102346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 102446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1025cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_DEATH) != 0) { 1026cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down."); 1027cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Process.killProcess(Process.myPid()); 102832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.exit(10); 102971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 103071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 103171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 103271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /** 103371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * Called from Parcel.writeNoException() 103471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick */ 103571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 103671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 103771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick if (violations == null) { 1038bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick p.writeInt(0); 103971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } else { 104071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick p.writeInt(violations.size()); 104171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 104271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 1043438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1044727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 1045727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 1046727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1047727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick gatheredViolations.set(null); 104832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 1049727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1050438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class LogStackTrace extends Exception {} 1051438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1052cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1053cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 1054438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * we here read back all the encoded violations. 105546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick */ 1056727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 1057727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Our own stack trace to append 105832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StringWriter sw = new StringWriter(); 1059438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick new LogStackTrace().printStackTrace(new PrintWriter(sw)); 1060438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick String ourStack = sw.toString(); 1061438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1062cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int policyMask = getThreadPolicyMask(); 1063438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 1064438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1065438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick int numViolations = p.readInt(); 1066438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 1067438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 1068438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 1069727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 1070bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 1071bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 1072bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 1073bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1074bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1075bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1076bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1077bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1078bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * Called from android_util_Binder.cpp's 1079bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 1080bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 1081bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 1082bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 1083bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * thread-local policy value. 1084bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 1085bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 1086bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 1087bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1088bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1089bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1090bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 1091bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * to report violations that happened during a cross-process call. 1092bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * 1093bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * @hide 1094bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 1095bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick public static class ViolationInfo { 1096bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1097bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * Stack and other stuff info. 1098bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 1099bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 1100bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1101bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1102bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * The strict mode policy mask at the time of violation. 1103bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 1104bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick public final int policy; 1105bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1106bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1107bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 11084b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom * not known. 11094b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom */ 11104b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public int durationMillis = -1; 11114b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 11124b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom /** 11134b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom * Which violation number this was (1-based) since the last Looper loop, 1114727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 11155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 11165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * thread. 11175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 1118703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick public int violationNumThisLoop; 1119703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1120703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1121703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 1122703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * violation occurred. 1123703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 1124703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick public long violationUptimeMillis; 1125703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1126703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1127703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 11285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 11295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public ViolationInfo() { 11305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick crashInfo = null; 113132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick policy = 0; 113232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 113332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 113432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 113532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 113632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 113732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 113832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 11394b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom violationUptimeMillis = SystemClock.uptimeMillis(); 114032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.policy = policy; 114132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 114232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 114332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 114432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 114532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 114632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ViolationInfo(Parcel in) { 114732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this(in, false); 114832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 114932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 115062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 115162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 115262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * 1153fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @param unsetGatheringBit if true, the caller is the root caller 1154fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * and the gathering penalty should be removed. 1155fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 115662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 115762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 115862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick int rawPolicy = in.readInt(); 115962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick if (unsetGatheringBit) { 116062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 116162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } else { 116262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick policy = rawPolicy; 116362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 1164fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom durationMillis = in.readInt(); 116562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick violationNumThisLoop = in.readInt(); 116662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick violationUptimeMillis = in.readLong(); 116762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 116862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick 116962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 117032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 117132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 117232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 117332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 117432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick dest.writeInt(policy); 117532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick dest.writeInt(durationMillis); 117632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 117732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 117832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 1179fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 1180fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 1181fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 1182fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Dump a ViolationInfo instance to a Printer. 1183fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 1184fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public void dump(Printer pw, String prefix) { 1185fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom crashInfo.dump(pw, prefix); 118632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 11874b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom if (durationMillis != -1) { 11884b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom pw.println(prefix + "durationMillis: " + durationMillis); 11894b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 11904b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom if (violationNumThisLoop != 0) { 11914b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 11924b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 11934b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 119432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 119532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 119632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 119732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick} 1198bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick