/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.os;

import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.IActivityManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.storage.IStorageManager;
import android.os.strictmode.CleartextNetworkViolation;
import android.os.strictmode.ContentUriWithoutPermissionViolation;
import android.os.strictmode.CredentialProtectedWhileLockedViolation;
import android.os.strictmode.CustomViolation;
import android.os.strictmode.DiskReadViolation;
import android.os.strictmode.DiskWriteViolation;
import android.os.strictmode.ExplicitGcViolation;
import android.os.strictmode.FileUriExposedViolation;
import android.os.strictmode.ImplicitDirectBootViolation;
import android.os.strictmode.IncorrectContextUseViolation;
import android.os.strictmode.InstanceCountViolation;
import android.os.strictmode.IntentReceiverLeakedViolation;
import android.os.strictmode.LeakedClosableViolation;
import android.os.strictmode.NetworkViolation;
import android.os.strictmode.NonSdkApiUsedViolation;
import android.os.strictmode.ResourceMismatchViolation;
import android.os.strictmode.ServiceConnectionLeakedViolation;
import android.os.strictmode.SqliteObjectLeakedViolation;
import android.os.strictmode.UnbufferedIoViolation;
import android.os.strictmode.UntaggedSocketViolation;
import android.os.strictmode.Violation;
import android.os.strictmode.WebViewMethodCalledOnWrongThreadViolation;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Printer;
import android.util.Singleton;
import android.util.Slog;
import android.view.IWindowManager;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.RuntimeInit;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.HexDump;

import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
import dalvik.system.VMDebug;
import dalvik.system.VMRuntime;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * StrictMode is a developer tool which detects things you might be doing by accident and brings
 * them to your attention so you can fix them.
 *
 * <p>StrictMode is most commonly used to catch accidental disk or network access on the
 * application's main thread, where UI operations are received and animations take place. Keeping
 * disk and network operations off the main thread makes for much smoother, more responsive
 * applications. By keeping your application's main thread responsive, you also prevent <a
 * href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a> from being shown to
 * users.
 *
 * <p class="note">Note that even though an Android device's disk is often on flash memory, many
 * devices run a filesystem on top of that memory with very limited concurrency. It's often the case
 * that almost all disk accesses are fast, but may in individual cases be dramatically slower when
 * certain I/O is happening in the background from other processes. If possible, it's best to assume
 * that such things are not fast.
 *
 * <p>Example code to enable from early in your {@link android.app.Application}, {@link
 * android.app.Activity}, or other application component's {@link android.app.Application#onCreate}
 * method:
 *
 * <pre>
 * public void onCreate() {
 *     if (DEVELOPER_MODE) {
 *         StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}()
 *                 .detectDiskReads()
 *                 .detectDiskWrites()
 *                 .detectNetwork()   // or .detectAll() for all detectable problems
 *                 .penaltyLog()
 *                 .build());
 *         StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}()
 *                 .detectLeakedSqlLiteObjects()
 *                 .detectLeakedClosableObjects()
 *                 .penaltyLog()
 *                 .penaltyDeath()
 *                 .build());
 *     }
 *     super.onCreate();
 * }
 * </pre>
 *
 * <p>You can decide what should happen when a violation is detected. For example, using {@link
 * ThreadPolicy.Builder#penaltyLog} you can watch the output of <code>adb logcat</code> while you
 * use your application to see the violations as they happen.
 *
 * <p>If you find violations that you feel are problematic, there are a variety of tools to help
 * solve them: threads, {@link android.os.Handler}, {@link android.os.AsyncTask}, {@link
 * android.app.IntentService}, etc. But don't feel compelled to fix everything that StrictMode
 * finds. In particular, many cases of disk access are often necessary during the normal activity
 * lifecycle. Use StrictMode to find things you did by accident. Network requests on the UI thread
 * are almost always a problem, though.
 *
 * <p class="note">StrictMode is not a security mechanism and is not guaranteed to find all disk or
 * network accesses. While it does propagate its state across process boundaries when doing {@link
 * android.os.Binder} calls, it's still ultimately a best effort mechanism. Notably, disk or network
 * access from JNI calls won't necessarily trigger it. Future versions of Android may catch more (or
 * fewer) operations, so you should never leave StrictMode enabled in applications distributed on
 * Google Play.
 */
public final class StrictMode {
    private static final String TAG = "StrictMode";
    private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE);

    /**
     * Boolean system property to disable strict mode checks outright. Set this to 'true' to force
     * disable; 'false' has no effect on other enable/disable policy.
     *
     * @hide
     */
    public static final String DISABLE_PROPERTY = "persist.sys.strictmode.disable";

    /**
     * The boolean system property to control screen flashes on violations.
     *
     * @hide
     */
    public static final String VISUAL_PROPERTY = "persist.sys.strictmode.visual";

    /**
     * Temporary property used to include {@link #DETECT_VM_CLEARTEXT_NETWORK} in {@link
     * VmPolicy.Builder#detectAll()}. Apps can still always opt-into detection using {@link
     * VmPolicy.Builder#detectCleartextNetwork()}.
     */
    private static final String CLEARTEXT_PROPERTY = "persist.sys.strictmode.clear";

    /**
     * Quick feature-flag that can be used to disable the defaults provided by {@link
     * #initThreadDefaults(ApplicationInfo)} and {@link #initVmDefaults(ApplicationInfo)}.
     */
    private static final boolean DISABLE = false;

    // Only apply VM penalties for the same violation at this interval.
    private static final long MIN_VM_INTERVAL_MS = 1000;

    // Only log a duplicate stack trace to the logs every second.
    private static final long MIN_LOG_INTERVAL_MS = 1000;

    // Only show an annoying dialog at most every 30 seconds
    private static final long MIN_DIALOG_INTERVAL_MS = 30000;

    // How many Span tags (e.g. animations) to report.
    private static final int MAX_SPAN_TAGS = 20;

    // How many offending stacks to keep track of (and time) per loop
    // of the Looper.
    private static final int MAX_OFFENSES_PER_LOOP = 10;

    /** @hide */
    @IntDef(flag = true, prefix = { "DETECT_THREAD_", "PENALTY_" }, value = {
            DETECT_THREAD_DISK_WRITE,
            DETECT_THREAD_DISK_READ,
            DETECT_THREAD_NETWORK,
            DETECT_THREAD_CUSTOM,
            DETECT_THREAD_RESOURCE_MISMATCH,
            DETECT_THREAD_UNBUFFERED_IO,
            DETECT_THREAD_EXPLICIT_GC,
            PENALTY_GATHER,
            PENALTY_LOG,
            PENALTY_DIALOG,
            PENALTY_DEATH,
            PENALTY_FLASH,
            PENALTY_DROPBOX,
            PENALTY_DEATH_ON_NETWORK,
            PENALTY_DEATH_ON_CLEARTEXT_NETWORK,
            PENALTY_DEATH_ON_FILE_URI_EXPOSURE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ThreadPolicyMask {}

    // Thread policy: bits 0-15

    /** @hide */
    private static final int DETECT_THREAD_DISK_WRITE = 1 << 0;
    /** @hide */
    private static final int DETECT_THREAD_DISK_READ = 1 << 1;
    /** @hide */
    private static final int DETECT_THREAD_NETWORK = 1 << 2;
    /** @hide */
    private static final int DETECT_THREAD_CUSTOM = 1 << 3;
    /** @hide */
    private static final int DETECT_THREAD_RESOURCE_MISMATCH = 1 << 4;
    /** @hide */
    private static final int DETECT_THREAD_UNBUFFERED_IO = 1 << 5;
    /** @hide  */
    private static final int DETECT_THREAD_EXPLICIT_GC = 1 << 6;

    /** @hide */
    private static final int DETECT_THREAD_ALL = 0x0000ffff;

    /** @hide */
    @IntDef(flag = true, prefix = { "DETECT_THREAD_", "PENALTY_" }, value = {
            DETECT_VM_CURSOR_LEAKS,
            DETECT_VM_CLOSABLE_LEAKS,
            DETECT_VM_ACTIVITY_LEAKS,
            DETECT_VM_INSTANCE_LEAKS,
            DETECT_VM_REGISTRATION_LEAKS,
            DETECT_VM_FILE_URI_EXPOSURE,
            DETECT_VM_CLEARTEXT_NETWORK,
            DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION,
            DETECT_VM_UNTAGGED_SOCKET,
            DETECT_VM_NON_SDK_API_USAGE,
            DETECT_VM_IMPLICIT_DIRECT_BOOT,
            DETECT_VM_INCORRECT_CONTEXT_USE,
            PENALTY_GATHER,
            PENALTY_LOG,
            PENALTY_DIALOG,
            PENALTY_DEATH,
            PENALTY_FLASH,
            PENALTY_DROPBOX,
            PENALTY_DEATH_ON_NETWORK,
            PENALTY_DEATH_ON_CLEARTEXT_NETWORK,
            PENALTY_DEATH_ON_FILE_URI_EXPOSURE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface VmPolicyMask {}

    // VM policy: bits 0-15

    /** @hide */
    private static final int DETECT_VM_CURSOR_LEAKS = 1 << 0;
    /** @hide */
    private static final int DETECT_VM_CLOSABLE_LEAKS = 1 << 1;
    /** @hide */
    private static final int DETECT_VM_ACTIVITY_LEAKS = 1 << 2;
    /** @hide */
    private static final int DETECT_VM_INSTANCE_LEAKS = 1 << 3;
    /** @hide */
    private static final int DETECT_VM_REGISTRATION_LEAKS = 1 << 4;
    /** @hide */
    private static final int DETECT_VM_FILE_URI_EXPOSURE = 1 << 5;
    /** @hide */
    private static final int DETECT_VM_CLEARTEXT_NETWORK = 1 << 6;
    /** @hide */
    private static final int DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION = 1 << 7;
    /** @hide */
    private static final int DETECT_VM_UNTAGGED_SOCKET = 1 << 8;
    /** @hide */
    private static final int DETECT_VM_NON_SDK_API_USAGE = 1 << 9;
    /** @hide */
    private static final int DETECT_VM_IMPLICIT_DIRECT_BOOT = 1 << 10;
    /** @hide */
    private static final int DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED = 1 << 11;
    /** @hide */
    private static final int DETECT_VM_INCORRECT_CONTEXT_USE = 1 << 12;

    /** @hide */
    private static final int DETECT_VM_ALL = 0x0000ffff;

    // Penalty policy: bits 16-31

    /**
     * Non-public penalty mode which overrides all the other penalty bits and signals that we're in
     * a Binder call and we should ignore the other penalty bits and instead serialize back all our
     * offending stack traces to the caller to ultimately handle in the originating process.
     *
     * <p>This must be kept in sync with the constant in libs/binder/Parcel.cpp
     *
     * @hide
     */
    public static final int PENALTY_GATHER = 1 << 31;

    /** {@hide} */
    public static final int PENALTY_LOG = 1 << 30;
    /** {@hide} */
    public static final int PENALTY_DIALOG = 1 << 29;
    /** {@hide} */
    public static final int PENALTY_DEATH = 1 << 28;
    /** {@hide} */
    public static final int PENALTY_FLASH = 1 << 27;
    /** {@hide} */
    public static final int PENALTY_DROPBOX = 1 << 26;
    /** {@hide} */
    public static final int PENALTY_DEATH_ON_NETWORK = 1 << 25;
    /** {@hide} */
    public static final int PENALTY_DEATH_ON_CLEARTEXT_NETWORK = 1 << 24;
    /** {@hide} */
    public static final int PENALTY_DEATH_ON_FILE_URI_EXPOSURE = 1 << 23;

    /** @hide */
    public static final int PENALTY_ALL = 0xffff0000;

    /** {@hide} */
    public static final int NETWORK_POLICY_ACCEPT = 0;
    /** {@hide} */
    public static final int NETWORK_POLICY_LOG = 1;
    /** {@hide} */
    public static final int NETWORK_POLICY_REJECT = 2;

    // TODO: wrap in some ImmutableHashMap thing.
    // Note: must be before static initialization of sVmPolicy.
    private static final HashMap<Class, Integer> EMPTY_CLASS_LIMIT_MAP =
            new HashMap<Class, Integer>();

    /** The current VmPolicy in effect. */
    private static volatile VmPolicy sVmPolicy = VmPolicy.LAX;

    /** {@hide} */
    @TestApi
    public interface ViolationLogger {

        /** Called when penaltyLog is enabled and a violation needs logging. */
        void log(ViolationInfo info);
    }

    private static final ViolationLogger LOGCAT_LOGGER =
            info -> {
                String msg;
                if (info.durationMillis != -1) {
                    msg = "StrictMode policy violation; ~duration=" + info.durationMillis + " ms:";
                } else {
                    msg = "StrictMode policy violation:";
                }
                Log.d(TAG, msg + " " + info.getStackTrace());
            };

    private static volatile ViolationLogger sLogger = LOGCAT_LOGGER;

    private static final ThreadLocal<OnThreadViolationListener> sThreadViolationListener =
            new ThreadLocal<>();
    private static final ThreadLocal<Executor> sThreadViolationExecutor = new ThreadLocal<>();

    /**
     * When #{@link ThreadPolicy.Builder#penaltyListener} is enabled, the listener is called on the
     * provided executor when a Thread violation occurs.
     */
    public interface OnThreadViolationListener {
        /** Called on a thread policy violation. */
        void onThreadViolation(Violation v);
    }

    /**
     * When #{@link VmPolicy.Builder#penaltyListener} is enabled, the listener is called on the
     * provided executor when a VM violation occurs.
     */
    public interface OnVmViolationListener {
        /** Called on a VM policy violation. */
        void onVmViolation(Violation v);
    }

    /** {@hide} */
    @TestApi
    public static void setViolationLogger(ViolationLogger listener) {
        if (listener == null) {
            listener = LOGCAT_LOGGER;
        }
        sLogger = listener;
    }

    /**
     * The number of threads trying to do an async dropbox write. Just to limit ourselves out of
     * paranoia.
     */
    private static final AtomicInteger sDropboxCallsInFlight = new AtomicInteger(0);

    /**
     * Callback supplied to dalvik / libcore to get informed of usages of java API that are not
     * a part of the public SDK.
     */
    private static final Consumer<String> sNonSdkApiUsageConsumer =
            message -> onVmPolicyViolation(new NonSdkApiUsedViolation(message));

    private StrictMode() {}

    /**
     * {@link StrictMode} policy applied to a certain thread.
     *
     * <p>The policy is enabled by {@link #setThreadPolicy}. The current policy can be retrieved
     * with {@link #getThreadPolicy}.
     *
     * <p>Note that multiple penalties may be provided and they're run in order from least to most
     * severe (logging before process death, for example). There's currently no mechanism to choose
     * different penalties for different detected actions.
     */
    public static final class ThreadPolicy {
        /** The default, lax policy which doesn't catch anything. */
        public static final ThreadPolicy LAX = new ThreadPolicy(0, null, null);

        @UnsupportedAppUsage
        final @ThreadPolicyMask int mask;
        final OnThreadViolationListener mListener;
        final Executor mCallbackExecutor;

        private ThreadPolicy(@ThreadPolicyMask int mask, OnThreadViolationListener listener,
                Executor executor) {
            this.mask = mask;
            mListener = listener;
            mCallbackExecutor = executor;
        }

        @Override
        public String toString() {
            return "[StrictMode.ThreadPolicy; mask=" + mask + "]";
        }

        /**
         * Creates {@link ThreadPolicy} instances. Methods whose names start with {@code detect}
         * specify what problems we should look for. Methods whose names start with {@code penalty}
         * specify what we should do when we detect a problem.
         *
         * <p>You can call as many {@code detect} and {@code penalty} methods as you like. Currently
         * order is insignificant: all penalties apply to all detected problems.
         *
         * <p>For example, detect everything and log anything that's found:
         *
         * <pre>
         * StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
         *     .detectAll()
         *     .penaltyLog()
         *     .build();
         * StrictMode.setThreadPolicy(policy);
         * </pre>
         */
        public static final class Builder {
            private @ThreadPolicyMask int mMask = 0;
            private OnThreadViolationListener mListener;
            private Executor mExecutor;

            /**
             * Create a Builder that detects nothing and has no violations. (but note that {@link
             * #build} will default to enabling {@link #penaltyLog} if no other penalties are
             * specified)
             */
            public Builder() {
                mMask = 0;
            }

            /** Initialize a Builder from an existing ThreadPolicy. */
            public Builder(ThreadPolicy policy) {
                mMask = policy.mask;
                mListener = policy.mListener;
                mExecutor = policy.mCallbackExecutor;
            }

            /**
             * Detect everything that's potentially suspect.
             *
             * <p>As of the Gingerbread release this includes network and disk operations but will
             * likely expand in future releases.
             */
            public @NonNull Builder detectAll() {
                detectDiskReads();
                detectDiskWrites();
                detectNetwork();

                final int targetSdk = VMRuntime.getRuntime().getTargetSdkVersion();
                if (targetSdk >= Build.VERSION_CODES.HONEYCOMB) {
                    detectCustomSlowCalls();
                }
                if (targetSdk >= Build.VERSION_CODES.M) {
                    detectResourceMismatches();
                }
                if (targetSdk >= Build.VERSION_CODES.O) {
                    detectUnbufferedIo();
                }
                return this;
            }

            /** Disable the detection of everything. */
            public @NonNull Builder permitAll() {
                return disable(DETECT_THREAD_ALL);
            }

            /** Enable detection of network operations. */
            public @NonNull Builder detectNetwork() {
                return enable(DETECT_THREAD_NETWORK);
            }

            /** Disable detection of network operations. */
            public @NonNull Builder permitNetwork() {
                return disable(DETECT_THREAD_NETWORK);
            }

            /** Enable detection of disk reads. */
            public @NonNull Builder detectDiskReads() {
                return enable(DETECT_THREAD_DISK_READ);
            }

            /** Disable detection of disk reads. */
            public @NonNull Builder permitDiskReads() {
                return disable(DETECT_THREAD_DISK_READ);
            }

            /** Enable detection of slow calls. */
            public @NonNull Builder detectCustomSlowCalls() {
                return enable(DETECT_THREAD_CUSTOM);
            }

            /** Disable detection of slow calls. */
            public @NonNull Builder permitCustomSlowCalls() {
                return disable(DETECT_THREAD_CUSTOM);
            }

            /** Disable detection of mismatches between defined resource types and getter calls. */
            public @NonNull Builder permitResourceMismatches() {
                return disable(DETECT_THREAD_RESOURCE_MISMATCH);
            }

            /** Detect unbuffered input/output operations. */
            public @NonNull Builder detectUnbufferedIo() {
                return enable(DETECT_THREAD_UNBUFFERED_IO);
            }

            /** Disable detection of unbuffered input/output operations. */
            public @NonNull Builder permitUnbufferedIo() {
                return disable(DETECT_THREAD_UNBUFFERED_IO);
            }

            /**
             * Enables detection of mismatches between defined resource types and getter calls.
             *
             * <p>This helps detect accidental type mismatches and potentially expensive type
             * conversions when obtaining typed resources.
             *
             * <p>For example, a strict mode violation would be thrown when calling {@link
             * android.content.res.TypedArray#getInt(int, int)} on an index that contains a
             * String-type resource. If the string value can be parsed as an integer, this method
             * call will return a value without crashing; however, the developer should format the
             * resource as an integer to avoid unnecessary type conversion.
             */
            public @NonNull Builder detectResourceMismatches() {
                return enable(DETECT_THREAD_RESOURCE_MISMATCH);
            }

            /** Enable detection of disk writes. */
            public @NonNull Builder detectDiskWrites() {
                return enable(DETECT_THREAD_DISK_WRITE);
            }

            /** Disable detection of disk writes. */
            public @NonNull Builder permitDiskWrites() {
                return disable(DETECT_THREAD_DISK_WRITE);
            }

            /**
             * Detect explicit GC requests, i.e. calls to Runtime.gc().
             *
             * @hide
             */
            @TestApi
            public @NonNull Builder detectExplicitGc() {
                // TODO(b/3400644): Un-hide this for next API update
                // TODO(b/3400644): Un-hide ExplicitGcViolation for next API update
                // TODO(b/3400644): Make DETECT_EXPLICIT_GC a @TestApi for next API update
                // TODO(b/3400644): Call this from detectAll in next API update
                return enable(DETECT_THREAD_EXPLICIT_GC);
            }

            /**
             * Disable detection of explicit GC requests, i.e. calls to Runtime.gc().
             *
             * @hide
             */
            public @NonNull Builder permitExplicitGc() {
                // TODO(b/3400644): Un-hide this for next API update
                return disable(DETECT_THREAD_EXPLICIT_GC);
            }

            /**
             * Show an annoying dialog to the developer on detected violations, rate-limited to be
             * only a little annoying.
             */
            public @NonNull Builder penaltyDialog() {
                return enable(PENALTY_DIALOG);
            }

            /**
             * Crash the whole process on violation. This penalty runs at the end of all enabled
             * penalties so you'll still get see logging or other violations before the process
             * dies.
             *
             * <p>Unlike {@link #penaltyDeathOnNetwork}, this applies to disk reads, disk writes,
             * and network usage if their corresponding detect flags are set.
             */
            public @NonNull Builder penaltyDeath() {
                return enable(PENALTY_DEATH);
            }

            /**
             * Crash the whole process on any network usage. Unlike {@link #penaltyDeath}, this
             * penalty runs <em>before</em> anything else. You must still have called {@link
             * #detectNetwork} to enable this.
             *
             * <p>In the Honeycomb or later SDKs, this is on by default.
             */
            public @NonNull Builder penaltyDeathOnNetwork() {
                return enable(PENALTY_DEATH_ON_NETWORK);
            }

            /** Flash the screen during a violation. */
            public @NonNull Builder penaltyFlashScreen() {
                return enable(PENALTY_FLASH);
            }

            /** Log detected violations to the system log. */
            public @NonNull Builder penaltyLog() {
                return enable(PENALTY_LOG);
            }

            /**
             * Enable detected violations log a stacktrace and timing data to the {@link
             * android.os.DropBoxManager DropBox} on policy violation. Intended mostly for platform
             * integrators doing beta user field data collection.
             */
            public @NonNull Builder penaltyDropBox() {
                return enable(PENALTY_DROPBOX);
            }

            /**
             * Call #{@link OnThreadViolationListener#onThreadViolation(Violation)} on specified
             * executor every violation.
             */
            public @NonNull Builder penaltyListener(
                    @NonNull Executor executor, @NonNull OnThreadViolationListener listener) {
                if (executor == null) {
                    throw new NullPointerException("executor must not be null");
                }
                mListener = listener;
                mExecutor = executor;
                return this;
            }

            /** @removed */
            public @NonNull Builder penaltyListener(
                    @NonNull OnThreadViolationListener listener, @NonNull Executor executor) {
                return penaltyListener(executor, listener);
            }

            private Builder enable(@ThreadPolicyMask int mask) {
                mMask |= mask;
                return this;
            }

            private Builder disable(@ThreadPolicyMask int mask) {
                mMask &= ~mask;
                return this;
            }

            /**
             * Construct the ThreadPolicy instance.
             *
             * <p>Note: if no penalties are enabled before calling <code>build</code>, {@link
             * #penaltyLog} is implicitly set.
             */
            public ThreadPolicy build() {
                // If there are detection bits set but no violation bits
                // set, enable simple logging.
                if (mListener == null
                        && mMask != 0
                        && (mMask
                                        & (PENALTY_DEATH
                                                | PENALTY_LOG
                                                | PENALTY_DROPBOX
                                                | PENALTY_DIALOG))
                                == 0) {
                    penaltyLog();
                }
                return new ThreadPolicy(mMask, mListener, mExecutor);
            }
        }
    }

    /**
     * {@link StrictMode} policy applied to all threads in the virtual machine's process.
     *
     * <p>The policy is enabled by {@link #setVmPolicy}.
     */
    public static final class VmPolicy {
        /** The default, lax policy which doesn't catch anything. */
        public static final VmPolicy LAX = new VmPolicy(0, EMPTY_CLASS_LIMIT_MAP, null, null);

        @UnsupportedAppUsage
        final @VmPolicyMask int mask;
        final OnVmViolationListener mListener;
        final Executor mCallbackExecutor;

        // Map from class to max number of allowed instances in memory.
        final HashMap<Class, Integer> classInstanceLimit;

        private VmPolicy(
                @VmPolicyMask int mask,
                HashMap<Class, Integer> classInstanceLimit,
                OnVmViolationListener listener,
                Executor executor) {
            if (classInstanceLimit == null) {
                throw new NullPointerException("classInstanceLimit == null");
            }
            this.mask = mask;
            this.classInstanceLimit = classInstanceLimit;
            mListener = listener;
            mCallbackExecutor = executor;
        }

        @Override
        public String toString() {
            return "[StrictMode.VmPolicy; mask=" + mask + "]";
        }

        /**
         * Creates {@link VmPolicy} instances. Methods whose names start with {@code detect} specify
         * what problems we should look for. Methods whose names start with {@code penalty} specify
         * what we should do when we detect a problem.
         *
         * <p>You can call as many {@code detect} and {@code penalty} methods as you like. Currently
         * order is insignificant: all penalties apply to all detected problems.
         *
         * <p>For example, detect everything and log anything that's found:
         *
         * <pre>
         * StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
         *     .detectAll()
         *     .penaltyLog()
         *     .build();
         * StrictMode.setVmPolicy(policy);
         * </pre>
         */
        public static final class Builder {
            @UnsupportedAppUsage
            private @VmPolicyMask int mMask;
            private OnVmViolationListener mListener;
            private Executor mExecutor;

            private HashMap<Class, Integer> mClassInstanceLimit; // null until needed
            private boolean mClassInstanceLimitNeedCow = false; // need copy-on-write

            public Builder() {
                mMask = 0;
            }

            /** Build upon an existing VmPolicy. */
            public Builder(VmPolicy base) {
                mMask = base.mask;
                mClassInstanceLimitNeedCow = true;
                mClassInstanceLimit = base.classInstanceLimit;
                mListener = base.mListener;
                mExecutor = base.mCallbackExecutor;
            }

            /**
             * Set an upper bound on how many instances of a class can be in memory at once. Helps
             * to prevent object leaks.
             */
            public @NonNull Builder setClassInstanceLimit(Class klass, int instanceLimit) {
                if (klass == null) {
                    throw new NullPointerException("klass == null");
                }
                if (mClassInstanceLimitNeedCow) {
                    if (mClassInstanceLimit.containsKey(klass)
                            && mClassInstanceLimit.get(klass) == instanceLimit) {
                        // no-op; don't break COW
                        return this;
                    }
                    mClassInstanceLimitNeedCow = false;
                    mClassInstanceLimit = (HashMap<Class, Integer>) mClassInstanceLimit.clone();
                } else if (mClassInstanceLimit == null) {
                    mClassInstanceLimit = new HashMap<Class, Integer>();
                }
                mMask |= DETECT_VM_INSTANCE_LEAKS;
                mClassInstanceLimit.put(klass, instanceLimit);
                return this;
            }

            /** Detect leaks of {@link android.app.Activity} subclasses. */
            public @NonNull Builder detectActivityLeaks() {
                return enable(DETECT_VM_ACTIVITY_LEAKS);
            }

            /** @hide */
            public @NonNull Builder permitActivityLeaks() {
                synchronized (StrictMode.class) {
                    sExpectedActivityInstanceCount.clear();
                }
                return disable(DETECT_VM_ACTIVITY_LEAKS);
            }

            /**
             * Detect reflective usage of APIs that are not part of the public Android SDK.
             *
             * <p>Note that any non-SDK APIs that this processes accesses before this detection is
             * enabled may not be detected. To ensure that all such API accesses are detected,
             * you should apply this policy as early as possible after process creation.
             */
            public @NonNull Builder detectNonSdkApiUsage() {
                return enable(DETECT_VM_NON_SDK_API_USAGE);
            }

            /**
             * Permit reflective usage of APIs that are not part of the public Android SDK. Note
             * that this <b>only</b> affects {@code StrictMode}, the underlying runtime may
             * continue to restrict or warn on access to methods that are not part of the
             * public SDK.
             */
            public @NonNull Builder permitNonSdkApiUsage() {
                return disable(DETECT_VM_NON_SDK_API_USAGE);
            }

            /**
             * Detect everything that's potentially suspect.
             *
             * <p>In the Honeycomb release this includes leaks of SQLite cursors, Activities, and
             * other closable objects but will likely expand in future releases.
             */
            public @NonNull Builder detectAll() {
                detectLeakedSqlLiteObjects();

                final int targetSdk = VMRuntime.getRuntime().getTargetSdkVersion();
                if (targetSdk >= Build.VERSION_CODES.HONEYCOMB) {
                    detectActivityLeaks();
                    detectLeakedClosableObjects();
                }
                if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) {
                    detectLeakedRegistrationObjects();
                }
                if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                    detectFileUriExposure();
                }
                if (targetSdk >= Build.VERSION_CODES.M) {
                    // TODO: always add DETECT_VM_CLEARTEXT_NETWORK once we have
                    // facility for apps to mark sockets that should be ignored
                    if (SystemProperties.getBoolean(CLEARTEXT_PROPERTY, false)) {
                        detectCleartextNetwork();
                    }
                }
                if (targetSdk >= Build.VERSION_CODES.O) {
                    detectContentUriWithoutPermission();
                    detectUntaggedSockets();
                }
                if (targetSdk >= Build.VERSION_CODES.Q) {
                    detectCredentialProtectedWhileLocked();
                }
                if (targetSdk >= Build.VERSION_CODES.R) {
                    detectIncorrectContextUse();
                }

                // TODO: Decide whether to detect non SDK API usage beyond a certain API level.
                // TODO: enable detectImplicitDirectBoot() once system is less noisy

                return this;
            }

            /**
             * Detect when an {@link android.database.sqlite.SQLiteCursor} or other SQLite object is
             * finalized without having been closed.
             *
             * <p>You always want to explicitly close your SQLite cursors to avoid unnecessary
             * database contention and temporary memory leaks.
             */
            public @NonNull Builder detectLeakedSqlLiteObjects() {
                return enable(DETECT_VM_CURSOR_LEAKS);
            }

            /**
             * Detect when an {@link java.io.Closeable} or other object with an explicit termination
             * method is finalized without having been closed.
             *
             * <p>You always want to explicitly close such objects to avoid unnecessary resources
             * leaks.
             */
            public @NonNull Builder detectLeakedClosableObjects() {
                return enable(DETECT_VM_CLOSABLE_LEAKS);
            }

            /**
             * Detect when a {@link BroadcastReceiver} or {@link ServiceConnection} is leaked during
             * {@link Context} teardown.
             */
            public @NonNull Builder detectLeakedRegistrationObjects() {
                return enable(DETECT_VM_REGISTRATION_LEAKS);
            }

            /**
             * Detect when the calling application exposes a {@code file://} {@link android.net.Uri}
             * to another app.
             *
             * <p>This exposure is discouraged since the receiving app may not have access to the
             * shared path. For example, the receiving app may not have requested the {@link
             * android.Manifest.permission#READ_EXTERNAL_STORAGE} runtime permission, or the
             * platform may be sharing the {@link android.net.Uri} across user profile boundaries.
             *
             * <p>Instead, apps should use {@code content://} Uris so the platform can extend
             * temporary permission for the receiving app to access the resource.
             *
             * @see android.support.v4.content.FileProvider
             * @see Intent#FLAG_GRANT_READ_URI_PERMISSION
             */
            public @NonNull Builder detectFileUriExposure() {
                return enable(DETECT_VM_FILE_URI_EXPOSURE);
            }

            /**
             * Detect any network traffic from the calling app which is not wrapped in SSL/TLS. This
             * can help you detect places that your app is inadvertently sending cleartext data
             * across the network.
             *
             * <p>Using {@link #penaltyDeath()} or {@link #penaltyDeathOnCleartextNetwork()} will
             * block further traffic on that socket to prevent accidental data leakage, in addition
             * to crashing your process.
             *
             * <p>Using {@link #penaltyDropBox()} will log the raw contents of the packet that
             * triggered the violation.
             *
             * <p>This inspects both IPv4/IPv6 and TCP/UDP network traffic, but it may be subject to
             * false positives, such as when STARTTLS protocols or HTTP proxies are used.
             */
            public @NonNull Builder detectCleartextNetwork() {
                return enable(DETECT_VM_CLEARTEXT_NETWORK);
            }

            /**
             * Detect when the calling application sends a {@code content://} {@link
             * android.net.Uri} to another app without setting {@link
             * Intent#FLAG_GRANT_READ_URI_PERMISSION} or {@link
             * Intent#FLAG_GRANT_WRITE_URI_PERMISSION}.
             *
             * <p>Forgetting to include one or more of these flags when sending an intent is
             * typically an app bug.
             *
             * @see Intent#FLAG_GRANT_READ_URI_PERMISSION
             * @see Intent#FLAG_GRANT_WRITE_URI_PERMISSION
             */
            public @NonNull Builder detectContentUriWithoutPermission() {
                return enable(DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION);
            }

            /**
             * Detect any sockets in the calling app which have not been tagged using {@link
             * TrafficStats}. Tagging sockets can help you investigate network usage inside your
             * app, such as a narrowing down heavy usage to a specific library or component.
             *
             * <p>This currently does not detect sockets created in native code.
             *
             * @see TrafficStats#setThreadStatsTag(int)
             * @see TrafficStats#tagSocket(java.net.Socket)
             * @see TrafficStats#tagDatagramSocket(java.net.DatagramSocket)
             */
            public @NonNull Builder detectUntaggedSockets() {
                return enable(DETECT_VM_UNTAGGED_SOCKET);
            }

            /** @hide */
            public @NonNull Builder permitUntaggedSockets() {
                return disable(DETECT_VM_UNTAGGED_SOCKET);
            }

            /**
             * Detect any implicit reliance on Direct Boot automatic filtering
             * of {@link PackageManager} values. Violations are only triggered
             * when implicit calls are made while the user is locked.
             * <p>
             * Apps becoming Direct Boot aware need to carefully inspect each
             * query site and explicitly decide which combination of flags they
             * want to use:
             * <ul>
             * <li>{@link PackageManager#MATCH_DIRECT_BOOT_AWARE}
             * <li>{@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE}
             * <li>{@link PackageManager#MATCH_DIRECT_BOOT_AUTO}
             * </ul>
             */
            public @NonNull Builder detectImplicitDirectBoot() {
                return enable(DETECT_VM_IMPLICIT_DIRECT_BOOT);
            }

            /** @hide */
            public @NonNull Builder permitImplicitDirectBoot() {
                return disable(DETECT_VM_IMPLICIT_DIRECT_BOOT);
            }

            /**
             * Detect access to filesystem paths stored in credential protected
             * storage areas while the user is locked.
             * <p>
             * When a user is locked, credential protected storage is
             * unavailable, and files stored in these locations appear to not
             * exist, which can result in subtle app bugs if they assume default
             * behaviors or empty states. Instead, apps should store data needed
             * while a user is locked under device protected storage areas.
             *
             * @see Context#createDeviceProtectedStorageContext()
             */
            public @NonNull Builder detectCredentialProtectedWhileLocked() {
                return enable(DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED);
            }

            /** @hide */
            public @NonNull Builder permitCredentialProtectedWhileLocked() {
                return disable(DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED);
            }

            /**
             * Detect attempts to invoke a method on a {@link Context} that is not suited for such
             * operation.
             * <p>An example of this is trying to obtain an instance of visual service (e.g.
             * {@link android.view.WindowManager}) from a non-visual {@link Context}. This is not
             * allowed, since a non-visual {@link Context} is not adjusted to any visual area, and
             * therefore can report incorrect metrics or resources.
             * @see Context#getDisplay()
             * @see Context#getSystemService(String)
             * @hide
             */
            @TestApi
            public @NonNull Builder detectIncorrectContextUse() {
                return enable(DETECT_VM_INCORRECT_CONTEXT_USE);
            }

            /**
             * Disable detection of incorrect context use.
             * TODO(b/149790106): Fix usages and remove.
             * @hide
             */
            @TestApi
            public @NonNull Builder permitIncorrectContextUse() {
                return disable(DETECT_VM_INCORRECT_CONTEXT_USE);
            }

            /**
             * Crashes the whole process on violation. This penalty runs at the end of all enabled
             * penalties so you'll still get your logging or other violations before the process
             * dies.
             */
            public @NonNull Builder penaltyDeath() {
                return enable(PENALTY_DEATH);
            }

            /**
             * Crashes the whole process when cleartext network traffic is detected.
             *
             * @see #detectCleartextNetwork()
             */
            public @NonNull Builder penaltyDeathOnCleartextNetwork() {
                return enable(PENALTY_DEATH_ON_CLEARTEXT_NETWORK);
            }

            /**
             * Crashes the whole process when a {@code file://} {@link android.net.Uri} is exposed
             * beyond this app.
             *
             * @see #detectFileUriExposure()
             */
            public @NonNull Builder penaltyDeathOnFileUriExposure() {
                return enable(PENALTY_DEATH_ON_FILE_URI_EXPOSURE);
            }

            /** Log detected violations to the system log. */
            public @NonNull Builder penaltyLog() {
                return enable(PENALTY_LOG);
            }

            /**
             * Enable detected violations log a stacktrace and timing data to the {@link
             * android.os.DropBoxManager DropBox} on policy violation. Intended mostly for platform
             * integrators doing beta user field data collection.
             */
            public @NonNull Builder penaltyDropBox() {
                return enable(PENALTY_DROPBOX);
            }

            /**
             * Call #{@link OnVmViolationListener#onVmViolation(Violation)} on every violation.
             */
            public @NonNull Builder penaltyListener(
                    @NonNull Executor executor, @NonNull OnVmViolationListener listener) {
                if (executor == null) {
                    throw new NullPointerException("executor must not be null");
                }
                mListener = listener;
                mExecutor = executor;
                return this;
            }

            /** @removed */
            public @NonNull Builder penaltyListener(
                    @NonNull OnVmViolationListener listener, @NonNull Executor executor) {
                return penaltyListener(executor, listener);
            }

            private Builder enable(@VmPolicyMask int mask) {
                mMask |= mask;
                return this;
            }

            Builder disable(@VmPolicyMask int mask) {
                mMask &= ~mask;
                return this;
            }

            /**
             * Construct the VmPolicy instance.
             *
             * <p>Note: if no penalties are enabled before calling <code>build</code>, {@link
             * #penaltyLog} is implicitly set.
             */
            public VmPolicy build() {
                // If there are detection bits set but no violation bits
                // set, enable simple logging.
                if (mListener == null
                        && mMask != 0
                        && (mMask
                                        & (PENALTY_DEATH
                                                | PENALTY_LOG
                                                | PENALTY_DROPBOX
                                                | PENALTY_DIALOG))
                                == 0) {
                    penaltyLog();
                }
                return new VmPolicy(
                        mMask,
                        mClassInstanceLimit != null ? mClassInstanceLimit : EMPTY_CLASS_LIMIT_MAP,
                        mListener,
                        mExecutor);
            }
        }
    }

    /**
     * Log of strict mode violation stack traces that have occurred during a Binder call, to be
     * serialized back later to the caller via Parcel.writeNoException() (amusingly) where the
     * caller can choose how to react.
     */
    private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations =
            new ThreadLocal<ArrayList<ViolationInfo>>() {
                @Override
                protected ArrayList<ViolationInfo> initialValue() {
                    // Starts null to avoid unnecessary allocations when
                    // checking whether there are any violations or not in
                    // hasGatheredViolations() below.
                    return null;
                }
            };

    /**
     * Sets the policy for what actions on the current thread should be detected, as well as the
     * penalty if such actions occur.
     *
     * <p>Internally this sets a thread-local variable which is propagated across cross-process IPC
     * calls, meaning you can catch violations when a system service or another process accesses the
     * disk or network on your behalf.
     *
     * @param policy the policy to put into place
     */
    public static void setThreadPolicy(final ThreadPolicy policy) {
        setThreadPolicyMask(policy.mask);
        sThreadViolationListener.set(policy.mListener);
        sThreadViolationExecutor.set(policy.mCallbackExecutor);
    }

    /** @hide */
    public static void setThreadPolicyMask(@ThreadPolicyMask int threadPolicyMask) {
        // In addition to the Java-level thread-local in Dalvik's
        // BlockGuard, we also need to keep a native thread-local in
        // Binder in order to propagate the value across Binder calls,
        // even across native-only processes.  The two are kept in
        // sync via the callback to onStrictModePolicyChange, below.
        setBlockGuardPolicy(threadPolicyMask);

        // And set the Android native version...
        Binder.setThreadStrictModePolicy(threadPolicyMask);
    }

    // Sets the policy in Dalvik/libcore (BlockGuard)
    private static void setBlockGuardPolicy(@ThreadPolicyMask int threadPolicyMask) {
        if (threadPolicyMask == 0) {
            BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY);
            return;
        }
        final BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        final AndroidBlockGuardPolicy androidPolicy;
        if (policy instanceof AndroidBlockGuardPolicy) {
            androidPolicy = (AndroidBlockGuardPolicy) policy;
        } else {
            androidPolicy = THREAD_ANDROID_POLICY.get();
            BlockGuard.setThreadPolicy(androidPolicy);
        }
        androidPolicy.setThreadPolicyMask(threadPolicyMask);
    }

    private static void setBlockGuardVmPolicy(@VmPolicyMask int vmPolicyMask) {
        // We only need to install BlockGuard for a small subset of VM policies
        vmPolicyMask &= DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED;
        if (vmPolicyMask != 0) {
            BlockGuard.setVmPolicy(VM_ANDROID_POLICY);
        } else {
            BlockGuard.setVmPolicy(BlockGuard.LAX_VM_POLICY);
        }
    }

    // Sets up CloseGuard in Dalvik/libcore
    private static void setCloseGuardEnabled(boolean enabled) {
        if (!(CloseGuard.getReporter() instanceof AndroidCloseGuardReporter)) {
            CloseGuard.setReporter(new AndroidCloseGuardReporter());
        }
        CloseGuard.setEnabled(enabled);
    }

    /**
     * Returns the bitmask of the current thread's policy.
     *
     * @return the bitmask of all the DETECT_* and PENALTY_* bits currently enabled
     * @hide
     */
    @UnsupportedAppUsage
    public static @ThreadPolicyMask int getThreadPolicyMask() {
        final BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (policy instanceof AndroidBlockGuardPolicy) {
            return ((AndroidBlockGuardPolicy) policy).getThreadPolicyMask();
        } else {
            return 0;
        }
    }

    /** Returns the current thread's policy. */
    public static ThreadPolicy getThreadPolicy() {
        // TODO: this was a last minute Gingerbread API change (to
        // introduce VmPolicy cleanly) but this isn't particularly
        // optimal for users who might call this method often.  This
        // should be in a thread-local and not allocate on each call.
        return new ThreadPolicy(
                getThreadPolicyMask(),
                sThreadViolationListener.get(),
                sThreadViolationExecutor.get());
    }

    /**
     * A convenience wrapper that takes the current {@link ThreadPolicy} from {@link
     * #getThreadPolicy}, modifies it to permit both disk reads &amp; writes, and sets the new
     * policy with {@link #setThreadPolicy}, returning the old policy so you can restore it at the
     * end of a block.
     *
     * @return the old policy, to be passed to {@link #setThreadPolicy} to restore the policy at the
     *     end of a block
     */
    public static ThreadPolicy allowThreadDiskWrites() {
        return new ThreadPolicy(
                allowThreadDiskWritesMask(),
                sThreadViolationListener.get(),
                sThreadViolationExecutor.get());
    }

    /** @hide */
    public static @ThreadPolicyMask int allowThreadDiskWritesMask() {
        int oldPolicyMask = getThreadPolicyMask();
        int newPolicyMask = oldPolicyMask & ~(DETECT_THREAD_DISK_WRITE | DETECT_THREAD_DISK_READ);
        if (newPolicyMask != oldPolicyMask) {
            setThreadPolicyMask(newPolicyMask);
        }
        return oldPolicyMask;
    }

    /**
     * A convenience wrapper that takes the current {@link ThreadPolicy} from {@link
     * #getThreadPolicy}, modifies it to permit disk reads, and sets the new policy with {@link
     * #setThreadPolicy}, returning the old policy so you can restore it at the end of a block.
     *
     * @return the old policy, to be passed to setThreadPolicy to restore the policy.
     */
    public static ThreadPolicy allowThreadDiskReads() {
        return new ThreadPolicy(
                allowThreadDiskReadsMask(),
                sThreadViolationListener.get(),
                sThreadViolationExecutor.get());
    }

    /** @hide */
    public static @ThreadPolicyMask int allowThreadDiskReadsMask() {
        int oldPolicyMask = getThreadPolicyMask();
        int newPolicyMask = oldPolicyMask & ~(DETECT_THREAD_DISK_READ);
        if (newPolicyMask != oldPolicyMask) {
            setThreadPolicyMask(newPolicyMask);
        }
        return oldPolicyMask;
    }

    /** @hide */
    public static ThreadPolicy allowThreadViolations() {
        ThreadPolicy oldPolicy = getThreadPolicy();
        setThreadPolicyMask(0);
        return oldPolicy;
    }

    /** @hide */
    public static VmPolicy allowVmViolations() {
        VmPolicy oldPolicy = getVmPolicy();
        sVmPolicy = VmPolicy.LAX;
        return oldPolicy;
    }

    /**
     * Determine if the given app is "bundled" as part of the system image. These bundled apps are
     * developed in lock-step with the OS, and they aren't updated outside of an OTA, so we want to
     * chase any {@link StrictMode} regressions by enabling detection when running on {@link
     * Build#IS_USERDEBUG} or {@link Build#IS_ENG} builds.
     *
     * <p>Unbundled apps included in the system image are expected to detect and triage their own
     * {@link StrictMode} issues separate from the OS release process, which is why we don't enable
     * them here.
     *
     * @hide
     */
    public static boolean isBundledSystemApp(ApplicationInfo ai) {
        if (ai == null || ai.packageName == null) {
            // Probably system server
            return true;
        } else if (ai.isSystemApp()) {
            // Ignore unbundled apps living in the wrong namespace
            if (ai.packageName.equals("com.android.vending")
                    || ai.packageName.equals("com.android.chrome")) {
                return false;
            }

            // Ignore bundled apps that are way too spammy
            // STOPSHIP: burn this list down to zero
            if (ai.packageName.equals("com.android.phone")) {
                return false;
            }

            if (ai.packageName.equals("android")
                    || ai.packageName.startsWith("android.")
                    || ai.packageName.startsWith("com.android.")) {
                return true;
            }
        }
        return false;
    }

    /**
     * Initialize default {@link ThreadPolicy} for the current thread.
     *
     * @hide
     */
    public static void initThreadDefaults(ApplicationInfo ai) {
        final ThreadPolicy.Builder builder = new ThreadPolicy.Builder();
        final int targetSdkVersion =
                (ai != null) ? ai.targetSdkVersion : Build.VERSION_CODES.CUR_DEVELOPMENT;

        // Starting in HC, we don't allow network usage on the main thread
        if (targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
            builder.detectNetwork();
            builder.penaltyDeathOnNetwork();
        }

        if (Build.IS_USER || DISABLE || SystemProperties.getBoolean(DISABLE_PROPERTY, false)) {
            // Detect nothing extra
        } else if (Build.IS_USERDEBUG) {
            // Detect everything in bundled apps
            if (isBundledSystemApp(ai)) {
                builder.detectAll();
                builder.penaltyDropBox();
                if (SystemProperties.getBoolean(VISUAL_PROPERTY, false)) {
                    builder.penaltyFlashScreen();
                }
            }
        } else if (Build.IS_ENG) {
            // Detect everything in bundled apps
            if (isBundledSystemApp(ai)) {
                builder.detectAll();
                builder.penaltyDropBox();
                builder.penaltyLog();
                builder.penaltyFlashScreen();
            }
        }

        setThreadPolicy(builder.build());
    }

    /**
     * Initialize default {@link VmPolicy} for the current VM.
     *
     * @hide
     */
    public static void initVmDefaults(ApplicationInfo ai) {
        final VmPolicy.Builder builder = new VmPolicy.Builder();
        final int targetSdkVersion =
                (ai != null) ? ai.targetSdkVersion : Build.VERSION_CODES.CUR_DEVELOPMENT;

        // Starting in N, we don't allow file:// Uri exposure
        if (targetSdkVersion >= Build.VERSION_CODES.N) {
            builder.detectFileUriExposure();
            builder.penaltyDeathOnFileUriExposure();
        }

        if (Build.IS_USER || DISABLE || SystemProperties.getBoolean(DISABLE_PROPERTY, false)) {
            // Detect nothing extra
        } else if (Build.IS_USERDEBUG) {
            // Detect everything in bundled apps (except activity leaks, which
            // are expensive to track)
            if (isBundledSystemApp(ai)) {
                builder.detectAll();
                builder.permitActivityLeaks();
                builder.penaltyDropBox();
            }
        } else if (Build.IS_ENG) {
            // Detect everything in bundled apps
            if (isBundledSystemApp(ai)) {
                builder.detectAll();
                builder.penaltyDropBox();
                builder.penaltyLog();
            }
        }

        setVmPolicy(builder.build());
    }

    /**
     * Used by the framework to make file usage a fatal error.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public static void enableDeathOnFileUriExposure() {
        sVmPolicy =
                new VmPolicy(
                        sVmPolicy.mask
                                | DETECT_VM_FILE_URI_EXPOSURE
                                | PENALTY_DEATH_ON_FILE_URI_EXPOSURE,
                        sVmPolicy.classInstanceLimit,
                        sVmPolicy.mListener,
                        sVmPolicy.mCallbackExecutor);
    }

    /**
     * Used by lame internal apps that haven't done the hard work to get themselves off file:// Uris
     * yet.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public static void disableDeathOnFileUriExposure() {
        sVmPolicy =
                new VmPolicy(
                        sVmPolicy.mask
                                & ~(DETECT_VM_FILE_URI_EXPOSURE
                                        | PENALTY_DEATH_ON_FILE_URI_EXPOSURE),
                        sVmPolicy.classInstanceLimit,
                        sVmPolicy.mListener,
                        sVmPolicy.mCallbackExecutor);
    }

    @UnsupportedAppUsage
    private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed =
            new ThreadLocal<ArrayList<ViolationInfo>>() {
                @Override
                protected ArrayList<ViolationInfo> initialValue() {
                    return new ArrayList<ViolationInfo>();
                }
            };

    // Note: only access this once verifying the thread has a Looper.
    private static final ThreadLocal<Handler> THREAD_HANDLER =
            new ThreadLocal<Handler>() {
                @Override
                protected Handler initialValue() {
                    return new Handler();
                }
            };

    private static final ThreadLocal<AndroidBlockGuardPolicy> THREAD_ANDROID_POLICY =
            new ThreadLocal<AndroidBlockGuardPolicy>() {
                @Override
                protected AndroidBlockGuardPolicy initialValue() {
                    return new AndroidBlockGuardPolicy(0);
                }
            };

    private static boolean tooManyViolationsThisLoop() {
        return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP;
    }

    private static class AndroidBlockGuardPolicy implements BlockGuard.Policy {
        private @ThreadPolicyMask int mThreadPolicyMask;

        // Map from violation stacktrace hashcode -> uptimeMillis of
        // last violation.  No locking needed, as this is only
        // accessed by the same thread.
        private ArrayMap<Integer, Long> mLastViolationTime;

        public AndroidBlockGuardPolicy(@ThreadPolicyMask int threadPolicyMask) {
            mThreadPolicyMask = threadPolicyMask;
        }

        @Override
        public String toString() {
            return "AndroidBlockGuardPolicy; mPolicyMask=" + mThreadPolicyMask;
        }

        // Part of BlockGuard.Policy interface:
        public int getPolicyMask() {
            return mThreadPolicyMask;
        }

        // Part of BlockGuard.Policy interface:
        public void onWriteToDisk() {
            if ((mThreadPolicyMask & DETECT_THREAD_DISK_WRITE) == 0) {
                return;
            }
            if (tooManyViolationsThisLoop()) {
                return;
            }
            startHandlingViolationException(new DiskWriteViolation());
        }

        // Not part of BlockGuard.Policy; just part of StrictMode:
        void onCustomSlowCall(String name) {
            if ((mThreadPolicyMask & DETECT_THREAD_CUSTOM) == 0) {
                return;
            }
            if (tooManyViolationsThisLoop()) {
                return;
            }
            startHandlingViolationException(new CustomViolation(name));
        }

        // Not part of BlockGuard.Policy; just part of StrictMode:
        void onResourceMismatch(Object tag) {
            if ((mThreadPolicyMask & DETECT_THREAD_RESOURCE_MISMATCH) == 0) {
                return;
            }
            if (tooManyViolationsThisLoop()) {
                return;
            }
            startHandlingViolationException(new ResourceMismatchViolation(tag));
        }

        // Not part of BlockGuard.Policy; just part of StrictMode:
        public void onUnbufferedIO() {
            if ((mThreadPolicyMask & DETECT_THREAD_UNBUFFERED_IO) == 0) {
                return;
            }
            if (tooManyViolationsThisLoop()) {
                return;
            }
            startHandlingViolationException(new UnbufferedIoViolation());
        }

        // Part of BlockGuard.Policy interface:
        public void onReadFromDisk() {
            if ((mThreadPolicyMask & DETECT_THREAD_DISK_READ) == 0) {
                return;
            }
            if (tooManyViolationsThisLoop()) {
                return;
            }
            startHandlingViolationException(new DiskReadViolation());
        }

        // Part of BlockGuard.Policy interface:
        public void onNetwork() {
            if ((mThreadPolicyMask & DETECT_THREAD_NETWORK) == 0) {
                return;
            }
            if ((mThreadPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) {
                throw new NetworkOnMainThreadException();
            }
            if (tooManyViolationsThisLoop()) {
                return;
            }
            startHandlingViolationException(new NetworkViolation());
        }

        // Part of BlockGuard.Policy interface:
        public void onExplicitGc() {
            if ((mThreadPolicyMask & DETECT_THREAD_EXPLICIT_GC) == 0) {
                return;
            }
            if (tooManyViolationsThisLoop()) {
                return;
            }
            startHandlingViolationException(new ExplicitGcViolation());
        }

        public @ThreadPolicyMask int getThreadPolicyMask() {
            return mThreadPolicyMask;
        }

        public void setThreadPolicyMask(@ThreadPolicyMask int threadPolicyMask) {
            mThreadPolicyMask = threadPolicyMask;
        }

        // Start handling a violation that just started and hasn't
        // actually run yet (e.g. no disk write or network operation
        // has yet occurred).  This sees if we're in an event loop
        // thread and, if so, uses it to roughly measure how long the
        // violation took.
        void startHandlingViolationException(Violation e) {
            final int penaltyMask = (mThreadPolicyMask & PENALTY_ALL);
            final ViolationInfo info = new ViolationInfo(e, penaltyMask);
            info.violationUptimeMillis = SystemClock.uptimeMillis();
            handleViolationWithTimingAttempt(info);
        }

        // Attempts to fill in the provided ViolationInfo's
        // durationMillis field if this thread has a Looper we can use
        // to measure with.  We measure from the time of violation
        // until the time the looper is idle again (right before
        // the next epoll_wait)
        void handleViolationWithTimingAttempt(final ViolationInfo info) {
            Looper looper = Looper.myLooper();

            // Without a Looper, we're unable to time how long the
            // violation takes place.  This case should be rare, as
            // most users will care about timing violations that
            // happen on their main UI thread.  Note that this case is
            // also hit when a violation takes place in a Binder
            // thread, in "gather" mode.  In this case, the duration
            // of the violation is computed by the ultimate caller and
            // its Looper, if any.
            //
            // Also, as a special short-cut case when the only penalty
            // bit is death, we die immediately, rather than timing
            // the violation's duration.  This makes it convenient to
            // use in unit tests too, rather than waiting on a Looper.
            //
            // TODO: if in gather mode, ignore Looper.myLooper() and always
            //       go into this immediate mode?
            if (looper == null || (info.mPenaltyMask == PENALTY_DEATH)) {
                info.durationMillis = -1; // unknown (redundant, already set)
                onThreadPolicyViolation(info);
                return;
            }

            final ArrayList<ViolationInfo> records = violationsBeingTimed.get();
            if (records.size() >= MAX_OFFENSES_PER_LOOP) {
                // Not worth measuring.  Too many offenses in one loop.
                return;
            }
            records.add(info);
            if (records.size() > 1) {
                // There's already been a violation this loop, so we've already
                // registered an idle handler to process the list of violations
                // at the end of this Looper's loop.
                return;
            }

            final IWindowManager windowManager =
                    info.penaltyEnabled(PENALTY_FLASH) ? sWindowManager.get() : null;
            if (windowManager != null) {
                try {
                    windowManager.showStrictModeViolation(true);
                } catch (RemoteException unused) {
                }
            }

            // We post a runnable to a Handler (== delay 0 ms) for
            // measuring the end time of a violation instead of using
            // an IdleHandler (as was previously used) because an
            // IdleHandler may not run for quite a long period of time
            // if an ongoing animation is happening and continually
            // posting ASAP (0 ms) animation steps.  Animations are
            // throttled back to 60fps via SurfaceFlinger/View
            // invalidates, _not_ by posting frame updates every 16
            // milliseconds.
            THREAD_HANDLER
                    .get()
                    .postAtFrontOfQueue(
                            () -> {
                                long loopFinishTime = SystemClock.uptimeMillis();

                                // Note: we do this early, before handling the
                                // violation below, as handling the violation
                                // may include PENALTY_DEATH and we don't want
                                // to keep the red border on.
                                if (windowManager != null) {
                                    try {
                                        windowManager.showStrictModeViolation(false);
                                    } catch (RemoteException unused) {
                                    }
                                }

                                for (int n = 0; n < records.size(); ++n) {
                                    ViolationInfo v = records.get(n);
                                    v.violationNumThisLoop = n + 1;
                                    v.durationMillis =
                                            (int) (loopFinishTime - v.violationUptimeMillis);
                                    onThreadPolicyViolation(v);
                                }
                                records.clear();
                            });
        }

        // Note: It's possible (even quite likely) that the
        // thread-local policy mask has changed from the time the
        // violation fired and now (after the violating code ran) due
        // to people who push/pop temporary policy in regions of code,
        // hence the policy being passed around.
        void onThreadPolicyViolation(final ViolationInfo info) {
            if (LOG_V) Log.d(TAG, "onThreadPolicyViolation; penalty=" + info.mPenaltyMask);

            if (info.penaltyEnabled(PENALTY_GATHER)) {
                ArrayList<ViolationInfo> violations = gatheredViolations.get();
                if (violations == null) {
                    violations = new ArrayList<>(1);
                    gatheredViolations.set(violations);
                }
                for (ViolationInfo previous : violations) {
                    if (info.getStackTrace().equals(previous.getStackTrace())) {
                        // Duplicate. Don't log.
                        return;
                    }
                }
                violations.add(info);
                return;
            }

            // Not perfect, but fast and good enough for dup suppression.
            Integer crashFingerprint = info.hashCode();
            long lastViolationTime = 0;
            if (mLastViolationTime != null) {
                Long vtime = mLastViolationTime.get(crashFingerprint);
                if (vtime != null) {
                    lastViolationTime = vtime;
                }
            } else {
                mLastViolationTime = new ArrayMap<>(1);
            }
            long now = SystemClock.uptimeMillis();
            mLastViolationTime.put(crashFingerprint, now);
            long timeSinceLastViolationMillis =
                    lastViolationTime == 0 ? Long.MAX_VALUE : (now - lastViolationTime);

            if (info.penaltyEnabled(PENALTY_LOG)
                    && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
                sLogger.log(info);
            }

            final Violation violation = info.mViolation;

            // Penalties that ActivityManager should execute on our behalf.
            int penaltyMask = 0;

            if (info.penaltyEnabled(PENALTY_DIALOG)
                    && timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) {
                penaltyMask |= PENALTY_DIALOG;
            }

            if (info.penaltyEnabled(PENALTY_DROPBOX) && lastViolationTime == 0) {
                penaltyMask |= PENALTY_DROPBOX;
            }

            if (penaltyMask != 0) {
                final boolean justDropBox = (info.mPenaltyMask == PENALTY_DROPBOX);
                if (justDropBox) {
                    // If all we're going to ask the activity manager
                    // to do is dropbox it (the common case during
                    // platform development), we can avoid doing this
                    // call synchronously which Binder data suggests
                    // isn't always super fast, despite the implementation
                    // in the ActivityManager trying to be mostly async.
                    dropboxViolationAsync(penaltyMask, info);
                } else {
                    handleApplicationStrictModeViolation(penaltyMask, info);
                }
            }

            if (info.penaltyEnabled(PENALTY_DEATH)) {
                throw new RuntimeException("StrictMode ThreadPolicy violation", violation);
            }

            // penaltyDeath will cause penaltyCallback to no-op since we cannot guarantee the
            // executor finishes before crashing.
            final OnThreadViolationListener listener = sThreadViolationListener.get();
            final Executor executor = sThreadViolationExecutor.get();
            if (listener != null && executor != null) {
                try {
                    executor.execute(
                            () -> {
                                // Lift violated policy to prevent infinite recursion.
                                ThreadPolicy oldPolicy = StrictMode.allowThreadViolations();
                                try {
                                    listener.onThreadViolation(violation);
                                } finally {
                                    StrictMode.setThreadPolicy(oldPolicy);
                                }
                            });
                } catch (RejectedExecutionException e) {
                    Log.e(TAG, "ThreadPolicy penaltyCallback failed", e);
                }
            }
        }
    }

    private static final BlockGuard.VmPolicy VM_ANDROID_POLICY = new BlockGuard.VmPolicy() {
        @Override
        public void onPathAccess(String path) {
            if (path == null) return;

            // NOTE: keep credential-protected paths in sync with Environment.java
            if (path.startsWith("/data/user/")
                    || path.startsWith("/data/media/")
                    || path.startsWith("/data/system_ce/")
                    || path.startsWith("/data/misc_ce/")
                    || path.startsWith("/data/vendor_ce/")
                    || path.startsWith("/storage/emulated/")) {
                final int second = path.indexOf('/', 1);
                final int third = path.indexOf('/', second + 1);
                final int fourth = path.indexOf('/', third + 1);
                if (fourth == -1) return;

                try {
                    final int userId = Integer.parseInt(path.substring(third + 1, fourth));
                    onCredentialProtectedPathAccess(path, userId);
                } catch (NumberFormatException ignored) {
                }
            } else if (path.startsWith("/data/data/")) {
                onCredentialProtectedPathAccess(path, UserHandle.USER_SYSTEM);
            }
        }
    };

    /**
     * In the common case, as set by conditionallyEnableDebugLogging, we're just dropboxing any
     * violations but not showing a dialog, not loggging, and not killing the process. In these
     * cases we don't need to do a synchronous call to the ActivityManager. This is used by both
     * per-thread and vm-wide violations when applicable.
     */
    private static void dropboxViolationAsync(
            final int penaltyMask, final ViolationInfo info) {
        int outstanding = sDropboxCallsInFlight.incrementAndGet();
        if (outstanding > 20) {
            // What's going on?  Let's not make make the situation
            // worse and just not log.
            sDropboxCallsInFlight.decrementAndGet();
            return;
        }

        if (LOG_V) Log.d(TAG, "Dropboxing async; in-flight=" + outstanding);

        BackgroundThread.getHandler().post(() -> {
            handleApplicationStrictModeViolation(penaltyMask, info);
            int outstandingInner = sDropboxCallsInFlight.decrementAndGet();
            if (LOG_V) Log.d(TAG, "Dropbox complete; in-flight=" + outstandingInner);
        });
    }

    private static void handleApplicationStrictModeViolation(int penaltyMask,
            ViolationInfo info) {
        final int oldMask = getThreadPolicyMask();
        try {
            // First, remove any policy before we call into the Activity Manager,
            // otherwise we'll infinite recurse as we try to log policy violations
            // to disk, thus violating policy, thus requiring logging, etc...
            // We restore the current policy below, in the finally block.
            setThreadPolicyMask(0);

            IActivityManager am = ActivityManager.getService();
            if (am == null) {
                Log.w(TAG, "No activity manager; failed to Dropbox violation.");
            } else {
                am.handleApplicationStrictModeViolation(
                        RuntimeInit.getApplicationObject(), penaltyMask, info);
            }
        } catch (RemoteException e) {
            if (e instanceof DeadObjectException) {
                // System process is dead; ignore
            } else {
                Log.e(TAG, "RemoteException handling StrictMode violation", e);
            }
        } finally {
            setThreadPolicyMask(oldMask);
        }
    }

    private static class AndroidCloseGuardReporter implements CloseGuard.Reporter {
        public void report(String message, Throwable allocationSite) {
            onVmPolicyViolation(new LeakedClosableViolation(message, allocationSite));
        }
    }

    /** Called from Parcel.writeNoException() */
    /* package */ static boolean hasGatheredViolations() {
        return gatheredViolations.get() != null;
    }

    /**
     * Called from Parcel.writeException(), so we drop this memory and don't incorrectly attribute
     * it to the wrong caller on the next Binder call on this thread.
     */
    /* package */ static void clearGatheredViolations() {
        gatheredViolations.set(null);
    }

    /** @hide */
    @UnsupportedAppUsage
    @TestApi
    public static void conditionallyCheckInstanceCounts() {
        VmPolicy policy = getVmPolicy();
        int policySize = policy.classInstanceLimit.size();
        if (policySize == 0) {
            return;
        }

        System.gc();
        System.runFinalization();
        System.gc();

        // Note: classInstanceLimit is immutable, so this is lock-free
        // Create the classes array.
        Class[] classes = policy.classInstanceLimit.keySet().toArray(new Class[policySize]);
        long[] instanceCounts = VMDebug.countInstancesOfClasses(classes, false);
        for (int i = 0; i < classes.length; ++i) {
            Class klass = classes[i];
            int limit = policy.classInstanceLimit.get(klass);
            long instances = instanceCounts[i];
            if (instances > limit) {
                onVmPolicyViolation(new InstanceCountViolation(klass, instances, limit));
            }
        }
    }

    private static long sLastInstanceCountCheckMillis = 0;
    private static boolean sIsIdlerRegistered = false; // guarded by StrictMode.class
    private static final MessageQueue.IdleHandler sProcessIdleHandler =
            new MessageQueue.IdleHandler() {
                public boolean queueIdle() {
                    long now = SystemClock.uptimeMillis();
                    if (now - sLastInstanceCountCheckMillis > 30 * 1000) {
                        sLastInstanceCountCheckMillis = now;
                        conditionallyCheckInstanceCounts();
                    }
                    return true;
                }
            };

    /**
     * Sets the policy for what actions in the VM process (on any thread) should be detected, as
     * well as the penalty if such actions occur.
     *
     * @param policy the policy to put into place
     */
    public static void setVmPolicy(final VmPolicy policy) {
        synchronized (StrictMode.class) {
            sVmPolicy = policy;
            setCloseGuardEnabled(vmClosableObjectLeaksEnabled());

            Looper looper = Looper.getMainLooper();
            if (looper != null) {
                MessageQueue mq = looper.mQueue;
                if (policy.classInstanceLimit.size() == 0
                        || (sVmPolicy.mask & PENALTY_ALL) == 0) {
                    mq.removeIdleHandler(sProcessIdleHandler);
                    sIsIdlerRegistered = false;
                } else if (!sIsIdlerRegistered) {
                    mq.addIdleHandler(sProcessIdleHandler);
                    sIsIdlerRegistered = true;
                }
            }

            int networkPolicy = NETWORK_POLICY_ACCEPT;
            if ((sVmPolicy.mask & DETECT_VM_CLEARTEXT_NETWORK) != 0) {
                if ((sVmPolicy.mask & PENALTY_DEATH) != 0
                        || (sVmPolicy.mask & PENALTY_DEATH_ON_CLEARTEXT_NETWORK) != 0) {
                    networkPolicy = NETWORK_POLICY_REJECT;
                } else {
                    networkPolicy = NETWORK_POLICY_LOG;
                }
            }

            final INetworkManagementService netd =
                    INetworkManagementService.Stub.asInterface(
                            ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
            if (netd != null) {
                try {
                    netd.setUidCleartextNetworkPolicy(android.os.Process.myUid(), networkPolicy);
                } catch (RemoteException ignored) {
                }
            } else if (networkPolicy != NETWORK_POLICY_ACCEPT) {
                Log.w(TAG, "Dropping requested network policy due to missing service!");
            }


            if ((sVmPolicy.mask & DETECT_VM_NON_SDK_API_USAGE) != 0) {
                VMRuntime.setNonSdkApiUsageConsumer(sNonSdkApiUsageConsumer);
                VMRuntime.setDedupeHiddenApiWarnings(false);
            } else {
                VMRuntime.setNonSdkApiUsageConsumer(null);
                VMRuntime.setDedupeHiddenApiWarnings(true);
            }

            setBlockGuardVmPolicy(sVmPolicy.mask);
        }
    }

    /** Gets the current VM policy. */
    public static VmPolicy getVmPolicy() {
        synchronized (StrictMode.class) {
            return sVmPolicy;
        }
    }

    /**
     * Enable the recommended StrictMode defaults, with violations just being logged.
     *
     * <p>This catches disk and network access on the main thread, as well as leaked SQLite cursors
     * and unclosed resources. This is simply a wrapper around {@link #setVmPolicy} and {@link
     * #setThreadPolicy}.
     */
    public static void enableDefaults() {
        setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
        setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
    }

    /** @hide */
    public static boolean vmSqliteObjectLeaksEnabled() {
        return (sVmPolicy.mask & DETECT_VM_CURSOR_LEAKS) != 0;
    }

    /** @hide */
    public static boolean vmClosableObjectLeaksEnabled() {
        return (sVmPolicy.mask & DETECT_VM_CLOSABLE_LEAKS) != 0;
    }

    /** @hide */
    public static boolean vmRegistrationLeaksEnabled() {
        return (sVmPolicy.mask & DETECT_VM_REGISTRATION_LEAKS) != 0;
    }

    /** @hide */
    public static boolean vmFileUriExposureEnabled() {
        return (sVmPolicy.mask & DETECT_VM_FILE_URI_EXPOSURE) != 0;
    }

    /** @hide */
    public static boolean vmCleartextNetworkEnabled() {
        return (sVmPolicy.mask & DETECT_VM_CLEARTEXT_NETWORK) != 0;
    }

    /** @hide */
    public static boolean vmContentUriWithoutPermissionEnabled() {
        return (sVmPolicy.mask & DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION) != 0;
    }

    /** @hide */
    public static boolean vmUntaggedSocketEnabled() {
        return (sVmPolicy.mask & DETECT_VM_UNTAGGED_SOCKET) != 0;
    }

    /** @hide */
    public static boolean vmImplicitDirectBootEnabled() {
        return (sVmPolicy.mask & DETECT_VM_IMPLICIT_DIRECT_BOOT) != 0;
    }

    /** @hide */
    public static boolean vmCredentialProtectedWhileLockedEnabled() {
        return (sVmPolicy.mask & DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED) != 0;
    }

    /** @hide */
    public static boolean vmIncorrectContextUseEnabled() {
        return (sVmPolicy.mask & DETECT_VM_INCORRECT_CONTEXT_USE) != 0;
    }

    /** @hide */
    public static void onSqliteObjectLeaked(String message, Throwable originStack) {
        onVmPolicyViolation(new SqliteObjectLeakedViolation(message, originStack));
    }

    /** @hide */
    @UnsupportedAppUsage
    public static void onWebViewMethodCalledOnWrongThread(Throwable originStack) {
        onVmPolicyViolation(new WebViewMethodCalledOnWrongThreadViolation(originStack));
    }

    /** @hide */
    public static void onIntentReceiverLeaked(Throwable originStack) {
        onVmPolicyViolation(new IntentReceiverLeakedViolation(originStack));
    }

    /** @hide */
    public static void onServiceConnectionLeaked(Throwable originStack) {
        onVmPolicyViolation(new ServiceConnectionLeakedViolation(originStack));
    }

    /** @hide */
    public static void onFileUriExposed(Uri uri, String location) {
        final String message = uri + " exposed beyond app through " + location;
        if ((sVmPolicy.mask & PENALTY_DEATH_ON_FILE_URI_EXPOSURE) != 0) {
            throw new FileUriExposedException(message);
        } else {
            onVmPolicyViolation(new FileUriExposedViolation(message));
        }
    }

    /** @hide */
    public static void onContentUriWithoutPermission(Uri uri, String location) {
        onVmPolicyViolation(new ContentUriWithoutPermissionViolation(uri, location));
    }

    /** @hide */
    public static void onCleartextNetworkDetected(byte[] firstPacket) {
        byte[] rawAddr = null;
        if (firstPacket != null) {
            if (firstPacket.length >= 20 && (firstPacket[0] & 0xf0) == 0x40) {
                // IPv4
                rawAddr = new byte[4];
                System.arraycopy(firstPacket, 16, rawAddr, 0, 4);
            } else if (firstPacket.length >= 40 && (firstPacket[0] & 0xf0) == 0x60) {
                // IPv6
                rawAddr = new byte[16];
                System.arraycopy(firstPacket, 24, rawAddr, 0, 16);
            }
        }

        final int uid = android.os.Process.myUid();
        String msg = "Detected cleartext network traffic from UID " + uid;
        if (rawAddr != null) {
            try {
                msg += " to " + InetAddress.getByAddress(rawAddr);
            } catch (UnknownHostException ignored) {
            }
        }
        msg += HexDump.dumpHexString(firstPacket).trim() + " ";
        final boolean forceDeath = (sVmPolicy.mask & PENALTY_DEATH_ON_CLEARTEXT_NETWORK) != 0;
        onVmPolicyViolation(new CleartextNetworkViolation(msg), forceDeath);
    }

    /** @hide */
    public static void onUntaggedSocket() {
        onVmPolicyViolation(new UntaggedSocketViolation());
    }

    /** @hide */
    public static void onImplicitDirectBoot() {
        onVmPolicyViolation(new ImplicitDirectBootViolation());
    }

    /** @hide */
    public static void onIncorrectContextUsed(String message, Throwable originStack) {
        onVmPolicyViolation(new IncorrectContextUseViolation(message, originStack));
    }

    /** Assume locked until we hear otherwise */
    private static volatile boolean sUserKeyUnlocked = false;

    private static boolean isUserKeyUnlocked(int userId) {
        final IStorageManager storage = IStorageManager.Stub
                .asInterface(ServiceManager.getService("mount"));
        if (storage != null) {
            try {
                return storage.isUserKeyUnlocked(userId);
            } catch (RemoteException ignored) {
            }
        }
        return false;
    }

    /** @hide */
    private static void onCredentialProtectedPathAccess(String path, int userId) {
        // We can cache the unlocked state for the userId we're running as,
        // since any relocking of that user will always result in our
        // process being killed to release any CE FDs we're holding onto.
        if (userId == UserHandle.myUserId()) {
            if (sUserKeyUnlocked) {
                return;
            } else if (isUserKeyUnlocked(userId)) {
                sUserKeyUnlocked = true;
                return;
            }
        } else if (isUserKeyUnlocked(userId)) {
            return;
        }

        onVmPolicyViolation(new CredentialProtectedWhileLockedViolation(
                "Accessed credential protected path " + path + " while user " + userId
                        + " was locked"));
    }

    // Map from VM violation fingerprint to uptime millis.
    @UnsupportedAppUsage
    private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<>();

    /** @hide */
    public static void onVmPolicyViolation(Violation originStack) {
        onVmPolicyViolation(originStack, false);
    }

    /** @hide */
    public static void onVmPolicyViolation(Violation violation, boolean forceDeath) {
        final boolean penaltyDropbox = (sVmPolicy.mask & PENALTY_DROPBOX) != 0;
        final boolean penaltyDeath = ((sVmPolicy.mask & PENALTY_DEATH) != 0) || forceDeath;
        final boolean penaltyLog = (sVmPolicy.mask & PENALTY_LOG) != 0;

        final int penaltyMask = (sVmPolicy.mask & PENALTY_ALL);
        final ViolationInfo info = new ViolationInfo(violation, penaltyMask);

        // Erase stuff not relevant for process-wide violations
        info.numAnimationsRunning = 0;
        info.tags = null;
        info.broadcastIntentAction = null;

        final Integer fingerprint = info.hashCode();
        final long now = SystemClock.uptimeMillis();
        long lastViolationTime;
        long timeSinceLastViolationMillis = Long.MAX_VALUE;
        synchronized (sLastVmViolationTime) {
            if (sLastVmViolationTime.containsKey(fingerprint)) {
                lastViolationTime = sLastVmViolationTime.get(fingerprint);
                timeSinceLastViolationMillis = now - lastViolationTime;
            }
            if (timeSinceLastViolationMillis > MIN_VM_INTERVAL_MS) {
                sLastVmViolationTime.put(fingerprint, now);
            }
        }
        if (timeSinceLastViolationMillis <= MIN_VM_INTERVAL_MS) {
            // Rate limit all penalties.
            return;
        }

        if (penaltyLog && sLogger != null && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
            sLogger.log(info);
        }

        if (penaltyDropbox) {
            if (penaltyDeath) {
                handleApplicationStrictModeViolation(PENALTY_DROPBOX, info);
            } else {
                // Common case for userdebug/eng builds.  If no death and
                // just dropboxing, we can do the ActivityManager call
                // asynchronously.
                dropboxViolationAsync(PENALTY_DROPBOX, info);
            }
        }

        if (penaltyDeath) {
            System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down.");
            Process.killProcess(Process.myPid());
            System.exit(10);
        }

        // If penaltyDeath, we can't guarantee this callback finishes before the process dies for
        // all executors. penaltyDeath supersedes penaltyCallback.
        if (sVmPolicy.mListener != null && sVmPolicy.mCallbackExecutor != null) {
            final OnVmViolationListener listener = sVmPolicy.mListener;
            try {
                sVmPolicy.mCallbackExecutor.execute(
                        () -> {
                            // Lift violated policy to prevent infinite recursion.
                            VmPolicy oldPolicy = allowVmViolations();
                            try {
                                listener.onVmViolation(violation);
                            } finally {
                                setVmPolicy(oldPolicy);
                            }
                        });
            } catch (RejectedExecutionException e) {
                Log.e(TAG, "VmPolicy penaltyCallback failed", e);
            }
        }
    }

    /** Called from Parcel.writeNoException() */
    /* package */ static void writeGatheredViolationsToParcel(Parcel p) {
        ArrayList<ViolationInfo> violations = gatheredViolations.get();
        if (violations == null) {
            p.writeInt(0);
        } else {
            // To avoid taking up too much transaction space, only include
            // details for the first 3 violations. Deep inside, CrashInfo
            // will truncate each stack trace to ~20kB.
            final int size = Math.min(violations.size(), 3);
            p.writeInt(size);
            for (int i = 0; i < size; i++) {
                violations.get(i).writeToParcel(p, 0);
            }
        }
        gatheredViolations.set(null);
    }

    /**
     * Called from Parcel.readException() when the exception is EX_STRICT_MODE_VIOLATIONS, we here
     * read back all the encoded violations.
     */
    /* package */ static void readAndHandleBinderCallViolations(Parcel p) {
        Throwable localCallSite = new Throwable();
        final int policyMask = getThreadPolicyMask();
        final boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0;

        final int size = p.readInt();
        for (int i = 0; i < size; i++) {
            final ViolationInfo info = new ViolationInfo(p, !currentlyGathering);
            info.addLocalStack(localCallSite);
            BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
            if (policy instanceof AndroidBlockGuardPolicy) {
                ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info);
            }
        }
    }

    /**
     * Called from android_util_Binder.cpp's android_os_Parcel_enforceInterface when an incoming
     * Binder call requires changing the StrictMode policy mask. The role of this function is to ask
     * Binder for its current (native) thread-local policy value and synchronize it to libcore's
     * (Java) thread-local policy value.
     */
    @UnsupportedAppUsage
    private static void onBinderStrictModePolicyChange(@ThreadPolicyMask int newPolicy) {
        setBlockGuardPolicy(newPolicy);
    }

    /**
     * A tracked, critical time span. (e.g. during an animation.)
     *
     * <p>The object itself is a linked list node, to avoid any allocations during rapid span
     * entries and exits.
     *
     * @hide
     */
    public static class Span {
        private String mName;
        private long mCreateMillis;
        private Span mNext;
        private Span mPrev; // not used when in freeList, only active
        private final ThreadSpanState mContainerState;

        Span(ThreadSpanState threadState) {
            mContainerState = threadState;
        }

        // Empty constructor for the NO_OP_SPAN
        protected Span() {
            mContainerState = null;
        }

        /**
         * To be called when the critical span is complete (i.e. the animation is done animating).
         * This can be called on any thread (even a different one from where the animation was
         * taking place), but that's only a defensive implementation measure. It really makes no
         * sense for you to call this on thread other than that where you created it.
         *
         * @hide
         */
        @UnsupportedAppUsage
        public void finish() {
            ThreadSpanState state = mContainerState;
            synchronized (state) {
                if (mName == null) {
                    // Duplicate finish call.  Ignore.
                    return;
                }

                // Remove ourselves from the active list.
                if (mPrev != null) {
                    mPrev.mNext = mNext;
                }
                if (mNext != null) {
                    mNext.mPrev = mPrev;
                }
                if (state.mActiveHead == this) {
                    state.mActiveHead = mNext;
                }

                state.mActiveSize--;

                if (LOG_V) Log.d(TAG, "Span finished=" + mName + "; size=" + state.mActiveSize);

                this.mCreateMillis = -1;
                this.mName = null;
                this.mPrev = null;
                this.mNext = null;

                // Add ourselves to the freeList, if it's not already
                // too big.
                if (state.mFreeListSize < 5) {
                    this.mNext = state.mFreeListHead;
                    state.mFreeListHead = this;
                    state.mFreeListSize++;
                }
            }
        }
    }

    // The no-op span that's used in user builds.
    private static final Span NO_OP_SPAN =
            new Span() {
                public void finish() {
                    // Do nothing.
                }
            };

    /**
     * Linked lists of active spans and a freelist.
     *
     * <p>Locking notes: there's one of these structures per thread and all members of this
     * structure (as well as the Span nodes under it) are guarded by the ThreadSpanState object
     * instance. While in theory there'd be no locking required because it's all local per-thread,
     * the finish() method above is defensive against people calling it on a different thread from
     * where they created the Span, hence the locking.
     */
    private static class ThreadSpanState {
        public Span mActiveHead; // doubly-linked list.
        public int mActiveSize;
        public Span mFreeListHead; // singly-linked list.  only changes at head.
        public int mFreeListSize;
    }

    private static final ThreadLocal<ThreadSpanState> sThisThreadSpanState =
            new ThreadLocal<ThreadSpanState>() {
                @Override
                protected ThreadSpanState initialValue() {
                    return new ThreadSpanState();
                }
            };

    @UnsupportedAppUsage
    private static Singleton<IWindowManager> sWindowManager =
            new Singleton<IWindowManager>() {
                protected IWindowManager create() {
                    return IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
                }
            };

    /**
     * Enter a named critical span (e.g. an animation)
     *
     * <p>The name is an arbitary label (or tag) that will be applied to any strictmode violation
     * that happens while this span is active. You must call finish() on the span when done.
     *
     * <p>This will never return null, but on devices without debugging enabled, this may return a
     * dummy object on which the finish() method is a no-op.
     *
     * <p>TODO: add CloseGuard to this, verifying callers call finish.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public static Span enterCriticalSpan(String name) {
        if (Build.IS_USER) {
            return NO_OP_SPAN;
        }
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("name must be non-null and non-empty");
        }
        ThreadSpanState state = sThisThreadSpanState.get();
        Span span = null;
        synchronized (state) {
            if (state.mFreeListHead != null) {
                span = state.mFreeListHead;
                state.mFreeListHead = span.mNext;
                state.mFreeListSize--;
            } else {
                // Shouldn't have to do this often.
                span = new Span(state);
            }
            span.mName = name;
            span.mCreateMillis = SystemClock.uptimeMillis();
            span.mNext = state.mActiveHead;
            span.mPrev = null;
            state.mActiveHead = span;
            state.mActiveSize++;
            if (span.mNext != null) {
                span.mNext.mPrev = span;
            }
            if (LOG_V) Log.d(TAG, "Span enter=" + name + "; size=" + state.mActiveSize);
        }
        return span;
    }

    /**
     * For code to note that it's slow. This is a no-op unless the current thread's {@link
     * android.os.StrictMode.ThreadPolicy} has {@link
     * android.os.StrictMode.ThreadPolicy.Builder#detectCustomSlowCalls} enabled.
     *
     * @param name a short string for the exception stack trace that's built if when this fires.
     */
    public static void noteSlowCall(String name) {
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            // StrictMode not enabled.
            return;
        }
        ((AndroidBlockGuardPolicy) policy).onCustomSlowCall(name);
    }

    /**
     * For code to note that a resource was obtained using a type other than its defined type. This
     * is a no-op unless the current thread's {@link android.os.StrictMode.ThreadPolicy} has {@link
     * android.os.StrictMode.ThreadPolicy.Builder#detectResourceMismatches()} enabled.
     *
     * @param tag an object for the exception stack trace that's built if when this fires.
     * @hide
     */
    public static void noteResourceMismatch(Object tag) {
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            // StrictMode not enabled.
            return;
        }
        ((AndroidBlockGuardPolicy) policy).onResourceMismatch(tag);
    }

    /** @hide */
    public static void noteUnbufferedIO() {
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            // StrictMode not enabled.
            return;
        }
        policy.onUnbufferedIO();
    }

    /** @hide */
    public static void noteDiskRead() {
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            // StrictMode not enabled.
            return;
        }
        policy.onReadFromDisk();
    }

    /** @hide */
    public static void noteDiskWrite() {
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            // StrictMode not enabled.
            return;
        }
        policy.onWriteToDisk();
    }

    @GuardedBy("StrictMode.class")
    private static final HashMap<Class, Integer> sExpectedActivityInstanceCount = new HashMap<>();

    /**
     * Returns an object that is used to track instances of activites. The activity should store a
     * reference to the tracker object in one of its fields.
     *
     * @hide
     */
    public static Object trackActivity(Object instance) {
        return new InstanceTracker(instance);
    }

    /** @hide */
    @UnsupportedAppUsage
    public static void incrementExpectedActivityCount(Class klass) {
        if (klass == null) {
            return;
        }

        synchronized (StrictMode.class) {
            if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) {
                return;
            }

            // Use the instance count from InstanceTracker as initial value.
            Integer expected = sExpectedActivityInstanceCount.get(klass);
            Integer newExpected =
                    expected == null ? InstanceTracker.getInstanceCount(klass) + 1 : expected + 1;
            sExpectedActivityInstanceCount.put(klass, newExpected);
        }
    }

    /** @hide */
    public static void decrementExpectedActivityCount(Class klass) {
        if (klass == null) {
            return;
        }

        final int limit;
        synchronized (StrictMode.class) {
            if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) {
                return;
            }

            Integer expected = sExpectedActivityInstanceCount.get(klass);
            int newExpected = (expected == null || expected == 0) ? 0 : expected - 1;
            if (newExpected == 0) {
                sExpectedActivityInstanceCount.remove(klass);
            } else {
                sExpectedActivityInstanceCount.put(klass, newExpected);
            }

            // Note: adding 1 here to give some breathing room during
            // orientation changes.  (shouldn't be necessary, though?)
            limit = newExpected + 1;
        }

        // Quick check.
        int actual = InstanceTracker.getInstanceCount(klass);
        if (actual <= limit) {
            return;
        }

        // Do a GC and explicit count to double-check.
        // This is the work that we are trying to avoid by tracking the object instances
        // explicity.  Running an explicit GC can be expensive (80ms) and so can walking
        // the heap to count instance (30ms).  This extra work can make the system feel
        // noticeably less responsive during orientation changes when activities are
        // being restarted.  Granted, it is only a problem when StrictMode is enabled
        // but it is annoying.

        System.gc();
        System.runFinalization();
        System.gc();

        long instances = VMDebug.countInstancesOfClass(klass, false);
        if (instances > limit) {
            onVmPolicyViolation(new InstanceCountViolation(klass, instances, limit));
        }
    }

    /**
     * Parcelable that gets sent in Binder call headers back to callers to report violations that
     * happened during a cross-process call.
     *
     * @hide
     */
    @TestApi
    public static final class ViolationInfo implements Parcelable {
        /** Stack and violation details. */
        private final Violation mViolation;

        /** Path leading to a violation that occurred across binder. */
        private final Deque<StackTraceElement[]> mBinderStack = new ArrayDeque<>();

        /** Memoized stack trace of full violation. */
        @Nullable private String mStackTrace;

        /** The strict mode penalty mask at the time of violation. */
        private final int mPenaltyMask;

        /** The wall time duration of the violation, when known. -1 when not known. */
        public int durationMillis = -1;

        /** The number of animations currently running. */
        public int numAnimationsRunning = 0;

        /** List of tags from active Span instances during this violation, or null for none. */
        public String[] tags;

        /**
         * Which violation number this was (1-based) since the last Looper loop, from the
         * perspective of the root caller (if it crossed any processes via Binder calls). The value
         * is 0 if the root caller wasn't on a Looper thread.
         */
        public int violationNumThisLoop;

        /** The time (in terms of SystemClock.uptimeMillis()) that the violation occurred. */
        public long violationUptimeMillis;

        /**
         * The action of the Intent being broadcast to somebody's onReceive on this thread right
         * now, or null.
         */
        public String broadcastIntentAction;

        /** If this is a instance count violation, the number of instances in memory, else -1. */
        public long numInstances = -1;

        /** Create an instance of ViolationInfo initialized from an exception. */
        ViolationInfo(Violation tr, int penaltyMask) {
            this.mViolation = tr;
            this.mPenaltyMask = penaltyMask;
            violationUptimeMillis = SystemClock.uptimeMillis();
            this.numAnimationsRunning = ValueAnimator.getCurrentAnimationsCount();
            Intent broadcastIntent = ActivityThread.getIntentBeingBroadcast();
            if (broadcastIntent != null) {
                broadcastIntentAction = broadcastIntent.getAction();
            }
            ThreadSpanState state = sThisThreadSpanState.get();
            if (tr instanceof InstanceCountViolation) {
                this.numInstances = ((InstanceCountViolation) tr).getNumberOfInstances();
            }
            synchronized (state) {
                int spanActiveCount = state.mActiveSize;
                if (spanActiveCount > MAX_SPAN_TAGS) {
                    spanActiveCount = MAX_SPAN_TAGS;
                }
                if (spanActiveCount != 0) {
                    this.tags = new String[spanActiveCount];
                    Span iter = state.mActiveHead;
                    int index = 0;
                    while (iter != null && index < spanActiveCount) {
                        this.tags[index] = iter.mName;
                        index++;
                        iter = iter.mNext;
                    }
                }
            }
        }

        /**
         * Equivalent output to
         * {@link android.app.ApplicationErrorReport.CrashInfo#stackTrace}.
         */
        public String getStackTrace() {
            if (mStackTrace == null) {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new FastPrintWriter(sw, false, 256);
                mViolation.printStackTrace(pw);
                for (StackTraceElement[] traces : mBinderStack) {
                    pw.append("# via Binder call with stack:\n");
                    for (StackTraceElement traceElement : traces) {
                        pw.append("\tat ");
                        pw.append(traceElement.toString());
                        pw.append('\n');
                    }
                }
                pw.flush();
                pw.close();
                mStackTrace = sw.toString();
            }
            return mStackTrace;
        }

        public Class<? extends Violation> getViolationClass() {
            return mViolation.getClass();
        }

        /**
         * Optional message describing this violation.
         *
         * @hide
         */
        @TestApi
        public String getViolationDetails() {
            return mViolation.getMessage();
        }

        boolean penaltyEnabled(int p) {
            return (mPenaltyMask & p) != 0;
        }

        /**
         * Add a {@link Throwable} from the current process that caused the underlying violation. We
         * only preserve the stack trace elements.
         *
         * @hide
         */
        void addLocalStack(Throwable t) {
            mBinderStack.addFirst(t.getStackTrace());
        }

        @Override
        public int hashCode() {
            int result = 17;
            if (mViolation != null) {
                result = 37 * result + mViolation.hashCode();
            }
            if (numAnimationsRunning != 0) {
                result *= 37;
            }
            if (broadcastIntentAction != null) {
                result = 37 * result + broadcastIntentAction.hashCode();
            }
            if (tags != null) {
                for (String tag : tags) {
                    result = 37 * result + tag.hashCode();
                }
            }
            return result;
        }

        /** Create an instance of ViolationInfo initialized from a Parcel. */
        @UnsupportedAppUsage
        public ViolationInfo(Parcel in) {
            this(in, false);
        }

        /**
         * Create an instance of ViolationInfo initialized from a Parcel.
         *
         * @param unsetGatheringBit if true, the caller is the root caller and the gathering penalty
         *     should be removed.
         */
        public ViolationInfo(Parcel in, boolean unsetGatheringBit) {
            mViolation = (Violation) in.readSerializable();
            int binderStackSize = in.readInt();
            for (int i = 0; i < binderStackSize; i++) {
                StackTraceElement[] traceElements = new StackTraceElement[in.readInt()];
                for (int j = 0; j < traceElements.length; j++) {
                    StackTraceElement element =
                            new StackTraceElement(
                                    in.readString(),
                                    in.readString(),
                                    in.readString(),
                                    in.readInt());
                    traceElements[j] = element;
                }
                mBinderStack.add(traceElements);
            }
            int rawPenaltyMask = in.readInt();
            if (unsetGatheringBit) {
                mPenaltyMask = rawPenaltyMask & ~PENALTY_GATHER;
            } else {
                mPenaltyMask = rawPenaltyMask;
            }
            durationMillis = in.readInt();
            violationNumThisLoop = in.readInt();
            numAnimationsRunning = in.readInt();
            violationUptimeMillis = in.readLong();
            numInstances = in.readLong();
            broadcastIntentAction = in.readString();
            tags = in.readStringArray();
        }

        /** Save a ViolationInfo instance to a parcel. */
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeSerializable(mViolation);
            dest.writeInt(mBinderStack.size());
            for (StackTraceElement[] traceElements : mBinderStack) {
                dest.writeInt(traceElements.length);
                for (StackTraceElement element : traceElements) {
                    dest.writeString(element.getClassName());
                    dest.writeString(element.getMethodName());
                    dest.writeString(element.getFileName());
                    dest.writeInt(element.getLineNumber());
                }
            }
            int start = dest.dataPosition();
            dest.writeInt(mPenaltyMask);
            dest.writeInt(durationMillis);
            dest.writeInt(violationNumThisLoop);
            dest.writeInt(numAnimationsRunning);
            dest.writeLong(violationUptimeMillis);
            dest.writeLong(numInstances);
            dest.writeString(broadcastIntentAction);
            dest.writeStringArray(tags);
            int total = dest.dataPosition() - start;
            if (Binder.CHECK_PARCEL_SIZE && total > 10 * 1024) {
                Slog.d(
                        TAG,
                        "VIO: penalty="
                                + mPenaltyMask
                                + " dur="
                                + durationMillis
                                + " numLoop="
                                + violationNumThisLoop
                                + " anim="
                                + numAnimationsRunning
                                + " uptime="
                                + violationUptimeMillis
                                + " numInst="
                                + numInstances);
                Slog.d(TAG, "VIO: action=" + broadcastIntentAction);
                Slog.d(TAG, "VIO: tags=" + Arrays.toString(tags));
                Slog.d(TAG, "VIO: TOTAL BYTES WRITTEN: " + (dest.dataPosition() - start));
            }
        }

        /** Dump a ViolationInfo instance to a Printer. */
        public void dump(Printer pw, String prefix) {
            pw.println(prefix + "stackTrace: " + getStackTrace());
            pw.println(prefix + "penalty: " + mPenaltyMask);
            if (durationMillis != -1) {
                pw.println(prefix + "durationMillis: " + durationMillis);
            }
            if (numInstances != -1) {
                pw.println(prefix + "numInstances: " + numInstances);
            }
            if (violationNumThisLoop != 0) {
                pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop);
            }
            if (numAnimationsRunning != 0) {
                pw.println(prefix + "numAnimationsRunning: " + numAnimationsRunning);
            }
            pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis);
            if (broadcastIntentAction != null) {
                pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction);
            }
            if (tags != null) {
                int index = 0;
                for (String tag : tags) {
                    pw.println(prefix + "tag[" + (index++) + "]: " + tag);
                }
            }
        }

        @Override
        public int describeContents() {
            return 0;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<ViolationInfo> CREATOR =
                new Parcelable.Creator<ViolationInfo>() {
                    @Override
                    public ViolationInfo createFromParcel(Parcel in) {
                        return new ViolationInfo(in);
                    }

                    @Override
                    public ViolationInfo[] newArray(int size) {
                        return new ViolationInfo[size];
                    }
                };
    }

    private static final class InstanceTracker {
        private static final HashMap<Class<?>, Integer> sInstanceCounts =
                new HashMap<Class<?>, Integer>();

        private final Class<?> mKlass;

        public InstanceTracker(Object instance) {
            mKlass = instance.getClass();

            synchronized (sInstanceCounts) {
                final Integer value = sInstanceCounts.get(mKlass);
                final int newValue = value != null ? value + 1 : 1;
                sInstanceCounts.put(mKlass, newValue);
            }
        }

        @Override
        protected void finalize() throws Throwable {
            try {
                synchronized (sInstanceCounts) {
                    final Integer value = sInstanceCounts.get(mKlass);
                    if (value != null) {
                        final int newValue = value - 1;
                        if (newValue > 0) {
                            sInstanceCounts.put(mKlass, newValue);
                        } else {
                            sInstanceCounts.remove(mKlass);
                        }
                    }
                }
            } finally {
                super.finalize();
            }
        }

        public static int getInstanceCount(Class<?> klass) {
            synchronized (sInstanceCounts) {
                final Integer value = sInstanceCounts.get(klass);
                return value != null ? value : 0;
            }
        }
    }
}
