StrictMode.java revision c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782
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; 221065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrickimport android.app.IActivityManager; 23bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.content.Intent; 24438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Log; 25cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrickimport android.util.Printer; 26cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrickimport android.util.Singleton; 276804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrickimport android.view.IWindowManager; 28438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 29438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit; 30438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 31438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport dalvik.system.BlockGuard; 32fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstromimport dalvik.system.CloseGuard; 33bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrickimport dalvik.system.VMDebug; 34438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.PrintWriter; 365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.StringWriter; 375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.util.ArrayList; 38758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrickimport java.util.Collections; 3946d42387464a651268648659e91d022566d4844cBrad Fitzpatrickimport java.util.HashMap; 405f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrickimport java.util.Map; 41bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrickimport java.util.concurrent.atomic.AtomicInteger; 4246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 43438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/** 4432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>StrictMode is a developer tool which detects things you might be 4532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * doing by accident and brings them to your attention so you can fix 4632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * them. 4715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 4815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or 4915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * network access on the application's main thread, where UI 5015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * operations are received and animations take place. Keeping disk 5115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and network operations off the main thread makes for much smoother, 529fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * more responsive applications. By keeping your application's main thread 539fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * responsive, you also prevent 549fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * <a href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a> 559fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * from being shown to users. 5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is 5815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that 5915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * memory with very limited concurrency. It's often the case that 6015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be 6115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background 6215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from other processes. If possible, it's best to assume that such 6315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p> 6415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 6515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your 6615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or 6715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's 6815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method: 6915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 7015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre> 7115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() { 7215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * if (DEVELOPER_MODE) { 7332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}() 7432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskReads() 7532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskWrites() 7632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectNetwork() // or .detectAll() for all detectable problems 7732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 7832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 7932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}() 8062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * .detectLeakedSqlLiteObjects() 81fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * .detectLeakedClosableObjects() 8232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 8332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyDeath() 8432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 8515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 8615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * super.onCreate(); 8715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 8815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * </pre> 8915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 9032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can decide what should happen when a violation is detected. 9132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * For example, using {@link ThreadPolicy.Builder#penaltyLog} you can 9232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * watch the output of <code>adb logcat</code> while you use your 9332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * application to see the violations as they happen. 9415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 9515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are 9615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler}, 9715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc. 9815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds. In particular, 9932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * many cases of disk access are often necessary during the normal activity lifecycle. Use 10032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode to find things you did by accident. Network requests on the UI thread 10115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * are almost always a problem, though. 10215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 10315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not 10415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses. While it does 10515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing 10615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best 10715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * effort mechanism. Notably, disk or network access from JNI calls 10815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * won't necessarily trigger it. Future versions of Android may catch 10915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode 11015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * enabled in shipping applications on the Android Market. 111438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 112438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpublic final class StrictMode { 113438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static final String TAG = "StrictMode"; 11482829ef3b7c72bee36d8c17b36ac565f1856a310Brad Fitzpatrick private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE); 115438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1161181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 1176804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE); 1181181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 119c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick /** 120c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * The boolean system property to control screen flashes on violations. 121c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * 122c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * @hide 123c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick */ 124c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick public static final String VISUAL_PROPERTY = "persist.sys.strictmode.visual"; 125c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 12646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 12746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 12846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 12946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 13046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 13146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 132e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // How many Span tags (e.g. animations) to report. 133e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final int MAX_SPAN_TAGS = 20; 134e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 135191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // How many offending stacks to keep track of (and time) per loop 136191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // of the Looper. 137191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final int MAX_OFFENSES_PER_LOOP = 10; 138191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 13932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Thread-policy: 140438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 14115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 14232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 14315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 14432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy 14515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 14615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 14732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 14815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 14932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy 15015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 15115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 15232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 15315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 15432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy 155438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 156e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 157e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * For StrictMode.noteSlowCall() 158e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * 159e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * @hide 160e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 161e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public static final int DETECT_CUSTOM = 0x08; // for ThreadPolicy 162e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 163e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick private static final int ALL_THREAD_DETECT_BITS = 164e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK | DETECT_CUSTOM; 165e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 16632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Process-policy: 167438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 168438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 16932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Note, a "VM_" bit, not thread. 17032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 17132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 172758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for VmPolicy 17332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 17432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 175fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Note, a "VM_" bit, not thread. 176fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 177fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 178758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for VmPolicy 179758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 180758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 181758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * Note, a "VM_" bit, not thread. 182758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * @hide 183758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 184758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final int DETECT_VM_ACTIVITY_LEAKS = 0x800; // for VmPolicy 185fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 186fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 18732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 188438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 189bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000; // for VmPolicy 190bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 191bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final int ALL_VM_DETECT_BITS = 192bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS | 193bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS; 194bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 195bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 196bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * @hide 197bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 198438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 199438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 20032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Used for both process and thread policy: 20132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 202438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 20332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 204438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 205438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 206438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 207438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 208b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death on any detected violation. 209b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 21032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 211438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 212438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DEATH = 0x40; 213438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 214438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 215b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death just for detected network usage. 216b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 217b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 218b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 219b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final int PENALTY_DEATH_ON_NETWORK = 0x200; 220b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 221b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 2226804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Flash the screen during violations. 2236804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * 2246804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * @hide 2256804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 2266804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick public static final int PENALTY_FLASH = 0x800; 2276804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 2286804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 22932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 230438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 231438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DROPBOX = 0x80; 232438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 233727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 234727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 235727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * bits and signals that we're in a Binder call and we should 236727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 237727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 238727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * in the originating process. 239727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 240703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 241703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * 242727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @hide 243727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 244727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 245727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 24632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 247c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick * Mask of all the penalty bits valid for thread policies. 24871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick */ 249c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick private static final int THREAD_PENALTY_MASK = 250b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | 2516804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; 25271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 253758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 254c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick /** 255c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick * Mask of all the penalty bits valid for VM policies. 256c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick */ 257c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick private static final int VM_PENALTY_MASK = 258c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick PENALTY_LOG | PENALTY_DEATH | PENALTY_DROPBOX; 259c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick 260c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick 261758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // TODO: wrap in some ImmutableHashMap thing. 262758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // Note: must be before static initialization of sVmPolicy. 263758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private static final HashMap<Class, Integer> EMPTY_CLASS_LIMIT_MAP = new HashMap<Class, Integer>(); 264758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 26571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /** 26632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The current VmPolicy in effect. 267758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * 268758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * TODO: these are redundant (mask is in VmPolicy). Should remove sVmPolicyMask. 26932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 27032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static volatile int sVmPolicyMask = 0; 271758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private static volatile VmPolicy sVmPolicy = VmPolicy.LAX; 27232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 273bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 274bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * The number of threads trying to do an async dropbox write. 275bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * Just to limit ourselves out of paranoia. 276bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 277bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick private static final AtomicInteger sDropboxCallsInFlight = new AtomicInteger(0); 278bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 27932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private StrictMode() {} 28032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 28132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 28232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to a certain thread. 28332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 28432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy 28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can be retrieved with {@link #getThreadPolicy}. 28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 28732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note that multiple penalties may be provided and they're run 28832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * in order from least to most severe (logging before process 28932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * death, for example). There's currently no mechanism to choose 29032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * different penalties for different detected actions. 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class ThreadPolicy { 29332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final ThreadPolicy LAX = new ThreadPolicy(0); 29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 29932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private ThreadPolicy(int mask) { 30132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 30232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 30332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.ThreadPolicy; mask=" + mask + "]"; 30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 310320274c5f17057a3a823fed50b7027cbd46fc025Brad Fitzpatrick * Creates {@link ThreadPolicy} instances. Methods whose names start 31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 321320274c5f17057a3a823fed50b7027cbd46fc025Brad Fitzpatrick * StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 32232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 325320274c5f17057a3a823fed50b7027cbd46fc025Brad Fitzpatrick * StrictMode.setThreadPolicy(policy); 32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 32932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask = 0; 33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create a Builder that detects nothing and has no 33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations. (but note that {@link #build} will default 33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to enabling {@link #penaltyLog} if no other penalties 33532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are specified) 33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder() { 33832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = 0; 33932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Initialize a Builder from an existing ThreadPolicy. 34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder(ThreadPolicy policy) { 34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = policy.mask; 34632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 34932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 35032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 35132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this includes network and 35232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * disk operations but will likely expand in future releases. 35332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 35432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 355e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(ALL_THREAD_DETECT_BITS); 35632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 35732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 35832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 35932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable the detection of everything. 36032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 36132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitAll() { 362e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return disable(ALL_THREAD_DETECT_BITS); 36332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 36432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 36532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 36632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of network operations. 36732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 36832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectNetwork() { 36932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_NETWORK); 37032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 37132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 37232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 37332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of network operations. 37432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitNetwork() { 37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_NETWORK); 37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 37832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 37932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 38032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk reads. 38132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 38232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskReads() { 38332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_READ); 38432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 38732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk reads. 38832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 38932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskReads() { 39032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_READ); 39132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 39232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 39332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 394e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * Enable detection of disk reads. 395e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 396e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public Builder detectCustomSlowCalls() { 397e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(DETECT_CUSTOM); 398e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 399e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 400e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 401e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * Enable detection of disk reads. 402e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 403e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public Builder permitCustomSlowCalls() { 404e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(DETECT_CUSTOM); 405e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 406e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 407e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk writes. 40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 41032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskWrites() { 41132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE); 41232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 41532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk writes. 41632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 41732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskWrites() { 41832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE); 41932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 42032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 42132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 42232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Show an annoying dialog to the developer on detected 42332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations, rate-limited to be only a little annoying. 42432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 42532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDialog() { 42632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DIALOG); 42732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 42832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 42932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 43032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crash the whole process on violation. This penalty runs at 43132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so you'll still get 43232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * see logging or other violations before the process dies. 433b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 434b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>Unlike {@link #penaltyDeathOnNetwork}, this applies 435b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * to disk reads, disk writes, and network usage if their 436b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * corresponding detect flags are set. 43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 443b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Crash the whole process on any network usage. Unlike 444b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * {@link #penaltyDeath}, this penalty runs 445b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <em>before</em> anything else. You must still have 446b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * called {@link #detectNetwork} to enable this. 447b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 448b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>In the Honeycomb or later SDKs, this is on by default. 449b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 450b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public Builder penaltyDeathOnNetwork() { 451b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return enable(PENALTY_DEATH_ON_NETWORK); 452b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 453b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 454b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 4556804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Flash the screen during a violation. 4566804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 4576804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick public Builder penaltyFlashScreen() { 4586804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick return enable(PENALTY_FLASH); 4596804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 4606804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 4616804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 46232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 46332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 46632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 46732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 46832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 46932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 47032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 47132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 47232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 47332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 47432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 47532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 47632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 47732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 47832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 47932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 48032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 48132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 48332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder disable(int bit) { 48432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask &= ~bit; 48532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 48632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 48732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 48832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 48932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the ThreadPolicy instance. 49032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 49132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 49232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 49332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 49432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 49532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ThreadPolicy build() { 49632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 49732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 49832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 49932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 50232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(mMask); 50432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 50932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to all threads in the virtual machine's process. 51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setVmPolicy}. 51232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 51332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class VmPolicy { 51432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 51532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 51632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 517758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final VmPolicy LAX = new VmPolicy(0, EMPTY_CLASS_LIMIT_MAP); 51832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 51932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 52032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 521758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // Map from class to max number of allowed instances in memory. 522758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick final HashMap<Class, Integer> classInstanceLimit; 523758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 524758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private VmPolicy(int mask, HashMap<Class, Integer> classInstanceLimit) { 525758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (classInstanceLimit == null) { 526758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick throw new NullPointerException("classInstanceLimit == null"); 527758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 52832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 529758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick this.classInstanceLimit = classInstanceLimit; 53032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 53132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 53232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 53332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 53432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.VmPolicy; mask=" + mask + "]"; 53532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 53632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 53732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 53832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates {@link VmPolicy} instances. Methods whose names start 53932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 54032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 54132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 54232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 54432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 54532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 54632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 54732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 54832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 54932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 55032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 55132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 55232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 55332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 55432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 55532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 55632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 55732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask; 55832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 559758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private HashMap<Class, Integer> mClassInstanceLimit; // null until needed 560758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private boolean mClassInstanceLimitNeedCow = false; // need copy-on-write 561758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 562758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public Builder() { 563758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mMask = 0; 564758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 565758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 566758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 567758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * Build upon an existing VmPolicy. 568758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 569758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public Builder(VmPolicy base) { 570758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mMask = base.mask; 571758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimitNeedCow = true; 572758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit = base.classInstanceLimit; 573758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 574758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 575758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 576758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * Set an upper bound on how many instances of a class can be in memory 577758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * at once. Helps to prevent object leaks. 578758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 579758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public Builder setClassInstanceLimit(Class klass, int instanceLimit) { 580758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (klass == null) { 581758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick throw new NullPointerException("klass == null"); 582758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 583758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (mClassInstanceLimitNeedCow) { 584758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (mClassInstanceLimit.containsKey(klass) && 585758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit.get(klass) == instanceLimit) { 586758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // no-op; don't break COW 587758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return this; 588758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 589758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimitNeedCow = false; 590758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit = (HashMap<Class, Integer>) mClassInstanceLimit.clone(); 591758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } else if (mClassInstanceLimit == null) { 592758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit = new HashMap<Class, Integer>(); 593758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 594bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mMask |= DETECT_VM_INSTANCE_LEAKS; 595758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit.put(klass, instanceLimit); 596758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return this; 597758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 598758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 599bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 600bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * Detect leaks of {@link android.app.Activity} subclasses. 601bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 602bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public Builder detectActivityLeaks() { 603758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return enable(DETECT_VM_ACTIVITY_LEAKS); 604758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 605758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 60632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 60732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 60832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 609fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>In the Honeycomb release this includes leaks of 610bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * SQLite cursors, Activities, and other closable objects 611bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * but will likely expand in future releases. 61232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 61332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 614758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return enable(DETECT_VM_ACTIVITY_LEAKS | 615758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); 61632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 61732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 61832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 61932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect when an 62032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link android.database.sqlite.SQLiteCursor} or other 62132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite object is finalized without having been closed. 62232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 62332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You always want to explicitly close your SQLite 62432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * cursors to avoid unnecessary database contention and 62532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * temporary memory leaks. 62632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 62732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectLeakedSqlLiteObjects() { 62832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 62932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 63032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 63132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 632fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Detect when an {@link java.io.Closeable} or other 633fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * object with a explict termination method is finalized 634fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * without having been closed. 635fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * 636fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>You always want to explicitly close such objects to 637fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * avoid unnecessary resources leaks. 638fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 639fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public Builder detectLeakedClosableObjects() { 640fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CLOSABLE_LEAKS); 641fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 642fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 643fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 64432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crashes the whole process on violation. This penalty runs at 64532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so yo you'll still get 64632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * your logging or other violations before the process dies. 64732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 64832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 64932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 65032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 65132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 65232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 65332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 65432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 65532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 65632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 65732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 65832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 65932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 66032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 66132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 66232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 66332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 66432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 66532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 66632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 66732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 66832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 66932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 67032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 67132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 67232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 67332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 67432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 67532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the VmPolicy instance. 67632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 67732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 67832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 67932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 68032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 68132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public VmPolicy build() { 68232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 68332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 68432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 68532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 68632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 68732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 68832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 689758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return new VmPolicy(mMask, 690758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit != null ? mClassInstanceLimit : EMPTY_CLASS_LIMIT_MAP); 69132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 69232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 69332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 694438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 695438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 6965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Log of strict mode violation stack traces that have occurred 6975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * during a Binder call, to be serialized back later to the caller 6985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 6995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * choose how to react. 7005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 701cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 702cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 703cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 704703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 705703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // checking whether there are any violations or not in 706703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // hasGatheredViolations() below. 707703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return null; 7085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick }; 7105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 71232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions on the current thread should 71332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * be detected, as well as the penalty if such actions occur. 71415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 71532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Internally this sets a thread-local variable which is 71615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 71715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * catch violations when a system service or another process 71815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * accesses the disk or network on your behalf. 719438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 72032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 721438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 72232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setThreadPolicy(final ThreadPolicy policy) { 72332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(policy.mask); 72432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 72532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 72632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static void setThreadPolicyMask(final int policyMask) { 727727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // In addition to the Java-level thread-local in Dalvik's 728727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // BlockGuard, we also need to keep a native thread-local in 729727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 730727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // even across native-only processes. The two are kept in 731727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 732727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(policyMask); 733727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 734727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // And set the Android native version... 735727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 736727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 737727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 738727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 739727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 74046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (policyMask == 0) { 74146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 74246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 74346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 744438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 745438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 746438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask)); 747438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 748438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy; 749438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick androidPolicy.setPolicyMask(policyMask); 750438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 751438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 752438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 7534b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom // Sets up CloseGuard in Dalvik/libcore 7544b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static void setCloseGuardEnabled(boolean enabled) { 7557c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick if (!(CloseGuard.getReporter() instanceof AndroidCloseGuardReporter)) { 7564b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setReporter(new AndroidCloseGuardReporter()); 7574b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 7584b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setEnabled(enabled); 7594b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 7604b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 7614e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 7624e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 7634e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 7644e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static class StrictModeViolation extends BlockGuard.BlockGuardPolicyException { 7654e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public StrictModeViolation(int policyState, int policyViolated, String message) { 7664e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyState, policyViolated, message); 7674e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 7684e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 7694e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 7704e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 7714e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 7724e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 7734e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static class StrictModeNetworkViolation extends StrictModeViolation { 7745b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 7754e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyMask, DETECT_NETWORK, null); 7765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7794e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 7804e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 7814e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 7824e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static class StrictModeDiskReadViolation extends StrictModeViolation { 7835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 7844e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyMask, DETECT_DISK_READ, null); 7855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7884e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 7894e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 7904e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 7914e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends StrictModeViolation { 7925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 7934e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyMask, DETECT_DISK_WRITE, null); 7945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7974e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 7984e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 7994e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 8004e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static class StrictModeCustomViolation extends StrictModeViolation { 801e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public StrictModeCustomViolation(int policyMask, String name) { 802e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick super(policyMask, DETECT_CUSTOM, name); 803e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 804e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 805e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 806438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 80715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 808438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 80932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled 81032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 81132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 812438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 81332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static int getThreadPolicyMask() { 814438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 815438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 816438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 8175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 81832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Returns the current thread's policy. 81932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 82032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy getThreadPolicy() { 821e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // TODO: this was a last minute Gingerbread API change (to 822e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // introduce VmPolicy cleanly) but this isn't particularly 823e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // optimal for users who might call this method often. This 824e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // should be in a thread-local and not allocate on each call. 82532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(getThreadPolicyMask()); 82632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 82732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 82832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 82932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 83032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 83132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit both disk reads & writes, and sets the new policy 83232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 83332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 83497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 83532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to {@link #setThreadPolicy} to 83632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * restore the policy at the end of a block 83797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 83832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskWrites() { 83932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 84032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ); 84132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 84232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 84397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 84432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 84597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 84697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 84797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 84832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 84932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 85032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit disk reads, and sets the new policy 85132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 85232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 85397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 85432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to setThreadPolicy to 85597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 85697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 85732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskReads() { 85832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 85932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ); 86032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 86132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 86297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 86332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 86497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 86597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 866f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // We don't want to flash the screen red in the system server 867f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // process, nor do we want to modify all the call sites of 868f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // conditionallyEnableDebugLogging() in the system server, 869f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // so instead we use this to determine if we are the system server. 870f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick private static boolean amTheSystemServerProcess() { 871f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // Fast path. Most apps don't have the system server's UID. 872f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick if (Process.myUid() != Process.SYSTEM_UID) { 873f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return false; 874f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 875f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick 876f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // The settings app, though, has the system server's UID so 877f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // look up our stack to see if we came from the system server. 878f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick Throwable stack = new Throwable(); 879f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick stack.fillInStackTrace(); 880f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick for (StackTraceElement ste : stack.getStackTrace()) { 881f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick String clsName = ste.getClassName(); 882f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick if (clsName != null && clsName.startsWith("com.android.server.")) { 883f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return true; 884f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 885f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 886f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return false; 887f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 888f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick 88997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 89050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * Enable DropBox logging for debug phone builds. 89150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * 89250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * @hide 89350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick */ 89450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 895f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick boolean doFlashes = !amTheSystemServerProcess() && 896f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick SystemProperties.getBoolean(VISUAL_PROPERTY, IS_ENG_BUILD); 897c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 89850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 89950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 900c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (IS_USER_BUILD && !doFlashes) { 9017c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick setCloseGuardEnabled(false); 90250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return false; 90350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 904c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 905c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick int threadPolicyMask = StrictMode.DETECT_DISK_WRITE | 906c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.DETECT_DISK_READ | 907c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.DETECT_NETWORK; 908c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 909c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (!IS_USER_BUILD) { 910c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick threadPolicyMask |= StrictMode.PENALTY_DROPBOX; 911c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 912c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (doFlashes) { 913c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick threadPolicyMask |= StrictMode.PENALTY_FLASH; 914c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 915c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 916c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.setThreadPolicyMask(threadPolicyMask); 917c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 918c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (IS_USER_BUILD) { 919c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick setCloseGuardEnabled(false); 920c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } else { 921758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick setVmPolicy(new VmPolicy.Builder().detectAll().penaltyDropBox().build()); 922c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 923c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 92450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return true; 92550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 92650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 92750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick /** 928b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Used by the framework to make network usage on the main 929b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * thread a fatal error. 930b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 931b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 932b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 933b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static void enableDeathOnNetwork() { 934b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int oldPolicy = getThreadPolicyMask(); 935b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int newPolicy = oldPolicy | DETECT_NETWORK | PENALTY_DEATH_ON_NETWORK; 936b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick setThreadPolicyMask(newPolicy); 937b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 938b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 939b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 9405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 9415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 9425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 9435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 944e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * Input is of the following forms: 945e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * "policy=137 violation=64" 946e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * "policy=137 violation=64 msg=Arbitrary text" 9475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 9485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 9495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 9505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 9515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 9525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 9535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 9545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 9555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 9575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (spaceIndex == -1) { 9585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 9595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 9615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 9625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 9635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 9645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 9655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9675b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 9685b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 9695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 9705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 9715b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 9725b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null) { 9735b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 9745b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9755b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 9765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (violationIndex == -1) { 9775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 9785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 979e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick int numberStartIndex = violationIndex + "violation=".length(); 980e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick int numberEndIndex = message.indexOf(' ', numberStartIndex); 981e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (numberEndIndex == -1) { 982e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick numberEndIndex = message.length(); 983e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 984e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick String violationString = message.substring(numberStartIndex, numberEndIndex); 9855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 9865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 9875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 9885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 9895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 992191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 993191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 994191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 995191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return new ArrayList<ViolationInfo>(); 996191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 997191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick }; 998191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 999bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // Note: only access this once verifying the thread has a Looper. 1000bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick private static final ThreadLocal<Handler> threadHandler = new ThreadLocal<Handler>() { 1001bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick @Override protected Handler initialValue() { 1002bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick return new Handler(); 1003bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1004bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick }; 1005bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1006191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static boolean tooManyViolationsThisLoop() { 1007191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; 1008191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1009191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 1010438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 1011438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private int mPolicyMask; 101246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 101346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 101446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // last violation. No locking needed, as this is only 101546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // accessed by the same thread. 101646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); 1017438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1018438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 1019438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 1020438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1021438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 10225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick @Override 10235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public String toString() { 10245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 10255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 1027438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1028438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public int getPolicyMask() { 1029438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mPolicyMask; 1030438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1031438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1032438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1033438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onWriteToDisk() { 103432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { 1035438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 1036438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1037191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1038191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 1039191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1040cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 1041cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 1042cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 1043438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1044438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1045e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // Not part of BlockGuard.Policy; just part of StrictMode: 1046e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick void onCustomSlowCall(String name) { 1047e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if ((mPolicyMask & DETECT_CUSTOM) == 0) { 1048e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 1049e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1050e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1051e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 1052e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1053e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeCustomViolation(mPolicyMask, name); 1054e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick e.fillInStackTrace(); 1055e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick startHandlingViolationException(e); 1056e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1057e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 1058438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1059438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onReadFromDisk() { 106032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_READ) == 0) { 1061438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 1062438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1063191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1064191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 1065191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1066cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 1067cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 1068cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 1069438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1070438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1071438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1072438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onNetwork() { 107332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_NETWORK) == 0) { 1074438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 1075438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1076b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) { 1077b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick throw new NetworkOnMainThreadException(); 1078b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 1079191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1080191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 1081191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1082cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 1083cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 1084cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 1085438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1086438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1087438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void setPolicyMask(int policyMask) { 1088438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 1089438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1090438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 10915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 10925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 10935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 10945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 10955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 10965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 1097cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 1098cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 1099cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolationWithTimingAttempt(info); 1100cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1101438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1102cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 1103cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 1104cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // to measure with. We measure from the time of violation 1105cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // until the time the looper is idle again (right before 1106cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // the next epoll_wait) 1107cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 1108438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Looper looper = Looper.myLooper(); 1109cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1110cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Without a Looper, we're unable to time how long the 1111cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // violation takes place. This case should be rare, as 1112cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // most users will care about timing violations that 1113cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // happen on their main UI thread. Note that this case is 1114cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // also hit when a violation takes place in a Binder 1115cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 1116cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // of the violation is computed by the ultimate caller and 1117cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // its Looper, if any. 11184e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // 11194e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // Also, as a special short-cut case when the only penalty 11204e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // bit is death, we die immediately, rather than timing 11214e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // the violation's duration. This makes it convenient to 11224e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // use in unit tests too, rather than waiting on a Looper. 11234e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // 1124cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 1125cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // go into this immediate mode? 11264e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick if (looper == null || 1127c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick (info.policy & THREAD_PENALTY_MASK) == PENALTY_DEATH) { 1128cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 1129cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(info); 1130cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1131438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1132438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1133cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 1134191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() >= MAX_OFFENSES_PER_LOOP) { 1135cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 1136cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1137cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1138cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.add(info); 1139cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() > 1) { 1140cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // There's already been a violation this loop, so we've already 1141cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // registered an idle handler to process the list of violations 1142cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // at the end of this Looper's loop. 1143cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1144cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1145cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 11466804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick final IWindowManager windowManager = (info.policy & PENALTY_FLASH) != 0 ? 1147cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick sWindowManager.get() : null; 11486804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick if (windowManager != null) { 11496804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick try { 11506804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick windowManager.showStrictModeViolation(true); 11516804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } catch (RemoteException unused) { 11526804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 11536804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 11546804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 1155bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // We post a runnable to a Handler (== delay 0 ms) for 1156bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // measuring the end time of a violation instead of using 1157bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // an IdleHandler (as was previously used) because an 1158bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // IdleHandler may not run for quite a long period of time 1159bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // if an ongoing animation is happening and continually 1160bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // posting ASAP (0 ms) animation steps. Animations are 1161bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // throttled back to 60fps via SurfaceFlinger/View 1162bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // invalidates, _not_ by posting frame updates every 16 1163bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // milliseconds. 1164bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick threadHandler.get().post(new Runnable() { 1165bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick public void run() { 1166cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 1167bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1168bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // Note: we do this early, before handling the 1169bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // violation below, as handling the violation 1170bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // may include PENALTY_DEATH and we don't want 1171bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // to keep the red border on. 1172bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick if (windowManager != null) { 1173bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick try { 1174bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick windowManager.showStrictModeViolation(false); 1175bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } catch (RemoteException unused) { 1176bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1177bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1178bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1179cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 1180cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo v = records.get(n); 1181cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.violationNumThisLoop = n + 1; 1182cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.durationMillis = 1183cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 1184cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(v); 1185cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1186cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.clear(); 1187cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1188cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }); 11895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1190438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 11915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Note: It's possible (even quite likely) that the 11925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread-local policy mask has changed from the time the 11935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation fired and now (after the violating code ran) due 11945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to people who push/pop temporary policy in regions of code, 11955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // hence the policy being passed around. 1196cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolation(final ViolationInfo info) { 1197cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 1198cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 11995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 12005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1201438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1202cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 120346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1204cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 1205cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1206703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1207cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 1208703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(violations); 1209703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else if (violations.size() >= 5) { 12105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 12115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 12125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1213cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 1214cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 12155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Duplicate. Don't log. 12165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 12175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1219cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations.add(info); 1220727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return; 1221727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1222727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 122346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 1224f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick Integer crashFingerprint = info.hashCode(); 122546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long lastViolationTime = 0; 122646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (mLastViolationTime.containsKey(crashFingerprint)) { 122746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick lastViolationTime = mLastViolationTime.get(crashFingerprint); 122846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 122946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 123046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 123146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 123246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 123346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1234cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 123546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 1236cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.durationMillis != -1) { 12375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 1238cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 1239438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 1240cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 1241438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1242438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1243438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 124471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // The violationMaskSubset, passed to ActivityManager, is a 124546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 124646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // only the bit violated and penalty bits to be executed 124746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // by the ActivityManagerService remaining set. 1248cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 124946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1250cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 125146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 1252cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 125346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 125446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1255cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 1256cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 125746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 125846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1259cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 1260cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 1261cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 126232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 126371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 1264c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick final boolean justDropBox = (info.policy & THREAD_PENALTY_MASK) == PENALTY_DROPBOX; 126571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick if (justDropBox) { 126671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // If all we're going to ask the activity manager 126771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // to do is dropbox it (the common case during 126871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // platform development), we can avoid doing this 126971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // call synchronously which Binder data suggests 127071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // isn't always super fast, despite the implementation 127171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // in the ActivityManager trying to be mostly async. 1272bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick dropboxViolationAsync(violationMaskSubset, info); 127371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick return; 127471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 127571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 127671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // Normal synchronous call to the ActivityManager. 1277438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 1278727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 1279727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 1280727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 1281727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // We restore the current policy below, in the finally block. 128232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 1283727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1284438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 1285438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 1286cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 1287cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 1288438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (RemoteException e) { 128946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 1290727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } finally { 1291727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Restore the policy. 129232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 1293438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1294438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1295438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1296cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 12974e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick executeDeathPenalty(info); 1298438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1299438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1300438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1301727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 13024e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static void executeDeathPenalty(ViolationInfo info) { 13034e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 13044e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick throw new StrictModeViolation(info.policy, violationBit, null); 13054e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 13064e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 1307bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1308bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * In the common case, as set by conditionallyEnableDebugLogging, 1309bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * we're just dropboxing any violations but not showing a dialog, 1310bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * not loggging, and not killing the process. In these cases we 1311bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * don't need to do a synchronous call to the ActivityManager. 1312bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * This is used by both per-thread and vm-wide violations when 1313bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * applicable. 1314bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 1315bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick private static void dropboxViolationAsync( 1316bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick final int violationMaskSubset, final ViolationInfo info) { 1317bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick int outstanding = sDropboxCallsInFlight.incrementAndGet(); 1318bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (outstanding > 20) { 1319bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // What's going on? Let's not make make the situation 1320bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // worse and just not log. 1321bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick sDropboxCallsInFlight.decrementAndGet(); 1322bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick return; 1323bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1324bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1325bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (LOG_V) Log.d(TAG, "Dropboxing async; in-flight=" + outstanding); 1326bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1327bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick new Thread("callActivityManagerForStrictModeDropbox") { 1328bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick public void run() { 1329bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1330bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick try { 13311065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick IActivityManager am = ActivityManagerNative.getDefault(); 13321065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick if (am == null) { 13331065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick Log.d(TAG, "No activity manager; failed to Dropbox violation."); 13341065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick } else { 13351065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick am.handleApplicationStrictModeViolation( 13361065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick RuntimeInit.getApplicationObject(), 13371065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick violationMaskSubset, 13381065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick info); 13391065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick } 1340bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } catch (RemoteException e) { 1341bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick Log.e(TAG, "RemoteException handling StrictMode violation", e); 1342bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1343bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick int outstanding = sDropboxCallsInFlight.decrementAndGet(); 1344bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (LOG_V) Log.d(TAG, "Dropbox complete; in-flight=" + outstanding); 1345bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1346bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick }.start(); 1347bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1348bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 13494b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { 13504b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public void report (String message, Throwable allocationSite) { 13514b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, allocationSite); 13524b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 13534b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 13544b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 1355727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 13565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 13575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 13585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 1359703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return gatheredViolations.get() != null; 1360703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1361703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1362703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1363703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 1364703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 1365703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Binder call on this thread. 1366703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 1367703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 1368703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 13695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 13705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 13715b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1372bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * @hide 1373bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 1374bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public static void conditionallyCheckInstanceCounts() { 1375bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick VmPolicy policy = getVmPolicy(); 1376bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (policy.classInstanceLimit.size() == 0) { 1377bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick return; 1378bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1379bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick Runtime.getRuntime().gc(); 1380bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // Note: classInstanceLimit is immutable, so this is lock-free 13815f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick for (Map.Entry<Class, Integer> entry : policy.classInstanceLimit.entrySet()) { 13825f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Class klass = entry.getKey(); 13835f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick int limit = entry.getValue(); 1384bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long instances = VMDebug.countInstancesOfClass(klass, false); 1385bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (instances <= limit) { 1386bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick continue; 1387bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1388bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick Throwable tr = new InstanceCountViolation(klass, instances, limit); 1389bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick onVmPolicyViolation(tr.getMessage(), tr); 1390bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1391bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1392bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 1393bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static long sLastInstanceCountCheckMillis = 0; 13945f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick private static boolean sIsIdlerRegistered = false; // guarded by StrictMode.class 1395bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final MessageQueue.IdleHandler sProcessIdleHandler = 1396bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick new MessageQueue.IdleHandler() { 1397bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public boolean queueIdle() { 1398bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 1399bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (now - sLastInstanceCountCheckMillis > 30 * 1000) { 1400bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick sLastInstanceCountCheckMillis = now; 1401bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick conditionallyCheckInstanceCounts(); 1402bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1403bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick return true; 1404bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1405bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick }; 1406bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 1407bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 140832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions in the VM process (on any 140932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * thread) should be detected, as well as the penalty if such 141032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * actions occur. 141132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 141232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 141332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 141432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setVmPolicy(final VmPolicy policy) { 14155f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 14165f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sVmPolicy = policy; 14175f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sVmPolicyMask = policy.mask; 14185f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 14195f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 14205f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Looper looper = Looper.getMainLooper(); 14215f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick if (looper != null) { 14225f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick MessageQueue mq = looper.mQueue; 1423c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick if (policy.classInstanceLimit.size() == 0 || 1424c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick (sVmPolicyMask & VM_PENALTY_MASK) == 0) { 1425bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mq.removeIdleHandler(sProcessIdleHandler); 1426c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick sIsIdlerRegistered = false; 1427bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } else if (!sIsIdlerRegistered) { 1428bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mq.addIdleHandler(sProcessIdleHandler); 1429bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick sIsIdlerRegistered = true; 1430bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1431bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1432bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 143332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 143432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 143532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 143632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Gets the current VM policy. 143732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 143832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static VmPolicy getVmPolicy() { 14395f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 14405f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick return sVmPolicy; 14415f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 144232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 144332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 144432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 144562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * Enable the recommended StrictMode defaults, with violations just being logged. 144662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * 144762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * <p>This catches disk and network access on the main thread, as 1448fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * well as leaked SQLite cursors and unclosed resources. This is 1449fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * simply a wrapper around {@link #setVmPolicy} and {@link 1450fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * #setThreadPolicy}. 145162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick */ 145262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick public static void enableDefaults() { 145362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 145462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectAll() 145562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 145662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 145762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 1458e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick .detectAll() 145962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 146062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 146162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 146262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick 146362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 146432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 146532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 146632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static boolean vmSqliteObjectLeaksEnabled() { 146732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0; 146832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 146932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 147032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 147132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 147232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 1473fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static boolean vmClosableObjectLeaksEnabled() { 1474fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return (sVmPolicyMask & DETECT_VM_CLOSABLE_LEAKS) != 0; 1475fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 1476fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 1477fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 1478fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 1479fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 148032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void onSqliteObjectLeaked(String message, Throwable originStack) { 14814b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, originStack); 14824b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 14834b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 1484bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // Map from VM violation fingerprint to uptime millis. 1485bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>(); 1486bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 14874b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom /** 14884b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom * @hide 14894b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom */ 14904b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public static void onVmPolicyViolation(String message, Throwable originStack) { 1491bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0; 1492bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0; 1493bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0; 1494bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); 1495bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 14965f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // Erase stuff not relevant for process-wide violations 14975f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick info.numAnimationsRunning = 0; 14985f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick info.tags = null; 14995f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick info.broadcastIntentAction = null; 15005f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 1501bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final Integer fingerprint = info.hashCode(); 1502bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final long now = SystemClock.uptimeMillis(); 1503bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long lastViolationTime = 0; 1504bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long timeSinceLastViolationMillis = Long.MAX_VALUE; 1505bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick synchronized (sLastVmViolationTime) { 1506bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (sLastVmViolationTime.containsKey(fingerprint)) { 1507bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick lastViolationTime = sLastVmViolationTime.get(fingerprint); 1508bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick timeSinceLastViolationMillis = now - lastViolationTime; 1509bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1510bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 1511bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick sLastVmViolationTime.put(fingerprint, now); 1512bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 151332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 151432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1515bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 1516bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick Log.e(TAG, message, originStack); 1517bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1518bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 1519bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicyMask); 1520bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1521bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (penaltyDropbox && !penaltyDeath) { 1522bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // Common case for userdebug/eng builds. If no death and 1523bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // just dropboxing, we can do the ActivityManager call 1524bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // asynchronously. 1525bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick dropboxViolationAsync(violationMaskSubset, info); 1526bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick return; 1527bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 152832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1529bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (penaltyDropbox && lastViolationTime == 0) { 153032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 153132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // subset of the original StrictMode policy bitmask, with 153232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // only the bit violated and penalty bits to be executed 153332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // by the ActivityManagerService remaining set. 153432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 153532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick try { 153632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 153732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 153832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 153932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // We restore the current policy below, in the finally block. 154032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 154132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 154232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 154332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick RuntimeInit.getApplicationObject(), 154432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick violationMaskSubset, 154532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick info); 154632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } catch (RemoteException e) { 154732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 154832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } finally { 154932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Restore the policy. 155032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 155132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 155232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 155332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1554bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (penaltyDeath) { 155532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down."); 155632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Process.killProcess(Process.myPid()); 155732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.exit(10); 155832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 155932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 156032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 156132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 15625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 15635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 15645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 1565cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1566703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1567703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(0); 1568703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else { 1569703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(violations.size()); 1570703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 1571703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 1572703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1573703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 1574703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 15755b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1576703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 15775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 15785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 15795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class LogStackTrace extends Exception {} 15805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 15815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 15825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 15835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * we here read back all the encoded violations. 15845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 15855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 15865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Our own stack trace to append 15875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StringWriter sw = new StringWriter(); 1588cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new LogStackTrace().printStackTrace(new PrintWriter(sw)); 15895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String ourStack = sw.toString(); 15905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 159132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int policyMask = getThreadPolicyMask(); 1592cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 15935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 15945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int numViolations = p.readInt(); 15955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 15965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 1597cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 1598cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 15995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 16005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 1601cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 16025b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 16035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 16045b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 16055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 16065b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1607727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Called from android_util_Binder.cpp's 1608727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 1609727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 1610727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 1611727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 1612727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * thread-local policy value. 1613727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 1614727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 1615727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 1616727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1617cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1618cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1619e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * A tracked, critical time span. (e.g. during an animation.) 1620e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1621e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * The object itself is a linked list node, to avoid any allocations 1622e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * during rapid span entries and exits. 1623e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1624e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1625e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1626e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static class Span { 1627e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private String mName; 1628e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private long mCreateMillis; 1629e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mNext; 1630e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mPrev; // not used when in freeList, only active 1631e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private final ThreadSpanState mContainerState; 1632e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1633e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span(ThreadSpanState threadState) { 1634e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mContainerState = threadState; 1635e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1636e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 16371181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Empty constructor for the NO_OP_SPAN 16381181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick protected Span() { 16391181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick mContainerState = null; 16401181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 16411181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1642e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1643e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * To be called when the critical span is complete (i.e. the 1644e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * animation is done animating). This can be called on any 1645e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread (even a different one from where the animation was 1646e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * taking place), but that's only a defensive implementation 1647e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * measure. It really makes no sense for you to call this on 1648e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread other than that where you created it. 1649e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1650e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1651e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1652e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public void finish() { 1653e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = mContainerState; 1654e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1655e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mName == null) { 1656e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Duplicate finish call. Ignore. 1657e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return; 1658e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1659e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1660e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Remove ourselves from the active list. 1661e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mPrev != null) { 1662e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mPrev.mNext = mNext; 1663e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1664e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mNext != null) { 1665e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mNext.mPrev = mPrev; 1666e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1667e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mActiveHead == this) { 1668e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = mNext; 1669e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1670e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 16711cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick state.mActiveSize--; 16721cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick 16731cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick if (LOG_V) Log.d(TAG, "Span finished=" + mName + "; size=" + state.mActiveSize); 16741cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick 1675e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mCreateMillis = -1; 1676e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mName = null; 1677e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mPrev = null; 1678e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = null; 1679e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1680e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Add ourselves to the freeList, if it's not already 1681e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // too big. 1682e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListSize < 5) { 1683e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = state.mFreeListHead; 1684e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = this; 1685e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize++; 1686e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1687e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1688e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1689e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1690e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 16911181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // The no-op span that's used in user builds. 16921181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final Span NO_OP_SPAN = new Span() { 16931181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick public void finish() { 16941181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Do nothing. 16951181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 16961181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick }; 16971181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1698e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1699e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Linked lists of active spans and a freelist. 1700e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1701e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Locking notes: there's one of these structures per thread and 1702e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * all members of this structure (as well as the Span nodes under 1703e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * it) are guarded by the ThreadSpanState object instance. While 1704e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * in theory there'd be no locking required because it's all local 1705e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * per-thread, the finish() method above is defensive against 1706e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * people calling it on a different thread from where they created 1707e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * the Span, hence the locking. 1708e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1709e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static class ThreadSpanState { 1710e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mActiveHead; // doubly-linked list. 1711e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mActiveSize; 1712e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mFreeListHead; // singly-linked list. only changes at head. 1713e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mFreeListSize; 1714e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1715e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1716e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final ThreadLocal<ThreadSpanState> sThisThreadSpanState = 1717e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick new ThreadLocal<ThreadSpanState>() { 1718e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick @Override protected ThreadSpanState initialValue() { 1719e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return new ThreadSpanState(); 1720e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1721e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick }; 1722e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1723cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick private static Singleton<IWindowManager> sWindowManager = new Singleton<IWindowManager>() { 1724cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick protected IWindowManager create() { 1725cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick return IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 1726cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick } 1727cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick }; 1728cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick 1729e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1730e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Enter a named critical span (e.g. an animation) 1731e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1732e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>The name is an arbitary label (or tag) that will be applied 1733e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * to any strictmode violation that happens while this span is 1734e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * active. You must call finish() on the span when done. 1735e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1736e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>This will never return null, but on devices without debugging 1737e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * enabled, this may return a dummy object on which the finish() 1738e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * method is a no-op. 1739e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1740e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>TODO: add CloseGuard to this, verifying callers call finish. 1741e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1742e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1743e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1744e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static Span enterCriticalSpan(String name) { 17451181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick if (IS_USER_BUILD) { 17461181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick return NO_OP_SPAN; 17471181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 1748e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (name == null || name.isEmpty()) { 1749e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick throw new IllegalArgumentException("name must be non-null and non-empty"); 1750e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1751e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 1752e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span span = null; 1753e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1754e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListHead != null) { 1755e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = state.mFreeListHead; 1756e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = span.mNext; 1757e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize--; 1758e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } else { 1759e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Shouldn't have to do this often. 1760e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = new Span(state); 1761e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1762e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mName = name; 1763e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mCreateMillis = SystemClock.uptimeMillis(); 1764e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext = state.mActiveHead; 1765e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mPrev = null; 1766e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = span; 1767e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveSize++; 1768e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (span.mNext != null) { 1769e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext.mPrev = span; 1770e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 17711cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick if (LOG_V) Log.d(TAG, "Span enter=" + name + "; size=" + state.mActiveSize); 1772e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1773e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return span; 1774e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1775e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1776e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 1777e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * For code to note that it's slow. This is a no-op unless the 1778e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * current thread's {@link android.os.StrictMode.ThreadPolicy} has 1779e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * {@link android.os.StrictMode.ThreadPolicy.Builder#detectCustomSlowCalls} 1780e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * enabled. 1781e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * 1782e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * @param name a short string for the exception stack trace that's 1783e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * built if when this fires. 1784e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 1785e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public static void noteSlowCall(String name) { 1786e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 1787e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 1788e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // StrictMode not enabled. 1789e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 1790e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1791e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick ((AndroidBlockGuardPolicy) policy).onCustomSlowCall(name); 1792e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1793e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1794e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 17954e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 17964e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 17974e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static void noteDiskRead() { 17984e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 17994e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 18004e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // StrictMode not enabled. 18014e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick return; 18024e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 18034e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).onReadFromDisk(); 18044e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 18054e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 18064e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 18074e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 18084e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 18094e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static void noteDiskWrite() { 18104e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 18114e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 18124e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // StrictMode not enabled. 18134e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick return; 18144e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 18154e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); 18164e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 18174e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 18185f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // Guarded by StrictMode.class 18195f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick private static final HashMap<Class, Integer> sExpectedActivityInstanceCount = 18205f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick new HashMap<Class, Integer>(); 18215f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 18224e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 1823758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * @hide 1824758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 18255f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick public static void incrementExpectedActivityCount(Class klass) { 18265f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { 1827758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return; 1828758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 18295f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 18305f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Integer expected = sExpectedActivityInstanceCount.get(klass); 18315f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Integer newExpected = expected == null ? 1 : expected + 1; 18325f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sExpectedActivityInstanceCount.put(klass, newExpected); 18335f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // Note: adding 1 here to give some breathing room during 18345f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // orientation changes. (shouldn't be necessary, though?) 18355f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick setExpectedClassInstanceCount(klass, newExpected + 1); 18365f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 18375f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 18385f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 18395f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick /** 18405f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick * @hide 18415f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick */ 18425f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick public static void decrementExpectedActivityCount(Class klass) { 18435f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { 1844758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return; 1845758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 18465f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 18475f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Integer expected = sExpectedActivityInstanceCount.get(klass); 18485f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Integer newExpected = (expected == null || expected == 0) ? 0 : expected - 1; 18495f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick if (newExpected == 0) { 18505f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sExpectedActivityInstanceCount.remove(klass); 18515f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } else { 18525f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sExpectedActivityInstanceCount.put(klass, newExpected); 18535f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 18545f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // Note: adding 1 here to give some breathing room during 18555f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // orientation changes. (shouldn't be necessary, though?) 18565f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick setExpectedClassInstanceCount(klass, newExpected + 1); 18575f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 18585f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 18595f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 18605f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick /** 18615f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick * @hide 18625f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick */ 18635f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick public static void setExpectedClassInstanceCount(Class klass, int count) { 18645f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 18655f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick setVmPolicy(new VmPolicy.Builder(sVmPolicy) 18665f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick .setClassInstanceLimit(klass, count) 18675f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick .build()); 18685f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 1869758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 1870758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 1871758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 1872cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 1873cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * to report violations that happened during a cross-process call. 1874cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1875cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @hide 1876cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1877cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static class ViolationInfo { 1878cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1879cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Stack and other stuff info. 1880cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1881cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 1882cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1883cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1884cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The strict mode policy mask at the time of violation. 1885cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1886cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final int policy; 1887cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1888cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1889cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 1890cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * not known. 1891cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1892cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int durationMillis = -1; 1893cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1894cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1895599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick * The number of animations currently running. 1896599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick */ 1897599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick public int numAnimationsRunning = 0; 1898599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick 1899599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick /** 1900e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * List of tags from active Span instances during this 1901e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * violation, or null for none. 1902e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1903e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public String[] tags; 1904e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1905e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1906cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Which violation number this was (1-based) since the last Looper loop, 1907cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 1908cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 1909cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * thread. 1910cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1911cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int violationNumThisLoop; 1912cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1913cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1914cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 1915cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * violation occurred. 1916cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1917cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public long violationUptimeMillis; 1918cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1919cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1920bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * The action of the Intent being broadcast to somebody's onReceive 1921bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * on this thread right now, or null. 1922bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick */ 1923bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick public String broadcastIntentAction; 1924bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick 1925bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick /** 1926bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * If this is a instance count violation, the number of instances in memory, 1927bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * else -1. 1928bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 1929bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public long numInstances = -1; 1930bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 1931bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 1932cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 1933cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1934cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo() { 1935cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = null; 1936cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = 0; 1937cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1938cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1939cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1940cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 1941cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1942cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 1943cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 1944cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = SystemClock.uptimeMillis(); 1945cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this.policy = policy; 1946599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount(); 1947bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast(); 1948bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntent != null) { 1949bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = broadcastIntent.getAction(); 1950bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1951e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 1952bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (tr instanceof InstanceCountViolation) { 1953bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick this.numInstances = ((InstanceCountViolation) tr).mInstances; 1954bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1955e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1956e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int spanActiveCount = state.mActiveSize; 1957e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount > MAX_SPAN_TAGS) { 1958e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick spanActiveCount = MAX_SPAN_TAGS; 1959e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1960e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount != 0) { 1961e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags = new String[spanActiveCount]; 1962e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span iter = state.mActiveHead; 1963e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 1964e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick while (iter != null && index < spanActiveCount) { 1965e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags[index] = iter.mName; 1966e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick index++; 1967e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick iter = iter.mNext; 1968e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1969e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1970e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1971cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1972cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1973f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick @Override 1974f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick public int hashCode() { 1975f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick int result = 17; 1976f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + crashInfo.stackTrace.hashCode(); 1977f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (numAnimationsRunning != 0) { 1978f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result *= 37; 1979f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1980f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (broadcastIntentAction != null) { 1981f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + broadcastIntentAction.hashCode(); 1982f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1983f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (tags != null) { 1984f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick for (String tag : tags) { 1985f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + tag.hashCode(); 1986f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1987f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1988f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick return result; 1989f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1990f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick 1991cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1992cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1993cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1994cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in) { 1995cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this(in, false); 1996cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1997cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1998cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1999cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 2000cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 2001cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @param unsetGatheringBit if true, the caller is the root caller 2002cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * and the gathering penalty should be removed. 2003cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2004cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 2005cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 2006cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int rawPolicy = in.readInt(); 2007cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (unsetGatheringBit) { 2008cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 2009cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } else { 2010cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy; 2011cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2012cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick durationMillis = in.readInt(); 2013cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationNumThisLoop = in.readInt(); 2014599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick numAnimationsRunning = in.readInt(); 2015cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = in.readLong(); 2016bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick numInstances = in.readLong(); 2017bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = in.readString(); 2018e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick tags = in.readStringArray(); 2019cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2020cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2021cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2022cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 2023cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2024cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 2025cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 2026cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(policy); 2027cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(durationMillis); 2028cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 2029599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick dest.writeInt(numAnimationsRunning); 2030cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 2031bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick dest.writeLong(numInstances); 2032bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick dest.writeString(broadcastIntentAction); 2033e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick dest.writeStringArray(tags); 2034cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2035cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2036cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2037cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2038cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Dump a ViolationInfo instance to a Printer. 2039cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2040cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void dump(Printer pw, String prefix) { 2041cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.dump(pw, prefix); 2042cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 2043cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (durationMillis != -1) { 2044cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "durationMillis: " + durationMillis); 2045cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2046bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (numInstances != -1) { 2047bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick pw.println(prefix + "numInstances: " + numInstances); 2048bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 2049cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationNumThisLoop != 0) { 2050cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 2051cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2052599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick if (numAnimationsRunning != 0) { 2053599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick pw.println(prefix + "numAnimationsRunning: " + numAnimationsRunning); 2054599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick } 2055cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 2056bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntentAction != null) { 2057bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction); 2058bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 2059e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (tags != null) { 2060e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 2061e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick for (String tag : tags) { 2062e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick pw.println(prefix + "tag[" + (index++) + "]: " + tag); 2063e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2064e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2065cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2066cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2067cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2068bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 2069bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // Dummy throwable, for now, since we don't know when or where the 2070bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // leaked instances came from. We might in the future, but for 2071bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // now we suppress the stack trace because it's useless and/or 2072bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // misleading. 2073bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static class InstanceCountViolation extends Throwable { 2074bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final Class mClass; 2075bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final long mInstances; 2076bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final int mLimit; 2077bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 20785f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick private static final StackTraceElement[] FAKE_STACK = { 20795f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit", 20805f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick "StrictMode.java", 1) 20815f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick }; 2082bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 2083bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public InstanceCountViolation(Class klass, long instances, int limit) { 20845f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick super(klass.toString() + "; instances=" + instances + "; limit=" + limit); 2085bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick setStackTrace(FAKE_STACK); 2086bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mClass = klass; 2087bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mInstances = instances; 2088bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mLimit = limit; 2089bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 2090bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 2091438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick} 2092