StrictMode.java revision 15ba4061116e088d62a7e05a0037f294f31dff06
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 18438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ActivityManagerNative; 19438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ApplicationErrorReport; 20438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Log; 21cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrickimport android.util.Printer; 22438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 23438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit; 24438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 25438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport dalvik.system.BlockGuard; 26438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.PrintWriter; 285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.StringWriter; 295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.util.ArrayList; 3046d42387464a651268648659e91d022566d4844cBrad Fitzpatrickimport java.util.HashMap; 3146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 32438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/** 3315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is a developer tool which lets you impose stricter 3415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * rules under which your application runs. 3515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 3615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or 3715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * network access on the application's main thread, where UI 3815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * operations are received and animations take place. Keeping disk 3915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and network operations off the main thread makes for much smoother, 4015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more responsive applications. 4115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 4215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is 4315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that 4415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * memory with very limited concurrency. It's often the case that 4515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be 4615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background 4715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from other processes. If possible, it's best to assume that such 4815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p> 4915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your 5115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or 5215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's 5315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method: 5415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre> 5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() { 5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * if (DEVELOPER_MODE) { 5815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * StrictMode.setThreadPolicy(StrictMode.DISALLOW_DISK_WRITE | 5915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * StrictMode.DISALLOW_DISK_READ | 6015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * StrictMode.DISALLOW_NETWORK | 6115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * StrictMode.PENALTY_LOG); 6215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 6315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * super.onCreate(); 6415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 6515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * </pre> 6615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 6715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Then you can watch the output of <code>adb logcat</code> while you 6815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * use your application. 6915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 7015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are 7115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler}, 7215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc. 7315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds. In particular, 7415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a lot of disk accesses are often necessary during the normal activity lifecycle. Use 7515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * StrictMode to find things you did on accident. Network requests on the UI thread 7615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * are almost always a problem, though. 7715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 7815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not 7915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses. While it does 8015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing 8115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best 8215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * effort mechanism. Notably, disk or network access from JNI calls 8315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * won't necessarily trigger it. Future versions of Android may catch 8415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode 8515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * enabled in shipping applications on the Android Market. 86438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 87438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpublic final class StrictMode { 88438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static final String TAG = "StrictMode"; 895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static final boolean LOG_V = false; 90438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 9146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 9246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 9346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 9446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 9546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 9646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 97438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private StrictMode() {} 98438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 9915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 10015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Flag for {@link #setThreadPolicy} to signal that you don't intend for this 10115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * thread to write to disk. 10215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 103438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int DISALLOW_DISK_WRITE = 0x01; 10415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 10515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 10615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Flag for {@link #setThreadPolicy} to signal that you don't intend for this 10715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * thread to read from disk. 10815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 109438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int DISALLOW_DISK_READ = 0x02; 11015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 11115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 11215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Flag for {@link #setThreadPolicy} to signal that you don't intend for this 11315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * thread to access the network. 11415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 115438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int DISALLOW_NETWORK = 0x04; 116438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 117438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** @hide */ 118438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int DISALLOW_MASK = 119438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick DISALLOW_DISK_WRITE | DISALLOW_DISK_READ | DISALLOW_NETWORK; 120438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 121438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 12215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Penalty flag for {@link #setThreadPolicy} to log violations to 12315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * the system log, visible with <code>adb logcat</code>. 124438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 125438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 126438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 127438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 12815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Penalty flag for {@link #setThreadPolicy} to show an annoying 12915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dialog to the developer, rate-limited to be only a little 13015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * annoying. 131438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 132438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 133438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 134438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 13515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Penalty flag for {@link #setThreadPolicy} to crash hard if 13615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * policy is violated. 137438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 138438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DEATH = 0x40; 139438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 140438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 14115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Penalty flag for {@link #setThreadPolicy} to log a stacktrace 14215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and timing data to the 14315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.DropBoxManager DropBox} on policy violation. 14415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Intended mostly for platform integrators doing beta user field 14515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * data collection. 146438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 147438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DROPBOX = 0x80; 148438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 149727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 150727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 151727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * bits and signals that we're in a Binder call and we should 152727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 153727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 154727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * in the originating process. 155727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 156703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 157703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * 158727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @hide 159727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 160727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 161727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 162438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** @hide */ 163438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_MASK = 164438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick PENALTY_LOG | PENALTY_DIALOG | 165438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick PENALTY_DROPBOX | PENALTY_DEATH; 166438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 167438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 1685b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Log of strict mode violation stack traces that have occurred 1695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * during a Binder call, to be serialized back later to the caller 1705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 1715b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * choose how to react. 1725b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 173cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 174cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 175cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 176703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 177703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // checking whether there are any violations or not in 178703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // hasGatheredViolations() below. 179703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return null; 1805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick }; 1825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 1835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 18415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Sets the policy for what actions the current thread isn't 18515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * expected to do, as well as the penalty if it does. 18615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 18715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Internally this sets a thread-local integer which is 18815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 18915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * catch violations when a system service or another process 19015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * accesses the disk or network on your behalf. 191438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 19215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * @param policyMask a bitmask of DISALLOW_* and PENALTY_* values, 19315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * e.g. {@link #DISALLOW_DISK_READ}, {@link #DISALLOW_DISK_WRITE}, 19415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link #DISALLOW_NETWORK}, {@link #PENALTY_LOG}. 195438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 19697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick public static void setThreadPolicy(final int policyMask) { 197727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // In addition to the Java-level thread-local in Dalvik's 198727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // BlockGuard, we also need to keep a native thread-local in 199727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 200727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // even across native-only processes. The two are kept in 201727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 202727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(policyMask); 203727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 204727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // And set the Android native version... 205727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 206727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 207727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 208727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 209727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 21046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (policyMask == 0) { 21146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 21246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 21346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 214438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 215438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 216438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask)); 217438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 218438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy; 219438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick androidPolicy.setPolicyMask(policyMask); 220438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 221438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 222438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 2235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { 2245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 2255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick super(policyMask, DISALLOW_NETWORK); 2265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 2275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 2285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 2295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { 2305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 2315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick super(policyMask, DISALLOW_DISK_READ); 2325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 2335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 2345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 2355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { 2365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 2375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick super(policyMask, DISALLOW_DISK_WRITE); 2385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 2395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 2405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 241438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 24215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 243438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 244438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * @return the bitmask of all the DISALLOW_* and PENALTY_* bits currently enabled 245438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 24697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick public static int getThreadPolicy() { 247438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 248438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 249438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 2505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 25115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * A convenience wrapper around {@link #getThreadPolicy} and 25215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link #setThreadPolicy}. Updates the current thread's policy 25315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * mask to allow both reading & writing to disk, returning the 25415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * old policy so you can restore it at the end of a block. 25597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 25697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * @return the old policy mask, to be passed to setThreadPolicy to 25797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 25897461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 25997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick public static int allowThreadDiskWrites() { 26097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick int oldPolicy = getThreadPolicy(); 26197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick int newPolicy = oldPolicy & ~(DISALLOW_DISK_WRITE | DISALLOW_DISK_READ); 26297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick if (newPolicy != oldPolicy) { 26397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick setThreadPolicy(newPolicy); 26497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 26597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick return oldPolicy; 26697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 26797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 26897461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 26915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * A convenience wrapper around {@link #getThreadPolicy} and 27015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link #setThreadPolicy}. Updates the current thread's policy 27115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * mask to allow reading from disk, returning the old 27215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * policy so you can restore it at the end of a block. 27397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 27497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * @return the old policy mask, to be passed to setThreadPolicy to 27597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 27697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 27797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick public static int allowThreadDiskReads() { 27897461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick int oldPolicy = getThreadPolicy(); 27997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick int newPolicy = oldPolicy & ~(DISALLOW_DISK_READ); 28097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick if (newPolicy != oldPolicy) { 28197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick setThreadPolicy(newPolicy); 28297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 28397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick return oldPolicy; 28497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 28597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 28697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 28750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * Enable DropBox logging for debug phone builds. 28850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * 28950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * @hide 29050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick */ 29150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 29250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 29350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 29450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick if ("user".equals(Build.TYPE)) { 29550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return false; 29650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 29750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.setThreadPolicy( 29850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.DISALLOW_DISK_WRITE | 29950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.DISALLOW_DISK_READ | 30050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.DISALLOW_NETWORK | 30150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick StrictMode.PENALTY_DROPBOX); 30250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return true; 30350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 30450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 30550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick /** 3065b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 3075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 3085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 3095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 3105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Input is of form "policy=137 violation=64" 3115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 3125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 3135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 3145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 3155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 3165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 3175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 3185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 3195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 3215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (spaceIndex == -1) { 3225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 3235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 3255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 3265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 3275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 3285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 3295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 3325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 3335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 3345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 3355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 3365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null) { 3375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 3385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 3405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (violationIndex == -1) { 3415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 3425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String violationString = message.substring(violationIndex + 10); 3445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 3455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 3465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 3475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 3485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 351438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 352438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private int mPolicyMask; 35346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 35446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 35546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // last violation. No locking needed, as this is only 35646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // accessed by the same thread. 35746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); 358438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 359438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 360438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 361438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 362438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 3635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick @Override 3645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public String toString() { 3655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 3665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 3675b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 368438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 369438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public int getPolicyMask() { 370438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mPolicyMask; 371438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 372438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 373438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 374438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onWriteToDisk() { 375438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if ((mPolicyMask & DISALLOW_DISK_WRITE) == 0) { 376438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 377438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 378cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 379cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 380cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 381438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 382438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 383438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 384438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onReadFromDisk() { 385438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if ((mPolicyMask & DISALLOW_DISK_READ) == 0) { 386438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 387438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 388cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 389cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 390cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 391438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 392438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 393438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 394438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onNetwork() { 395438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if ((mPolicyMask & DISALLOW_NETWORK) == 0) { 396438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 397438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 398cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 399cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 400cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 401438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 402438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 403438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void setPolicyMask(int policyMask) { 404438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 405438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 406438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 4075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 4085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 4095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 4105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 4115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 4125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 413cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 414cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 415cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolationWithTimingAttempt(info); 416cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 417438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 418cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 419cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 420cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 421cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return new ArrayList<ViolationInfo>(); 422cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 423cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }; 424cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 425cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 426cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 427cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // to measure with. We measure from the time of violation 428cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // until the time the looper is idle again (right before 429cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // the next epoll_wait) 430cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 431438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Looper looper = Looper.myLooper(); 432cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 433cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Without a Looper, we're unable to time how long the 434cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // violation takes place. This case should be rare, as 435cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // most users will care about timing violations that 436cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // happen on their main UI thread. Note that this case is 437cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // also hit when a violation takes place in a Binder 438cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 439cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // of the violation is computed by the ultimate caller and 440cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // its Looper, if any. 441cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 442cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // go into this immediate mode? 443438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (looper == null) { 444cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 445cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(info); 446cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 447438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 448438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 449cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick MessageQueue queue = Looper.myQueue(); 450cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 451cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() >= 10) { 452cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 453cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 454cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 455cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.add(info); 456cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() > 1) { 457cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // There's already been a violation this loop, so we've already 458cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // registered an idle handler to process the list of violations 459cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // at the end of this Looper's loop. 460cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 461cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 462cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 463cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick queue.addIdleHandler(new MessageQueue.IdleHandler() { 464cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public boolean queueIdle() { 465cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 466cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 467cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo v = records.get(n); 468cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.violationNumThisLoop = n + 1; 469cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.durationMillis = 470cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 471cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(v); 472cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 473cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.clear(); 474cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return false; // remove this idle handler from the array 475cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 476cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }); 4775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 478438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 4795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Note: It's possible (even quite likely) that the 4805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread-local policy mask has changed from the time the 4815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation fired and now (after the violating code ran) due 4825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to people who push/pop temporary policy in regions of code, 4835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // hence the policy being passed around. 484cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolation(final ViolationInfo info) { 485cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 486cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 4875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 4885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 489438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 490cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 49146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 492cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 493cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 494703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 495cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 496703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(violations); 497703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else if (violations.size() >= 5) { 4985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 4995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 5005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 501cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 502cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 5035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Duplicate. Don't log. 5045b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 5055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5065b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 507cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations.add(info); 508727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return; 509727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 510727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 51146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 512cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Integer crashFingerprint = info.crashInfo.stackTrace.hashCode(); 51346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long lastViolationTime = 0; 51446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (mLastViolationTime.containsKey(crashFingerprint)) { 51546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick lastViolationTime = mLastViolationTime.get(crashFingerprint); 51646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 51746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 51846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 51946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 52046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 52146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 522cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 52346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 524cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.durationMillis != -1) { 5255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 526cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 527438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 528cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 529438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 530438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 531438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 53246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // The violationMask, passed to ActivityManager, is a 53346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 53446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // only the bit violated and penalty bits to be executed 53546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // by the ActivityManagerService remaining set. 536cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 53746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 538cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 53946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 540cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 54146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 54246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 543cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 544cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 54546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 54646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 547cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 548cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 549cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 55097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick final int savedPolicy = getThreadPolicy(); 551438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 552727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 553727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 554727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 555727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // We restore the current policy below, in the finally block. 55697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick setThreadPolicy(0); 557727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 558438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 559438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 560cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 561cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 562438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (RemoteException e) { 56346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 564727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } finally { 565727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Restore the policy. 56697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick setThreadPolicy(savedPolicy); 567438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 568438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 569438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 570cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 571438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); 572438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Process.killProcess(Process.myPid()); 573438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.exit(10); 574438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 575438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 576438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 577727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 578727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 5795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 5805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 5815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 582703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return gatheredViolations.get() != null; 583703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 584703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 585703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 586703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 587703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 588703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Binder call on this thread. 589703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 590703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 591703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 5925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 5935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 5945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 5955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 5965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 5975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 598cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 599703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 600703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(0); 601703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else { 602703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(violations.size()); 603703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 604703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 605703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 606703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 607703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 6085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 609703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 6105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class LogStackTrace extends Exception {} 6135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 6155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 6165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * we here read back all the encoded violations. 6175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 6185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 6195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Our own stack trace to append 6205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StringWriter sw = new StringWriter(); 621cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new LogStackTrace().printStackTrace(new PrintWriter(sw)); 6225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String ourStack = sw.toString(); 6235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 62497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick int policyMask = getThreadPolicy(); 625cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 6265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int numViolations = p.readInt(); 6285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 6295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 630cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 631cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 6325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 6335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 634cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 6355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 640727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Called from android_util_Binder.cpp's 641727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 642727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 643727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 644727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 645727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * thread-local policy value. 646727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 647727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 648727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 649727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 650cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 651cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 652cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 653cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * to report violations that happened during a cross-process call. 654cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 655cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @hide 656cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 657cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static class ViolationInfo { 658cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 659cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Stack and other stuff info. 660cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 661cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 662cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 663cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 664cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The strict mode policy mask at the time of violation. 665cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 666cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final int policy; 667cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 668cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 669cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 670cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * not known. 671cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 672cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int durationMillis = -1; 673cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 674cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 675cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Which violation number this was (1-based) since the last Looper loop, 676cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 677cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 678cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * thread. 679cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 680cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int violationNumThisLoop; 681cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 682cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 683cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 684cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * violation occurred. 685cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 686cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public long violationUptimeMillis; 687cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 688cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 689cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 690cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 691cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo() { 692cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = null; 693cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = 0; 694cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 695cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 696cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 697cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 698cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 699cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 700cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 701cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = SystemClock.uptimeMillis(); 702cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this.policy = policy; 703cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 704cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 705cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 706cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 707cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 708cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in) { 709cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this(in, false); 710cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 711cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 712cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 713cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 714cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 715cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @param unsetGatheringBit if true, the caller is the root caller 716cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * and the gathering penalty should be removed. 717cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 718cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 719cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 720cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int rawPolicy = in.readInt(); 721cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (unsetGatheringBit) { 722cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 723cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } else { 724cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy; 725cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 726cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick durationMillis = in.readInt(); 727cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationNumThisLoop = in.readInt(); 728cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = in.readLong(); 729cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 730cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 731cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 732cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 733cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 734cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 735cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 736cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(policy); 737cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(durationMillis); 738cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 739cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 740cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 741cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 742cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 743cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 744cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Dump a ViolationInfo instance to a Printer. 745cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 746cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void dump(Printer pw, String prefix) { 747cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.dump(pw, prefix); 748cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 749cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (durationMillis != -1) { 750cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "durationMillis: " + durationMillis); 751cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 752cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationNumThisLoop != 0) { 753cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 754cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 755cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 756cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 757cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 758cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 759438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick} 760