StrictMode.java revision 32e60c7942eeba920ec5c27b372ec0899fd75a20
1438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/*
2438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Copyright (C) 2010 The Android Open Source Project
3438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick *
4438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Licensed under the Apache License, Version 2.0 (the "License");
5438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * you may not use this file except in compliance with the License.
6438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * You may obtain a copy of the License at
7438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick *
8438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick *      http://www.apache.org/licenses/LICENSE-2.0
9438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick *
10438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * Unless required by applicable law or agreed to in writing, software
11438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * distributed under the License is distributed on an "AS IS" BASIS,
12438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * See the License for the specific language governing permissions and
14438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick * limitations under the License.
15438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */
16438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpackage android.os;
17438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
18438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ActivityManagerNative;
19438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.app.ApplicationErrorReport;
20438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport android.util.Log;
21cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrickimport android.util.Printer;
22438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
23438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport com.android.internal.os.RuntimeInit;
24438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
25438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickimport dalvik.system.BlockGuard;
26438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.PrintWriter;
285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.io.StringWriter;
295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrickimport java.util.ArrayList;
3046d42387464a651268648659e91d022566d4844cBrad Fitzpatrickimport java.util.HashMap;
3146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
32438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick/**
3332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>StrictMode is a developer tool which detects things you might be
3432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * doing by accident and brings them to your attention so you can fix
3532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * them.
3615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *
3715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>StrictMode is most commonly used to catch accidental disk or
3815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * network access on the application's main thread, where UI
3915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * operations are received and animations take place.  Keeping disk
4015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * and network operations off the main thread makes for much smoother,
4115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more responsive applications.
4215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *
4315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">Note that even though an Android device's disk is
4415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * often on flash memory, many devices run a filesystem on top of that
4515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * memory with very limited concurrency.  It's often the case that
4615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * almost all disk accesses are fast, but may in individual cases be
4715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * dramatically slower when certain I/O is happening in the background
4815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * from other processes.  If possible, it's best to assume that such
4915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * things are not fast.</p>
5015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *
5115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>Example code to enable from early in your
5215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application}, {@link android.app.Activity}, or
5315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * other application component's
5415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.app.Application#onCreate} method:
5515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *
5615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <pre>
5715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * public void onCreate() {
5815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *     if (DEVELOPER_MODE) {
5932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *         StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}()
6032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .detectDiskReads()
6132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .detectDiskWrites()
6232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .detectNetwork()   // or .detectAll() for all detectable problems
6332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .penaltyLog()
6432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .build());
6532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *         StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}()
6632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .detectLeakedSqlLiteCursors()
6732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .penaltyLog()
6832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .penaltyDeath()
6932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick *                 .build());
7015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *     }
7115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *     super.onCreate();
7215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * }
7315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * </pre>
7415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *
7532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * <p>You can decide what should happen when a violation is detected.
7632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * For example, using {@link ThreadPolicy.Builder#penaltyLog} you can
7732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * watch the output of <code>adb logcat</code> while you use your
7832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * application to see the violations as they happen.
7915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *
8015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p>If you find violations that you feel are problematic, there are
8115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * a variety of tools to help solve them: threads, {@link android.os.Handler},
8215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.AsyncTask}, {@link android.app.IntentService}, etc.
8315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * But don't feel compelled to fix everything that StrictMode finds.  In particular,
8432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * many cases of disk access are often necessary during the normal activity lifecycle.  Use
8532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick * StrictMode to find things you did by accident.  Network requests on the UI thread
8615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * are almost always a problem, though.
8715ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick *
8815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * <p class="note">StrictMode is not a security mechanism and is not
8915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * guaranteed to find all disk or network accesses.  While it does
9015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * propagate its state across process boundaries when doing
9115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * {@link android.os.Binder} calls, it's still ultimately a best
9215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * effort mechanism.  Notably, disk or network access from JNI calls
9315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * won't necessarily trigger it.  Future versions of Android may catch
9415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * more (or fewer) operations, so you should never leave StrictMode
9515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick * enabled in shipping applications on the Android Market.
96438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick */
97438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrickpublic final class StrictMode {
98438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    private static final String TAG = "StrictMode";
995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    private static final boolean LOG_V = false;
100438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
10146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick    // Only log a duplicate stack trace to the logs every second.
10246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick    private static final long MIN_LOG_INTERVAL_MS = 1000;
10346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
10446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick    // Only show an annoying dialog at most every 30 seconds
10546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick    private static final long MIN_DIALOG_INTERVAL_MS = 30000;
10646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
10732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    // Thread-policy:
108438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
10915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick    /**
11032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
11115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     */
11232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static final int DETECT_DISK_WRITE = 0x01;  // for ThreadPolicy
11315ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick
11415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick    /**
11532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick      * @hide
11615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     */
11732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static final int DETECT_DISK_READ = 0x02;  // for ThreadPolicy
11815ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick
11915ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick    /**
12032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
12115ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     */
12232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static final int DETECT_NETWORK = 0x04;  // for ThreadPolicy
123438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
12432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    // Process-policy:
125438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
126438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    /**
12732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * Note, a "VM_" bit, not thread.
12832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
12932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
13032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static final int DETECT_VM_CURSOR_LEAKS = 0x200;  // for ProcessPolicy
13132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
13232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
13332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
134438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     */
135438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    public static final int PENALTY_LOG = 0x10;  // normal android.util.Log
136438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
13732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    // Used for both process and thread policy:
13832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
139438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    /**
14032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
141438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     */
142438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    public static final int PENALTY_DIALOG = 0x20;
143438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
144438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    /**
14532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
146438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     */
147438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    public static final int PENALTY_DEATH = 0x40;
148438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
149438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    /**
15032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
151438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     */
152438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    public static final int PENALTY_DROPBOX = 0x80;
153438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
154727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    /**
155727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * Non-public penalty mode which overrides all the other penalty
156727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * bits and signals that we're in a Binder call and we should
157727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * ignore the other penalty bits and instead serialize back all
158727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * our offending stack traces to the caller to ultimately handle
159727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * in the originating process.
160727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     *
161703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick     * This must be kept in sync with the constant in libs/binder/Parcel.cpp
162703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick     *
163727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * @hide
164727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     */
165727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    public static final int PENALTY_GATHER = 0x100;
166727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
16732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
16832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * The current VmPolicy in effect.
16932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
17032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    private static volatile int sVmPolicyMask = 0;
17132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
17232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    private StrictMode() {}
17332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
17432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
17532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * {@link StrictMode} policy applied to a certain thread.
17632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     *
17732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * <p>The policy is enabled by {@link #setThreadPolicy}.  The current policy
17832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * can be retrieved with {@link #getThreadPolicy}.
17932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     *
18032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * <p>Note that multiple penalties may be provided and they're run
18132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * in order from least to most severe (logging before process
18232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * death, for example).  There's currently no mechanism to choose
18332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * different penalties for different detected actions.
18432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
18532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static final class ThreadPolicy {
18632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        /**
18732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * The default, lax policy which doesn't catch anything.
18832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         */
18932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        public static final ThreadPolicy LAX = new ThreadPolicy(0);
19032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
19132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        final int mask;
19232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
19332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        private ThreadPolicy(int mask) {
19432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            this.mask = mask;
19532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
19632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
19732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        @Override
19832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        public String toString() {
19932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            return "[StrictMode.ThreadPolicy; mask=" + mask + "]";
20032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
20132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
20232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        /**
20332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * Creates ThreadPolicy instances.  Methods whose names start
20432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * with {@code detect} specify what problems we should look
20532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * for.  Methods whose names start with {@code penalty} specify what
20632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * we should do when we detect a problem.
20732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *
20832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * <p>You can call as many {@code detect} and {@code penalty}
20932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * methods as you like. Currently order is insignificant: all
21032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * penalties apply to all detected problems.
21132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *
21232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * <p>For example, detect everything and log anything that's found:
21332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * <pre>
21432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
21532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *     .detectAll()
21632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *     .penaltyLog()
21732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *     .build();
21832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * StrictMode.setVmPolicy(policy);
21932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * </pre>
22032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         */
22132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        public static final class Builder {
22232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            private int mMask = 0;
22332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
22432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
22532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Create a Builder that detects nothing and has no
22632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * violations.  (but note that {@link #build} will default
22732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * to enabling {@link #penaltyLog} if no other penalties
22832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * are specified)
22932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
23032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder() {
23132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                mMask = 0;
23232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
23332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
23432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
23532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Initialize a Builder from an existing ThreadPolicy.
23632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
23732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder(ThreadPolicy policy) {
23832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                mMask = policy.mask;
23932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
24032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
24132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
24232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Detect everything that's potentially suspect.
24332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             *
24432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * <p>As of the Gingerbread release this includes network and
24532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * disk operations but will likely expand in future releases.
24632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
24732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder detectAll() {
24832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK);
24932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
25032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
25132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
25232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Disable the detection of everything.
25332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
25432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder permitAll() {
25532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return disable(DETECT_DISK_WRITE | DETECT_DISK_READ | DETECT_NETWORK);
25632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
25732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
25832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
25932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Enable detection of network operations.
26032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
26132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder detectNetwork() {
26232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(DETECT_NETWORK);
26332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
26432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
26532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
26632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Disable detection of network operations.
26732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
26832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder permitNetwork() {
26932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return disable(DETECT_NETWORK);
27032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
27132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
27232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
27332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Enable detection of disk reads.
27432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
27532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder detectDiskReads() {
27632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(DETECT_DISK_READ);
27732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
27832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
27932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
28032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Disable detection of disk reads.
28132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
28232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder permitDiskReads() {
28332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return disable(DETECT_DISK_READ);
28432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
28532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
28632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
28732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Enable detection of disk writes.
28832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
28932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder detectDiskWrites() {
29032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(DETECT_DISK_WRITE);
29132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
29232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
29332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
29432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Disable detection of disk writes.
29532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
29632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder permitDiskWrites() {
29732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return disable(DETECT_DISK_WRITE);
29832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
29932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
30032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
30132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Show an annoying dialog to the developer on detected
30232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * violations, rate-limited to be only a little annoying.
30332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
30432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder penaltyDialog() {
30532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(PENALTY_DIALOG);
30632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
30732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
30832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
30932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Crash the whole process on violation.  This penalty runs at
31032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * the end of all enabled penalties so you'll still get
31132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * see logging or other violations before the process dies.
31232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
31332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder penaltyDeath() {
31432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(PENALTY_DEATH);
31532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
31632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
31732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
31832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Log detected violations to the system log.
31932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
32032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder penaltyLog() {
32132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(PENALTY_LOG);
32232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
32332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
32432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
32532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Enable detected violations log a stacktrace and timing data
32632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * to the {@link android.os.DropBoxManager DropBox} on policy
32732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * violation.  Intended mostly for platform integrators doing
32832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * beta user field data collection.
32932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
33032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder penaltyDropBox() {
33132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(PENALTY_DROPBOX);
33232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
33332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
33432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            private Builder enable(int bit) {
33532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                mMask |= bit;
33632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return this;
33732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
33832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
33932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            private Builder disable(int bit) {
34032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                mMask &= ~bit;
34132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return this;
34232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
34332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
34432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
34532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Construct the ThreadPolicy instance.
34632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             *
34732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * <p>Note: if no penalties are enabled before calling
34832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * <code>build</code>, {@link #penaltyLog} is implicitly
34932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * set.
35032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
35132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public ThreadPolicy build() {
35232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // If there are detection bits set but no violation bits
35332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // set, enable simple logging.
35432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                if (mMask != 0 &&
35532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    (mMask & (PENALTY_DEATH | PENALTY_LOG |
35632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                              PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) {
35732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    penaltyLog();
35832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                }
35932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return new ThreadPolicy(mMask);
36032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
36132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
36232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
36332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
36432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
36532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * {@link StrictMode} policy applied to all threads in the virtual machine's process.
36632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     *
36732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * <p>The policy is enabled by {@link #setVmPolicy}.
36832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
36932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static final class VmPolicy {
37032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        /**
37132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * The default, lax policy which doesn't catch anything.
37232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         */
37332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        public static final VmPolicy LAX = new VmPolicy(0);
37432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
37532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        final int mask;
37632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
37732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        private VmPolicy(int mask) {
37832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            this.mask = mask;
37932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
38032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
38132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        @Override
38232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        public String toString() {
38332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            return "[StrictMode.VmPolicy; mask=" + mask + "]";
38432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
38532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
38632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        /**
38732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * Creates {@link VmPolicy} instances.  Methods whose names start
38832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * with {@code detect} specify what problems we should look
38932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * for.  Methods whose names start with {@code penalty} specify what
39032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * we should do when we detect a problem.
39132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *
39232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * <p>You can call as many {@code detect} and {@code penalty}
39332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * methods as you like. Currently order is insignificant: all
39432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * penalties apply to all detected problems.
39532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *
39632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * <p>For example, detect everything and log anything that's found:
39732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * <pre>
39832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
39932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *     .detectAll()
40032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *     .penaltyLog()
40132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         *     .build();
40232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * StrictMode.setVmPolicy(policy);
40332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         * </pre>
40432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick         */
40532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        public static final class Builder {
40632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            private int mMask;
40732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
40832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
40932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Detect everything that's potentially suspect.
41032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             *
41132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * <p>As of the Gingerbread release this only includes
41232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * SQLite cursor leaks but will likely expand in future
41332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * releases.
41432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
41532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder detectAll() {
41632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(DETECT_VM_CURSOR_LEAKS);
41732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
41832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
41932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
42032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Detect when an
42132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * {@link android.database.sqlite.SQLiteCursor} or other
42232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * SQLite object is finalized without having been closed.
42332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             *
42432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * <p>You always want to explicitly close your SQLite
42532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * cursors to avoid unnecessary database contention and
42632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * temporary memory leaks.
42732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
42832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder detectLeakedSqlLiteObjects() {
42932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(DETECT_VM_CURSOR_LEAKS);
43032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
43132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
43232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
43332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Crashes the whole process on violation.  This penalty runs at
43432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * the end of all enabled penalties so yo you'll still get
43532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * your logging or other violations before the process dies.
43632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
43732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder penaltyDeath() {
43832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(PENALTY_DEATH);
43932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
44032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
44132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
44232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Log detected violations to the system log.
44332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
44432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder penaltyLog() {
44532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(PENALTY_LOG);
44632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
44732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
44832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
44932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Enable detected violations log a stacktrace and timing data
45032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * to the {@link android.os.DropBoxManager DropBox} on policy
45132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * violation.  Intended mostly for platform integrators doing
45232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * beta user field data collection.
45332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
45432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public Builder penaltyDropBox() {
45532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return enable(PENALTY_DROPBOX);
45632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
45732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
45832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            private Builder enable(int bit) {
45932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                mMask |= bit;
46032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return this;
46132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
46232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
46332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            /**
46432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * Construct the VmPolicy instance.
46532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             *
46632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * <p>Note: if no penalties are enabled before calling
46732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * <code>build</code>, {@link #penaltyLog} is implicitly
46832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             * set.
46932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick             */
47032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            public VmPolicy build() {
47132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // If there are detection bits set but no violation bits
47232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // set, enable simple logging.
47332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                if (mMask != 0 &&
47432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    (mMask & (PENALTY_DEATH | PENALTY_LOG |
47532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                              PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) {
47632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    penaltyLog();
47732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                }
47832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                return new VmPolicy(mMask);
47932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
48032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
48132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
482438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
483438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    /**
4845b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Log of strict mode violation stack traces that have occurred
4855b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * during a Binder call, to be serialized back later to the caller
4865b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * via Parcel.writeNoException() (amusingly) where the caller can
4875b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * choose how to react.
4885b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     */
489cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick    private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations =
490cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            new ThreadLocal<ArrayList<ViolationInfo>>() {
491cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        @Override protected ArrayList<ViolationInfo> initialValue() {
492703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            // Starts null to avoid unnecessary allocations when
493703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            // checking whether there are any violations or not in
494703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            // hasGatheredViolations() below.
495703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            return null;
4965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
4975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    };
4985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
4995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /**
50032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * Sets the policy for what actions on the current thread should
50132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * be detected, as well as the penalty if such actions occur.
50215ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     *
50332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * <p>Internally this sets a thread-local variable which is
50415ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     * propagated across cross-process IPC calls, meaning you can
50515ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     * catch violations when a system service or another process
50615ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     * accesses the disk or network on your behalf.
507438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     *
50832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @param policy the policy to put into place
509438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     */
51032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static void setThreadPolicy(final ThreadPolicy policy) {
51132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        setThreadPolicyMask(policy.mask);
51232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
51332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
51432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    private static void setThreadPolicyMask(final int policyMask) {
515727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // In addition to the Java-level thread-local in Dalvik's
516727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // BlockGuard, we also need to keep a native thread-local in
517727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // Binder in order to propagate the value across Binder calls,
518727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // even across native-only processes.  The two are kept in
519727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // sync via the callback to onStrictModePolicyChange, below.
520727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        setBlockGuardPolicy(policyMask);
521727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
522727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        // And set the Android native version...
523727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        Binder.setThreadStrictModePolicy(policyMask);
524727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    }
525727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
526727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    // Sets the policy in Dalvik/libcore (BlockGuard)
527727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    private static void setBlockGuardPolicy(final int policyMask) {
52846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick        if (policyMask == 0) {
52946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY);
53046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            return;
53146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick        }
532438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
533438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        if (!(policy instanceof AndroidBlockGuardPolicy)) {
534438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask));
535438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        } else {
536438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy;
537438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            androidPolicy.setPolicyMask(policyMask);
538438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
539438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    }
540438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
5415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException {
5425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        public StrictModeNetworkViolation(int policyMask) {
54332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            super(policyMask, DETECT_NETWORK);
5445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
5455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
5465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
5475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException {
5485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        public StrictModeDiskReadViolation(int policyMask) {
54932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            super(policyMask, DETECT_DISK_READ);
5505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
5515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
5525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
5535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException {
5545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        public StrictModeDiskWriteViolation(int policyMask) {
55532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            super(policyMask, DETECT_DISK_WRITE);
5565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
5575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
5585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
559438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    /**
56015ba4061116e088d62a7e05a0037f294f31dff06Brad Fitzpatrick     * Returns the bitmask of the current thread's policy.
561438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     *
56232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled
56332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     *
56432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
565438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick     */
56632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static int getThreadPolicyMask() {
567438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        return BlockGuard.getThreadPolicy().getPolicyMask();
568438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    }
569438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
5705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /**
57132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * Returns the current thread's policy.
57232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
57332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static ThreadPolicy getThreadPolicy() {
57432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        return new ThreadPolicy(getThreadPolicyMask());
57532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
57632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
57732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
57832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * A convenience wrapper that takes the current
57932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it
58032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * to permit both disk reads &amp; writes, and sets the new policy
58132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * with {@link #setThreadPolicy}, returning the old policy so you
58232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * can restore it at the end of a block.
58397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick     *
58432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @return the old policy, to be passed to {@link #setThreadPolicy} to
58532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     *         restore the policy at the end of a block
58697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick     */
58732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static ThreadPolicy allowThreadDiskWrites() {
58832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        int oldPolicyMask = getThreadPolicyMask();
58932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_WRITE | DETECT_DISK_READ);
59032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        if (newPolicyMask != oldPolicyMask) {
59132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            setThreadPolicyMask(newPolicyMask);
59297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick        }
59332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        return new ThreadPolicy(oldPolicyMask);
59497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick    }
59597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick
59697461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick    /**
59732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * A convenience wrapper that takes the current
59832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * {@link ThreadPolicy} from {@link #getThreadPolicy}, modifies it
59932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * to permit disk reads, and sets the new policy
60032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * with {@link #setThreadPolicy}, returning the old policy so you
60132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * can restore it at the end of a block.
60297461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick     *
60332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @return the old policy, to be passed to setThreadPolicy to
60497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick     *         restore the policy.
60597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick     */
60632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static ThreadPolicy allowThreadDiskReads() {
60732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        int oldPolicyMask = getThreadPolicyMask();
60832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        int newPolicyMask = oldPolicyMask & ~(DETECT_DISK_READ);
60932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        if (newPolicyMask != oldPolicyMask) {
61032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            setThreadPolicyMask(newPolicyMask);
61197461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick        }
61232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        return new ThreadPolicy(oldPolicyMask);
61397461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick    }
61497461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick
61597461bd25c3821f3fb6af9705f0612259c6b4492Brad Fitzpatrick    /**
61650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick     * Enable DropBox logging for debug phone builds.
61750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick     *
61850d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick     * @hide
61950d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick     */
62050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick    public static boolean conditionallyEnableDebugLogging() {
62150d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick        // For debug builds, log event loop stalls to dropbox for analysis.
62250d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick        // Similar logic also appears in ActivityThread.java for system apps.
62350d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick        if ("user".equals(Build.TYPE)) {
62450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick            return false;
62550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick        }
62632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        StrictMode.setThreadPolicyMask(
62732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            StrictMode.DETECT_DISK_WRITE |
62832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            StrictMode.DETECT_DISK_READ |
62932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            StrictMode.DETECT_NETWORK |
63050d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick            StrictMode.PENALTY_DROPBOX);
63132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS |
63232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                StrictMode.PENALTY_DROPBOX |
63332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                StrictMode.PENALTY_LOG;
63450d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick        return true;
63550d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick    }
63650d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick
63750d66f9fcdac84b2af65a82be56728f54b1a7ef0Brad Fitzpatrick    /**
6385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Parses the BlockGuard policy mask out from the Exception's
6395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * getMessage() String value.  Kinda gross, but least
6405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * invasive.  :/
6415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     *
6425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Input is of form "policy=137 violation=64"
6435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     *
6445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Returns 0 on failure, which is a valid policy, but not a
6455b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * valid policy during a violation (else there must've been
6465b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * some policy in effect to violate).
6475b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     */
6485b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    private static int parsePolicyFromMessage(String message) {
6495b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        if (message == null || !message.startsWith("policy=")) {
6505b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return 0;
6515b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
6525b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        int spaceIndex = message.indexOf(' ');
6535b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        if (spaceIndex == -1) {
6545b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return 0;
6555b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
6565b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        String policyString = message.substring(7, spaceIndex);
6575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        try {
6585b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return Integer.valueOf(policyString).intValue();
6595b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        } catch (NumberFormatException e) {
6605b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return 0;
6615b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
6625b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
6635b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
6645b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /**
6655b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Like parsePolicyFromMessage(), but returns the violation.
6665b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     */
6675b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    private static int parseViolationFromMessage(String message) {
6685b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        if (message == null) {
6695b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return 0;
6705b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
6715b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        int violationIndex = message.indexOf("violation=");
6725b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        if (violationIndex == -1) {
6735b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return 0;
6745b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
6755b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        String violationString = message.substring(violationIndex + 10);
6765b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        try {
6775b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return Integer.valueOf(violationString).intValue();
6785b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        } catch (NumberFormatException e) {
6795b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return 0;
6805b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
6815b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
6825b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
683438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    private static class AndroidBlockGuardPolicy implements BlockGuard.Policy {
684438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        private int mPolicyMask;
68546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
68646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick        // Map from violation stacktrace hashcode -> uptimeMillis of
68746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick        // last violation.  No locking needed, as this is only
68846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick        // accessed by the same thread.
68946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick        private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>();
690438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
691438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        public AndroidBlockGuardPolicy(final int policyMask) {
692438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            mPolicyMask = policyMask;
693438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
694438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
6955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        @Override
6965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        public String toString() {
6975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            return "AndroidBlockGuardPolicy; mPolicyMask=" + mPolicyMask;
6985b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
6995b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
700438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        // Part of BlockGuard.Policy interface:
701438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        public int getPolicyMask() {
702438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            return mPolicyMask;
703438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
704438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
705438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        // Part of BlockGuard.Policy interface:
706438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        public void onWriteToDisk() {
70732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            if ((mPolicyMask & DETECT_DISK_WRITE) == 0) {
708438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                return;
709438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            }
710cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask);
711cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            e.fillInStackTrace();
712cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            startHandlingViolationException(e);
713438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
714438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
715438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        // Part of BlockGuard.Policy interface:
716438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        public void onReadFromDisk() {
71732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            if ((mPolicyMask & DETECT_DISK_READ) == 0) {
718438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                return;
719438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            }
720cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask);
721cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            e.fillInStackTrace();
722cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            startHandlingViolationException(e);
723438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
724438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
725438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        // Part of BlockGuard.Policy interface:
726438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        public void onNetwork() {
72732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            if ((mPolicyMask & DETECT_NETWORK) == 0) {
728438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                return;
729438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            }
730cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask);
731cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            e.fillInStackTrace();
732cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            startHandlingViolationException(e);
733438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
734438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
735438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        public void setPolicyMask(int policyMask) {
736438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            mPolicyMask = policyMask;
737438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
738438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
7395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // Start handling a violation that just started and hasn't
7405b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // actually run yet (e.g. no disk write or network operation
7415b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // has yet occurred).  This sees if we're in an event loop
7425b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // thread and, if so, uses it to roughly measure how long the
7435b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // violation took.
7445b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) {
745cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            final ViolationInfo info = new ViolationInfo(e, e.getPolicy());
746cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            info.violationUptimeMillis = SystemClock.uptimeMillis();
747cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            handleViolationWithTimingAttempt(info);
748cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        }
749438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
750cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed =
751cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                new ThreadLocal<ArrayList<ViolationInfo>>() {
752cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            @Override protected ArrayList<ViolationInfo> initialValue() {
753cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                return new ArrayList<ViolationInfo>();
754cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            }
755cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        };
756cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
757cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        // Attempts to fill in the provided ViolationInfo's
758cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        // durationMillis field if this thread has a Looper we can use
759cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        // to measure with.  We measure from the time of violation
760cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        // until the time the looper is idle again (right before
761cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        // the next epoll_wait)
762cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        void handleViolationWithTimingAttempt(final ViolationInfo info) {
763438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            Looper looper = Looper.myLooper();
764cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
765cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // Without a Looper, we're unable to time how long the
766cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // violation takes place.  This case should be rare, as
767cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // most users will care about timing violations that
768cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // happen on their main UI thread.  Note that this case is
769cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // also hit when a violation takes place in a Binder
770cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // thread, in "gather" mode.  In this case, the duration
771cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // of the violation is computed by the ultimate caller and
772cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // its Looper, if any.
773cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            // TODO: if in gather mode, ignore Looper.myLooper() and always
774cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            //       go into this immediate mode?
775438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            if (looper == null) {
776cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                info.durationMillis = -1;  // unknown (redundant, already set)
777cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                handleViolation(info);
778cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                return;
779438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            }
780438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
781cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            MessageQueue queue = Looper.myQueue();
782cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            final ArrayList<ViolationInfo> records = violationsBeingTimed.get();
783cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (records.size() >= 10) {
784cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                // Not worth measuring.  Too many offenses in one loop.
785cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                return;
786cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            }
787cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            records.add(info);
788cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (records.size() > 1) {
789cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                // There's already been a violation this loop, so we've already
790cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                // registered an idle handler to process the list of violations
791cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                // at the end of this Looper's loop.
792cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                return;
793cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            }
794cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
795cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            queue.addIdleHandler(new MessageQueue.IdleHandler() {
796cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                    public boolean queueIdle() {
797cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                        long loopFinishTime = SystemClock.uptimeMillis();
798cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                        for (int n = 0; n < records.size(); ++n) {
799cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                            ViolationInfo v = records.get(n);
800cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                            v.violationNumThisLoop = n + 1;
801cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                            v.durationMillis =
802cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                                    (int) (loopFinishTime - v.violationUptimeMillis);
803cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                            handleViolation(v);
804cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                        }
805cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                        records.clear();
806cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                        return false;  // remove this idle handler from the array
807cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                    }
808cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                });
8095b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
810438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
8115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // Note: It's possible (even quite likely) that the
8125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // thread-local policy mask has changed from the time the
8135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // violation fired and now (after the violating code ran) due
8145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // to people who push/pop temporary policy in regions of code,
8155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // hence the policy being passed around.
816cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        void handleViolation(final ViolationInfo info) {
817cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) {
818cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                Log.wtf(TAG, "unexpected null stacktrace");
8195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                return;
8205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            }
821438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
822cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy);
82346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
824cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if ((info.policy & PENALTY_GATHER) != 0) {
825cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                ArrayList<ViolationInfo> violations = gatheredViolations.get();
826703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick                if (violations == null) {
827cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                    violations = new ArrayList<ViolationInfo>(1);
828703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick                    gatheredViolations.set(violations);
829703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick                } else if (violations.size() >= 5) {
8305b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                    // Too many.  In a loop or something?  Don't gather them all.
8315b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                    return;
8325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                }
833cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                for (ViolationInfo previous : violations) {
834cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                    if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) {
8355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                        // Duplicate. Don't log.
8365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                        return;
8375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                    }
8385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                }
839cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                violations.add(info);
840727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                return;
841727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick            }
842727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
84346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            // Not perfect, but fast and good enough for dup suppression.
844cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            Integer crashFingerprint = info.crashInfo.stackTrace.hashCode();
84546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            long lastViolationTime = 0;
84646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            if (mLastViolationTime.containsKey(crashFingerprint)) {
84746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick                lastViolationTime = mLastViolationTime.get(crashFingerprint);
84846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            }
84946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            long now = SystemClock.uptimeMillis();
85046d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            mLastViolationTime.put(crashFingerprint, now);
85146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            long timeSinceLastViolationMillis = lastViolationTime == 0 ?
85246d42387464a651268648659e91d022566d4844cBrad Fitzpatrick                    Long.MAX_VALUE : (now - lastViolationTime);
85346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
854cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if ((info.policy & PENALTY_LOG) != 0 &&
85546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick                timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
856cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                if (info.durationMillis != -1) {
8575b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick                    Log.d(TAG, "StrictMode policy violation; ~duration=" +
858cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                          info.durationMillis + " ms: " + info.crashInfo.stackTrace);
859438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                } else {
860cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                    Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace);
861438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                }
862438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            }
863438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
86446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            // The violationMask, passed to ActivityManager, is a
86546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            // subset of the original StrictMode policy bitmask, with
86646d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            // only the bit violated and penalty bits to be executed
86746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            // by the ActivityManagerService remaining set.
868cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            int violationMaskSubset = 0;
86946d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
870cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if ((info.policy & PENALTY_DIALOG) != 0 &&
87146d42387464a651268648659e91d022566d4844cBrad Fitzpatrick                timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) {
872cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                violationMaskSubset |= PENALTY_DIALOG;
87346d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            }
87446d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
875cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) {
876cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                violationMaskSubset |= PENALTY_DROPBOX;
87746d42387464a651268648659e91d022566d4844cBrad Fitzpatrick            }
87846d42387464a651268648659e91d022566d4844cBrad Fitzpatrick
879cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (violationMaskSubset != 0) {
880cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage);
881cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                violationMaskSubset |= violationBit;
88232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                final int savedPolicyMask = getThreadPolicyMask();
883438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                try {
884727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // First, remove any policy before we call into the Activity Manager,
885727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // otherwise we'll infinite recurse as we try to log policy violations
886727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // to disk, thus violating policy, thus requiring logging, etc...
887727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // We restore the current policy below, in the finally block.
88832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    setThreadPolicyMask(0);
889727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
890438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                    ActivityManagerNative.getDefault().handleApplicationStrictModeViolation(
891438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                        RuntimeInit.getApplicationObject(),
892cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                        violationMaskSubset,
893cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                        info);
894438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                } catch (RemoteException e) {
89546d42387464a651268648659e91d022566d4844cBrad Fitzpatrick                    Log.e(TAG, "RemoteException trying to handle StrictMode violation", e);
896727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                } finally {
897727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick                    // Restore the policy.
89832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    setThreadPolicyMask(savedPolicyMask);
899438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                }
900438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            }
901438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick
902cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if ((info.policy & PENALTY_DEATH) != 0) {
903438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down.");
904438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                Process.killProcess(Process.myPid());
905438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick                System.exit(10);
906438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick            }
907438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick        }
908438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick    }
909727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick
910727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    /**
9115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Called from Parcel.writeNoException()
9125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     */
9135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /* package */ static boolean hasGatheredViolations() {
914703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick        return gatheredViolations.get() != null;
915703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick    }
916703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick
917703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick    /**
918703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick     * Called from Parcel.writeException(), so we drop this memory and
919703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick     * don't incorrectly attribute it to the wrong caller on the next
920703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick     * Binder call on this thread.
921703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick     */
922703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick    /* package */ static void clearGatheredViolations() {
923703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick        gatheredViolations.set(null);
9245b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
9255b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
9265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /**
92732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * Sets the policy for what actions in the VM process (on any
92832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * thread) should be detected, as well as the penalty if such
92932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * actions occur.
93032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     *
93132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @param policy the policy to put into place
93232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
93332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static void setVmPolicy(final VmPolicy policy) {
93432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        sVmPolicyMask = policy.mask;
93532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
93632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
93732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
93832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * Gets the current VM policy.
93932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
94032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static VmPolicy getVmPolicy() {
94132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        return new VmPolicy(sVmPolicyMask);
94232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
94332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
94432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
94532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
94632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
94732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static boolean vmSqliteObjectLeaksEnabled() {
94832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        return (sVmPolicyMask & DETECT_VM_CURSOR_LEAKS) != 0;
94932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
95032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
95132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
95232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     * @hide
95332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick     */
95432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    public static void onSqliteObjectLeaked(String message, Throwable originStack) {
95532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        if ((sVmPolicyMask & PENALTY_LOG) != 0) {
95632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            Log.e(TAG, message, originStack);
95732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
95832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
95932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        if ((sVmPolicyMask & PENALTY_DROPBOX) != 0) {
96032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
96132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
96232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            // The violationMask, passed to ActivityManager, is a
96332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            // subset of the original StrictMode policy bitmask, with
96432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            // only the bit violated and penalty bits to be executed
96532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            // by the ActivityManagerService remaining set.
96632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
96732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            final int savedPolicyMask = getThreadPolicyMask();
96832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            try {
96932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // First, remove any policy before we call into the Activity Manager,
97032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // otherwise we'll infinite recurse as we try to log policy violations
97132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // to disk, thus violating policy, thus requiring logging, etc...
97232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // We restore the current policy below, in the finally block.
97332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                setThreadPolicyMask(0);
97432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
97532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                ActivityManagerNative.getDefault().handleApplicationStrictModeViolation(
97632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    RuntimeInit.getApplicationObject(),
97732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    violationMaskSubset,
97832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                    info);
97932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            } catch (RemoteException e) {
98032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                Log.e(TAG, "RemoteException trying to handle StrictMode violation", e);
98132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            } finally {
98232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                // Restore the policy.
98332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick                setThreadPolicyMask(savedPolicyMask);
98432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            }
98532e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
98632e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
98732e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        if ((sVmPolicyMask & PENALTY_DEATH) != 0) {
98832e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down.");
98932e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            Process.killProcess(Process.myPid());
99032e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick            System.exit(10);
99132e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        }
99232e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    }
99332e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick
99432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick    /**
9955b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Called from Parcel.writeNoException()
9965b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     */
9975b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /* package */ static void writeGatheredViolationsToParcel(Parcel p) {
998cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        ArrayList<ViolationInfo> violations = gatheredViolations.get();
999703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick        if (violations == null) {
1000703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            p.writeInt(0);
1001703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick        } else {
1002703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            p.writeInt(violations.size());
1003703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            for (int i = 0; i < violations.size(); ++i) {
1004703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick                violations.get(i).writeToParcel(p, 0 /* unused flags? */);
1005703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            }
1006703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size());
1007703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick            violations.clear(); // somewhat redundant, as we're about to null the threadlocal
10085b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
1009703e5d3c7fbeb8ca0978045db01d40318f838612Brad Fitzpatrick        gatheredViolations.set(null);
10105b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
10115b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
10125b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    private static class LogStackTrace extends Exception {}
10135b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
10145b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /**
10155b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS,
10165b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     * we here read back all the encoded violations.
10175b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick     */
10185b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /* package */ static void readAndHandleBinderCallViolations(Parcel p) {
10195b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        // Our own stack trace to append
10205b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        StringWriter sw = new StringWriter();
1021cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        new LogStackTrace().printStackTrace(new PrintWriter(sw));
10225b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        String ourStack = sw.toString();
10235b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
102432e60c7942eeba920ec5c27b372ec0899fd75a20Brad Fitzpatrick        int policyMask = getThreadPolicyMask();
1025cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0;
10265b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
10275b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        int numViolations = p.readInt();
10285b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        for (int i = 0; i < numViolations; ++i) {
10295b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call.  i=" + i);
1030cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            ViolationInfo info = new ViolationInfo(p, !currentlyGathering);
1031cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack;
10325b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
10335b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            if (policy instanceof AndroidBlockGuardPolicy) {
1034cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info);
10355b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick            }
10365b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick        }
10375b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    }
10385b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick
10395b747191ff8ad43a54d41faf50436271d1d7fcc8Brad Fitzpatrick    /**
1040727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * Called from android_util_Binder.cpp's
1041727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * android_os_Parcel_enforceInterface when an incoming Binder call
1042727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * requires changing the StrictMode policy mask.  The role of this
1043727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * function is to ask Binder for its current (native) thread-local
1044727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * policy value and synchronize it to libcore's (Java)
1045727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     * thread-local policy value.
1046727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick     */
1047727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    private static void onBinderStrictModePolicyChange(int newPolicy) {
1048727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick        setBlockGuardPolicy(newPolicy);
1049727de40c6bc7c6521a0542ea9def5d5c7b1c5e06Brad Fitzpatrick    }
1050cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1051cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick    /**
1052cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick     * Parcelable that gets sent in Binder call headers back to callers
1053cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick     * to report violations that happened during a cross-process call.
1054cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick     *
1055cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick     * @hide
1056cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick     */
1057cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick    public static class ViolationInfo {
1058cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1059cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Stack and other stuff info.
1060cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1061cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public final ApplicationErrorReport.CrashInfo crashInfo;
1062cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1063cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1064cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * The strict mode policy mask at the time of violation.
1065cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1066cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public final int policy;
1067cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1068cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1069cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * The wall time duration of the violation, when known.  -1 when
1070cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * not known.
1071cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1072cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public int durationMillis = -1;
1073cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1074cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1075cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Which violation number this was (1-based) since the last Looper loop,
1076cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * from the perspective of the root caller (if it crossed any processes
1077cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * via Binder calls).  The value is 0 if the root caller wasn't on a Looper
1078cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * thread.
1079cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1080cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public int violationNumThisLoop;
1081cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1082cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1083cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * The time (in terms of SystemClock.uptimeMillis()) that the
1084cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * violation occurred.
1085cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1086cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public long violationUptimeMillis;
1087cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1088cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1089cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Create an uninitialized instance of ViolationInfo
1090cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1091cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public ViolationInfo() {
1092cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            crashInfo = null;
1093cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            policy = 0;
1094cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        }
1095cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1096cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1097cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Create an instance of ViolationInfo initialized from an exception.
1098cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1099cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public ViolationInfo(Throwable tr, int policy) {
1100cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            crashInfo = new ApplicationErrorReport.CrashInfo(tr);
1101cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            violationUptimeMillis = SystemClock.uptimeMillis();
1102cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            this.policy = policy;
1103cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        }
1104cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1105cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1106cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Create an instance of ViolationInfo initialized from a Parcel.
1107cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1108cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public ViolationInfo(Parcel in) {
1109cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            this(in, false);
1110cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        }
1111cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1112cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1113cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Create an instance of ViolationInfo initialized from a Parcel.
1114cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         *
1115cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * @param unsetGatheringBit if true, the caller is the root caller
1116cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         *   and the gathering penalty should be removed.
1117cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1118cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public ViolationInfo(Parcel in, boolean unsetGatheringBit) {
1119cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            crashInfo = new ApplicationErrorReport.CrashInfo(in);
1120cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            int rawPolicy = in.readInt();
1121cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (unsetGatheringBit) {
1122cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                policy = rawPolicy & ~PENALTY_GATHER;
1123cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            } else {
1124cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                policy = rawPolicy;
1125cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            }
1126cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            durationMillis = in.readInt();
1127cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            violationNumThisLoop = in.readInt();
1128cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            violationUptimeMillis = in.readLong();
1129cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        }
1130cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1131cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1132cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Save a ViolationInfo instance to a parcel.
1133cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1134cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public void writeToParcel(Parcel dest, int flags) {
1135cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            crashInfo.writeToParcel(dest, flags);
1136cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            dest.writeInt(policy);
1137cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            dest.writeInt(durationMillis);
1138cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            dest.writeInt(violationNumThisLoop);
1139cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            dest.writeLong(violationUptimeMillis);
1140cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        }
1141cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1142cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1143cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        /**
1144cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         * Dump a ViolationInfo instance to a Printer.
1145cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick         */
1146cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        public void dump(Printer pw, String prefix) {
1147cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            crashInfo.dump(pw, prefix);
1148cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            pw.println(prefix + "policy: " + policy);
1149cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (durationMillis != -1) {
1150cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                pw.println(prefix + "durationMillis: " + durationMillis);
1151cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            }
1152cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            if (violationNumThisLoop != 0) {
1153cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick                pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop);
1154cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            }
1155cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick            pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis);
1156cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick        }
1157cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick
1158cb9ceb1029036363a81952d8ed5dfcbc83e6ff72Brad Fitzpatrick    }
1159438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick}
1160