StrictMode.java revision 1181cbbfd7c913c51d9836272ad30cfe851c4699
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 1091181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 1101181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 11146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 11246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 11346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 11446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 11546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 11646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 117e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // How many Span tags (e.g. animations) to report. 118e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final int MAX_SPAN_TAGS = 20; 119e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 120191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // How many offending stacks to keep track of (and time) per loop 121191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // of the Looper. 122191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final int MAX_OFFENSES_PER_LOOP = 10; 123191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 12432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Thread-policy: 125438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 12615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 12732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 12815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 12932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy 13015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 13115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 13232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 13315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 13432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy 13515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 13615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 13732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 13815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 13932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy 140438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 14132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Process-policy: 142438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 143438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 14432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Note, a "VM_" bit, not thread. 14532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 14632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 14732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy 14832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 14932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 150fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Note, a "VM_" bit, not thread. 151fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 152fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 153fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for ProcessPolicy 154fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 155fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 15632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 157438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 158438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 159438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 16032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Used for both process and thread policy: 16132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 162438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 16332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 164438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 165438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 166438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 167438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 168b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death on any detected violation. 169b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 17032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 171438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 172438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DEATH = 0x40; 173438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 174438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 175b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death just for detected network usage. 176b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 177b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 178b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 179b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final int PENALTY_DEATH_ON_NETWORK = 0x200; 180b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 181b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 18232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 183438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 184438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DROPBOX = 0x80; 185438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 186727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 187727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 188727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * bits and signals that we're in a Binder call and we should 189727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 190727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 191727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * in the originating process. 192727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 193703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 194703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * 195727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @hide 196727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 197727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 198727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 19932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 20071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * Mask of all the penalty bits. 20171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick */ 20271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick private static final int PENALTY_MASK = 203b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | 204b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_DEATH_ON_NETWORK; 20571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 20671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /** 20732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The current VmPolicy in effect. 20832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 20932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static volatile int sVmPolicyMask = 0; 21032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 21132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private StrictMode() {} 21232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 21332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 21432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to a certain thread. 21532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 21632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy 21732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can be retrieved with {@link #getThreadPolicy}. 21832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 21932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note that multiple penalties may be provided and they're run 22032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * in order from least to most severe (logging before process 22132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * death, for example). There's currently no mechanism to choose 22232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * different penalties for different detected actions. 22332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 22432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class ThreadPolicy { 22532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 22632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 22732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 22832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final ThreadPolicy LAX = new ThreadPolicy(0); 22932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 23032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 23132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 23232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private ThreadPolicy(int mask) { 23332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 23432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 23532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 23632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 23732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 23832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.ThreadPolicy; mask=" + mask + "]"; 23932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 24032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 24132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 24232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates ThreadPolicy instances. Methods whose names start 24332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 24432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 24532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 24632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 24732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 24832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 24932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 25032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 25132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 25232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 25332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 25432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 25532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 25632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 25732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 25832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 25932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 26032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 26132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask = 0; 26232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 26332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 26432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create a Builder that detects nothing and has no 26532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations. (but note that {@link #build} will default 26632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to enabling {@link #penaltyLog} if no other penalties 26732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are specified) 26832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 26932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder() { 27032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = 0; 27132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 27332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 27432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Initialize a Builder from an existing ThreadPolicy. 27532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 27632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder(ThreadPolicy policy) { 27732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = policy.mask; 27832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 28032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 28132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 28232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 28332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this includes network and 28432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * disk operations but will likely expand in future releases. 28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 28732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 28832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 28932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable the detection of everything. 29232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitAll() { 29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK); 29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 29632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of network operations. 29932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectNetwork() { 30132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_NETWORK); 30232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 30332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of network operations. 30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitNetwork() { 30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_NETWORK); 30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk reads. 31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskReads() { 31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_READ); 31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk reads. 32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskReads() { 32232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_READ); 32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk writes. 32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskWrites() { 32932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE); 33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk writes. 33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 33532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskWrites() { 33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE); 33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 34032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Show an annoying dialog to the developer on detected 34132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations, rate-limited to be only a little annoying. 34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDialog() { 34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DIALOG); 34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 34832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crash the whole process on violation. This penalty runs at 34932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so you'll still get 35032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * see logging or other violations before the process dies. 351b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 352b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>Unlike {@link #penaltyDeathOnNetwork}, this applies 353b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * to disk reads, disk writes, and network usage if their 354b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * corresponding detect flags are set. 35532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 35632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 35732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 35832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 35932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 36032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 361b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Crash the whole process on any network usage. Unlike 362b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * {@link #penaltyDeath}, this penalty runs 363b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <em>before</em> anything else. You must still have 364b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * called {@link #detectNetwork} to enable this. 365b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 366b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>In the Honeycomb or later SDKs, this is on by default. 367b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 368b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public Builder penaltyDeathOnNetwork() { 369b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return enable(PENALTY_DEATH_ON_NETWORK); 370b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 371b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 372b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 37332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 37432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 37832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 37932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 38032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 38132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 38232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 38332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 38432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 38532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 38632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 38732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 39032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 39132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 39232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 39332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 39432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder disable(int bit) { 39532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask &= ~bit; 39632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 39732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 39832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 39932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 40032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the ThreadPolicy instance. 40132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 40232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 40332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 40432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 40532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 40632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ThreadPolicy build() { 40732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 41032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 41132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 41232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 41332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(mMask); 41532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 42032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to all threads in the virtual machine's process. 42132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 42232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setVmPolicy}. 42332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 42432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class VmPolicy { 42532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 42632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 42732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 42832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final VmPolicy LAX = new VmPolicy(0); 42932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 43132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private VmPolicy(int mask) { 43332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 43432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 43532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.VmPolicy; mask=" + mask + "]"; 43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates {@link VmPolicy} instances. Methods whose names start 44332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 44432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 44532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 44632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 44732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 44832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 44932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 45032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 45132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 45232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 45332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 45432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 45532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 45632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 45732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 45832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 45932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 46032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 46132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask; 46232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 46332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 466fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>In the Honeycomb release this includes leaks of 467fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * SQLite cursors and other closable objects but will 468fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * likely expand in future releases. 46932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 47032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 471fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); 47232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 47332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 47432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 47532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect when an 47632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link android.database.sqlite.SQLiteCursor} or other 47732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite object is finalized without having been closed. 47832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 47932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You always want to explicitly close your SQLite 48032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * cursors to avoid unnecessary database contention and 48132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * temporary memory leaks. 48232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 48332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectLeakedSqlLiteObjects() { 48432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 48532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 48732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 488fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Detect when an {@link java.io.Closeable} or other 489fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * object with a explict termination method is finalized 490fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * without having been closed. 491fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * 492fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>You always want to explicitly close such objects to 493fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * avoid unnecessary resources leaks. 494fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 495fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public Builder detectLeakedClosableObjects() { 496fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CLOSABLE_LEAKS); 497fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 498fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 499fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crashes the whole process on violation. This penalty runs at 50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so yo you'll still get 50232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * your logging or other violations before the process dies. 50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 50432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 50532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 50632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 50932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 51232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 51332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 51432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 51532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 51632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 51732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 51832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 51932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 52032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 52132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 52232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 52332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 52532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 52632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 52732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 52832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 53032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 53132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the VmPolicy instance. 53232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 53332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 53432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 53532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 53632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 53732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public VmPolicy build() { 53832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 53932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 54032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 54132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 54232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 54432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(mMask); 54632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 549438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 550438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 5515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Log of strict mode violation stack traces that have occurred 5525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * during a Binder call, to be serialized back later to the caller 5535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 5545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * choose how to react. 5555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 556cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 557cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 558cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 559703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 560703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // checking whether there are any violations or not in 561703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // hasGatheredViolations() below. 562703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return null; 5635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick }; 5655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 5665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 56732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions on the current thread should 56832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * be detected, as well as the penalty if such actions occur. 56915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 57032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Internally this sets a thread-local variable which is 57115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 57215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * catch violations when a system service or another process 57315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * accesses the disk or network on your behalf. 574438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 57532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 576438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 57732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setThreadPolicy(final ThreadPolicy policy) { 57832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(policy.mask); 57932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 58032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 58132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static void setThreadPolicyMask(final int policyMask) { 582727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // In addition to the Java-level thread-local in Dalvik's 583727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // BlockGuard, we also need to keep a native thread-local in 584727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 585727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // even across native-only processes. The two are kept in 586727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 587727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(policyMask); 588727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 589727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // And set the Android native version... 590727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 591727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 592727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 593727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 594727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 59546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (policyMask == 0) { 59646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 59746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 59846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 599438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 600438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 601438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask)); 602438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 603438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy; 604438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick androidPolicy.setPolicyMask(policyMask); 605438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 606438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 607438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 6084b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom // Sets up CloseGuard in Dalvik/libcore 6094b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static void setCloseGuardEnabled(boolean enabled) { 6107c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick if (!(CloseGuard.getReporter() instanceof AndroidCloseGuardReporter)) { 6114b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setReporter(new AndroidCloseGuardReporter()); 6124b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 6134b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setEnabled(enabled); 6144b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 6154b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 6165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { 6175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 61832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_NETWORK); 6195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { 6235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 62432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_READ); 6255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { 6295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 63032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_WRITE); 6315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 634438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 63515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 636438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 63732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled 63832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 63932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 640438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 64132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static int getThreadPolicyMask() { 642438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 643438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 644438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 6455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 64632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Returns the current thread's policy. 64732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 64832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy getThreadPolicy() { 64932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(getThreadPolicyMask()); 65032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 65132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 65232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 65332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 65432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 65532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit both disk reads & writes, and sets the new policy 65632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 65732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 65897461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 65932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to {@link #setThreadPolicy} to 66032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * restore the policy at the end of a block 66197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 66232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskWrites() { 66332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 66432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ); 66532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 66632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 66797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 66832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 66997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 67097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 67197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 67232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 67332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 67432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit disk reads, and sets the new policy 67532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 67632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 67797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 67832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to setThreadPolicy to 67997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 68097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 68132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskReads() { 68232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 68332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ); 68432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 68532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 68697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 68732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 68897461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 68997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 69097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 69150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * Enable DropBox logging for debug phone builds. 69250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * 69350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * @hide 69450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick */ 69550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 69650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 69750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 6981181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick if (IS_USER_BUILD) { 6997c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick setCloseGuardEnabled(false); 70050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return false; 70150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 70232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.setThreadPolicyMask( 70332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_DISK_WRITE | 70432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_DISK_READ | 70532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.DETECT_NETWORK | 70650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.PENALTY_DROPBOX); 70732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | 708fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom StrictMode.DETECT_VM_CLOSABLE_LEAKS | 70932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.PENALTY_DROPBOX | 71032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick StrictMode.PENALTY_LOG; 7117c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 71250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return true; 71350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 71450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 71550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick /** 716b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Used by the framework to make network usage on the main 717b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * thread a fatal error. 718b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 719b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 720b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 721b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static void enableDeathOnNetwork() { 722b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int oldPolicy = getThreadPolicyMask(); 723b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int newPolicy = oldPolicy | DETECT_NETWORK | PENALTY_DEATH_ON_NETWORK; 724b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick setThreadPolicyMask(newPolicy); 725b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 726b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 727b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 7285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 7295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 7305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 7315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 7325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Input is of form "policy=137 violation=64" 7335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 7345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 7355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 7365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 7375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 7385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 7395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 7405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 7435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (spaceIndex == -1) { 7445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 7475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 7485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 7495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 7505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 7555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 7565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 7575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 7585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null) { 7595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 7625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (violationIndex == -1) { 7635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String violationString = message.substring(violationIndex + 10); 7665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 7675b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 7685b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 7695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 7705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7715b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7725b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 773191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 774191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 775191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 776191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return new ArrayList<ViolationInfo>(); 777191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 778191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick }; 779191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 780191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static boolean tooManyViolationsThisLoop() { 781191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; 782191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 783191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 784438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 785438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private int mPolicyMask; 78646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 78746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 78846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // last violation. No locking needed, as this is only 78946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // accessed by the same thread. 79046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); 791438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 792438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 793438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 794438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 795438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 7965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick @Override 7975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public String toString() { 7985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 7995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 801438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 802438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public int getPolicyMask() { 803438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mPolicyMask; 804438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 805438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 806438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 807438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onWriteToDisk() { 80832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { 809438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 810438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 811191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 812191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 813191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 814cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 815cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 816cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 817438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 818438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 819438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 820438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onReadFromDisk() { 82132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_READ) == 0) { 822438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 823438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 824191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 825191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 826191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 827cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 828cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 829cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 830438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 831438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 832438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 833438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onNetwork() { 83432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_NETWORK) == 0) { 835438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 836438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 837b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) { 838b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick throw new NetworkOnMainThreadException(); 839b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 840191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 841191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 842191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 843cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 844cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 845cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 846438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 847438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 848438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void setPolicyMask(int policyMask) { 849438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 850438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 851438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 8525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 8535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 8545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 8555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 8565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 8575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 858cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 859cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 860cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolationWithTimingAttempt(info); 861cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 862438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 863cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 864cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 865cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // to measure with. We measure from the time of violation 866cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // until the time the looper is idle again (right before 867cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // the next epoll_wait) 868cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 869438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Looper looper = Looper.myLooper(); 870cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 871cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Without a Looper, we're unable to time how long the 872cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // violation takes place. This case should be rare, as 873cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // most users will care about timing violations that 874cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // happen on their main UI thread. Note that this case is 875cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // also hit when a violation takes place in a Binder 876cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 877cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // of the violation is computed by the ultimate caller and 878cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // its Looper, if any. 879cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 880cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // go into this immediate mode? 881438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (looper == null) { 882cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 883cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(info); 884cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 885438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 886438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 887cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick MessageQueue queue = Looper.myQueue(); 888cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 889191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() >= MAX_OFFENSES_PER_LOOP) { 890cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 891cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 892cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 893cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.add(info); 894cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() > 1) { 895cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // There's already been a violation this loop, so we've already 896cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // registered an idle handler to process the list of violations 897cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // at the end of this Looper's loop. 898cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 899cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 900cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 901cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick queue.addIdleHandler(new MessageQueue.IdleHandler() { 902cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public boolean queueIdle() { 903cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 904cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 905cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo v = records.get(n); 906cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.violationNumThisLoop = n + 1; 907cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.durationMillis = 908cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 909cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(v); 910cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 911cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.clear(); 912cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return false; // remove this idle handler from the array 913cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 914cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }); 9155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 916438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 9175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Note: It's possible (even quite likely) that the 9185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread-local policy mask has changed from the time the 9195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation fired and now (after the violating code ran) due 9205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to people who push/pop temporary policy in regions of code, 9215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // hence the policy being passed around. 922cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolation(final ViolationInfo info) { 923cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 924cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 9255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 927438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 928cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 92946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 930cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 931cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 932703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 933cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 934703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(violations); 935703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else if (violations.size() >= 5) { 9365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 9375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 939cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 940cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 9415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Duplicate. Don't log. 9425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 9435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 945cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations.add(info); 946727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return; 947727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 948727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 94946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 950cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Integer crashFingerprint = info.crashInfo.stackTrace.hashCode(); 95146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long lastViolationTime = 0; 95246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (mLastViolationTime.containsKey(crashFingerprint)) { 95346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick lastViolationTime = mLastViolationTime.get(crashFingerprint); 95446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 95546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 95646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 95746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 95846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 95946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 960cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 96146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 962cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.durationMillis != -1) { 9635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 964cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 965438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 966cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 967438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 968438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 969438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 97071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // The violationMaskSubset, passed to ActivityManager, is a 97146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 97246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // only the bit violated and penalty bits to be executed 97346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // by the ActivityManagerService remaining set. 974cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 97546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 976cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 97746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 978cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 97946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 98046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 981cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 982cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 98346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 98446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 985cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 986cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 987cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 98871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick final int violationMaskSubsetFinal = violationMaskSubset; 98932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 99071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 99171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick final boolean justDropBox = (info.policy & PENALTY_MASK) == PENALTY_DROPBOX; 99271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick if (justDropBox) { 99371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // If all we're going to ask the activity manager 99471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // to do is dropbox it (the common case during 99571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // platform development), we can avoid doing this 99671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // call synchronously which Binder data suggests 99771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // isn't always super fast, despite the implementation 99871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // in the ActivityManager trying to be mostly async. 99971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick new Thread("callActivityManagerForStrictModeDropbox") { 100071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick public void run() { 100171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 100271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick try { 100371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick ActivityManagerNative.getDefault(). 100471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick handleApplicationStrictModeViolation( 100571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick RuntimeInit.getApplicationObject(), 100671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick violationMaskSubsetFinal, 100771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick info); 100871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } catch (RemoteException e) { 100971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick Log.e(TAG, "RemoteException handling StrictMode violation", e); 101071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 101171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 101271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick }.start(); 101371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick return; 101471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 101571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 101671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // Normal synchronous call to the ActivityManager. 1017438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 1018727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 1019727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 1020727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 1021727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // We restore the current policy below, in the finally block. 102232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 1023727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1024438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 1025438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 1026cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 1027cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 1028438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (RemoteException e) { 102946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 1030727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } finally { 1031727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Restore the policy. 103232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 1033438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1034438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1035438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1036cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 1037438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); 1038438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Process.killProcess(Process.myPid()); 1039438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.exit(10); 1040438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1041438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1042438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1043727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 10444b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { 10454b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public void report (String message, Throwable allocationSite) { 10464b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, allocationSite); 10474b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 10484b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 10494b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 1050727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 10515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 10525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 10535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 1054703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return gatheredViolations.get() != null; 1055703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1056703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1057703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1058703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 1059703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 1060703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Binder call on this thread. 1061703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 1062703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 1063703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 10645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 10665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 106732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions in the VM process (on any 106832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * thread) should be detected, as well as the penalty if such 106932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * actions occur. 107032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 107132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 107232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 107332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setVmPolicy(final VmPolicy policy) { 107432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick sVmPolicyMask = policy.mask; 10754b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 107632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 107732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 107832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 107932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Gets the current VM policy. 108032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 108132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static VmPolicy getVmPolicy() { 108232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(sVmPolicyMask); 108332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 108432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 108532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 108662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * Enable the recommended StrictMode defaults, with violations just being logged. 108762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * 108862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * <p>This catches disk and network access on the main thread, as 1089fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * well as leaked SQLite cursors and unclosed resources. This is 1090fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * simply a wrapper around {@link #setVmPolicy} and {@link 1091fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * #setThreadPolicy}. 109262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick */ 109362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick public static void enableDefaults() { 109462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 109562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectAll() 109662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 109762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 109862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 109962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectLeakedSqlLiteObjects() 1100fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom .detectLeakedClosableObjects() 110162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 110262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 110362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 110462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick 110562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 110632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 110732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 110832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static boolean vmSqliteObjectLeaksEnabled() { 110932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0; 111032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 111132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 111232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 111332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 111432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 1115fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static boolean vmClosableObjectLeaksEnabled() { 1116fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return (sVmPolicyMask & DETECT_VM_CLOSABLE_LEAKS) != 0; 1117fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 1118fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 1119fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 1120fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 1121fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 112232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void onSqliteObjectLeaked(String message, Throwable originStack) { 11234b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, originStack); 11244b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 11254b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 11264b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom /** 11274b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom * @hide 11284b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom */ 11294b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public static void onVmPolicyViolation(String message, Throwable originStack) { 113032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_LOG) != 0) { 113132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, message, originStack); 113232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 113332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 113432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_DROPBOX) != 0) { 113532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); 113632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 113732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 113832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // subset of the original StrictMode policy bitmask, with 113932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // only the bit violated and penalty bits to be executed 114032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // by the ActivityManagerService remaining set. 114132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS; 114232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 114332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick try { 114432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 114532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 114632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 114732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // We restore the current policy below, in the finally block. 114832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 114932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 115032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 115132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick RuntimeInit.getApplicationObject(), 115232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick violationMaskSubset, 115332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick info); 115432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } catch (RemoteException e) { 115532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 115632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } finally { 115732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Restore the policy. 115832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 115932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 116032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 116132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 116232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_DEATH) != 0) { 116332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down."); 116432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Process.killProcess(Process.myPid()); 116532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.exit(10); 116632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 116732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 116832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 116932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 11705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 11715b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 11725b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 1173cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1174703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1175703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(0); 1176703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else { 1177703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(violations.size()); 1178703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 1179703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 1180703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1181703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 1182703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 11835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1184703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 11855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 11865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class LogStackTrace extends Exception {} 11885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 11895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 11905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 11915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * we here read back all the encoded violations. 11925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 11935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 11945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Our own stack trace to append 11955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StringWriter sw = new StringWriter(); 1196cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new LogStackTrace().printStackTrace(new PrintWriter(sw)); 11975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String ourStack = sw.toString(); 11985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 119932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int policyMask = getThreadPolicyMask(); 1200cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 12015b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 12025b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int numViolations = p.readInt(); 12035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 12045b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 1205cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 1206cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 12075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 12085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 1209cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 12105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 12145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1215727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Called from android_util_Binder.cpp's 1216727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 1217727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 1218727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 1219727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 1220727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * thread-local policy value. 1221727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 1222727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 1223727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 1224727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1225cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1226cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1227e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * A tracked, critical time span. (e.g. during an animation.) 1228e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1229e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * The object itself is a linked list node, to avoid any allocations 1230e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * during rapid span entries and exits. 1231e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1232e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1233e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1234e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static class Span { 1235e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private String mName; 1236e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private long mCreateMillis; 1237e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mNext; 1238e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mPrev; // not used when in freeList, only active 1239e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private final ThreadSpanState mContainerState; 1240e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1241e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span(ThreadSpanState threadState) { 1242e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mContainerState = threadState; 1243e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1244e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 12451181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Empty constructor for the NO_OP_SPAN 12461181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick protected Span() { 12471181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick mContainerState = null; 12481181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 12491181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1250e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1251e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * To be called when the critical span is complete (i.e. the 1252e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * animation is done animating). This can be called on any 1253e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread (even a different one from where the animation was 1254e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * taking place), but that's only a defensive implementation 1255e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * measure. It really makes no sense for you to call this on 1256e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread other than that where you created it. 1257e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1258e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1259e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1260e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public void finish() { 1261e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = mContainerState; 1262e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1263e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mName == null) { 1264e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Duplicate finish call. Ignore. 1265e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return; 1266e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1267e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1268e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Remove ourselves from the active list. 1269e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mPrev != null) { 1270e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mPrev.mNext = mNext; 1271e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1272e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mNext != null) { 1273e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mNext.mPrev = mPrev; 1274e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1275e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mActiveHead == this) { 1276e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = mNext; 1277e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1278e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1279e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mCreateMillis = -1; 1280e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mName = null; 1281e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mPrev = null; 1282e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = null; 1283e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveSize--; 1284e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1285e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Add ourselves to the freeList, if it's not already 1286e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // too big. 1287e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListSize < 5) { 1288e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = state.mFreeListHead; 1289e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = this; 1290e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize++; 1291e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1292e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1293e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1294e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1295e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 12961181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // The no-op span that's used in user builds. 12971181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final Span NO_OP_SPAN = new Span() { 12981181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick public void finish() { 12991181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Do nothing. 13001181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 13011181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick }; 13021181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1303e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1304e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Linked lists of active spans and a freelist. 1305e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1306e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Locking notes: there's one of these structures per thread and 1307e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * all members of this structure (as well as the Span nodes under 1308e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * it) are guarded by the ThreadSpanState object instance. While 1309e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * in theory there'd be no locking required because it's all local 1310e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * per-thread, the finish() method above is defensive against 1311e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * people calling it on a different thread from where they created 1312e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * the Span, hence the locking. 1313e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1314e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static class ThreadSpanState { 1315e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mActiveHead; // doubly-linked list. 1316e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mActiveSize; 1317e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mFreeListHead; // singly-linked list. only changes at head. 1318e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mFreeListSize; 1319e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1320e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1321e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final ThreadLocal<ThreadSpanState> sThisThreadSpanState = 1322e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick new ThreadLocal<ThreadSpanState>() { 1323e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick @Override protected ThreadSpanState initialValue() { 1324e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return new ThreadSpanState(); 1325e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1326e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick }; 1327e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1328e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1329e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Enter a named critical span (e.g. an animation) 1330e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1331e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>The name is an arbitary label (or tag) that will be applied 1332e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * to any strictmode violation that happens while this span is 1333e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * active. You must call finish() on the span when done. 1334e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1335e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>This will never return null, but on devices without debugging 1336e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * enabled, this may return a dummy object on which the finish() 1337e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * method is a no-op. 1338e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1339e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>TODO: add CloseGuard to this, verifying callers call finish. 1340e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1341e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1342e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1343e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static Span enterCriticalSpan(String name) { 13441181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick if (IS_USER_BUILD) { 13451181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick return NO_OP_SPAN; 13461181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 1347e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (name == null || name.isEmpty()) { 1348e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick throw new IllegalArgumentException("name must be non-null and non-empty"); 1349e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1350e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 1351e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span span = null; 1352e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1353e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListHead != null) { 1354e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = state.mFreeListHead; 1355e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = span.mNext; 1356e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize--; 1357e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } else { 1358e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Shouldn't have to do this often. 1359e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = new Span(state); 1360e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1361e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mName = name; 1362e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mCreateMillis = SystemClock.uptimeMillis(); 1363e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext = state.mActiveHead; 1364e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mPrev = null; 1365e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = span; 1366e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveSize++; 1367e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (span.mNext != null) { 1368e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext.mPrev = span; 1369e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1370e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1371e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return span; 1372e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1373e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1374e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1375e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1376cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 1377cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * to report violations that happened during a cross-process call. 1378cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1379cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @hide 1380cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1381cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static class ViolationInfo { 1382cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1383cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Stack and other stuff info. 1384cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1385cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 1386cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1387cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1388cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The strict mode policy mask at the time of violation. 1389cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1390cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final int policy; 1391cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1392cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1393cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 1394cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * not known. 1395cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1396cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int durationMillis = -1; 1397cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1398cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1399599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick * The number of animations currently running. 1400599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick */ 1401599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick public int numAnimationsRunning = 0; 1402599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick 1403599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick /** 1404e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * List of tags from active Span instances during this 1405e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * violation, or null for none. 1406e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1407e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public String[] tags; 1408e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1409e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1410cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Which violation number this was (1-based) since the last Looper loop, 1411cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 1412cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 1413cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * thread. 1414cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1415cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int violationNumThisLoop; 1416cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1417cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1418cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 1419cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * violation occurred. 1420cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1421cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public long violationUptimeMillis; 1422cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1423cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1424bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * The action of the Intent being broadcast to somebody's onReceive 1425bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * on this thread right now, or null. 1426bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick */ 1427bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick public String broadcastIntentAction; 1428bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick 1429bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick /** 1430cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 1431cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1432cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo() { 1433cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = null; 1434cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = 0; 1435cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1436cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1437cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1438cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 1439cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1440cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 1441cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 1442cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = SystemClock.uptimeMillis(); 1443cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this.policy = policy; 1444599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount(); 1445bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast(); 1446bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntent != null) { 1447bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = broadcastIntent.getAction(); 1448bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1449e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 1450e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1451e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int spanActiveCount = state.mActiveSize; 1452e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount > MAX_SPAN_TAGS) { 1453e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick spanActiveCount = MAX_SPAN_TAGS; 1454e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1455e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount != 0) { 1456e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags = new String[spanActiveCount]; 1457e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span iter = state.mActiveHead; 1458e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 1459e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick while (iter != null && index < spanActiveCount) { 1460e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags[index] = iter.mName; 1461e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick index++; 1462e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick iter = iter.mNext; 1463e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1464e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1465e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1466cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1467cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1468cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1469cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1470cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1471cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in) { 1472cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this(in, false); 1473cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1474cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1475cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1476cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1477cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1478cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @param unsetGatheringBit if true, the caller is the root caller 1479cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * and the gathering penalty should be removed. 1480cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1481cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 1482cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 1483cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int rawPolicy = in.readInt(); 1484cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (unsetGatheringBit) { 1485cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 1486cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } else { 1487cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy; 1488cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1489cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick durationMillis = in.readInt(); 1490cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationNumThisLoop = in.readInt(); 1491599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick numAnimationsRunning = in.readInt(); 1492cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = in.readLong(); 1493bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = in.readString(); 1494e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick tags = in.readStringArray(); 1495cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1496cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1497cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1498cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 1499cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1500cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 1501cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 1502cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(policy); 1503cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(durationMillis); 1504cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 1505599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick dest.writeInt(numAnimationsRunning); 1506cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 1507bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick dest.writeString(broadcastIntentAction); 1508e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick dest.writeStringArray(tags); 1509cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1510cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1511cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1512cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1513cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Dump a ViolationInfo instance to a Printer. 1514cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1515cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void dump(Printer pw, String prefix) { 1516cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.dump(pw, prefix); 1517cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 1518cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (durationMillis != -1) { 1519cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "durationMillis: " + durationMillis); 1520cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1521cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationNumThisLoop != 0) { 1522cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 1523cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1524599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick if (numAnimationsRunning != 0) { 1525599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick pw.println(prefix + "numAnimationsRunning: " + numAnimationsRunning); 1526599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick } 1527cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 1528bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntentAction != null) { 1529bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction); 1530bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1531e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (tags != null) { 1532e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 1533e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick for (String tag : tags) { 1534e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick pw.println(prefix + "tag[" + (index++) + "]: " + tag); 1535e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1536e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1537cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1538cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1539cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1540438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick} 1541