StrictMode.java revision e36f9bf123c7cd07ce1007a16de564b2840ea1fe
1438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/* 2438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Copyright (C) 2010 The Android Open Source Project 3438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 4438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 5438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * you may not use this file except in compliance with the License. 6438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * You may obtain a copy of the License at 7438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 8438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * http://www.apache.org/licenses/LICENSE-2.0 9438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 10438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Unless required by applicable law or agreed to in writing, software 11438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * distributed under the License is distributed on an "AS IS" BASIS, 12438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * See the License for the specific language governing permissions and 14438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * limitations under the License. 15438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 16438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpackage android.os; 17438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 18599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrickimport android.animation.ValueAnimator; 19438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ActivityManagerNative; 20bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.app.ActivityThread; 21438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ApplicationErrorReport; 221065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrickimport android.app.IActivityManager; 23bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrickimport android.content.Intent; 24438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Log; 25cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrickimport android.util.Printer; 26cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrickimport android.util.Singleton; 276804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrickimport android.view.IWindowManager; 28438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 29438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit; 30438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 31438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport dalvik.system.BlockGuard; 32fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstromimport dalvik.system.CloseGuard; 33438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.PrintWriter; 355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.StringWriter; 365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.util.ArrayList; 3746d42387464a651268648659e91d022566d4844cBrad Fitzpatrickimport java.util.HashMap; 38bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrickimport java.util.concurrent.atomic.AtomicInteger; 3946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 40438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/** 4132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>StrictMode is a developer tool which detects things you might be 4232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * doing by accident and brings them to your attention so you can fix 4332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * them. 4415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 4515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or 4615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * network access on the application's main thread, where UI 4715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * operations are received and animations take place. Keeping disk 4815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and network operations off the main thread makes for much smoother, 499fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * more responsive applications. By keeping your application's main thread 509fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * responsive, you also prevent 519fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * <a href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a> 529fc2fc5757a3d28d098bd2b0ad0f869a3cf3fa14Brad Fitzpatrick * from being shown to users. 5315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 5415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is 5515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that 5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * memory with very limited concurrency. It's often the case that 5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be 5815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background 5915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from other processes. If possible, it's best to assume that such 6015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p> 6115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 6215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your 6315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or 6415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's 6515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method: 6615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 6715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre> 6815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() { 6915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * if (DEVELOPER_MODE) { 7032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}() 7132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskReads() 7232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectDiskWrites() 7332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectNetwork() // or .detectAll() for all detectable problems 7432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 7532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 7632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}() 7762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * .detectLeakedSqlLiteObjects() 78fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * .detectLeakedClosableObjects() 7932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 8032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyDeath() 8132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build()); 8215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 8315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * super.onCreate(); 8415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * } 8515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * </pre> 8615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 8732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can decide what should happen when a violation is detected. 8832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * For example, using {@link ThreadPolicy.Builder#penaltyLog} you can 8932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * watch the output of <code>adb logcat</code> while you use your 9032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * application to see the violations as they happen. 9115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 9215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are 9315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler}, 9415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc. 9515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds. In particular, 9632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * many cases of disk access are often necessary during the normal activity lifecycle. Use 9732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode to find things you did by accident. Network requests on the UI thread 9815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * are almost always a problem, though. 9915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 10015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not 10115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses. While it does 10215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing 10315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best 10415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * effort mechanism. Notably, disk or network access from JNI calls 10515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * won't necessarily trigger it. Future versions of Android may catch 10615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode 10715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * enabled in shipping applications on the Android Market. 108438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 109438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpublic final class StrictMode { 110438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static final String TAG = "StrictMode"; 11182829ef3b7c72bee36d8c17b36ac565f1856a310Brad Fitzpatrick private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE); 112438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1131181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 1146804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE); 1151181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 116c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick /** 117c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * The boolean system property to control screen flashes on violations. 118c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * 119c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick * @hide 120c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick */ 121c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick public static final String VISUAL_PROPERTY = "persist.sys.strictmode.visual"; 122c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 12346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only log a duplicate stack trace to the logs every second. 12446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_LOG_INTERVAL_MS = 1000; 12546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 12646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Only show an annoying dialog at most every 30 seconds 12746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private static final long MIN_DIALOG_INTERVAL_MS = 30000; 12846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 129e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // How many Span tags (e.g. animations) to report. 130e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final int MAX_SPAN_TAGS = 20; 131e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 132191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // How many offending stacks to keep track of (and time) per loop 133191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick // of the Looper. 134191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final int MAX_OFFENSES_PER_LOOP = 10; 135191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 13632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Thread-policy: 137438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 13815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 13932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 14015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 14132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_WRITE = 0x01; // for ThreadPolicy 14215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 14315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 14432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 14515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 14632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_DISK_READ = 0x02; // for ThreadPolicy 14715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick 14815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick /** 14932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 15015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick */ 15132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_NETWORK = 0x04; // for ThreadPolicy 152438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 153e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 154e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * For StrictMode.noteSlowCall() 155e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * 156e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * @hide 157e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 158e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public static final int DETECT_CUSTOM = 0x08; // for ThreadPolicy 159e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 160e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick private static final int ALL_THREAD_DETECT_BITS = 161e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK | DETECT_CUSTOM; 162e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 16332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Process-policy: 164438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 165438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 16632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Note, a "VM_" bit, not thread. 16732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 16832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 16932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy 17032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 17132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 172fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Note, a "VM_" bit, not thread. 173fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 174fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 175fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for ProcessPolicy 176fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 177fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 17832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 179438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 180438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_LOG = 0x10; // normal android.util.Log 181438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 18232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Used for both process and thread policy: 18332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 184438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 18532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 186438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 187438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DIALOG = 0x20; 188438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 189438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 190b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death on any detected violation. 191b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 19232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 193438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 194438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DEATH = 0x40; 195438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 196438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 197b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Death just for detected network usage. 198b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 199b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 200b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 201b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static final int PENALTY_DEATH_ON_NETWORK = 0x200; 202b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 203b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 2046804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Flash the screen during violations. 2056804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * 2066804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * @hide 2076804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 2086804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick public static final int PENALTY_FLASH = 0x800; 2096804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 2106804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 21132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 212438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 213438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final int PENALTY_DROPBOX = 0x80; 214438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 215727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 216727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Non-public penalty mode which overrides all the other penalty 217727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * bits and signals that we're in a Binder call and we should 218727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * ignore the other penalty bits and instead serialize back all 219727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * our offending stack traces to the caller to ultimately handle 220727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * in the originating process. 221727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * 222703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * This must be kept in sync with the constant in libs/binder/Parcel.cpp 223703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * 224727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * @hide 225727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 226727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick public static final int PENALTY_GATHER = 0x100; 227727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 22832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 22971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick * Mask of all the penalty bits. 23071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick */ 23171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick private static final int PENALTY_MASK = 232b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | 2336804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; 23471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 23571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick /** 23632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The current VmPolicy in effect. 23732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 23832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static volatile int sVmPolicyMask = 0; 23932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 240bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 241bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * The number of threads trying to do an async dropbox write. 242bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * Just to limit ourselves out of paranoia. 243bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 244bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick private static final AtomicInteger sDropboxCallsInFlight = new AtomicInteger(0); 245bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 24632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private StrictMode() {} 24732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 24832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 24932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to a certain thread. 25032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 25132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy 25232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can be retrieved with {@link #getThreadPolicy}. 25332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 25432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note that multiple penalties may be provided and they're run 25532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * in order from least to most severe (logging before process 25632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * death, for example). There's currently no mechanism to choose 25732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * different penalties for different detected actions. 25832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 25932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class ThreadPolicy { 26032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 26132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 26232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 26332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final ThreadPolicy LAX = new ThreadPolicy(0); 26432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 26532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 26632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 26732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private ThreadPolicy(int mask) { 26832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 26932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 27132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 27232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 27332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.ThreadPolicy; mask=" + mask + "]"; 27432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 27532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 27632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 27732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates ThreadPolicy instances. Methods whose names start 27832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 27932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 28032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 28132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 28232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 28332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 28432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 28732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 28832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 28932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 29032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 29232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 29332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 29632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask = 0; 29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 29832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 29932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Create a Builder that detects nothing and has no 30032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations. (but note that {@link #build} will default 30132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to enabling {@link #penaltyLog} if no other penalties 30232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * are specified) 30332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder() { 30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = 0; 30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Initialize a Builder from an existing ThreadPolicy. 31032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder(ThreadPolicy policy) { 31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask = policy.mask; 31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>As of the Gingerbread release this includes network and 31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * disk operations but will likely expand in future releases. 32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 322e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(ALL_THREAD_DETECT_BITS); 32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 32532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable the detection of everything. 32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitAll() { 329e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return disable(ALL_THREAD_DETECT_BITS); 33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of network operations. 33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 33532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectNetwork() { 33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_NETWORK); 33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 33832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 33932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 34032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of network operations. 34132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitNetwork() { 34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_NETWORK); 34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 34632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 34732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk reads. 34832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 34932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskReads() { 35032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_READ); 35132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 35232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 35332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 35432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk reads. 35532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 35632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskReads() { 35732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_READ); 35832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 35932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 36032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 361e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * Enable detection of disk reads. 362e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 363e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public Builder detectCustomSlowCalls() { 364e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(DETECT_CUSTOM); 365e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 366e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 367e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 368e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * Enable detection of disk reads. 369e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 370e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public Builder permitCustomSlowCalls() { 371e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return enable(DETECT_CUSTOM); 372e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 373e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 374e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detection of disk writes. 37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectDiskWrites() { 37832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_DISK_WRITE); 37932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 38232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Disable detection of disk writes. 38332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 38432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder permitDiskWrites() { 38532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return disable(DETECT_DISK_WRITE); 38632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 38732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 38832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 38932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Show an annoying dialog to the developer on detected 39032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violations, rate-limited to be only a little annoying. 39132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 39232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDialog() { 39332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DIALOG); 39432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 39532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 39632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 39732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crash the whole process on violation. This penalty runs at 39832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so you'll still get 39932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * see logging or other violations before the process dies. 400b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 401b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>Unlike {@link #penaltyDeathOnNetwork}, this applies 402b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * to disk reads, disk writes, and network usage if their 403b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * corresponding detect flags are set. 40432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 40532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 40632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 40732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 410b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Crash the whole process on any network usage. Unlike 411b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * {@link #penaltyDeath}, this penalty runs 412b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <em>before</em> anything else. You must still have 413b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * called {@link #detectNetwork} to enable this. 414b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 415b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * <p>In the Honeycomb or later SDKs, this is on by default. 416b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 417b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public Builder penaltyDeathOnNetwork() { 418b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick return enable(PENALTY_DEATH_ON_NETWORK); 419b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 420b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 421b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 4226804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick * Flash the screen during a violation. 4236804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick */ 4246804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick public Builder penaltyFlashScreen() { 4256804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick return enable(PENALTY_FLASH); 4266804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 4276804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 4286804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick /** 42932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 43032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 43132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 43232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 43332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 43432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 43532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 43632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 44332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 44432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 44532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 44632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 44732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 44832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 44932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 45032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder disable(int bit) { 45132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask &= ~bit; 45232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 45332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 45432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 45532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 45632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the ThreadPolicy instance. 45732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 45832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 45932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 46032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 46132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 46232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public ThreadPolicy build() { 46332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 46632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 46732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 46832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 46932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 47032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(mMask); 47132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 47232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 47332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 47432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 47532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 47632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link StrictMode} policy applied to all threads in the virtual machine's process. 47732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 47832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>The policy is enabled by {@link #setVmPolicy}. 47932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 48032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class VmPolicy { 48132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 48232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * The default, lax policy which doesn't catch anything. 48332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 48432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final VmPolicy LAX = new VmPolicy(0); 48532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 48632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int mask; 48732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 48832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private VmPolicy(int mask) { 48932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick this.mask = mask; 49032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 49132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 49232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick @Override 49332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public String toString() { 49432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return "[StrictMode.VmPolicy; mask=" + mask + "]"; 49532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 49632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 49732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 49832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Creates {@link VmPolicy} instances. Methods whose names start 49932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@code detect} specify what problems we should look 50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * for. Methods whose names start with {@code penalty} specify what 50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * we should do when we detect a problem. 50232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can call as many {@code detect} and {@code penalty} 50432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * methods as you like. Currently order is insignificant: all 50532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * penalties apply to all detected problems. 50632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 50732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>For example, detect everything and log anything that's found: 50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <pre> 50932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() 51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .detectAll() 51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .penaltyLog() 51232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * .build(); 51332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode.setVmPolicy(policy); 51432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * </pre> 51532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 51632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static final class Builder { 51732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private int mMask; 51832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 51932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 52032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect everything that's potentially suspect. 52132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 522fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>In the Honeycomb release this includes leaks of 523fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * SQLite cursors and other closable objects but will 524fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * likely expand in future releases. 52532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 52632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectAll() { 527fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); 52832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 52932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 53032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 53132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Detect when an 53232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link android.database.sqlite.SQLiteCursor} or other 53332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * SQLite object is finalized without having been closed. 53432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 53532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You always want to explicitly close your SQLite 53632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * cursors to avoid unnecessary database contention and 53732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * temporary memory leaks. 53832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 53932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder detectLeakedSqlLiteObjects() { 54032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(DETECT_VM_CURSOR_LEAKS); 54132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 54232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 544fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * Detect when an {@link java.io.Closeable} or other 545fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * object with a explict termination method is finalized 546fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * without having been closed. 547fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * 548fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * <p>You always want to explicitly close such objects to 549fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * avoid unnecessary resources leaks. 550fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 551fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public Builder detectLeakedClosableObjects() { 552fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return enable(DETECT_VM_CLOSABLE_LEAKS); 553fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 554fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 555fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 55632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Crashes the whole process on violation. This penalty runs at 55732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * the end of all enabled penalties so yo you'll still get 55832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * your logging or other violations before the process dies. 55932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 56032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDeath() { 56132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DEATH); 56232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 56332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 56432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 56532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Log detected violations to the system log. 56632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 56732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyLog() { 56832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_LOG); 56932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 57032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 57132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 57232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Enable detected violations log a stacktrace and timing data 57332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to the {@link android.os.DropBoxManager DropBox} on policy 57432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * violation. Intended mostly for platform integrators doing 57532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * beta user field data collection. 57632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 57732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public Builder penaltyDropBox() { 57832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return enable(PENALTY_DROPBOX); 57932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 58032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 58132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private Builder enable(int bit) { 58232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick mMask |= bit; 58332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return this; 58432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 58532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 58632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 58732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Construct the VmPolicy instance. 58832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 58932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Note: if no penalties are enabled before calling 59032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <code>build</code>, {@link #penaltyLog} is implicitly 59132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * set. 59232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 59332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public VmPolicy build() { 59432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // If there are detection bits set but no violation bits 59532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // set, enable simple logging. 59632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (mMask != 0 && 59732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick (mMask & (PENALTY_DEATH | PENALTY_LOG | 59832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { 59932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick penaltyLog(); 60032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 60132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(mMask); 60232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 60332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 60432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 605438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 606438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 6075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Log of strict mode violation stack traces that have occurred 6085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * during a Binder call, to be serialized back later to the caller 6095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * via Parcel.writeNoException() (amusingly) where the caller can 6105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * choose how to react. 6115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 612cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations = 613cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 614cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 615703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // Starts null to avoid unnecessary allocations when 616703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // checking whether there are any violations or not in 617703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick // hasGatheredViolations() below. 618703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return null; 6195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick }; 6215b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 62332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions on the current thread should 62432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * be detected, as well as the penalty if such actions occur. 62515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * 62632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>Internally this sets a thread-local variable which is 62715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagated across cross-process IPC calls, meaning you can 62815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * catch violations when a system service or another process 62915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * accesses the disk or network on your behalf. 630438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 63132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 632438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 63332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setThreadPolicy(final ThreadPolicy policy) { 63432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(policy.mask); 63532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 63632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 63732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick private static void setThreadPolicyMask(final int policyMask) { 638727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // In addition to the Java-level thread-local in Dalvik's 639727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // BlockGuard, we also need to keep a native thread-local in 640727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Binder in order to propagate the value across Binder calls, 641727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // even across native-only processes. The two are kept in 642727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // sync via the callback to onStrictModePolicyChange, below. 643727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(policyMask); 644727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 645727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // And set the Android native version... 646727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick Binder.setThreadStrictModePolicy(policyMask); 647727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 648727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 649727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Sets the policy in Dalvik/libcore (BlockGuard) 650727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void setBlockGuardPolicy(final int policyMask) { 65146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (policyMask == 0) { 65246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY); 65346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick return; 65446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 655438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 656438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 657438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask)); 658438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 659438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy; 660438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick androidPolicy.setPolicyMask(policyMask); 661438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 662438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 663438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 6644b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom // Sets up CloseGuard in Dalvik/libcore 6654b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static void setCloseGuardEnabled(boolean enabled) { 6667c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick if (!(CloseGuard.getReporter() instanceof AndroidCloseGuardReporter)) { 6674b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setReporter(new AndroidCloseGuardReporter()); 6684b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 6694b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom CloseGuard.setEnabled(enabled); 6704b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 6714b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 6725b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { 6735b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeNetworkViolation(int policyMask) { 67432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_NETWORK); 6755b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { 6795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskReadViolation(int policyMask) { 68032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_READ); 6815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 6845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { 6855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public StrictModeDiskWriteViolation(int policyMask) { 68632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick super(policyMask, DETECT_DISK_WRITE); 6875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 6895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 690e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick private static class StrictModeCustomViolation extends BlockGuard.BlockGuardPolicyException { 691e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public StrictModeCustomViolation(int policyMask, String name) { 692e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick super(policyMask, DETECT_CUSTOM, name); 693e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 694e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 695e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 696438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick /** 69715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * Returns the bitmask of the current thread's policy. 698438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * 69932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled 70032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 70132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 702438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */ 70332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static int getThreadPolicyMask() { 704438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return BlockGuard.getThreadPolicy().getPolicyMask(); 705438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 706438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 7075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 70832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Returns the current thread's policy. 70932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 71032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy getThreadPolicy() { 711e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // TODO: this was a last minute Gingerbread API change (to 712e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // introduce VmPolicy cleanly) but this isn't particularly 713e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // optimal for users who might call this method often. This 714e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // should be in a thread-local and not allocate on each call. 71532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(getThreadPolicyMask()); 71632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 71732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 71832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 71932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 72032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 72132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit both disk reads & writes, and sets the new policy 72232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 72332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 72497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 72532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to {@link #setThreadPolicy} to 72632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * restore the policy at the end of a block 72797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 72832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskWrites() { 72932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 73032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ); 73132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 73232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 73397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 73432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 73597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 73697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 73797461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 73832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * A convenience wrapper that takes the current 73932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it 74032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * to permit disk reads, and sets the new policy 74132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * with {@link #setThreadPolicy}, returning the old policy so you 74232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * can restore it at the end of a block. 74397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * 74432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @return the old policy, to be passed to setThreadPolicy to 74597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick * restore the policy. 74697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick */ 74732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static ThreadPolicy allowThreadDiskReads() { 74832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int oldPolicyMask = getThreadPolicyMask(); 74932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ); 75032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if (newPolicyMask != oldPolicyMask) { 75132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(newPolicyMask); 75297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 75332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new ThreadPolicy(oldPolicyMask); 75497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick } 75597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick 756f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // We don't want to flash the screen red in the system server 757f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // process, nor do we want to modify all the call sites of 758f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // conditionallyEnableDebugLogging() in the system server, 759f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // so instead we use this to determine if we are the system server. 760f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick private static boolean amTheSystemServerProcess() { 761f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // Fast path. Most apps don't have the system server's UID. 762f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick if (Process.myUid() != Process.SYSTEM_UID) { 763f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return false; 764f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 765f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick 766f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // The settings app, though, has the system server's UID so 767f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick // look up our stack to see if we came from the system server. 768f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick Throwable stack = new Throwable(); 769f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick stack.fillInStackTrace(); 770f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick for (StackTraceElement ste : stack.getStackTrace()) { 771f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick String clsName = ste.getClassName(); 772f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick if (clsName != null && clsName.startsWith("com.android.server.")) { 773f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return true; 774f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 775f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 776f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick return false; 777f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick } 778f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick 77997461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick /** 78050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * Enable DropBox logging for debug phone builds. 78150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * 78250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick * @hide 78350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick */ 78450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick public static boolean conditionallyEnableDebugLogging() { 785f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick boolean doFlashes = !amTheSystemServerProcess() && 786f54545927f365d6e55cbf66ff9f7ffe91aada774Brad Fitzpatrick SystemProperties.getBoolean(VISUAL_PROPERTY, IS_ENG_BUILD); 787c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 78850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // For debug builds, log event loop stalls to dropbox for analysis. 78950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick // Similar logic also appears in ActivityThread.java for system apps. 790c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (IS_USER_BUILD && !doFlashes) { 7917c2ae6570321575ad74a25bdc72bea1ec6558660Brad Fitzpatrick setCloseGuardEnabled(false); 79250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return false; 79350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 794c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 795c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick int threadPolicyMask = StrictMode.DETECT_DISK_WRITE | 796c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.DETECT_DISK_READ | 797c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.DETECT_NETWORK; 798c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 799c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (!IS_USER_BUILD) { 800c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick threadPolicyMask |= StrictMode.PENALTY_DROPBOX; 801c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 802c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (doFlashes) { 803c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick threadPolicyMask |= StrictMode.PENALTY_FLASH; 804c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 805c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 806c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.setThreadPolicyMask(threadPolicyMask); 807c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick 808c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick if (IS_USER_BUILD) { 809c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick setCloseGuardEnabled(false); 810c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } else { 811c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | 812c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.DETECT_VM_CLOSABLE_LEAKS | 813c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick StrictMode.PENALTY_DROPBOX; 814c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 815c1a968a8ed45181312f7d4bcdbba0cc8ddc201baBrad Fitzpatrick } 81650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick return true; 81750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick } 81850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick 81950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick /** 820b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * Used by the framework to make network usage on the main 821b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * thread a fatal error. 822b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * 823b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick * @hide 824b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick */ 825b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick public static void enableDeathOnNetwork() { 826b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int oldPolicy = getThreadPolicyMask(); 827b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick int newPolicy = oldPolicy | DETECT_NETWORK | PENALTY_DEATH_ON_NETWORK; 828b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick setThreadPolicyMask(newPolicy); 829b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 830b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick 831b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick /** 8325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Parses the BlockGuard policy mask out from the Exception's 8335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * getMessage() String value. Kinda gross, but least 8345b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * invasive. :/ 8355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 836e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * Input is of the following forms: 837e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * "policy=137 violation=64" 838e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * "policy=137 violation=64 msg=Arbitrary text" 8395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * 8405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Returns 0 on failure, which is a valid policy, but not a 8415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * valid policy during a violation (else there must've been 8425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * some policy in effect to violate). 8435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 8445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parsePolicyFromMessage(String message) { 8455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null || !message.startsWith("policy=")) { 8465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 8475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int spaceIndex = message.indexOf(' '); 8495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (spaceIndex == -1) { 8505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 8515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String policyString = message.substring(7, spaceIndex); 8535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 8545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(policyString).intValue(); 8555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 8565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 8575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 8605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 8615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Like parsePolicyFromMessage(), but returns the violation. 8625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 8635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static int parseViolationFromMessage(String message) { 8645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (message == null) { 8655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 8665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8675b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int violationIndex = message.indexOf("violation="); 8685b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (violationIndex == -1) { 8695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 8705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 871e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick int numberStartIndex = violationIndex + "violation=".length(); 872e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick int numberEndIndex = message.indexOf(' ', numberStartIndex); 873e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (numberEndIndex == -1) { 874e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick numberEndIndex = message.length(); 875e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 876e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick String violationString = message.substring(numberStartIndex, numberEndIndex); 8775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick try { 8785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return Integer.valueOf(violationString).intValue(); 8795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } catch (NumberFormatException e) { 8805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return 0; 8815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 8835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 884191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = 885191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick new ThreadLocal<ArrayList<ViolationInfo>>() { 886191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick @Override protected ArrayList<ViolationInfo> initialValue() { 887191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return new ArrayList<ViolationInfo>(); 888191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 889191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick }; 890191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 891bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // Note: only access this once verifying the thread has a Looper. 892bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick private static final ThreadLocal<Handler> threadHandler = new ThreadLocal<Handler>() { 893bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick @Override protected Handler initialValue() { 894bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick return new Handler(); 895bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 896bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick }; 897bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 898191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick private static boolean tooManyViolationsThisLoop() { 899191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; 900191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 901191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick 902438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { 903438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick private int mPolicyMask; 90446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 90546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Map from violation stacktrace hashcode -> uptimeMillis of 90646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // last violation. No locking needed, as this is only 90746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // accessed by the same thread. 90846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>(); 909438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 910438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public AndroidBlockGuardPolicy(final int policyMask) { 911438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 912438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 913438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 9145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick @Override 9155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick public String toString() { 9165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask; 9175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 9185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 919438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 920438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public int getPolicyMask() { 921438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mPolicyMask; 922438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 923438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 924438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 925438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onWriteToDisk() { 92632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { 927438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 928438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 929191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 930191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 931191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 932cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); 933cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 934cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 935438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 936438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 937e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // Not part of BlockGuard.Policy; just part of StrictMode: 938e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick void onCustomSlowCall(String name) { 939e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if ((mPolicyMask & DETECT_CUSTOM) == 0) { 940e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 941e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 942e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 943e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 944e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 945e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeCustomViolation(mPolicyMask, name); 946e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick e.fillInStackTrace(); 947e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick startHandlingViolationException(e); 948e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 949e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick 950438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 951438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onReadFromDisk() { 95232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_DISK_READ) == 0) { 953438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 954438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 955191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 956191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 957191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 958cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); 959cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 960cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 961438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 962438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 963438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick // Part of BlockGuard.Policy interface: 964438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void onNetwork() { 96532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((mPolicyMask & DETECT_NETWORK) == 0) { 966438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return; 967438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 968b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) { 969b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick throw new NetworkOnMainThreadException(); 970b6e18412af35bf724298796eed65ef1fbbe1925eBrad Fitzpatrick } 971191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (tooManyViolationsThisLoop()) { 972191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick return; 973191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick } 974cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); 975cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick e.fillInStackTrace(); 976cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick startHandlingViolationException(e); 977438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 978438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 979438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public void setPolicyMask(int policyMask) { 980438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick mPolicyMask = policyMask; 981438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 982438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 9835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Start handling a violation that just started and hasn't 9845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // actually run yet (e.g. no disk write or network operation 9855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // has yet occurred). This sees if we're in an event loop 9865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread and, if so, uses it to roughly measure how long the 9875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation took. 9885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) { 989cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ViolationInfo info = new ViolationInfo(e, e.getPolicy()); 990cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.violationUptimeMillis = SystemClock.uptimeMillis(); 991cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolationWithTimingAttempt(info); 992cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 993438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 994cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Attempts to fill in the provided ViolationInfo's 995cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // durationMillis field if this thread has a Looper we can use 996cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // to measure with. We measure from the time of violation 997cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // until the time the looper is idle again (right before 998cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // the next epoll_wait) 999cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolationWithTimingAttempt(final ViolationInfo info) { 1000438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Looper looper = Looper.myLooper(); 1001cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1002cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Without a Looper, we're unable to time how long the 1003cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // violation takes place. This case should be rare, as 1004cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // most users will care about timing violations that 1005cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // happen on their main UI thread. Note that this case is 1006cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // also hit when a violation takes place in a Binder 1007cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // thread, in "gather" mode. In this case, the duration 1008cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // of the violation is computed by the ultimate caller and 1009cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // its Looper, if any. 1010cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // TODO: if in gather mode, ignore Looper.myLooper() and always 1011cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // go into this immediate mode? 1012438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick if (looper == null) { 1013cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis = -1; // unknown (redundant, already set) 1014cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(info); 1015cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1016438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1017438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1018cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); 1019191cdf023c3c1ab441087a77f7881c7bb376613aBrad Fitzpatrick if (records.size() >= MAX_OFFENSES_PER_LOOP) { 1020cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // Not worth measuring. Too many offenses in one loop. 1021cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1022cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1023cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.add(info); 1024cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (records.size() > 1) { 1025cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // There's already been a violation this loop, so we've already 1026cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // registered an idle handler to process the list of violations 1027cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick // at the end of this Looper's loop. 1028cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick return; 1029cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1030cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 10316804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick final IWindowManager windowManager = (info.policy & PENALTY_FLASH) != 0 ? 1032cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick sWindowManager.get() : null; 10336804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick if (windowManager != null) { 10346804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick try { 10356804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick windowManager.showStrictModeViolation(true); 10366804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } catch (RemoteException unused) { 10376804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 10386804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick } 10396804433b0af50f33a338307ae8ddb50bc49e886bBrad Fitzpatrick 1040bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // We post a runnable to a Handler (== delay 0 ms) for 1041bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // measuring the end time of a violation instead of using 1042bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // an IdleHandler (as was previously used) because an 1043bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // IdleHandler may not run for quite a long period of time 1044bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // if an ongoing animation is happening and continually 1045bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // posting ASAP (0 ms) animation steps. Animations are 1046bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // throttled back to 60fps via SurfaceFlinger/View 1047bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // invalidates, _not_ by posting frame updates every 16 1048bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // milliseconds. 1049bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick threadHandler.get().post(new Runnable() { 1050bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick public void run() { 1051cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick long loopFinishTime = SystemClock.uptimeMillis(); 1052bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1053bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // Note: we do this early, before handling the 1054bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // violation below, as handling the violation 1055bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // may include PENALTY_DEATH and we don't want 1056bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick // to keep the red border on. 1057bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick if (windowManager != null) { 1058bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick try { 1059bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick windowManager.showStrictModeViolation(false); 1060bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } catch (RemoteException unused) { 1061bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1062bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick } 1063bea168c09d173fb99cfc91c562c4a497a5e7d2d2Brad Fitzpatrick 1064cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (int n = 0; n < records.size(); ++n) { 1065cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo v = records.get(n); 1066cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.violationNumThisLoop = n + 1; 1067cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick v.durationMillis = 1068cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick (int) (loopFinishTime - v.violationUptimeMillis); 1069cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick handleViolation(v); 1070cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1071cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick records.clear(); 1072cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1073cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick }); 10745b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1075438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 10765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Note: It's possible (even quite likely) that the 10775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // thread-local policy mask has changed from the time the 10785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // violation fired and now (after the violating code ran) due 10795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // to people who push/pop temporary policy in regions of code, 10805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // hence the policy being passed around. 1081cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick void handleViolation(final ViolationInfo info) { 1082cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) { 1083cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.wtf(TAG, "unexpected null stacktrace"); 10845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 10855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1086438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1087cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy); 108846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1089cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_GATHER) != 0) { 1090cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1091703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1092cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations = new ArrayList<ViolationInfo>(1); 1093703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(violations); 1094703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else if (violations.size() >= 5) { 10955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Too many. In a loop or something? Don't gather them all. 10965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 10975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1098cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick for (ViolationInfo previous : violations) { 1099cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) { 11005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Duplicate. Don't log. 11015b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick return; 11025b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 11035b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1104cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violations.add(info); 1105727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick return; 1106727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1107727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 110846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // Not perfect, but fast and good enough for dup suppression. 1109f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick Integer crashFingerprint = info.hashCode(); 111046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long lastViolationTime = 0; 111146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick if (mLastViolationTime.containsKey(crashFingerprint)) { 111246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick lastViolationTime = mLastViolationTime.get(crashFingerprint); 111346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 111446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long now = SystemClock.uptimeMillis(); 111546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick mLastViolationTime.put(crashFingerprint, now); 111646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick long timeSinceLastViolationMillis = lastViolationTime == 0 ? 111746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Long.MAX_VALUE : (now - lastViolationTime); 111846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1119cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_LOG) != 0 && 112046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { 1121cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (info.durationMillis != -1) { 11225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation; ~duration=" + 1123cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.durationMillis + " ms: " + info.crashInfo.stackTrace); 1124438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } else { 1125cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace); 1126438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1127438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1128438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 112971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // The violationMaskSubset, passed to ActivityManager, is a 113046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // subset of the original StrictMode policy bitmask, with 113146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // only the bit violated and penalty bits to be executed 113246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick // by the ActivityManagerService remaining set. 1133cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationMaskSubset = 0; 113446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1135cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DIALOG) != 0 && 113646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) { 1137cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DIALOG; 113846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 113946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1140cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) { 1141cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= PENALTY_DROPBOX; 114246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick } 114346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick 1144cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationMaskSubset != 0) { 1145cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); 1146cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset |= violationBit; 114732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 114871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 114971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick final boolean justDropBox = (info.policy & PENALTY_MASK) == PENALTY_DROPBOX; 115071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick if (justDropBox) { 115171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // If all we're going to ask the activity manager 115271678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // to do is dropbox it (the common case during 115371678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // platform development), we can avoid doing this 115471678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // call synchronously which Binder data suggests 115571678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // isn't always super fast, despite the implementation 115671678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // in the ActivityManager trying to be mostly async. 1157bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick dropboxViolationAsync(violationMaskSubset, info); 115871678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick return; 115971678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick } 116071678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick 116171678ddcc45d9cd4557f3bed8bba5382bf36b68bBrad Fitzpatrick // Normal synchronous call to the ActivityManager. 1162438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick try { 1163727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 1164727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 1165727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 1166727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // We restore the current policy below, in the finally block. 116732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 1168727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1169438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 1170438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick RuntimeInit.getApplicationObject(), 1171cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationMaskSubset, 1172cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info); 1173438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } catch (RemoteException e) { 117446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 1175727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } finally { 1176727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick // Restore the policy. 117732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 1178438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1179438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1180438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 1181cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if ((info.policy & PENALTY_DEATH) != 0) { 1182438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); 1183438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick Process.killProcess(Process.myPid()); 1184438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick System.exit(10); 1185438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1186438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1187438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 1188727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick 1189bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick /** 1190bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * In the common case, as set by conditionallyEnableDebugLogging, 1191bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * we're just dropboxing any violations but not showing a dialog, 1192bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * not loggging, and not killing the process. In these cases we 1193bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * don't need to do a synchronous call to the ActivityManager. 1194bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * This is used by both per-thread and vm-wide violations when 1195bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick * applicable. 1196bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick */ 1197bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick private static void dropboxViolationAsync( 1198bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick final int violationMaskSubset, final ViolationInfo info) { 1199bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick int outstanding = sDropboxCallsInFlight.incrementAndGet(); 1200bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (outstanding > 20) { 1201bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // What's going on? Let's not make make the situation 1202bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // worse and just not log. 1203bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick sDropboxCallsInFlight.decrementAndGet(); 1204bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick return; 1205bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1206bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1207bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (LOG_V) Log.d(TAG, "Dropboxing async; in-flight=" + outstanding); 1208bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1209bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick new Thread("callActivityManagerForStrictModeDropbox") { 1210bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick public void run() { 1211bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1212bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick try { 12131065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick IActivityManager am = ActivityManagerNative.getDefault(); 12141065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick if (am == null) { 12151065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick Log.d(TAG, "No activity manager; failed to Dropbox violation."); 12161065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick } else { 12171065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick am.handleApplicationStrictModeViolation( 12181065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick RuntimeInit.getApplicationObject(), 12191065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick violationMaskSubset, 12201065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick info); 12211065685400335ef8c1220f34b4e896e7da603789Brad Fitzpatrick } 1222bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } catch (RemoteException e) { 1223bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick Log.e(TAG, "RemoteException handling StrictMode violation", e); 1224bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1225bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick int outstanding = sDropboxCallsInFlight.decrementAndGet(); 1226bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (LOG_V) Log.d(TAG, "Dropbox complete; in-flight=" + outstanding); 1227bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1228bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick }.start(); 1229bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 1230bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 12314b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom private static class AndroidCloseGuardReporter implements CloseGuard.Reporter { 12324b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public void report (String message, Throwable allocationSite) { 12334b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, allocationSite); 12344b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 12354b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 12364b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 1237727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick /** 12385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 12395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 12405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static boolean hasGatheredViolations() { 1241703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick return gatheredViolations.get() != null; 1242703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1243703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick 1244703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /** 1245703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Called from Parcel.writeException(), so we drop this memory and 1246703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * don't incorrectly attribute it to the wrong caller on the next 1247703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick * Binder call on this thread. 1248703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick */ 1249703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick /* package */ static void clearGatheredViolations() { 1250703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 12515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 12525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 12535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 125432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Sets the policy for what actions in the VM process (on any 125532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * thread) should be detected, as well as the penalty if such 125632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * actions occur. 125732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * 125832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @param policy the policy to put into place 125932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 126032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void setVmPolicy(final VmPolicy policy) { 126132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick sVmPolicyMask = policy.mask; 12624b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); 126332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 126432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 126532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 126632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * Gets the current VM policy. 126732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 126832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static VmPolicy getVmPolicy() { 126932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return new VmPolicy(sVmPolicyMask); 127032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 127132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 127232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 127362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * Enable the recommended StrictMode defaults, with violations just being logged. 127462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * 127562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick * <p>This catches disk and network access on the main thread, as 1276fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * well as leaked SQLite cursors and unclosed resources. This is 1277fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * simply a wrapper around {@link #setVmPolicy} and {@link 1278fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * #setThreadPolicy}. 127962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick */ 128062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick public static void enableDefaults() { 128162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 128262a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .detectAll() 128362a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 128462a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 128562a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 1286e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick .detectAll() 128762a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .penaltyLog() 128862a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick .build()); 128962a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick } 129062a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick 129162a1eb58bfafe8744d7a65f651e11b88fdb0938dBrad Fitzpatrick /** 129232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 129332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 129432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static boolean vmSqliteObjectLeaksEnabled() { 129532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0; 129632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 129732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 129832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 129932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * @hide 130032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick */ 1301fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom public static boolean vmClosableObjectLeaksEnabled() { 1302fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom return (sVmPolicyMask & DETECT_VM_CLOSABLE_LEAKS) != 0; 1303fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom } 1304fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom 1305fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom /** 1306fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom * @hide 1307fd9ddd1a40efc801dc7512950cb9336967b6f775Brian Carlstrom */ 130832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick public static void onSqliteObjectLeaked(String message, Throwable originStack) { 13094b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom onVmPolicyViolation(message, originStack); 13104b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom } 13114b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom 13124b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom /** 13134b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom * @hide 13144b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom */ 13154b9b7c38e8f52259f9d2f960072d35e8a1ab2129Brian Carlstrom public static void onVmPolicyViolation(String message, Throwable originStack) { 131632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick if ((sVmPolicyMask & PENALTY_LOG) != 0) { 131732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, message, originStack); 131832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 131932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1320bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0; 1321bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0; 1322bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1323bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS; 1324bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); 1325bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick 1326bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (penaltyDropbox && !penaltyDeath) { 1327bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // Common case for userdebug/eng builds. If no death and 1328bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // just dropboxing, we can do the ActivityManager call 1329bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick // asynchronously. 1330bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick dropboxViolationAsync(violationMaskSubset, info); 1331bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick return; 1332bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick } 133332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1334bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (penaltyDropbox) { 133532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // The violationMask, passed to ActivityManager, is a 133632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // subset of the original StrictMode policy bitmask, with 133732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // only the bit violated and penalty bits to be executed 133832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // by the ActivityManagerService remaining set. 133932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick final int savedPolicyMask = getThreadPolicyMask(); 134032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick try { 134132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // First, remove any policy before we call into the Activity Manager, 134232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // otherwise we'll infinite recurse as we try to log policy violations 134332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // to disk, thus violating policy, thus requiring logging, etc... 134432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // We restore the current policy below, in the finally block. 134532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(0); 134632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 134732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick ActivityManagerNative.getDefault().handleApplicationStrictModeViolation( 134832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick RuntimeInit.getApplicationObject(), 134932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick violationMaskSubset, 135032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick info); 135132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } catch (RemoteException e) { 135232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Log.e(TAG, "RemoteException trying to handle StrictMode violation", e); 135332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } finally { 135432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick // Restore the policy. 135532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick setThreadPolicyMask(savedPolicyMask); 135632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 135732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 135832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 1359bee248769d51adb335b71b329b3d7813c5c71851Brad Fitzpatrick if (penaltyDeath) { 136032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down."); 136132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick Process.killProcess(Process.myPid()); 136232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick System.exit(10); 136332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 136432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick } 136532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick 136632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick /** 13675b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.writeNoException() 13685b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 13695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void writeGatheredViolationsToParcel(Parcel p) { 1370cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ArrayList<ViolationInfo> violations = gatheredViolations.get(); 1371703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (violations == null) { 1372703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(0); 1373703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } else { 1374703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick p.writeInt(violations.size()); 1375703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick for (int i = 0; i < violations.size(); ++i) { 1376703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.get(i).writeToParcel(p, 0 /* unused flags? */); 1377703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick } 1378703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); 1379703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick violations.clear(); // somewhat redundant, as we're about to null the threadlocal 13805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 1381703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick gatheredViolations.set(null); 13825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 13835b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 13845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick private static class LogStackTrace extends Exception {} 13855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 13865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 13875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, 13885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick * we here read back all the encoded violations. 13895b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick */ 13905b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /* package */ static void readAndHandleBinderCallViolations(Parcel p) { 13915b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick // Our own stack trace to append 13925b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick StringWriter sw = new StringWriter(); 1393cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick new LogStackTrace().printStackTrace(new PrintWriter(sw)); 13945b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick String ourStack = sw.toString(); 13955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 139632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick int policyMask = getThreadPolicyMask(); 1397cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0; 13985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 13995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick int numViolations = p.readInt(); 14005b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick for (int i = 0; i < numViolations; ++i) { 14015b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); 1402cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ViolationInfo info = new ViolationInfo(p, !currentlyGathering); 1403cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; 14045b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 14055b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick if (policy instanceof AndroidBlockGuardPolicy) { 1406cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info); 14075b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 14085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 14095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick } 14105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick 14115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick /** 1412727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * Called from android_util_Binder.cpp's 1413727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * android_os_Parcel_enforceInterface when an incoming Binder call 1414727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * requires changing the StrictMode policy mask. The role of this 1415727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * function is to ask Binder for its current (native) thread-local 1416727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * policy value and synchronize it to libcore's (Java) 1417727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick * thread-local policy value. 1418727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick */ 1419727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick private static void onBinderStrictModePolicyChange(int newPolicy) { 1420727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick setBlockGuardPolicy(newPolicy); 1421727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick } 1422cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1423cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1424e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * A tracked, critical time span. (e.g. during an animation.) 1425e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1426e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * The object itself is a linked list node, to avoid any allocations 1427e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * during rapid span entries and exits. 1428e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1429e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1430e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1431e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static class Span { 1432e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private String mName; 1433e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private long mCreateMillis; 1434e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mNext; 1435e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private Span mPrev; // not used when in freeList, only active 1436e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private final ThreadSpanState mContainerState; 1437e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1438e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span(ThreadSpanState threadState) { 1439e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mContainerState = threadState; 1440e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1441e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 14421181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Empty constructor for the NO_OP_SPAN 14431181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick protected Span() { 14441181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick mContainerState = null; 14451181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 14461181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1447e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1448e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * To be called when the critical span is complete (i.e. the 1449e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * animation is done animating). This can be called on any 1450e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread (even a different one from where the animation was 1451e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * taking place), but that's only a defensive implementation 1452e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * measure. It really makes no sense for you to call this on 1453e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * thread other than that where you created it. 1454e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1455e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1456e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1457e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public void finish() { 1458e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = mContainerState; 1459e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1460e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mName == null) { 1461e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Duplicate finish call. Ignore. 1462e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return; 1463e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1464e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1465e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Remove ourselves from the active list. 1466e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mPrev != null) { 1467e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mPrev.mNext = mNext; 1468e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1469e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (mNext != null) { 1470e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick mNext.mPrev = mPrev; 1471e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1472e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mActiveHead == this) { 1473e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = mNext; 1474e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1475e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 14761cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick state.mActiveSize--; 14771cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick 14781cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick if (LOG_V) Log.d(TAG, "Span finished=" + mName + "; size=" + state.mActiveSize); 14791cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick 1480e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mCreateMillis = -1; 1481e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mName = null; 1482e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mPrev = null; 1483e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = null; 1484e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1485e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Add ourselves to the freeList, if it's not already 1486e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // too big. 1487e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListSize < 5) { 1488e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.mNext = state.mFreeListHead; 1489e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = this; 1490e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize++; 1491e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1492e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1493e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1494e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1495e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 14961181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // The no-op span that's used in user builds. 14971181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick private static final Span NO_OP_SPAN = new Span() { 14981181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick public void finish() { 14991181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick // Do nothing. 15001181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 15011181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick }; 15021181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick 1503e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1504e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Linked lists of active spans and a freelist. 1505e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1506e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Locking notes: there's one of these structures per thread and 1507e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * all members of this structure (as well as the Span nodes under 1508e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * it) are guarded by the ThreadSpanState object instance. While 1509e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * in theory there'd be no locking required because it's all local 1510e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * per-thread, the finish() method above is defensive against 1511e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * people calling it on a different thread from where they created 1512e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * the Span, hence the locking. 1513e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1514e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static class ThreadSpanState { 1515e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mActiveHead; // doubly-linked list. 1516e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mActiveSize; 1517e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public Span mFreeListHead; // singly-linked list. only changes at head. 1518e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public int mFreeListSize; 1519e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1520e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1521e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick private static final ThreadLocal<ThreadSpanState> sThisThreadSpanState = 1522e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick new ThreadLocal<ThreadSpanState>() { 1523e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick @Override protected ThreadSpanState initialValue() { 1524e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return new ThreadSpanState(); 1525e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1526e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick }; 1527e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1528cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick private static Singleton<IWindowManager> sWindowManager = new Singleton<IWindowManager>() { 1529cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick protected IWindowManager create() { 1530cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick return IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 1531cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick } 1532cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick }; 1533cdcb73ef781b8f7d37d9f758409a0c7671517b37Brad Fitzpatrick 1534e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1535e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * Enter a named critical span (e.g. an animation) 1536e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1537e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>The name is an arbitary label (or tag) that will be applied 1538e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * to any strictmode violation that happens while this span is 1539e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * active. You must call finish() on the span when done. 1540e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1541e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>This will never return null, but on devices without debugging 1542e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * enabled, this may return a dummy object on which the finish() 1543e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * method is a no-op. 1544e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1545e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * <p>TODO: add CloseGuard to this, verifying callers call finish. 1546e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * 1547e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * @hide 1548e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1549e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public static Span enterCriticalSpan(String name) { 15501181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick if (IS_USER_BUILD) { 15511181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick return NO_OP_SPAN; 15521181cbbfd7c913c51d9836272ad30cfe851c4699Brad Fitzpatrick } 1553e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (name == null || name.isEmpty()) { 1554e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick throw new IllegalArgumentException("name must be non-null and non-empty"); 1555e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1556e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 1557e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span span = null; 1558e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1559e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (state.mFreeListHead != null) { 1560e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = state.mFreeListHead; 1561e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListHead = span.mNext; 1562e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mFreeListSize--; 1563e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } else { 1564e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick // Shouldn't have to do this often. 1565e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span = new Span(state); 1566e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1567e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mName = name; 1568e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mCreateMillis = SystemClock.uptimeMillis(); 1569e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext = state.mActiveHead; 1570e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mPrev = null; 1571e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveHead = span; 1572e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick state.mActiveSize++; 1573e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (span.mNext != null) { 1574e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick span.mNext.mPrev = span; 1575e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 15761cc13b6d1cc7203ad126b0708f0bf697e111264fBrad Fitzpatrick if (LOG_V) Log.d(TAG, "Span enter=" + name + "; size=" + state.mActiveSize); 1577e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1578e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick return span; 1579e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1580e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1581e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick /** 1582e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * For code to note that it's slow. This is a no-op unless the 1583e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * current thread's {@link android.os.StrictMode.ThreadPolicy} has 1584e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * {@link android.os.StrictMode.ThreadPolicy.Builder#detectCustomSlowCalls} 1585e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * enabled. 1586e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * 1587e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * @param name a short string for the exception stack trace that's 1588e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick * built if when this fires. 1589e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick */ 1590e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick public static void noteSlowCall(String name) { 1591e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); 1592e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick if (!(policy instanceof AndroidBlockGuardPolicy)) { 1593e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick // StrictMode not enabled. 1594e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick return; 1595e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1596e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick ((AndroidBlockGuardPolicy) policy).onCustomSlowCall(name); 1597e36f9bf123c7cd07ce1007a16de564b2840ea1feBrad Fitzpatrick } 1598e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1599e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1600cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Parcelable that gets sent in Binder call headers back to callers 1601cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * to report violations that happened during a cross-process call. 1602cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1603cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @hide 1604cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1605cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public static class ViolationInfo { 1606cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1607cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Stack and other stuff info. 1608cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1609cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final ApplicationErrorReport.CrashInfo crashInfo; 1610cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1611cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1612cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The strict mode policy mask at the time of violation. 1613cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1614cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public final int policy; 1615cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1616cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1617cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The wall time duration of the violation, when known. -1 when 1618cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * not known. 1619cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1620cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int durationMillis = -1; 1621cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1622cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1623599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick * The number of animations currently running. 1624599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick */ 1625599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick public int numAnimationsRunning = 0; 1626599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick 1627599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick /** 1628e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * List of tags from active Span instances during this 1629e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick * violation, or null for none. 1630e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick */ 1631e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick public String[] tags; 1632e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick 1633e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick /** 1634cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Which violation number this was (1-based) since the last Looper loop, 1635cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * from the perspective of the root caller (if it crossed any processes 1636cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * via Binder calls). The value is 0 if the root caller wasn't on a Looper 1637cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * thread. 1638cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1639cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public int violationNumThisLoop; 1640cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1641cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1642cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * The time (in terms of SystemClock.uptimeMillis()) that the 1643cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * violation occurred. 1644cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1645cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public long violationUptimeMillis; 1646cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1647cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1648bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * The action of the Intent being broadcast to somebody's onReceive 1649bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick * on this thread right now, or null. 1650bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick */ 1651bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick public String broadcastIntentAction; 1652bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick 1653bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick /** 1654cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an uninitialized instance of ViolationInfo 1655cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1656cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo() { 1657cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = null; 1658cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = 0; 1659cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1660cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1661cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1662cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from an exception. 1663cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1664cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Throwable tr, int policy) { 1665cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(tr); 1666cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = SystemClock.uptimeMillis(); 1667cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this.policy = policy; 1668599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount(); 1669bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast(); 1670bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntent != null) { 1671bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = broadcastIntent.getAction(); 1672bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1673e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick ThreadSpanState state = sThisThreadSpanState.get(); 1674e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick synchronized (state) { 1675e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int spanActiveCount = state.mActiveSize; 1676e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount > MAX_SPAN_TAGS) { 1677e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick spanActiveCount = MAX_SPAN_TAGS; 1678e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1679e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (spanActiveCount != 0) { 1680e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags = new String[spanActiveCount]; 1681e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick Span iter = state.mActiveHead; 1682e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 1683e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick while (iter != null && index < spanActiveCount) { 1684e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick this.tags[index] = iter.mName; 1685e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick index++; 1686e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick iter = iter.mNext; 1687e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1688e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1689e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1690cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1691cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1692f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick @Override 1693f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick public int hashCode() { 1694f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick int result = 17; 1695f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + crashInfo.stackTrace.hashCode(); 1696f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (numAnimationsRunning != 0) { 1697f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result *= 37; 1698f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1699f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (broadcastIntentAction != null) { 1700f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + broadcastIntentAction.hashCode(); 1701f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1702f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick if (tags != null) { 1703f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick for (String tag : tags) { 1704f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick result = 37 * result + tag.hashCode(); 1705f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1706f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1707f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick return result; 1708f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick } 1709f3d86be6d7d2999cd6bae236817688490df7da71Brad Fitzpatrick 1710cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1711cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1712cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1713cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in) { 1714cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick this(in, false); 1715cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1716cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1717cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1718cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Create an instance of ViolationInfo initialized from a Parcel. 1719cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * 1720cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * @param unsetGatheringBit if true, the caller is the root caller 1721cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * and the gathering penalty should be removed. 1722cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1723cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public ViolationInfo(Parcel in, boolean unsetGatheringBit) { 1724cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo = new ApplicationErrorReport.CrashInfo(in); 1725cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick int rawPolicy = in.readInt(); 1726cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (unsetGatheringBit) { 1727cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy & ~PENALTY_GATHER; 1728cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } else { 1729cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick policy = rawPolicy; 1730cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1731cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick durationMillis = in.readInt(); 1732cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationNumThisLoop = in.readInt(); 1733599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick numAnimationsRunning = in.readInt(); 1734cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick violationUptimeMillis = in.readLong(); 1735bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick broadcastIntentAction = in.readString(); 1736e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick tags = in.readStringArray(); 1737cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1738cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1739cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1740cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Save a ViolationInfo instance to a parcel. 1741cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1742cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void writeToParcel(Parcel dest, int flags) { 1743cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.writeToParcel(dest, flags); 1744cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(policy); 1745cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(durationMillis); 1746cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeInt(violationNumThisLoop); 1747599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick dest.writeInt(numAnimationsRunning); 1748cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick dest.writeLong(violationUptimeMillis); 1749bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick dest.writeString(broadcastIntentAction); 1750e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick dest.writeStringArray(tags); 1751cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1752cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1753cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1754cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick /** 1755cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick * Dump a ViolationInfo instance to a Printer. 1756cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick */ 1757cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick public void dump(Printer pw, String prefix) { 1758cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick crashInfo.dump(pw, prefix); 1759cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "policy: " + policy); 1760cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (durationMillis != -1) { 1761cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "durationMillis: " + durationMillis); 1762cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1763cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick if (violationNumThisLoop != 0) { 1764cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop); 1765cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1766599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick if (numAnimationsRunning != 0) { 1767599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick pw.println(prefix + "numAnimationsRunning: " + numAnimationsRunning); 1768599ca29986235e07f532c7b112507f6c39b5dba9Brad Fitzpatrick } 1769cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis); 1770bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick if (broadcastIntentAction != null) { 1771bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction); 1772bfb191998eba2ebc710ff9eb59480b10909ba4c9Brad Fitzpatrick } 1773e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick if (tags != null) { 1774e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick int index = 0; 1775e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick for (String tag : tags) { 1776e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick pw.println(prefix + "tag[" + (index++) + "]: " + tag); 1777e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1778e7520d89fe2c5dc9dd833ecd9769c981df855b61Brad Fitzpatrick } 1779cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1780cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick 1781cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick } 1782438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick} 1783