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; 23d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkeyimport android.content.BroadcastReceiver; 24d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkeyimport android.content.Context; 25bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.content.Intent; 26d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkeyimport android.content.ServiceConnection; 27390517be2d60dd6e6264150c190c372d89bb331aDianne Hackbornimport android.util.ArrayMap; 28438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Log; 29cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrickimport android.util.Printer; 30cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrickimport android.util.Singleton; 3173d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackbornimport android.util.Slog; 326804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrickimport android.view.IWindowManager; 33438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 34438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit; 35438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 368c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackbornimport com.android.internal.util.FastPrintWriter; 37438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport dalvik.system.BlockGuard; 38fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstromimport dalvik.system.CloseGuard; 39bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrickimport dalvik.system.VMDebug; 40438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.PrintWriter; 425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.StringWriter; 435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.util.ArrayList; 4473d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackbornimport java.util.Arrays; 4546d42387464a651268648659e91d022566d4844cBrad Fitzpatrickimport java.util.HashMap; 465f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrickimport java.util.Map; 47bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrickimport java.util.concurrent.atomic.AtomicInteger; 4846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 49438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/** 5032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>StrictMode is a developer tool which detects things you might be 5132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * doing by accident and brings them to your attention so you can fix 5232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * them. 5315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or 5515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * network access on the application's main thread, where UI 5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * operations are received and animations take place. Keeping disk 5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and network operations off the main thread makes for much smoother, 589fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * more responsive applications. By keeping your application's main thread 599fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * responsive, you also prevent 609fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * <a href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a> 619fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * from being shown to users. 6215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 6315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is 6415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that 6515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * memory with very limited concurrency. It's often the case that 6615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be 6715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background 6815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from other processes. If possible, it's best to assume that such 6915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p> 7015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 7115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your 7215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or 7315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's 7415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method: 7515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 7615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre> 7715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() { 7815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * if (DEVELOPER_MODE) { 7932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}() 8032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskReads() 8132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskWrites() 8232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectNetwork() // or .detectAll() for all detectable problems 8332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 8432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 8532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}() 8662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * .detectLeakedSqlLiteObjects() 87fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * .detectLeakedClosableObjects() 8832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 8932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyDeath() 9032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 9115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 9215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * super.onCreate(); 9315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 9415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * </pre> 9515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 9632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can decide what should happen when a violation is detected. 9732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * For example, using {@link ThreadPolicy.Builder#penaltyLog} you can 9832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * watch the output of <code>adb logcat</code> while you use your 9932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * application to see the violations as they happen. 10015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 10115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are 10215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler}, 10315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc. 10415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds. In particular, 10532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * many cases of disk access are often necessary during the normal activity lifecycle. Use 10632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode to find things you did by accident. Network requests on the UI thread 10715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * are almost always a problem, though. 10815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 10915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not 11015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses. While it does 11115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing 11215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best 11315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * effort mechanism. Notably, disk or network access from JNI calls 11415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * won't necessarily trigger it. Future versions of Android may catch 11515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode 1164d7bc65538c7cd9fbb1fbbcf22d1da47fcee1219Dirk Dougherty * enabled in applications distributed on Google Play. 117438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 118438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpublic final class StrictMode { 119438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static final String TAG = "StrictMode"; 12082829ef3b7c72bee36d8c17b36ac565f1856a310Brad Fitzpatrick private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE); 121438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1221181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 1236804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE); 1241181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 125c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick /** 126bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate * Boolean system property to disable strict mode checks outright. 127bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate * Set this to 'true' to force disable; 'false' has no effect on other 128bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate * enable/disable policy. 129bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate * @hide 130bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate */ 131bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate public static final String DISABLE_PROPERTY = "persist.sys.strictmode.disable"; 132bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate 133bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate /** 134c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * The boolean system property to control screen flashes on violations. 135c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * 136c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * @hide 137c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick */ 138c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick public static final String VISUAL_PROPERTY = "persist.sys.strictmode.visual"; 139c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 14046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 14146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 14246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 14346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 14446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 14546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 146e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // How many Span tags (e.g. animations) to report. 147e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final int MAX_SPAN_TAGS = 20; 148e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 149191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // How many offending stacks to keep track of (and time) per loop 150191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // of the Looper. 151191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final int MAX_OFFENSES_PER_LOOP = 10; 152191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 15332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Thread-policy: 154438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 15515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 15632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 15715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 15832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy 15915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 16015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 16132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 16215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 16332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy 16415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 16515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 16632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 16715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 16832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy 169438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 170e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 171e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * For StrictMode.noteSlowCall() 172e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * 173e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * @hide 174e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 175e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public static final int DETECT_CUSTOM = 0x08; // for ThreadPolicy 176e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 177e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick private static final int ALL_THREAD_DETECT_BITS = 178e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK | DETECT_CUSTOM; 179e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 18032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Process-policy: 181438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 182438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 18332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Note, a "VM_" bit, not thread. 18432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 18532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 186758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for VmPolicy 18732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 18832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 189fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Note, a "VM_" bit, not thread. 190fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 191fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 192758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for VmPolicy 193758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 194758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 195758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * Note, a "VM_" bit, not thread. 196758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * @hide 197758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 198758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final int DETECT_VM_ACTIVITY_LEAKS = 0x800; // for VmPolicy 199fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 200fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 20132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 202438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 203bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000; // for VmPolicy 204bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 205d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey /** 206d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey * @hide 207d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey */ 208d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey public static final int DETECT_VM_REGISTRATION_LEAKS = 0x2000; // for VmPolicy 209d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey 210a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey /** 211a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * @hide 212a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey */ 213a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey private static final int DETECT_VM_FILE_URI_EXPOSURE = 0x4000; // for VmPolicy 214a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey 215bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final int ALL_VM_DETECT_BITS = 216bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS | 217d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS | 218a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey DETECT_VM_REGISTRATION_LEAKS | DETECT_VM_FILE_URI_EXPOSURE; 219bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 220bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 221bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * @hide 222bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 223438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 224438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 22532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Used for both process and thread policy: 22632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 227438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 22832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 229438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 230438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 231438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 232438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 233b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death on any detected violation. 234b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 23532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 236438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 237438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DEATH = 0x40; 238438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 239438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 240b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death just for detected network usage. 241b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 242b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 243b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 244b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final int PENALTY_DEATH_ON_NETWORK = 0x200; 245b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 246b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 2476804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Flash the screen during violations. 2486804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * 2496804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * @hide 2506804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 2516804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick public static final int PENALTY_FLASH = 0x800; 2526804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 2536804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 25432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 255438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 256438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DROPBOX = 0x80; 257438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 258727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 259727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 260727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * bits and signals that we're in a Binder call and we should 261727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 262727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 263727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * in the originating process. 264727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 265703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 266703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * 267727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @hide 268727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 269727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 270727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 27132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 272c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick * Mask of all the penalty bits valid for thread policies. 27371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick */ 274c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick private static final int THREAD_PENALTY_MASK = 275b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | 2766804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; 27771678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 278758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 279c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick /** 280c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick * Mask of all the penalty bits valid for VM policies. 281c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick */ 282c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick private static final int VM_PENALTY_MASK = 283c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick PENALTY_LOG | PENALTY_DEATH | PENALTY_DROPBOX; 284c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick 285c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick 286758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // TODO: wrap in some ImmutableHashMap thing. 287758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // Note: must be before static initialization of sVmPolicy. 288758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private static final HashMap<Class, Integer> EMPTY_CLASS_LIMIT_MAP = new HashMap<Class, Integer>(); 289758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 29071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /** 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The current VmPolicy in effect. 292758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * 293758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * TODO: these are redundant (mask is in VmPolicy). Should remove sVmPolicyMask. 29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static volatile int sVmPolicyMask = 0; 296758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private static volatile VmPolicy sVmPolicy = VmPolicy.LAX; 29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 298bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 299bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * The number of threads trying to do an async dropbox write. 300bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * Just to limit ourselves out of paranoia. 301bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 302bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick private static final AtomicInteger sDropboxCallsInFlight = new AtomicInteger(0); 303bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private StrictMode() {} 30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to a certain thread. 30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy 31032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can be retrieved with {@link #getThreadPolicy}. 31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note that multiple penalties may be provided and they're run 31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * in order from least to most severe (logging before process 31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * death, for example). There's currently no mechanism to choose 31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * different penalties for different detected actions. 31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class ThreadPolicy { 31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final ThreadPolicy LAX = new ThreadPolicy(0); 32232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private ThreadPolicy(int mask) { 32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.ThreadPolicy; mask=" + mask + "]"; 33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 335320274c5f17057a3a823fed50b7027cbd46fc025Brad Fitzpatrick * Creates {@link ThreadPolicy} instances. Methods whose names start 33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 33832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 33932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 34032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 34132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 346320274c5f17057a3a823fed50b7027cbd46fc025Brad Fitzpatrick * StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 34732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 34832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 34932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 350320274c5f17057a3a823fed50b7027cbd46fc025Brad Fitzpatrick * StrictMode.setThreadPolicy(policy); 35132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 35232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 35332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 35432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask = 0; 35532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 35632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 35732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create a Builder that detects nothing and has no 35832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations. (but note that {@link #build} will default 35932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to enabling {@link #penaltyLog} if no other penalties 36032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are specified) 36132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 36232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder() { 36332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = 0; 36432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 36532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 36632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 36732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Initialize a Builder from an existing ThreadPolicy. 36832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 36932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder(ThreadPolicy policy) { 37032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = policy.mask; 37132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 37232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 37332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 37432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this includes network and 37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * disk operations but will likely expand in future releases. 37832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 37932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 380e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(ALL_THREAD_DETECT_BITS); 38132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 38432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable the detection of everything. 38532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 38632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitAll() { 387e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return disable(ALL_THREAD_DETECT_BITS); 38832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 39032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 39132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of network operations. 39232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 39332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectNetwork() { 39432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_NETWORK); 39532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 39632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 39732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 39832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of network operations. 39932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 40032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitNetwork() { 40132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_NETWORK); 40232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 40332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 40432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 40532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk reads. 40632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 40732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskReads() { 40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_READ); 40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 41232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk reads. 41332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 41432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskReads() { 41532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_READ); 41632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 41732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 41832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 419097fbf2e98e0d32baf6cbd1a5659c4145afb191fQi Wang * Enable detection of slow calls. 420e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 421e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public Builder detectCustomSlowCalls() { 422e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(DETECT_CUSTOM); 423e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 424e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 425e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 426097fbf2e98e0d32baf6cbd1a5659c4145afb191fQi Wang * Disable detection of slow calls. 427e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 428e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public Builder permitCustomSlowCalls() { 429097fbf2e98e0d32baf6cbd1a5659c4145afb191fQi Wang return disable(DETECT_CUSTOM); 430e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 431e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 432e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 43332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk writes. 43432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 43532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskWrites() { 43632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE); 43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk writes. 44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskWrites() { 44332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE); 44432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 44532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 44632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 44732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Show an annoying dialog to the developer on detected 44832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations, rate-limited to be only a little annoying. 44932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 45032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDialog() { 45132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DIALOG); 45232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 45332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 45432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 45532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crash the whole process on violation. This penalty runs at 45632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so you'll still get 45732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * see logging or other violations before the process dies. 458b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 459b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>Unlike {@link #penaltyDeathOnNetwork}, this applies 460b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * to disk reads, disk writes, and network usage if their 461b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * corresponding detect flags are set. 46232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 46332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 46632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 46732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 468b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Crash the whole process on any network usage. Unlike 469b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * {@link #penaltyDeath}, this penalty runs 470b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <em>before</em> anything else. You must still have 471b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * called {@link #detectNetwork} to enable this. 472b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 473b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>In the Honeycomb or later SDKs, this is on by default. 474b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 475b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public Builder penaltyDeathOnNetwork() { 476b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return enable(PENALTY_DEATH_ON_NETWORK); 477b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 478b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 479b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 4806804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Flash the screen during a violation. 4816804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 4826804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick public Builder penaltyFlashScreen() { 4836804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick return enable(PENALTY_FLASH); 4846804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 4856804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 4866804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 48732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 48832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 48932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 49032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 49132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 49232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 49332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 49432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 49532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 49632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 49732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 49832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 49932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 50432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 50532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 50632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 50732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder disable(int bit) { 50932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask &= ~bit; 51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 51232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 51332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 51432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the ThreadPolicy instance. 51532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 51632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 51732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 51832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 51932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 52032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ThreadPolicy build() { 52132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 52232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 52332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 52432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 52532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 52632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 52732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(mMask); 52932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 53032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 53132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 53232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 53332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 53432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to all threads in the virtual machine's process. 53532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 53632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setVmPolicy}. 53732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 53832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class VmPolicy { 53932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 54032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 54132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 542758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public static final VmPolicy LAX = new VmPolicy(0, EMPTY_CLASS_LIMIT_MAP); 54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 54432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 54532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 546758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // Map from class to max number of allowed instances in memory. 547758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick final HashMap<Class, Integer> classInstanceLimit; 548758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 549758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private VmPolicy(int mask, HashMap<Class, Integer> classInstanceLimit) { 550758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (classInstanceLimit == null) { 551758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick throw new NullPointerException("classInstanceLimit == null"); 552758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 55332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 554758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick this.classInstanceLimit = classInstanceLimit; 55532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 55632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 55732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 55832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 55932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.VmPolicy; mask=" + mask + "]"; 56032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 56132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 56232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 56332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates {@link VmPolicy} instances. Methods whose names start 56432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 56532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 56632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 56732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 56832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 56932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 57032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 57132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 57232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 57332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 57432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 57532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 57632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 57732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 57832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 57932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 58032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 58132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 58232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask; 58332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 584758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private HashMap<Class, Integer> mClassInstanceLimit; // null until needed 585758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick private boolean mClassInstanceLimitNeedCow = false; // need copy-on-write 586758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 587758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public Builder() { 588758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mMask = 0; 589758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 590758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 591758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 592758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * Build upon an existing VmPolicy. 593758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 594758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public Builder(VmPolicy base) { 595758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mMask = base.mask; 596758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimitNeedCow = true; 597758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit = base.classInstanceLimit; 598758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 599758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 600758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 601758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * Set an upper bound on how many instances of a class can be in memory 602758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * at once. Helps to prevent object leaks. 603758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 604758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick public Builder setClassInstanceLimit(Class klass, int instanceLimit) { 605758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (klass == null) { 606758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick throw new NullPointerException("klass == null"); 607758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 608758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (mClassInstanceLimitNeedCow) { 609758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick if (mClassInstanceLimit.containsKey(klass) && 610758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit.get(klass) == instanceLimit) { 611758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick // no-op; don't break COW 612758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return this; 613758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 614758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimitNeedCow = false; 615758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit = (HashMap<Class, Integer>) mClassInstanceLimit.clone(); 616758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } else if (mClassInstanceLimit == null) { 617758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit = new HashMap<Class, Integer>(); 618758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 619bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mMask |= DETECT_VM_INSTANCE_LEAKS; 620758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit.put(klass, instanceLimit); 621758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return this; 622758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 623758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 624bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 625bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * Detect leaks of {@link android.app.Activity} subclasses. 626bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 627bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public Builder detectActivityLeaks() { 628758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return enable(DETECT_VM_ACTIVITY_LEAKS); 629758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 630758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 63132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 63232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 63332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 634fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>In the Honeycomb release this includes leaks of 635bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * SQLite cursors, Activities, and other closable objects 636bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * but will likely expand in future releases. 63732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 63832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 639d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey return enable(DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS 640a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey | DETECT_VM_CLOSABLE_LEAKS | DETECT_VM_REGISTRATION_LEAKS 641a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey | DETECT_VM_FILE_URI_EXPOSURE); 64232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 64332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 64432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 64532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect when an 64632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link android.database.sqlite.SQLiteCursor} or other 64732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite object is finalized without having been closed. 64832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 64932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You always want to explicitly close your SQLite 65032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * cursors to avoid unnecessary database contention and 65132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * temporary memory leaks. 65232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 65332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectLeakedSqlLiteObjects() { 65432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 65532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 65632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 65732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 658fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Detect when an {@link java.io.Closeable} or other 659fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * object with a explict termination method is finalized 660fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * without having been closed. 661fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * 662fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>You always want to explicitly close such objects to 663fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * avoid unnecessary resources leaks. 664fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 665fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public Builder detectLeakedClosableObjects() { 666fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CLOSABLE_LEAKS); 667fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 668fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 669fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 670d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey * Detect when a {@link BroadcastReceiver} or 671d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey * {@link ServiceConnection} is leaked during {@link Context} 672d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey * teardown. 673d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey */ 674d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey public Builder detectLeakedRegistrationObjects() { 675d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey return enable(DETECT_VM_REGISTRATION_LEAKS); 676d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey } 677d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey 678d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey /** 6790fa30372c7768692f9deef3e33655382e8a683fdYing Wang * Detect when a {@code file://} {@link android.net.Uri} is exposed beyond this 680a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * app. The receiving app may not have access to the sent path. 681a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * Instead, when sharing files between apps, {@code content://} 682a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * should be used with permission grants. 683a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey */ 684a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey public Builder detectFileUriExposure() { 685a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey return enable(DETECT_VM_FILE_URI_EXPOSURE); 686a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 687a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey 688a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey /** 68932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crashes the whole process on violation. This penalty runs at 69032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so yo you'll still get 69132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * your logging or other violations before the process dies. 69232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 69332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 69432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 69532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 69632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 69732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 69832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 69932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 70032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 70132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 70232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 70332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 70432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 70532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 70632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 70732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 70832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 70932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 71032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 71132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 71232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 71332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 71432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 71532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 71632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 71732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 71832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 71932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 72032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the VmPolicy instance. 72132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 72232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 72332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 72432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 72532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 72632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public VmPolicy build() { 72732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 72832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 72932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 73032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 73132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 73232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 73332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 734758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return new VmPolicy(mMask, 735758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick mClassInstanceLimit != null ? mClassInstanceLimit : EMPTY_CLASS_LIMIT_MAP); 73632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 73732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 73832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 739438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 740438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 7415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Log of strict mode violation stack traces that have occurred 7425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * during a Binder call, to be serialized back later to the caller 7435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 7445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * choose how to react. 7455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 746cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 747cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 748cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 749703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 750703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // checking whether there are any violations or not in 751703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // hasGatheredViolations() below. 752703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return null; 7535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 7545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick }; 7555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 7565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 75732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions on the current thread should 75832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * be detected, as well as the penalty if such actions occur. 75915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 76032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Internally this sets a thread-local variable which is 76115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 76215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * catch violations when a system service or another process 76315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * accesses the disk or network on your behalf. 764438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 76532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 766438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 76732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setThreadPolicy(final ThreadPolicy policy) { 76832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(policy.mask); 76932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 77032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 77132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static void setThreadPolicyMask(final int policyMask) { 772727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // In addition to the Java-level thread-local in Dalvik's 773727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // BlockGuard, we also need to keep a native thread-local in 774727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 775727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // even across native-only processes. The two are kept in 776727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 777727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(policyMask); 778727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 779727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // And set the Android native version... 780727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 781727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 782727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 783727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 784727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 78546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (policyMask == 0) { 78646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 78746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 78846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 789a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey final BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 790a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey final AndroidBlockGuardPolicy androidPolicy; 791a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey if (policy instanceof AndroidBlockGuardPolicy) { 792a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey androidPolicy = (AndroidBlockGuardPolicy) policy; 793438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 794a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey androidPolicy = threadAndroidPolicy.get(); 795a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey BlockGuard.setThreadPolicy(androidPolicy); 796438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 797a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey androidPolicy.setPolicyMask(policyMask); 798438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 799438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 8004b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom // Sets up CloseGuard in Dalvik/libcore 8014b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static void setCloseGuardEnabled(boolean enabled) { 8027c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick if (!(CloseGuard.getReporter() instanceof AndroidCloseGuardReporter)) { 8034b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setReporter(new AndroidCloseGuardReporter()); 8044b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 8054b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setEnabled(enabled); 8064b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 8074b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 8084e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 8094e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 8104e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 8114e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static class StrictModeViolation extends BlockGuard.BlockGuardPolicyException { 8124e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public StrictModeViolation(int policyState, int policyViolated, String message) { 8134e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyState, policyViolated, message); 8144e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 8154e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 8164e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 8174e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 8184e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 8194e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 8204e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static class StrictModeNetworkViolation extends StrictModeViolation { 8215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 8224e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyMask, DETECT_NETWORK, null); 8235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 8264e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 8274e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 8284e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 8294e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static class StrictModeDiskReadViolation extends StrictModeViolation { 8305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 8314e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyMask, DETECT_DISK_READ, null); 8325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 8354e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 8364e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 8374e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 8384e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends StrictModeViolation { 8395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 8404e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick super(policyMask, DETECT_DISK_WRITE, null); 8415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 8444e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 8454e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 8464e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 8474e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static class StrictModeCustomViolation extends StrictModeViolation { 848e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public StrictModeCustomViolation(int policyMask, String name) { 849e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick super(policyMask, DETECT_CUSTOM, name); 850e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 851e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 852e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 853438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 85415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 855438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 85632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled 85732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 85832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 859438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 86032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static int getThreadPolicyMask() { 861438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 862438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 863438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 8645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 86532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Returns the current thread's policy. 86632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 86732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy getThreadPolicy() { 868e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // TODO: this was a last minute Gingerbread API change (to 869e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // introduce VmPolicy cleanly) but this isn't particularly 870e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // optimal for users who might call this method often. This 871e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // should be in a thread-local and not allocate on each call. 87232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(getThreadPolicyMask()); 87332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 87432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 87532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 87632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 87732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 87832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit both disk reads & writes, and sets the new policy 87932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 88032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 88197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 88232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to {@link #setThreadPolicy} to 88332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * restore the policy at the end of a block 88497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 88532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskWrites() { 88632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 88732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ); 88832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 88932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 89097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 89132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 89297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 89397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 89497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 89532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 89632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 89732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit disk reads, and sets the new policy 89832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 89932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 90097461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 90132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to setThreadPolicy to 90297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 90397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 90432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskReads() { 90532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 90632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ); 90732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 90832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 90997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 91032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 91197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 91297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 913f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // We don't want to flash the screen red in the system server 914f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // process, nor do we want to modify all the call sites of 915f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // conditionallyEnableDebugLogging() in the system server, 916f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // so instead we use this to determine if we are the system server. 917f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick private static boolean amTheSystemServerProcess() { 918f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // Fast path. Most apps don't have the system server's UID. 919f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick if (Process.myUid() != Process.SYSTEM_UID) { 920f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return false; 921f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 922f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick 923f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // The settings app, though, has the system server's UID so 924f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // look up our stack to see if we came from the system server. 925f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick Throwable stack = new Throwable(); 926f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick stack.fillInStackTrace(); 927f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick for (StackTraceElement ste : stack.getStackTrace()) { 928f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick String clsName = ste.getClassName(); 929f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick if (clsName != null && clsName.startsWith("com.android.server.")) { 930f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return true; 931f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 932f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 933f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return false; 934f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 935f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick 93697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 93750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * Enable DropBox logging for debug phone builds. 93850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * 93950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * @hide 94050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick */ 94150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 942bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate boolean doFlashes = SystemProperties.getBoolean(VISUAL_PROPERTY, false) 943bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate && !amTheSystemServerProcess(); 944bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate final boolean suppress = SystemProperties.getBoolean(DISABLE_PROPERTY, false); 945c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 94650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 94750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 948bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate if (!doFlashes && (IS_USER_BUILD || suppress)) { 9497c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick setCloseGuardEnabled(false); 95050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return false; 95150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 952c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 953bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate // Eng builds have flashes on all the time. The suppression property 954bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate // overrides this, so we force the behavior only after the short-circuit 955bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate // check above. 956bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate if (IS_ENG_BUILD) { 957bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate doFlashes = true; 958bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate } 959bc6f0ce8be64a74b695fb21dab5f4805b68dce16Christopher Tate 960be7c29c9f7e3d7b75d4374c8b5c0ca43c9d09c68Jeff Brown // Thread policy controls BlockGuard. 961c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick int threadPolicyMask = StrictMode.DETECT_DISK_WRITE | 962c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.DETECT_DISK_READ | 963c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.DETECT_NETWORK; 964c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 965c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (!IS_USER_BUILD) { 966c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick threadPolicyMask |= StrictMode.PENALTY_DROPBOX; 967c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 968c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (doFlashes) { 969c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick threadPolicyMask |= StrictMode.PENALTY_FLASH; 970c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 971c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 972c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.setThreadPolicyMask(threadPolicyMask); 973c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 974be7c29c9f7e3d7b75d4374c8b5c0ca43c9d09c68Jeff Brown // VM Policy controls CloseGuard, detection of Activity leaks, 975be7c29c9f7e3d7b75d4374c8b5c0ca43c9d09c68Jeff Brown // and instance counting. 976c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (IS_USER_BUILD) { 977c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick setCloseGuardEnabled(false); 978c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } else { 979d5875d98f06817f78bd974842a8a9c2d41802d20Jeff Brown VmPolicy.Builder policyBuilder = new VmPolicy.Builder().detectAll().penaltyDropBox(); 980d5875d98f06817f78bd974842a8a9c2d41802d20Jeff Brown if (IS_ENG_BUILD) { 981d5875d98f06817f78bd974842a8a9c2d41802d20Jeff Brown policyBuilder.penaltyLog(); 982d5875d98f06817f78bd974842a8a9c2d41802d20Jeff Brown } 983d5875d98f06817f78bd974842a8a9c2d41802d20Jeff Brown setVmPolicy(policyBuilder.build()); 984c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 985c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 98650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return true; 98750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 98850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 98950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick /** 990b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Used by the framework to make network usage on the main 991b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * thread a fatal error. 992b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 993b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 994b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 995b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static void enableDeathOnNetwork() { 996b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int oldPolicy = getThreadPolicyMask(); 997b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int newPolicy = oldPolicy | DETECT_NETWORK | PENALTY_DEATH_ON_NETWORK; 998b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick setThreadPolicyMask(newPolicy); 999b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 1000b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 1001b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 10025b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 10035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 10045b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 10055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 1006e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * Input is of the following forms: 1007e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * "policy=137 violation=64" 1008e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * "policy=137 violation=64 msg=Arbitrary text" 10095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 10105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 10115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 10125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 10135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 10145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 10155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 10165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 10175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 10195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (spaceIndex == -1) { 10205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 10215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 10235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 10245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 10255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 10265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 10275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 10305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 10315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 10325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 10335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 10345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null) { 10355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 10365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 10385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (violationIndex == -1) { 10395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 10405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1041e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick int numberStartIndex = violationIndex + "violation=".length(); 1042e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick int numberEndIndex = message.indexOf(' ', numberStartIndex); 1043e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (numberEndIndex == -1) { 1044e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick numberEndIndex = message.length(); 1045e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1046e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick String violationString = message.substring(numberStartIndex, numberEndIndex); 10475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 10485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 10495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 10505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 10515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 1054191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 1055191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 1056191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 1057191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return new ArrayList<ViolationInfo>(); 1058191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1059191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick }; 1060191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 1061bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // Note: only access this once verifying the thread has a Looper. 1062bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick private static final ThreadLocal<Handler> threadHandler = new ThreadLocal<Handler>() { 1063bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick @Override protected Handler initialValue() { 1064bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick return new Handler(); 1065bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1066bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick }; 1067bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1068a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey private static final ThreadLocal<AndroidBlockGuardPolicy> 1069a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey threadAndroidPolicy = new ThreadLocal<AndroidBlockGuardPolicy>() { 1070a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey @Override 1071a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey protected AndroidBlockGuardPolicy initialValue() { 1072a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey return new AndroidBlockGuardPolicy(0); 1073a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey } 1074a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey }; 1075a2934d5ff0b5c4098408cd583c2c259edf37c118Jeff Sharkey 1076191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static boolean tooManyViolationsThisLoop() { 1077191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; 1078191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1079191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 1080438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 1081438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private int mPolicyMask; 108246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 108346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 108446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // last violation. No locking needed, as this is only 108546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // accessed by the same thread. 1086390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn private ArrayMap<Integer, Long> mLastViolationTime; 1087438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1088438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 1089438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 1090438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1091438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 10925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick @Override 10935b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public String toString() { 10945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 10955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 10965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 1097438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1098438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public int getPolicyMask() { 1099438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mPolicyMask; 1100438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1101438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1102438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1103438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onWriteToDisk() { 110432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { 1105438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 1106438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1107191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1108191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 1109191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1110cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 1111cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 1112cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 1113438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1114438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1115e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // Not part of BlockGuard.Policy; just part of StrictMode: 1116e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick void onCustomSlowCall(String name) { 1117e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if ((mPolicyMask & DETECT_CUSTOM) == 0) { 1118e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 1119e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1120e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1121e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 1122e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1123e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeCustomViolation(mPolicyMask, name); 1124e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick e.fillInStackTrace(); 1125e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick startHandlingViolationException(e); 1126e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1127e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 1128438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1129438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onReadFromDisk() { 113032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_READ) == 0) { 1131438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 1132438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1133191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1134191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 1135191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1136cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 1137cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 1138cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 1139438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1140438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1141438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 1142438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onNetwork() { 114332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_NETWORK) == 0) { 1144438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 1145438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1146b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) { 1147b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick throw new NetworkOnMainThreadException(); 1148b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 1149191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 1150191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 1151191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 1152cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 1153cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 1154cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 1155438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1156438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1157438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void setPolicyMask(int policyMask) { 1158438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 1159438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1160438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 11615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 11625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 11635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 11645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 11655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 11665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 1167cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 1168cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 1169cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolationWithTimingAttempt(info); 1170cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1171438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1172cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 1173cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 1174cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // to measure with. We measure from the time of violation 1175cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // until the time the looper is idle again (right before 1176cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // the next epoll_wait) 1177cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 1178438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Looper looper = Looper.myLooper(); 1179cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1180cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Without a Looper, we're unable to time how long the 1181cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // violation takes place. This case should be rare, as 1182cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // most users will care about timing violations that 1183cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // happen on their main UI thread. Note that this case is 1184cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // also hit when a violation takes place in a Binder 1185cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 1186cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // of the violation is computed by the ultimate caller and 1187cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // its Looper, if any. 11884e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // 11894e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // Also, as a special short-cut case when the only penalty 11904e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // bit is death, we die immediately, rather than timing 11914e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // the violation's duration. This makes it convenient to 11924e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // use in unit tests too, rather than waiting on a Looper. 11934e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // 1194cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 1195cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // go into this immediate mode? 11964e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick if (looper == null || 1197c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick (info.policy & THREAD_PENALTY_MASK) == PENALTY_DEATH) { 1198cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 1199cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(info); 1200cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1201438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1202438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1203cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 1204191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() >= MAX_OFFENSES_PER_LOOP) { 1205cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 1206cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1207cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1208cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.add(info); 1209cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() > 1) { 1210cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // There's already been a violation this loop, so we've already 1211cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // registered an idle handler to process the list of violations 1212cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // at the end of this Looper's loop. 1213cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1214cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1215cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 12166804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick final IWindowManager windowManager = (info.policy & PENALTY_FLASH) != 0 ? 1217cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick sWindowManager.get() : null; 12186804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick if (windowManager != null) { 12196804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick try { 12206804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick windowManager.showStrictModeViolation(true); 12216804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } catch (RemoteException unused) { 12226804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 12236804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 12246804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 1225bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // We post a runnable to a Handler (== delay 0 ms) for 1226bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // measuring the end time of a violation instead of using 1227bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // an IdleHandler (as was previously used) because an 1228bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // IdleHandler may not run for quite a long period of time 1229bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // if an ongoing animation is happening and continually 1230bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // posting ASAP (0 ms) animation steps. Animations are 1231bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // throttled back to 60fps via SurfaceFlinger/View 1232bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // invalidates, _not_ by posting frame updates every 16 1233bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // milliseconds. 12343761f33387f980d7a6c6e06555a5a932ba7247a2Jeff Sharkey threadHandler.get().postAtFrontOfQueue(new Runnable() { 1235bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick public void run() { 1236cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 1237bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1238bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // Note: we do this early, before handling the 1239bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // violation below, as handling the violation 1240bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // may include PENALTY_DEATH and we don't want 1241bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // to keep the red border on. 1242bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick if (windowManager != null) { 1243bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick try { 1244bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick windowManager.showStrictModeViolation(false); 1245bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } catch (RemoteException unused) { 1246bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1247bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1248bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1249cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 1250cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo v = records.get(n); 1251cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.violationNumThisLoop = n + 1; 1252cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.durationMillis = 1253cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 1254cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(v); 1255cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1256cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.clear(); 1257cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1258cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }); 12595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1260438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 12615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Note: It's possible (even quite likely) that the 12625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread-local policy mask has changed from the time the 12635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation fired and now (after the violating code ran) due 12645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to people who push/pop temporary policy in regions of code, 12655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // hence the policy being passed around. 1266cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolation(final ViolationInfo info) { 1267cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 1268cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 12695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 12705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1271438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1272cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 127346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1274cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 1275cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1276703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1277cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 1278703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(violations); 1279703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else if (violations.size() >= 5) { 12805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 12815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 12825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1283cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 1284cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 12855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Duplicate. Don't log. 12865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 12875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1289cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations.add(info); 1290727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return; 1291727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1292727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 129346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 1294f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick Integer crashFingerprint = info.hashCode(); 129546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long lastViolationTime = 0; 1296390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (mLastViolationTime != null) { 1297390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn Long vtime = mLastViolationTime.get(crashFingerprint); 1298390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn if (vtime != null) { 1299390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn lastViolationTime = vtime; 1300390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } 1301390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn } else { 1302390517be2d60dd6e6264150c190c372d89bb331aDianne Hackborn mLastViolationTime = new ArrayMap<Integer, Long>(1); 130346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 130446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 130546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 130646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 130746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 130846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1309cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 131046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 1311cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.durationMillis != -1) { 13125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 1313cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 1314438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 1315cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 1316438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1317438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1318438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 131971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // The violationMaskSubset, passed to ActivityManager, is a 132046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 132146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // only the bit violated and penalty bits to be executed 132246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // by the ActivityManagerService remaining set. 1323cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 132446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1325cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 132646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 1327cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 132846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 132946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1330cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 1331cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 133246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 133346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1334cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 1335cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 1336cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 133732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 133871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 1339c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick final boolean justDropBox = (info.policy & THREAD_PENALTY_MASK) == PENALTY_DROPBOX; 134071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick if (justDropBox) { 134171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // If all we're going to ask the activity manager 134271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // to do is dropbox it (the common case during 134371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // platform development), we can avoid doing this 134471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // call synchronously which Binder data suggests 134571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // isn't always super fast, despite the implementation 134671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // in the ActivityManager trying to be mostly async. 1347bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick dropboxViolationAsync(violationMaskSubset, info); 134871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick return; 134971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 135071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 135171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // Normal synchronous call to the ActivityManager. 1352438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 1353727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 1354727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 1355727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 1356727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // We restore the current policy below, in the finally block. 135732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 1358727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1359438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 1360438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 1361cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 1362cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 1363438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (RemoteException e) { 136446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 1365727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } finally { 1366727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Restore the policy. 136732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 1368438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1369438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1370438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1371cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 13724e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick executeDeathPenalty(info); 1373438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1374438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1375438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1376727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 13774e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick private static void executeDeathPenalty(ViolationInfo info) { 13784e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 13794e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick throw new StrictModeViolation(info.policy, violationBit, null); 13804e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 13814e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 1382bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1383bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * In the common case, as set by conditionallyEnableDebugLogging, 1384bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * we're just dropboxing any violations but not showing a dialog, 1385bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * not loggging, and not killing the process. In these cases we 1386bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * don't need to do a synchronous call to the ActivityManager. 1387bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * This is used by both per-thread and vm-wide violations when 1388bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * applicable. 1389bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 1390bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick private static void dropboxViolationAsync( 1391bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick final int violationMaskSubset, final ViolationInfo info) { 1392bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick int outstanding = sDropboxCallsInFlight.incrementAndGet(); 1393bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (outstanding > 20) { 1394bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // What's going on? Let's not make make the situation 1395bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // worse and just not log. 1396bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick sDropboxCallsInFlight.decrementAndGet(); 1397bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick return; 1398bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1399bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1400bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (LOG_V) Log.d(TAG, "Dropboxing async; in-flight=" + outstanding); 1401bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1402bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick new Thread("callActivityManagerForStrictModeDropbox") { 1403bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick public void run() { 1404bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1405bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick try { 14061065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick IActivityManager am = ActivityManagerNative.getDefault(); 14071065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick if (am == null) { 14081065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick Log.d(TAG, "No activity manager; failed to Dropbox violation."); 14091065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick } else { 14101065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick am.handleApplicationStrictModeViolation( 14111065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick RuntimeInit.getApplicationObject(), 14121065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick violationMaskSubset, 14131065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick info); 14141065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick } 1415bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } catch (RemoteException e) { 1416bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick Log.e(TAG, "RemoteException handling StrictMode violation", e); 1417bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1418bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick int outstanding = sDropboxCallsInFlight.decrementAndGet(); 1419bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (LOG_V) Log.d(TAG, "Dropbox complete; in-flight=" + outstanding); 1420bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1421bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick }.start(); 1422bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1423bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 14244b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { 14254b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public void report (String message, Throwable allocationSite) { 14264b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, allocationSite); 14274b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 14284b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 14294b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 1430727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 14315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 14325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 14335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 1434703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return gatheredViolations.get() != null; 1435703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1436703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1437703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1438703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 1439703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 1440703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Binder call on this thread. 1441703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 1442703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 1443703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 14445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 14455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 14465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1447bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * @hide 1448bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 1449bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public static void conditionallyCheckInstanceCounts() { 1450bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick VmPolicy policy = getVmPolicy(); 1451bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (policy.classInstanceLimit.size() == 0) { 1452bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick return; 1453bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 14546f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey 14556f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey System.gc(); 14566f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey System.runFinalization(); 14576f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey System.gc(); 14586f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey 1459bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // Note: classInstanceLimit is immutable, so this is lock-free 14605f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick for (Map.Entry<Class, Integer> entry : policy.classInstanceLimit.entrySet()) { 14615f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Class klass = entry.getKey(); 14625f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick int limit = entry.getValue(); 1463bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long instances = VMDebug.countInstancesOfClass(klass, false); 1464bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (instances <= limit) { 1465bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick continue; 1466bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1467bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick Throwable tr = new InstanceCountViolation(klass, instances, limit); 1468bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick onVmPolicyViolation(tr.getMessage(), tr); 1469bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1470bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1471bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 1472bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static long sLastInstanceCountCheckMillis = 0; 14735f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick private static boolean sIsIdlerRegistered = false; // guarded by StrictMode.class 1474bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final MessageQueue.IdleHandler sProcessIdleHandler = 1475bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick new MessageQueue.IdleHandler() { 1476bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public boolean queueIdle() { 1477bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 1478bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (now - sLastInstanceCountCheckMillis > 30 * 1000) { 1479bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick sLastInstanceCountCheckMillis = now; 1480bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick conditionallyCheckInstanceCounts(); 1481bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1482bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick return true; 1483bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1484bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick }; 1485bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 1486bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 148732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions in the VM process (on any 148832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * thread) should be detected, as well as the penalty if such 148932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * actions occur. 149032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 149132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 149232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 149332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setVmPolicy(final VmPolicy policy) { 14945f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 14955f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sVmPolicy = policy; 14965f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sVmPolicyMask = policy.mask; 14975f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 14985f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 14995f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Looper looper = Looper.getMainLooper(); 15005f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick if (looper != null) { 15015f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick MessageQueue mq = looper.mQueue; 1502c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick if (policy.classInstanceLimit.size() == 0 || 1503c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick (sVmPolicyMask & VM_PENALTY_MASK) == 0) { 1504bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mq.removeIdleHandler(sProcessIdleHandler); 1505c0bb0bb5e3425b77b6e7820ebe25fe72bdd07782Brad Fitzpatrick sIsIdlerRegistered = false; 1506bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } else if (!sIsIdlerRegistered) { 1507bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mq.addIdleHandler(sProcessIdleHandler); 1508bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick sIsIdlerRegistered = true; 1509bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1510bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1511bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 151232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 151332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 151432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 151532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Gets the current VM policy. 151632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 151732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static VmPolicy getVmPolicy() { 15185f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 15195f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick return sVmPolicy; 15205f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 152132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 152232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 152332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 152462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * Enable the recommended StrictMode defaults, with violations just being logged. 152562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * 152662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * <p>This catches disk and network access on the main thread, as 1527fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * well as leaked SQLite cursors and unclosed resources. This is 1528fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * simply a wrapper around {@link #setVmPolicy} and {@link 1529fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * #setThreadPolicy}. 153062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick */ 153162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick public static void enableDefaults() { 153262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 153362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectAll() 153462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 153562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 153662a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 1537e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick .detectAll() 153862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 153962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 154062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 154162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick 154262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 154332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 154432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 154532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static boolean vmSqliteObjectLeaksEnabled() { 154632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0; 154732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 154832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 154932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 155032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 155132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 1552fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static boolean vmClosableObjectLeaksEnabled() { 1553fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return (sVmPolicyMask & DETECT_VM_CLOSABLE_LEAKS) != 0; 1554fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 1555fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 1556fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 1557fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 1558fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 1559d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey public static boolean vmRegistrationLeaksEnabled() { 1560d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey return (sVmPolicyMask & DETECT_VM_REGISTRATION_LEAKS) != 0; 1561d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey } 1562d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey 1563d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey /** 1564d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey * @hide 1565d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey */ 1566a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey public static boolean vmFileUriExposureEnabled() { 1567a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey return (sVmPolicyMask & DETECT_VM_FILE_URI_EXPOSURE) != 0; 1568a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 1569a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey 1570a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey /** 1571a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * @hide 1572a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey */ 157332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void onSqliteObjectLeaked(String message, Throwable originStack) { 15744b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, originStack); 15754b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 15764b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 157708d584cd1cba05284ccd2d0ea128c297624f0c47Steve Block /** 157808d584cd1cba05284ccd2d0ea128c297624f0c47Steve Block * @hide 157908d584cd1cba05284ccd2d0ea128c297624f0c47Steve Block */ 158008d584cd1cba05284ccd2d0ea128c297624f0c47Steve Block public static void onWebViewMethodCalledOnWrongThread(Throwable originStack) { 158108d584cd1cba05284ccd2d0ea128c297624f0c47Steve Block onVmPolicyViolation(null, originStack); 158208d584cd1cba05284ccd2d0ea128c297624f0c47Steve Block } 158308d584cd1cba05284ccd2d0ea128c297624f0c47Steve Block 1584d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey /** 1585d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey * @hide 1586d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey */ 1587d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey public static void onIntentReceiverLeaked(Throwable originStack) { 1588d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey onVmPolicyViolation(null, originStack); 1589d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey } 1590d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey 1591d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey /** 1592d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey * @hide 1593d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey */ 1594d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey public static void onServiceConnectionLeaked(Throwable originStack) { 1595d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey onVmPolicyViolation(null, originStack); 1596d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey } 1597d7026f1612a7c1e8cc9b484038fa99b7fc29cfd7Jeff Sharkey 1598a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey /** 1599a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * @hide 1600a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey */ 1601a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey public static void onFileUriExposed(String location) { 1602a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey final String message = "file:// Uri exposed through " + location; 1603a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey onVmPolicyViolation(message, new Throwable(message)); 1604a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 1605a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey 1606bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // Map from VM violation fingerprint to uptime millis. 1607bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>(); 1608bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 16094b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom /** 16104b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom * @hide 16114b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom */ 16124b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public static void onVmPolicyViolation(String message, Throwable originStack) { 1613bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0; 1614bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0; 1615bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0; 1616bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); 1617bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 16185f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // Erase stuff not relevant for process-wide violations 16195f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick info.numAnimationsRunning = 0; 16205f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick info.tags = null; 16215f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick info.broadcastIntentAction = null; 16225f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 1623bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final Integer fingerprint = info.hashCode(); 1624bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final long now = SystemClock.uptimeMillis(); 1625bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long lastViolationTime = 0; 1626bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick long timeSinceLastViolationMillis = Long.MAX_VALUE; 1627bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick synchronized (sLastVmViolationTime) { 1628bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (sLastVmViolationTime.containsKey(fingerprint)) { 1629bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick lastViolationTime = sLastVmViolationTime.get(fingerprint); 1630bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick timeSinceLastViolationMillis = now - lastViolationTime; 1631bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1632bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 1633bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick sLastVmViolationTime.put(fingerprint, now); 1634bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 163532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 163632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1637bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 1638bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick Log.e(TAG, message, originStack); 1639bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 1640bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 1641bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicyMask); 1642bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1643bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (penaltyDropbox && !penaltyDeath) { 1644bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // Common case for userdebug/eng builds. If no death and 1645bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // just dropboxing, we can do the ActivityManager call 1646bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // asynchronously. 1647bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick dropboxViolationAsync(violationMaskSubset, info); 1648bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick return; 1649bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 165032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1651bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (penaltyDropbox && lastViolationTime == 0) { 165232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 165332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // subset of the original StrictMode policy bitmask, with 165432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // only the bit violated and penalty bits to be executed 165532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // by the ActivityManagerService remaining set. 165632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 165732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick try { 165832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 165932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 166032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 166132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // We restore the current policy below, in the finally block. 166232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 166332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 166432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 166532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick RuntimeInit.getApplicationObject(), 166632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick violationMaskSubset, 166732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick info); 166832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } catch (RemoteException e) { 166932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 167032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } finally { 167132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Restore the policy. 167232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 167332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 167432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 167532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1676bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (penaltyDeath) { 167732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down."); 167832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Process.killProcess(Process.myPid()); 167932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.exit(10); 168032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 168132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 168232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 168332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 16845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 16855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 16865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 1687cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1688703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1689703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(0); 1690703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else { 1691703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(violations.size()); 1692703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 169373d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn int start = p.dataPosition(); 1694703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 169573d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn int size = p.dataPosition()-start; 1696ce92b0d070c4967914698b4e257c203d7121c972Dianne Hackborn if (size > 10*1024) { 169773d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn Slog.d(TAG, "Wrote violation #" + i + " of " + violations.size() + ": " 169873d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn + (p.dataPosition()-start) + " bytes"); 169973d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn } 1700703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1701703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 1702703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 17035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1704703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 17055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 17065b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 17075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class LogStackTrace extends Exception {} 17085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 17095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 17105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 17115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * we here read back all the encoded violations. 17125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 17135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 17145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Our own stack trace to append 17155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StringWriter sw = new StringWriter(); 17168c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn PrintWriter pw = new FastPrintWriter(sw, false, 256); 17178c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn new LogStackTrace().printStackTrace(pw); 17188c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn pw.flush(); 17195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String ourStack = sw.toString(); 17205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 172132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int policyMask = getThreadPolicyMask(); 1722cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 17235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 17245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int numViolations = p.readInt(); 17255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 17265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 1727cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 1728d867b7c7a2c8c151c01b57597b6612ca5355a51aDianne Hackborn if (info.crashInfo.stackTrace != null && info.crashInfo.stackTrace.length() > 10000) { 17299bb3dacbf9da4dae2cc0585c2e382c8b29476d32John Spurlock String front = info.crashInfo.stackTrace.substring(256); 17308d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // 10000 characters is way too large for this to be any sane kind of 17318d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // strict mode collection of stacks. We've had a problem where we leave 17328d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // strict mode violations associated with the thread, and it keeps tacking 17338d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // more and more stacks on to the violations. Looks like we're in this casse, 17348d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // so we'll report it and bail on all of the current strict mode violations 17358d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // we currently are maintaining for this thread. 17368d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // First, drain the remaining violations from the parcel. 17378d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn while (i < numViolations) { 17388d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn info = new ViolationInfo(p, !currentlyGathering); 17398d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn i++; 17408d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn } 17418d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // Next clear out all gathered violations. 17428d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn clearGatheredViolations(); 17438d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn // Now report the problem. 17448d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn Slog.wtfStack(TAG, "Stack is too large: numViolations=" + numViolations 17458d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn + " policy=#" + Integer.toHexString(policyMask) 17469bb3dacbf9da4dae2cc0585c2e382c8b29476d32John Spurlock + " front=" + front); 17478d05172112436a81bed6e4a0810f8914509d8a4dDianne Hackborn return; 1748ce92b0d070c4967914698b4e257c203d7121c972Dianne Hackborn } 1749cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 17505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 17515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 1752cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 17535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 17545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 17555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 17565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 17575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1758727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Called from android_util_Binder.cpp's 1759727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 1760727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 1761727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 1762727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 1763727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * thread-local policy value. 1764727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 1765727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 1766727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 1767727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1768cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1769cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1770e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * A tracked, critical time span. (e.g. during an animation.) 1771e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1772e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * The object itself is a linked list node, to avoid any allocations 1773e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * during rapid span entries and exits. 1774e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1775e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1776e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1777e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static class Span { 1778e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private String mName; 1779e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private long mCreateMillis; 1780e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mNext; 1781e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mPrev; // not used when in freeList, only active 1782e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private final ThreadSpanState mContainerState; 1783e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1784e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span(ThreadSpanState threadState) { 1785e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mContainerState = threadState; 1786e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1787e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 17881181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Empty constructor for the NO_OP_SPAN 17891181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick protected Span() { 17901181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick mContainerState = null; 17911181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 17921181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1793e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1794e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * To be called when the critical span is complete (i.e. the 1795e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * animation is done animating). This can be called on any 1796e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread (even a different one from where the animation was 1797e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * taking place), but that's only a defensive implementation 1798e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * measure. It really makes no sense for you to call this on 1799e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread other than that where you created it. 1800e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1801e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1802e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1803e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public void finish() { 1804e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = mContainerState; 1805e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1806e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mName == null) { 1807e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Duplicate finish call. Ignore. 1808e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return; 1809e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1810e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1811e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Remove ourselves from the active list. 1812e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mPrev != null) { 1813e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mPrev.mNext = mNext; 1814e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1815e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mNext != null) { 1816e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mNext.mPrev = mPrev; 1817e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1818e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mActiveHead == this) { 1819e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = mNext; 1820e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1821e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 18221cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick state.mActiveSize--; 18231cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick 18241cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick if (LOG_V) Log.d(TAG, "Span finished=" + mName + "; size=" + state.mActiveSize); 18251cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick 1826e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mCreateMillis = -1; 1827e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mName = null; 1828e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mPrev = null; 1829e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = null; 1830e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1831e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Add ourselves to the freeList, if it's not already 1832e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // too big. 1833e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListSize < 5) { 1834e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = state.mFreeListHead; 1835e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = this; 1836e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize++; 1837e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1838e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1839e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1840e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1841e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 18421181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // The no-op span that's used in user builds. 18431181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final Span NO_OP_SPAN = new Span() { 18441181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick public void finish() { 18451181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Do nothing. 18461181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 18471181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick }; 18481181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1849e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1850e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Linked lists of active spans and a freelist. 1851e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1852e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Locking notes: there's one of these structures per thread and 1853e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * all members of this structure (as well as the Span nodes under 1854e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * it) are guarded by the ThreadSpanState object instance. While 1855e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * in theory there'd be no locking required because it's all local 1856e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * per-thread, the finish() method above is defensive against 1857e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * people calling it on a different thread from where they created 1858e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * the Span, hence the locking. 1859e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1860e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static class ThreadSpanState { 1861e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mActiveHead; // doubly-linked list. 1862e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mActiveSize; 1863e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mFreeListHead; // singly-linked list. only changes at head. 1864e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mFreeListSize; 1865e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1866e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1867e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final ThreadLocal<ThreadSpanState> sThisThreadSpanState = 1868e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick new ThreadLocal<ThreadSpanState>() { 1869e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick @Override protected ThreadSpanState initialValue() { 1870e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return new ThreadSpanState(); 1871e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1872e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick }; 1873e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1874cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick private static Singleton<IWindowManager> sWindowManager = new Singleton<IWindowManager>() { 1875cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick protected IWindowManager create() { 1876cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick return IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 1877cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick } 1878cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick }; 1879cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick 1880e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1881e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Enter a named critical span (e.g. an animation) 1882e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1883e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>The name is an arbitary label (or tag) that will be applied 1884e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * to any strictmode violation that happens while this span is 1885e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * active. You must call finish() on the span when done. 1886e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1887e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>This will never return null, but on devices without debugging 1888e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * enabled, this may return a dummy object on which the finish() 1889e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * method is a no-op. 1890e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1891e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>TODO: add CloseGuard to this, verifying callers call finish. 1892e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1893e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1894e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1895e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static Span enterCriticalSpan(String name) { 18961181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick if (IS_USER_BUILD) { 18971181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick return NO_OP_SPAN; 18981181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 1899e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (name == null || name.isEmpty()) { 1900e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick throw new IllegalArgumentException("name must be non-null and non-empty"); 1901e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1902e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 1903e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span span = null; 1904e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1905e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListHead != null) { 1906e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = state.mFreeListHead; 1907e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = span.mNext; 1908e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize--; 1909e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } else { 1910e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Shouldn't have to do this often. 1911e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = new Span(state); 1912e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1913e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mName = name; 1914e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mCreateMillis = SystemClock.uptimeMillis(); 1915e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext = state.mActiveHead; 1916e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mPrev = null; 1917e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = span; 1918e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveSize++; 1919e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (span.mNext != null) { 1920e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext.mPrev = span; 1921e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 19221cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick if (LOG_V) Log.d(TAG, "Span enter=" + name + "; size=" + state.mActiveSize); 1923e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1924e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return span; 1925e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1926e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1927e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 1928e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * For code to note that it's slow. This is a no-op unless the 1929e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * current thread's {@link android.os.StrictMode.ThreadPolicy} has 1930e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * {@link android.os.StrictMode.ThreadPolicy.Builder#detectCustomSlowCalls} 1931e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * enabled. 1932e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * 1933e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * @param name a short string for the exception stack trace that's 1934e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * built if when this fires. 1935e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 1936e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public static void noteSlowCall(String name) { 1937e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 1938e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 1939e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // StrictMode not enabled. 1940e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 1941e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1942e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick ((AndroidBlockGuardPolicy) policy).onCustomSlowCall(name); 1943e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1944e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1945e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 19464e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 19474e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 19484e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static void noteDiskRead() { 19494e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 19504e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 19514e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // StrictMode not enabled. 19524e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick return; 19534e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 19544e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).onReadFromDisk(); 19554e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 19564e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 19574e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 19584e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick * @hide 19594e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick */ 19604e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick public static void noteDiskWrite() { 19614e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 19624e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 19634e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick // StrictMode not enabled. 19644e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick return; 19654e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 19664e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); 19674e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick } 19684e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick 19695f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // Guarded by StrictMode.class 19705f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick private static final HashMap<Class, Integer> sExpectedActivityInstanceCount = 19715f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick new HashMap<Class, Integer>(); 19725f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 19734e920f70f38d52d3a74c6a3133388a2e2cb6c175Brad Fitzpatrick /** 19747e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown * Returns an object that is used to track instances of activites. 19757e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown * The activity should store a reference to the tracker object in one of its fields. 19767e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown * @hide 19777e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown */ 19787e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown public static Object trackActivity(Object instance) { 19797e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown return new InstanceTracker(instance); 19807e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 19817e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 19827e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown /** 1983758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick * @hide 1984758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick */ 19855f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick public static void incrementExpectedActivityCount(Class klass) { 19867e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if (klass == null) { 1987758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return; 1988758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 19897e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 19905f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 19917e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { 19927e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown return; 19937e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 19947e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 19955f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Integer expected = sExpectedActivityInstanceCount.get(klass); 19965f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Integer newExpected = expected == null ? 1 : expected + 1; 19975f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sExpectedActivityInstanceCount.put(klass, newExpected); 19985f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 19995f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 20005f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 20015f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick /** 20025f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick * @hide 20035f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick */ 20045f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick public static void decrementExpectedActivityCount(Class klass) { 20057e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if (klass == null) { 2006758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick return; 2007758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 20087e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 20097e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown final int limit; 20105f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick synchronized (StrictMode.class) { 20117e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { 20127e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown return; 20137e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 20147e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 20155f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick Integer expected = sExpectedActivityInstanceCount.get(klass); 20167e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown int newExpected = (expected == null || expected == 0) ? 0 : expected - 1; 20175f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick if (newExpected == 0) { 20185f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sExpectedActivityInstanceCount.remove(klass); 20195f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } else { 20205f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick sExpectedActivityInstanceCount.put(klass, newExpected); 20215f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 20227e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 20235f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // Note: adding 1 here to give some breathing room during 20245f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick // orientation changes. (shouldn't be necessary, though?) 20257e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown limit = newExpected + 1; 20265f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 20275f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick 20287e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // Quick check. 20297e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown int actual = InstanceTracker.getInstanceCount(klass); 20307e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if (actual <= limit) { 20317e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown return; 20327e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 20337e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 20347e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // Do a GC and explicit count to double-check. 20357e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // This is the work that we are trying to avoid by tracking the object instances 20367e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // explicity. Running an explicit GC can be expensive (80ms) and so can walking 20377e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // the heap to count instance (30ms). This extra work can make the system feel 20387e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // noticeably less responsive during orientation changes when activities are 20397e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // being restarted. Granted, it is only a problem when StrictMode is enabled 20407e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown // but it is annoying. 20416f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey 20426f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey System.gc(); 20436f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey System.runFinalization(); 20446f3a38f3afd79ed6dddcef5c83cb442d6749e2ffJeff Sharkey System.gc(); 20457e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 20467e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown long instances = VMDebug.countInstancesOfClass(klass, false); 20477e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if (instances > limit) { 20487e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown Throwable tr = new InstanceCountViolation(klass, instances, limit); 20497e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown onVmPolicyViolation(tr.getMessage(), tr); 20505f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick } 2051758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick } 2052758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick 2053758035757f11a085a12b54daa9467f1d6bb251efBrad Fitzpatrick /** 2054cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 2055cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * to report violations that happened during a cross-process call. 2056cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 2057cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @hide 2058cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2059cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static class ViolationInfo { 2060cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2061cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Stack and other stuff info. 2062cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2063cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 2064cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2065cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2066cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The strict mode policy mask at the time of violation. 2067cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2068cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final int policy; 2069cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2070cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2071cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 2072cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * not known. 2073cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2074cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int durationMillis = -1; 2075cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2076cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2077599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick * The number of animations currently running. 2078599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick */ 2079599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick public int numAnimationsRunning = 0; 2080599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick 2081599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick /** 2082e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * List of tags from active Span instances during this 2083e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * violation, or null for none. 2084e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 2085e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public String[] tags; 2086e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 2087e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 2088cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Which violation number this was (1-based) since the last Looper loop, 2089cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 2090cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 2091cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * thread. 2092cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2093cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int violationNumThisLoop; 2094cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2095cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2096cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 2097cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * violation occurred. 2098cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2099cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public long violationUptimeMillis; 2100cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2101cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2102bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * The action of the Intent being broadcast to somebody's onReceive 2103bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * on this thread right now, or null. 2104bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick */ 2105bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick public String broadcastIntentAction; 2106bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick 2107bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick /** 2108bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * If this is a instance count violation, the number of instances in memory, 2109bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick * else -1. 2110bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick */ 2111bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public long numInstances = -1; 2112bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 2113bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick /** 2114cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 2115cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2116cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo() { 2117cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = null; 2118cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = 0; 2119cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2120cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2121cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2122cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 2123cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2124cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 2125cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 2126cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = SystemClock.uptimeMillis(); 2127cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this.policy = policy; 2128599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount(); 2129bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast(); 2130bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntent != null) { 2131bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = broadcastIntent.getAction(); 2132bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 2133e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 2134bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (tr instanceof InstanceCountViolation) { 2135bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick this.numInstances = ((InstanceCountViolation) tr).mInstances; 2136bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 2137e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 2138e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int spanActiveCount = state.mActiveSize; 2139e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount > MAX_SPAN_TAGS) { 2140e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick spanActiveCount = MAX_SPAN_TAGS; 2141e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2142e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount != 0) { 2143e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags = new String[spanActiveCount]; 2144e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span iter = state.mActiveHead; 2145e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 2146e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick while (iter != null && index < spanActiveCount) { 2147e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags[index] = iter.mName; 2148e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick index++; 2149e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick iter = iter.mNext; 2150e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2151e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2152e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2153cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2154cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2155f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick @Override 2156f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick public int hashCode() { 2157f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick int result = 17; 2158f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + crashInfo.stackTrace.hashCode(); 2159f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (numAnimationsRunning != 0) { 2160f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result *= 37; 2161f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 2162f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (broadcastIntentAction != null) { 2163f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + broadcastIntentAction.hashCode(); 2164f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 2165f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (tags != null) { 2166f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick for (String tag : tags) { 2167f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + tag.hashCode(); 2168f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 2169f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 2170f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick return result; 2171f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 2172f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick 2173cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2174cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 2175cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2176cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in) { 2177cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this(in, false); 2178cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2179cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2180cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2181cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 2182cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 2183cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @param unsetGatheringBit if true, the caller is the root caller 2184cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * and the gathering penalty should be removed. 2185cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2186cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 2187cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 2188cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int rawPolicy = in.readInt(); 2189cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (unsetGatheringBit) { 2190cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 2191cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } else { 2192cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy; 2193cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2194cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick durationMillis = in.readInt(); 2195cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationNumThisLoop = in.readInt(); 2196599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick numAnimationsRunning = in.readInt(); 2197cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = in.readLong(); 2198bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick numInstances = in.readLong(); 2199bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = in.readString(); 2200e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick tags = in.readStringArray(); 2201cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2202cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2203cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2204cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 2205cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2206cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 2207cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 220873d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn int start = dest.dataPosition(); 2209cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(policy); 2210cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(durationMillis); 2211cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 2212599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick dest.writeInt(numAnimationsRunning); 2213cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 2214bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick dest.writeLong(numInstances); 2215bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick dest.writeString(broadcastIntentAction); 2216e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick dest.writeStringArray(tags); 221773d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn int total = dest.dataPosition()-start; 2218ce92b0d070c4967914698b4e257c203d7121c972Dianne Hackborn if (total > 10*1024) { 221973d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn Slog.d(TAG, "VIO: policy=" + policy + " dur=" + durationMillis 222073d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn + " numLoop=" + violationNumThisLoop 222173d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn + " anim=" + numAnimationsRunning 222273d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn + " uptime=" + violationUptimeMillis 222373d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn + " numInst=" + numInstances); 222473d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn Slog.d(TAG, "VIO: action=" + broadcastIntentAction); 222573d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn Slog.d(TAG, "VIO: tags=" + Arrays.toString(tags)); 222673d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn Slog.d(TAG, "VIO: TOTAL BYTES WRITTEN: " + (dest.dataPosition()-start)); 222773d6a821aeecd6003c70c32f7ae6c38f062c4290Dianne Hackborn } 2228cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2229cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2230cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2231cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 2232cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Dump a ViolationInfo instance to a Printer. 2233cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 2234cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void dump(Printer pw, String prefix) { 2235cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.dump(pw, prefix); 2236cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 2237cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (durationMillis != -1) { 2238cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "durationMillis: " + durationMillis); 2239cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2240bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick if (numInstances != -1) { 2241bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick pw.println(prefix + "numInstances: " + numInstances); 2242bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 2243cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationNumThisLoop != 0) { 2244cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 2245cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2246599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick if (numAnimationsRunning != 0) { 2247599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick pw.println(prefix + "numAnimationsRunning: " + numAnimationsRunning); 2248599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick } 2249cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 2250bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntentAction != null) { 2251bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction); 2252bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 2253e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (tags != null) { 2254e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 2255e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick for (String tag : tags) { 2256e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick pw.println(prefix + "tag[" + (index++) + "]: " + tag); 2257e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2258e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 2259cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2260cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 2261cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 2262bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 2263bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // Dummy throwable, for now, since we don't know when or where the 2264bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // leaked instances came from. We might in the future, but for 2265bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // now we suppress the stack trace because it's useless and/or 2266bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick // misleading. 2267bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick private static class InstanceCountViolation extends Throwable { 2268bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final Class mClass; 2269bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final long mInstances; 2270bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick final int mLimit; 2271bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 22725f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick private static final StackTraceElement[] FAKE_STACK = { 22735f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit", 22745f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick "StrictMode.java", 1) 22755f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick }; 2276bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick 2277bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick public InstanceCountViolation(Class klass, long instances, int limit) { 22785f8b5c191cae77f536ee64f0b625e4a7f8596787Brad Fitzpatrick super(klass.toString() + "; instances=" + instances + "; limit=" + limit); 2279bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick setStackTrace(FAKE_STACK); 2280bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mClass = klass; 2281bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mInstances = instances; 2282bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick mLimit = limit; 2283bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 2284bfbe5771106a07f9c8e8685e402b1003db40526fBrad Fitzpatrick } 22857e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 22867e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown private static final class InstanceTracker { 22877e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown private static final HashMap<Class<?>, Integer> sInstanceCounts = 22887e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown new HashMap<Class<?>, Integer>(); 22897e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 22907e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown private final Class<?> mKlass; 22917e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 22927e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown public InstanceTracker(Object instance) { 22937e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown mKlass = instance.getClass(); 22947e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 22957e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown synchronized (sInstanceCounts) { 22967e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown final Integer value = sInstanceCounts.get(mKlass); 22977e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown final int newValue = value != null ? value + 1 : 1; 22987e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown sInstanceCounts.put(mKlass, newValue); 22997e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23007e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23017e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 23027e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown @Override 23037e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown protected void finalize() throws Throwable { 23047e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown try { 23057e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown synchronized (sInstanceCounts) { 23067e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown final Integer value = sInstanceCounts.get(mKlass); 23077e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if (value != null) { 23087e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown final int newValue = value - 1; 23097e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown if (newValue > 0) { 23107e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown sInstanceCounts.put(mKlass, newValue); 23117e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } else { 23127e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown sInstanceCounts.remove(mKlass); 23137e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23147e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23157e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23167e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } finally { 23177e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown super.finalize(); 23187e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23197e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23207e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown 23217e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown public static int getInstanceCount(Class<?> klass) { 23227e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown synchronized (sInstanceCounts) { 23237e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown final Integer value = sInstanceCounts.get(klass); 23247e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown return value != null ? value : 0; 23257e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23267e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 23277e442837702a6e026c73a01fedb62c222b63cfc9Jeff Brown } 2328438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick} 2329