StrictMode.java revision 4b9b7c38e8f52259f9d2f960072d35e8a1ab2129
1438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/* 2438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Copyright (C) 2010 The Android Open Source Project 3438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 4438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 5438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * you may not use this file except in compliance with the License. 6438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * You may obtain a copy of the License at 7438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 8438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * http://www.apache.org/licenses/LICENSE-2.0 9438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 10438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Unless required by applicable law or agreed to in writing, software 11438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * distributed under the License is distributed on an "AS IS" BASIS, 12438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * See the License for the specific language governing permissions and 14438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * limitations under the License. 15438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 16438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpackage android.os; 17438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 18599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrickimport android.animation.ValueAnimator; 19438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ActivityManagerNative; 20bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.app.ActivityThread; 21438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ApplicationErrorReport; 22bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.content.Intent; 23438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Log; 24cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrickimport android.util.Printer; 25438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 26438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit; 27438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 28438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport dalvik.system.BlockGuard; 29fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstromimport dalvik.system.CloseGuard; 30438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.PrintWriter; 325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.StringWriter; 335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.util.ArrayList; 3446d42387464a651268648659e91d022566d4844cBrad Fitzpatrickimport java.util.HashMap; 3546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 36438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/** 3732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>StrictMode is a developer tool which detects things you might be 3832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * doing by accident and brings them to your attention so you can fix 3932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * them. 4015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 4115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or 4215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * network access on the application's main thread, where UI 4315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * operations are received and animations take place. Keeping disk 4415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and network operations off the main thread makes for much smoother, 459fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * more responsive applications. By keeping your application's main thread 469fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * responsive, you also prevent 479fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * <a href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a> 489fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * from being shown to users. 4915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is 5115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that 5215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * memory with very limited concurrency. It's often the case that 5315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be 5415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background 5515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from other processes. If possible, it's best to assume that such 5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p> 5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your 5915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or 6015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's 6115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method: 6215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 6315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre> 6415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() { 6515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * if (DEVELOPER_MODE) { 6632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}() 6732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskReads() 6832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskWrites() 6932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectNetwork() // or .detectAll() for all detectable problems 7032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 7132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 7232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}() 7362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * .detectLeakedSqlLiteObjects() 74fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * .detectLeakedClosableObjects() 7532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 7632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyDeath() 7732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 7815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 7915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * super.onCreate(); 8015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 8115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * </pre> 8215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 8332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can decide what should happen when a violation is detected. 8432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * For example, using {@link ThreadPolicy.Builder#penaltyLog} you can 8532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * watch the output of <code>adb logcat</code> while you use your 8632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * application to see the violations as they happen. 8715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 8815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are 8915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler}, 9015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc. 9115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds. In particular, 9232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * many cases of disk access are often necessary during the normal activity lifecycle. Use 9332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode to find things you did by accident. Network requests on the UI thread 9415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * are almost always a problem, though. 9515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 9615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not 9715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses. While it does 9815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing 9915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best 10015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * effort mechanism. Notably, disk or network access from JNI calls 10115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * won't necessarily trigger it. Future versions of Android may catch 10215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode 10315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * enabled in shipping applications on the Android Market. 104438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 105438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpublic final class StrictMode { 106438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static final String TAG = "StrictMode"; 1075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static final boolean LOG_V = false; 108438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 10946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 11046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 11146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 11246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 11346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 11446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 115191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // How many offending stacks to keep track of (and time) per loop 116191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // of the Looper. 117191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final int MAX_OFFENSES_PER_LOOP = 10; 118191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 11932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Thread-policy: 120438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 12115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 12232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 12315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 12432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy 12515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 12615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 12732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 12815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 12932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy 13015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 13115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 13232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 13315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 13432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy 135438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 13632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Process-policy: 137438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 138438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 13932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Note, a "VM_" bit, not thread. 14032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 14132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 14232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy 14332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 14432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 145fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Note, a "VM_" bit, not thread. 146fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 147fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 148fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for ProcessPolicy 149fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 150fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 15132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 152438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 153438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 154438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 15532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Used for both process and thread policy: 15632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 157438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 15832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 159438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 160438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 161438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 162438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 163b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death on any detected violation. 164b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 16532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 166438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 167438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DEATH = 0x40; 168438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 169438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 170b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death just for detected network usage. 171b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 172b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 173b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 174b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final int PENALTY_DEATH_ON_NETWORK = 0x200; 175b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 176b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 17732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 178438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 179438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DROPBOX = 0x80; 180438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 181727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 182727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 183727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * bits and signals that we're in a Binder call and we should 184727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 185727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 186727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * in the originating process. 187727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 188703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 189703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * 190727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @hide 191727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 192727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 193727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 19432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 19571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * Mask of all the penalty bits. 19671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick */ 19771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick private static final int PENALTY_MASK = 198b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | 199b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_DEATH_ON_NETWORK; 20071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 20171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /** 20232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The current VmPolicy in effect. 20332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 20432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static volatile int sVmPolicyMask = 0; 20532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 20632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private StrictMode() {} 20732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 20832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 20932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to a certain thread. 21032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 21132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy 21232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can be retrieved with {@link #getThreadPolicy}. 21332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 21432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note that multiple penalties may be provided and they're run 21532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * in order from least to most severe (logging before process 21632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * death, for example). There's currently no mechanism to choose 21732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * different penalties for different detected actions. 21832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 21932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class ThreadPolicy { 22032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 22132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 22232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 22332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final ThreadPolicy LAX = new ThreadPolicy(0); 22432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 22532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 22632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 22732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private ThreadPolicy(int mask) { 22832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 22932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 23032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 23132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 23232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 23332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.ThreadPolicy; mask=" + mask + "]"; 23432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 23532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 23632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 23732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates ThreadPolicy instances. Methods whose names start 23832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 23932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 24032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 24132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 24232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 24332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 24432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 24532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 24632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 24732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 24832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 24932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 25032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 25132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 25232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 25332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 25432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 25532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 25632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask = 0; 25732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 25832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 25932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create a Builder that detects nothing and has no 26032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations. (but note that {@link #build} will default 26132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to enabling {@link #penaltyLog} if no other penalties 26232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are specified) 26332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 26432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder() { 26532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = 0; 26632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 26732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 26832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 26932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Initialize a Builder from an existing ThreadPolicy. 27032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 27132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder(ThreadPolicy policy) { 27232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = policy.mask; 27332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 27532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 27632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 27732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 27832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this includes network and 27932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * disk operations but will likely expand in future releases. 28032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 28132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 28232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 28332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 28432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable the detection of everything. 28732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 28832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitAll() { 28932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 29032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of network operations. 29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectNetwork() { 29632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_NETWORK); 29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 29832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of network operations. 30132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitNetwork() { 30332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_NETWORK); 30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk reads. 30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskReads() { 31032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_READ); 31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk reads. 31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskReads() { 31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_READ); 31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 32132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk writes. 32232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskWrites() { 32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE); 32532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk writes. 32932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskWrites() { 33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE); 33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 33532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Show an annoying dialog to the developer on detected 33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations, rate-limited to be only a little annoying. 33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 33832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDialog() { 33932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DIALOG); 34032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crash the whole process on violation. This penalty runs at 34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so you'll still get 34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * see logging or other violations before the process dies. 346b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 347b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>Unlike {@link #penaltyDeathOnNetwork}, this applies 348b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * to disk reads, disk writes, and network usage if their 349b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * corresponding detect flags are set. 35032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 35132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 35232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 35332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 35432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 35532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 356b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Crash the whole process on any network usage. Unlike 357b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * {@link #penaltyDeath}, this penalty runs 358b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <em>before</em> anything else. You must still have 359b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * called {@link #detectNetwork} to enable this. 360b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 361b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>In the Honeycomb or later SDKs, this is on by default. 362b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 363b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public Builder penaltyDeathOnNetwork() { 364b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return enable(PENALTY_DEATH_ON_NETWORK); 365b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 366b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 367b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 36832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 36932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 37032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 37132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 37232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 37332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 37432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 37832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 37932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 38032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 38132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 38232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 38532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 38632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 38732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder disable(int bit) { 39032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask &= ~bit; 39132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 39232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 39332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 39432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 39532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the ThreadPolicy instance. 39632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 39732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 39832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 39932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 40032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 40132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ThreadPolicy build() { 40232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 40332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 40432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 40532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 40632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 40732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(mMask); 41032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 41532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to all threads in the virtual machine's process. 41632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 41732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setVmPolicy}. 41832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 41932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class VmPolicy { 42032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 42132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 42232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 42332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final VmPolicy LAX = new VmPolicy(0); 42432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 42532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 42632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 42732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private VmPolicy(int mask) { 42832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 42932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 43032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 43232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 43332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.VmPolicy; mask=" + mask + "]"; 43432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 43532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates {@link VmPolicy} instances. Methods whose names start 43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 44332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 44432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 44532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 44632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 44732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 44832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 44932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 45032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 45132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 45232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 45332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 45432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 45532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 45632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask; 45732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 45832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 45932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 46032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 461fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>In the Honeycomb release this includes leaks of 462fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * SQLite cursors and other closable objects but will 463fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * likely expand in future releases. 46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 466fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); 46732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 46832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 46932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 47032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect when an 47132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link android.database.sqlite.SQLiteCursor} or other 47232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite object is finalized without having been closed. 47332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 47432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You always want to explicitly close your SQLite 47532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * cursors to avoid unnecessary database contention and 47632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * temporary memory leaks. 47732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 47832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectLeakedSqlLiteObjects() { 47932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 48032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 48232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 483fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Detect when an {@link java.io.Closeable} or other 484fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * object with a explict termination method is finalized 485fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * without having been closed. 486fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * 487fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>You always want to explicitly close such objects to 488fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * avoid unnecessary resources leaks. 489fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 490fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public Builder detectLeakedClosableObjects() { 491fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CLOSABLE_LEAKS); 492fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 493fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 494fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 49532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crashes the whole process on violation. This penalty runs at 49632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so yo you'll still get 49732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * your logging or other violations before the process dies. 49832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 49932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 50432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 50532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 50632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 50732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 51232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 51332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 51432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 51532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 51632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 51732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 51832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 51932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 52032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 52132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 52232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 52332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 52532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 52632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the VmPolicy instance. 52732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 52832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 52932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 53032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 53132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 53232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public VmPolicy build() { 53332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 53432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 53532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 53632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 53732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 53832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 53932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(mMask); 54132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 544438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 545438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 5465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Log of strict mode violation stack traces that have occurred 5475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * during a Binder call, to be serialized back later to the caller 5485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 5495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * choose how to react. 5505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 551cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 552cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 553cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 554703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 555703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // checking whether there are any violations or not in 556703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // hasGatheredViolations() below. 557703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return null; 5585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick }; 5605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 5615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 56232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions on the current thread should 56332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * be detected, as well as the penalty if such actions occur. 56415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 56532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Internally this sets a thread-local variable which is 56615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 56715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * catch violations when a system service or another process 56815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * accesses the disk or network on your behalf. 569438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 57032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 571438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 57232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setThreadPolicy(final ThreadPolicy policy) { 57332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(policy.mask); 57432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 57532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 57632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static void setThreadPolicyMask(final int policyMask) { 577727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // In addition to the Java-level thread-local in Dalvik's 578727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // BlockGuard, we also need to keep a native thread-local in 579727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 580727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // even across native-only processes. The two are kept in 581727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 582727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(policyMask); 583727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 584727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // And set the Android native version... 585727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 586727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 587727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 588727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 589727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 59046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (policyMask == 0) { 59146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 59246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 59346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 594438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 595438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 596438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask)); 597438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 598438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy; 599438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick androidPolicy.setPolicyMask(policyMask); 600438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 601438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 602438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 6034b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom // Sets up CloseGuard in Dalvik/libcore 6044b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static void setCloseGuardEnabled(boolean enabled) { 6054b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom if (!(CloseGuard.getReporter() instanceof AndroidBlockGuardPolicy)) { 6064b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setReporter(new AndroidCloseGuardReporter()); 6074b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 6084b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setEnabled(enabled); 6094b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 6104b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 6115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { 6125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 61332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_NETWORK); 6145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { 6185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 61932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_READ); 6205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { 6245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 62532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_WRITE); 6265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 629438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 63015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 631438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 63232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled 63332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 63432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 635438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 63632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static int getThreadPolicyMask() { 637438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 638438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 639438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 6405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 64132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Returns the current thread's policy. 64232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 64332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy getThreadPolicy() { 64432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(getThreadPolicyMask()); 64532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 64632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 64732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 64832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 64932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 65032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit both disk reads & writes, and sets the new policy 65132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 65232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 65397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 65432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to {@link #setThreadPolicy} to 65532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * restore the policy at the end of a block 65697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 65732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskWrites() { 65832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 65932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ); 66032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 66132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 66297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 66332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 66497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 66597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 66697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 66732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 66832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 66932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit disk reads, and sets the new policy 67032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 67132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 67297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 67332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to setThreadPolicy to 67497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 67597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 67632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskReads() { 67732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 67832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ); 67932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 68032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 68197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 68232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 68397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 68497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 68597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 68650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * Enable DropBox logging for debug phone builds. 68750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * 68850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * @hide 68950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick */ 69050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 69150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 69250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 69350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick if ("user".equals(Build.TYPE)) { 69450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return false; 69550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 69632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.setThreadPolicyMask( 69732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_DISK_WRITE | 69832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_DISK_READ | 69932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_NETWORK | 70050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.PENALTY_DROPBOX); 70132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | 702fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom StrictMode.DETECT_VM_CLOSABLE_LEAKS | 70332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.PENALTY_DROPBOX | 70432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.PENALTY_LOG; 70550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return true; 70650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 70750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 70850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick /** 709b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Used by the framework to make network usage on the main 710b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * thread a fatal error. 711b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 712b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 713b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 714b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static void enableDeathOnNetwork() { 715b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int oldPolicy = getThreadPolicyMask(); 716b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int newPolicy = oldPolicy | DETECT_NETWORK | PENALTY_DEATH_ON_NETWORK; 717b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick setThreadPolicyMask(newPolicy); 718b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 719b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 720b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 7215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 7225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 7235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 7245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 7255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Input is of form "policy=137 violation=64" 7265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 7275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 7285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 7295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 7305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 7315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 7325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 7335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 7365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (spaceIndex == -1) { 7375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 7405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 7415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 7425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 7435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 7485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 7495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 7505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 7515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null) { 7525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 7555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (violationIndex == -1) { 7565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String violationString = message.substring(violationIndex + 10); 7595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 7605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 7615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 7625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 766191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 767191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 768191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 769191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return new ArrayList<ViolationInfo>(); 770191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 771191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick }; 772191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 773191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static boolean tooManyViolationsThisLoop() { 774191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; 775191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 776191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 777438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 778438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private int mPolicyMask; 77946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 78046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 78146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // last violation. No locking needed, as this is only 78246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // accessed by the same thread. 78346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); 784438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 785438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 786438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 787438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 788438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 7895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick @Override 7905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public String toString() { 7915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 7925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 794438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 795438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public int getPolicyMask() { 796438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mPolicyMask; 797438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 798438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 799438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 800438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onWriteToDisk() { 80132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { 802438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 803438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 804191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 805191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 806191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 807cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 808cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 809cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 810438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 811438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 812438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 813438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onReadFromDisk() { 81432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_READ) == 0) { 815438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 816438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 817191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 818191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 819191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 820cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 821cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 822cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 823438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 824438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 825438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 826438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onNetwork() { 82732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_NETWORK) == 0) { 828438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 829438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 830b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) { 831b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick throw new NetworkOnMainThreadException(); 832b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 833191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 834191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 835191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 836cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 837cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 838cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 839438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 840438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 841438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void setPolicyMask(int policyMask) { 842438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 843438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 844438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 8455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 8465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 8475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 8485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 8495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 8505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 851cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 852cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 853cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolationWithTimingAttempt(info); 854cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 855438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 856cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 857cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 858cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // to measure with. We measure from the time of violation 859cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // until the time the looper is idle again (right before 860cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // the next epoll_wait) 861cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 862438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Looper looper = Looper.myLooper(); 863cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 864cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Without a Looper, we're unable to time how long the 865cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // violation takes place. This case should be rare, as 866cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // most users will care about timing violations that 867cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // happen on their main UI thread. Note that this case is 868cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // also hit when a violation takes place in a Binder 869cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 870cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // of the violation is computed by the ultimate caller and 871cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // its Looper, if any. 872cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 873cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // go into this immediate mode? 874438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (looper == null) { 875cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 876cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(info); 877cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 878438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 879438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 880cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick MessageQueue queue = Looper.myQueue(); 881cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 882191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() >= MAX_OFFENSES_PER_LOOP) { 883cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 884cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 885cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 886cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.add(info); 887cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() > 1) { 888cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // There's already been a violation this loop, so we've already 889cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // registered an idle handler to process the list of violations 890cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // at the end of this Looper's loop. 891cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 892cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 893cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 894cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick queue.addIdleHandler(new MessageQueue.IdleHandler() { 895cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public boolean queueIdle() { 896cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 897cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 898cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo v = records.get(n); 899cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.violationNumThisLoop = n + 1; 900cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.durationMillis = 901cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 902cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(v); 903cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 904cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.clear(); 905cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return false; // remove this idle handler from the array 906cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 907cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }); 9085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 909438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 9105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Note: It's possible (even quite likely) that the 9115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread-local policy mask has changed from the time the 9125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation fired and now (after the violating code ran) due 9135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to people who push/pop temporary policy in regions of code, 9145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // hence the policy being passed around. 915cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolation(final ViolationInfo info) { 916cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 917cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 9185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 920438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 921cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 92246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 923cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 924cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 925703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 926cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 927703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(violations); 928703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else if (violations.size() >= 5) { 9295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 9305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 932cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 933cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 9345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Duplicate. Don't log. 9355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 938cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations.add(info); 939727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return; 940727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 941727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 94246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 943cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Integer crashFingerprint = info.crashInfo.stackTrace.hashCode(); 94446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long lastViolationTime = 0; 94546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (mLastViolationTime.containsKey(crashFingerprint)) { 94646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick lastViolationTime = mLastViolationTime.get(crashFingerprint); 94746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 94846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 94946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 95046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 95146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 95246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 953cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 95446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 955cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.durationMillis != -1) { 9565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 957cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 958438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 959cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 960438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 961438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 962438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 96371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // The violationMaskSubset, passed to ActivityManager, is a 96446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 96546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // only the bit violated and penalty bits to be executed 96646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // by the ActivityManagerService remaining set. 967cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 96846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 969cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 97046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 971cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 97246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 97346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 974cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 975cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 97646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 97746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 978cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 979cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 980cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 98171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick final int violationMaskSubsetFinal = violationMaskSubset; 98232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 98371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 98471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick final boolean justDropBox = (info.policy & PENALTY_MASK) == PENALTY_DROPBOX; 98571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick if (justDropBox) { 98671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // If all we're going to ask the activity manager 98771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // to do is dropbox it (the common case during 98871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // platform development), we can avoid doing this 98971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // call synchronously which Binder data suggests 99071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // isn't always super fast, despite the implementation 99171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // in the ActivityManager trying to be mostly async. 99271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick new Thread("callActivityManagerForStrictModeDropbox") { 99371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick public void run() { 99471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 99571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick try { 99671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick ActivityManagerNative.getDefault(). 99771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick handleApplicationStrictModeViolation( 99871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick RuntimeInit.getApplicationObject(), 99971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick violationMaskSubsetFinal, 100071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick info); 100171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } catch (RemoteException e) { 100271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick Log.e(TAG, "RemoteException handling StrictMode violation", e); 100371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 100471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 100571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick }.start(); 100671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick return; 100771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 100871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 100971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // Normal synchronous call to the ActivityManager. 1010438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 1011727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 1012727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 1013727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 1014727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // We restore the current policy below, in the finally block. 101532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 1016727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1017438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 1018438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 1019cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 1020cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 1021438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (RemoteException e) { 102246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 1023727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } finally { 1024727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Restore the policy. 102532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 1026438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1027438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1028438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1029cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 1030438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); 1031438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Process.killProcess(Process.myPid()); 1032438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.exit(10); 1033438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1034438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1035438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1036727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 10374b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { 10384b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public void report (String message, Throwable allocationSite) { 10394b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, allocationSite); 10404b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 10414b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 10424b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 1043727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 10445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 10455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 10465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 1047703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return gatheredViolations.get() != null; 1048703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1049703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1050703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1051703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 1052703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 1053703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Binder call on this thread. 1054703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 1055703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 1056703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 10575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 10595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 106032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions in the VM process (on any 106132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * thread) should be detected, as well as the penalty if such 106232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * actions occur. 106332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 106432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 106532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 106632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setVmPolicy(final VmPolicy policy) { 106732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick sVmPolicyMask = policy.mask; 10684b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 106932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 107032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 107132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 107232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Gets the current VM policy. 107332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 107432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static VmPolicy getVmPolicy() { 107532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(sVmPolicyMask); 107632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 107732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 107832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 107962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * Enable the recommended StrictMode defaults, with violations just being logged. 108062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * 108162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * <p>This catches disk and network access on the main thread, as 1082fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * well as leaked SQLite cursors and unclosed resources. This is 1083fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * simply a wrapper around {@link #setVmPolicy} and {@link 1084fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * #setThreadPolicy}. 108562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick */ 108662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick public static void enableDefaults() { 108762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 108862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectAll() 108962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 109062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 109162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 109262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectLeakedSqlLiteObjects() 1093fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom .detectLeakedClosableObjects() 109462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 109562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 109662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 109762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick 109862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 109932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 110032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 110132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static boolean vmSqliteObjectLeaksEnabled() { 110232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0; 110332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 110432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 110532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 110632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 110732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 1108fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static boolean vmClosableObjectLeaksEnabled() { 1109fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return (sVmPolicyMask & DETECT_VM_CLOSABLE_LEAKS) != 0; 1110fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 1111fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 1112fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 1113fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 1114fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 111532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void onSqliteObjectLeaked(String message, Throwable originStack) { 11164b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, originStack); 11174b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 11184b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 11194b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom /** 11204b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom * @hide 11214b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom */ 11224b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public static void onVmPolicyViolation(String message, Throwable originStack) { 112332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_LOG) != 0) { 112432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, message, originStack); 112532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 112632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 112732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_DROPBOX) != 0) { 112832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); 112932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 113032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 113132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // subset of the original StrictMode policy bitmask, with 113232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // only the bit violated and penalty bits to be executed 113332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // by the ActivityManagerService remaining set. 113432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS; 113532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 113632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick try { 113732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 113832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 113932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 114032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // We restore the current policy below, in the finally block. 114132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 114232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 114332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 114432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick RuntimeInit.getApplicationObject(), 114532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick violationMaskSubset, 114632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick info); 114732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } catch (RemoteException e) { 114832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 114932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } finally { 115032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Restore the policy. 115132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 115232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 115332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 115432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 115532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_DEATH) != 0) { 115632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down."); 115732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Process.killProcess(Process.myPid()); 115832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.exit(10); 115932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 116032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 116132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 116232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 11635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 11645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 11655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 1166cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1167703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1168703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(0); 1169703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else { 1170703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(violations.size()); 1171703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 1172703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 1173703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1174703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 1175703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 11765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1177703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 11785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 11795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class LogStackTrace extends Exception {} 11815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 11835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 11845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * we here read back all the encoded violations. 11855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 11865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 11875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Our own stack trace to append 11885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StringWriter sw = new StringWriter(); 1189cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new LogStackTrace().printStackTrace(new PrintWriter(sw)); 11905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String ourStack = sw.toString(); 11915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 119232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int policyMask = getThreadPolicyMask(); 1193cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 11945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int numViolations = p.readInt(); 11965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 11975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 1198cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 1199cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 12005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 12015b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 1202cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 12035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12045b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12065b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 12075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1208727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Called from android_util_Binder.cpp's 1209727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 1210727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 1211727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 1212727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 1213727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * thread-local policy value. 1214727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 1215727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 1216727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 1217727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1218cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1219cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1220cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 1221cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * to report violations that happened during a cross-process call. 1222cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1223cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @hide 1224cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1225cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static class ViolationInfo { 1226cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1227cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Stack and other stuff info. 1228cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1229cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 1230cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1231cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1232cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The strict mode policy mask at the time of violation. 1233cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1234cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final int policy; 1235cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1236cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1237cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 1238cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * not known. 1239cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1240cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int durationMillis = -1; 1241cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1242cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1243599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick * The number of animations currently running. 1244599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick */ 1245599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick public int numAnimationsRunning = 0; 1246599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick 1247599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick /** 1248cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Which violation number this was (1-based) since the last Looper loop, 1249cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 1250cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 1251cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * thread. 1252cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1253cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int violationNumThisLoop; 1254cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1255cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1256cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 1257cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * violation occurred. 1258cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1259cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public long violationUptimeMillis; 1260cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1261cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1262bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * The action of the Intent being broadcast to somebody's onReceive 1263bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * on this thread right now, or null. 1264bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick */ 1265bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick public String broadcastIntentAction; 1266bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick 1267bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick /** 1268cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 1269cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1270cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo() { 1271cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = null; 1272cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = 0; 1273cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1274cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1275cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1276cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 1277cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1278cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 1279cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 1280cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = SystemClock.uptimeMillis(); 1281cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this.policy = policy; 1282599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount(); 1283bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast(); 1284bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntent != null) { 1285bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = broadcastIntent.getAction(); 1286bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1287cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1288cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1289cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1290cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1291cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1292cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in) { 1293cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this(in, false); 1294cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1295cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1296cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1297cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1298cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1299cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @param unsetGatheringBit if true, the caller is the root caller 1300cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * and the gathering penalty should be removed. 1301cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1302cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 1303cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 1304cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int rawPolicy = in.readInt(); 1305cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (unsetGatheringBit) { 1306cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 1307cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } else { 1308cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy; 1309cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1310cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick durationMillis = in.readInt(); 1311cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationNumThisLoop = in.readInt(); 1312599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick numAnimationsRunning = in.readInt(); 1313cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = in.readLong(); 1314bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = in.readString(); 1315cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1316cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1317cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1318cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 1319cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1320cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 1321cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 1322cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(policy); 1323cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(durationMillis); 1324cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 1325599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick dest.writeInt(numAnimationsRunning); 1326cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 1327bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick dest.writeString(broadcastIntentAction); 1328cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1329cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1330cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1331cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1332cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Dump a ViolationInfo instance to a Printer. 1333cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1334cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void dump(Printer pw, String prefix) { 1335cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.dump(pw, prefix); 1336cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 1337cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (durationMillis != -1) { 1338cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "durationMillis: " + durationMillis); 1339cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1340cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationNumThisLoop != 0) { 1341cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 1342cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1343599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick if (numAnimationsRunning != 0) { 1344599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick pw.println(prefix + "numAnimationsRunning: " + numAnimationsRunning); 1345599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick } 1346cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 1347bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntentAction != null) { 1348bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction); 1349bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1350cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1351cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1352cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1353438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick} 1354