Loading api/current.xml +25 −0 Original line number Diff line number Diff line Loading @@ -146691,6 +146691,16 @@ visibility="public" > </constructor> <constructor name="StrictMode.VmPolicy.Builder" type="android.os.StrictMode.VmPolicy.Builder" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="base" type="android.os.StrictMode.VmPolicy"> </parameter> </constructor> <method name="build" return="android.os.StrictMode.VmPolicy" abstract="false" Loading Loading @@ -146768,6 +146778,21 @@ visibility="public" > </method> <method name="setClassInstanceLimit" return="android.os.StrictMode.VmPolicy.Builder" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="klass" type="java.lang.Class"> </parameter> <parameter name="instanceLimit" type="int"> </parameter> </method> </class> <class name="SystemClock" extends="java.lang.Object" core/java/android/app/Activity.java +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Parcelable; import android.os.RemoteException; import android.os.StrictMode; import android.text.Selection; import android.text.SpannableStringBuilder; import android.text.TextUtils; Loading Loading @@ -858,6 +859,7 @@ public class Activity extends ContextThemeWrapper mFragments.restoreAllState(p, mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.fragments : null); } StrictMode.noteActivityClass(this.getClass()); mFragments.dispatchCreate(); mCalled = true; } Loading core/java/android/os/StrictMode.java +90 −10 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import dalvik.system.CloseGuard; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger; Loading Loading @@ -166,13 +167,19 @@ public final class StrictMode { * Note, a "VM_" bit, not thread. * @hide */ public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for VmPolicy /** * Note, a "VM_" bit, not thread. * @hide */ public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for ProcessPolicy public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for VmPolicy /** * Note, a "VM_" bit, not thread. * @hide */ public static final int DETECT_VM_ACTIVITY_LEAKS = 0x800; // for VmPolicy /** * @hide Loading Loading @@ -232,10 +239,18 @@ public final class StrictMode { PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; // 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. * * TODO: these are redundant (mask is in VmPolicy). Should remove sVmPolicyMask. */ private static volatile int sVmPolicyMask = 0; private static volatile VmPolicy sVmPolicy = VmPolicy.LAX; /** * The number of threads trying to do an async dropbox write. Loading Loading @@ -481,12 +496,19 @@ public final class StrictMode { /** * The default, lax policy which doesn't catch anything. */ public static final VmPolicy LAX = new VmPolicy(0); public static final VmPolicy LAX = new VmPolicy(0, EMPTY_CLASS_LIMIT_MAP); final int mask; private VmPolicy(int mask) { // Map from class to max number of allowed instances in memory. final HashMap<Class, Integer> classInstanceLimit; private VmPolicy(int mask, HashMap<Class, Integer> classInstanceLimit) { if (classInstanceLimit == null) { throw new NullPointerException("classInstanceLimit == null"); } this.mask = mask; this.classInstanceLimit = classInstanceLimit; } @Override Loading Loading @@ -516,6 +538,49 @@ public final class StrictMode { public static final class Builder { private int mMask; 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; } /** * Set an upper bound on how many instances of a class can be in memory * at once. Helps to prevent object leaks. */ public 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>(); } mClassInstanceLimit.put(klass, instanceLimit); return this; } private Builder detectActivityLeaks() { return enable(DETECT_VM_ACTIVITY_LEAKS); } /** * Detect everything that's potentially suspect. * Loading @@ -524,7 +589,8 @@ public final class StrictMode { * likely expand in future releases. */ public Builder detectAll() { return enable(DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); return enable(DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); } /** Loading Loading @@ -598,7 +664,8 @@ public final class StrictMode { PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { penaltyLog(); } return new VmPolicy(mMask); return new VmPolicy(mMask, mClassInstanceLimit != null ? mClassInstanceLimit : EMPTY_CLASS_LIMIT_MAP); } } } Loading Loading @@ -829,9 +896,7 @@ public final class StrictMode { if (IS_USER_BUILD) { setCloseGuardEnabled(false); } else { sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | StrictMode.DETECT_VM_CLOSABLE_LEAKS | StrictMode.PENALTY_DROPBOX; setVmPolicy(new VmPolicy.Builder().detectAll().penaltyDropBox().build()); setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); } return true; Loading Loading @@ -1289,6 +1354,7 @@ public final class StrictMode { * @param policy the policy to put into place */ public static void setVmPolicy(final VmPolicy policy) { sVmPolicy = policy; sVmPolicyMask = policy.mask; setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); } Loading @@ -1297,7 +1363,7 @@ public final class StrictMode { * Gets the current VM policy. */ public static VmPolicy getVmPolicy() { return new VmPolicy(sVmPolicyMask); return sVmPolicy; } /** Loading Loading @@ -1651,6 +1717,20 @@ public final class StrictMode { ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); } /** * @hide */ public static void noteActivityClass(Class klass) { if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { return; } if (sVmPolicy.classInstanceLimit.containsKey(klass)) { return; } // Note: capping at 2, not 1, to give some breathing room. setVmPolicy(new VmPolicy.Builder(sVmPolicy).setClassInstanceLimit(klass, 2).build()); } /** * Parcelable that gets sent in Binder call headers back to callers * to report violations that happened during a cross-process call. Loading Loading
api/current.xml +25 −0 Original line number Diff line number Diff line Loading @@ -146691,6 +146691,16 @@ visibility="public" > </constructor> <constructor name="StrictMode.VmPolicy.Builder" type="android.os.StrictMode.VmPolicy.Builder" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="base" type="android.os.StrictMode.VmPolicy"> </parameter> </constructor> <method name="build" return="android.os.StrictMode.VmPolicy" abstract="false" Loading Loading @@ -146768,6 +146778,21 @@ visibility="public" > </method> <method name="setClassInstanceLimit" return="android.os.StrictMode.VmPolicy.Builder" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="klass" type="java.lang.Class"> </parameter> <parameter name="instanceLimit" type="int"> </parameter> </method> </class> <class name="SystemClock" extends="java.lang.Object"
core/java/android/app/Activity.java +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Parcelable; import android.os.RemoteException; import android.os.StrictMode; import android.text.Selection; import android.text.SpannableStringBuilder; import android.text.TextUtils; Loading Loading @@ -858,6 +859,7 @@ public class Activity extends ContextThemeWrapper mFragments.restoreAllState(p, mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.fragments : null); } StrictMode.noteActivityClass(this.getClass()); mFragments.dispatchCreate(); mCalled = true; } Loading
core/java/android/os/StrictMode.java +90 −10 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import dalvik.system.CloseGuard; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger; Loading Loading @@ -166,13 +167,19 @@ public final class StrictMode { * Note, a "VM_" bit, not thread. * @hide */ public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for VmPolicy /** * Note, a "VM_" bit, not thread. * @hide */ public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for ProcessPolicy public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for VmPolicy /** * Note, a "VM_" bit, not thread. * @hide */ public static final int DETECT_VM_ACTIVITY_LEAKS = 0x800; // for VmPolicy /** * @hide Loading Loading @@ -232,10 +239,18 @@ public final class StrictMode { PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; // 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. * * TODO: these are redundant (mask is in VmPolicy). Should remove sVmPolicyMask. */ private static volatile int sVmPolicyMask = 0; private static volatile VmPolicy sVmPolicy = VmPolicy.LAX; /** * The number of threads trying to do an async dropbox write. Loading Loading @@ -481,12 +496,19 @@ public final class StrictMode { /** * The default, lax policy which doesn't catch anything. */ public static final VmPolicy LAX = new VmPolicy(0); public static final VmPolicy LAX = new VmPolicy(0, EMPTY_CLASS_LIMIT_MAP); final int mask; private VmPolicy(int mask) { // Map from class to max number of allowed instances in memory. final HashMap<Class, Integer> classInstanceLimit; private VmPolicy(int mask, HashMap<Class, Integer> classInstanceLimit) { if (classInstanceLimit == null) { throw new NullPointerException("classInstanceLimit == null"); } this.mask = mask; this.classInstanceLimit = classInstanceLimit; } @Override Loading Loading @@ -516,6 +538,49 @@ public final class StrictMode { public static final class Builder { private int mMask; 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; } /** * Set an upper bound on how many instances of a class can be in memory * at once. Helps to prevent object leaks. */ public 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>(); } mClassInstanceLimit.put(klass, instanceLimit); return this; } private Builder detectActivityLeaks() { return enable(DETECT_VM_ACTIVITY_LEAKS); } /** * Detect everything that's potentially suspect. * Loading @@ -524,7 +589,8 @@ public final class StrictMode { * likely expand in future releases. */ public Builder detectAll() { return enable(DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); return enable(DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS); } /** Loading Loading @@ -598,7 +664,8 @@ public final class StrictMode { PENALTY_DROPBOX | PENALTY_DIALOG)) == 0) { penaltyLog(); } return new VmPolicy(mMask); return new VmPolicy(mMask, mClassInstanceLimit != null ? mClassInstanceLimit : EMPTY_CLASS_LIMIT_MAP); } } } Loading Loading @@ -829,9 +896,7 @@ public final class StrictMode { if (IS_USER_BUILD) { setCloseGuardEnabled(false); } else { sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | StrictMode.DETECT_VM_CLOSABLE_LEAKS | StrictMode.PENALTY_DROPBOX; setVmPolicy(new VmPolicy.Builder().detectAll().penaltyDropBox().build()); setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); } return true; Loading Loading @@ -1289,6 +1354,7 @@ public final class StrictMode { * @param policy the policy to put into place */ public static void setVmPolicy(final VmPolicy policy) { sVmPolicy = policy; sVmPolicyMask = policy.mask; setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); } Loading @@ -1297,7 +1363,7 @@ public final class StrictMode { * Gets the current VM policy. */ public static VmPolicy getVmPolicy() { return new VmPolicy(sVmPolicyMask); return sVmPolicy; } /** Loading Loading @@ -1651,6 +1717,20 @@ public final class StrictMode { ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); } /** * @hide */ public static void noteActivityClass(Class klass) { if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { return; } if (sVmPolicy.classInstanceLimit.containsKey(klass)) { return; } // Note: capping at 2, not 1, to give some breathing room. setVmPolicy(new VmPolicy.Builder(sVmPolicy).setClassInstanceLimit(klass, 2).build()); } /** * Parcelable that gets sent in Binder call headers back to callers * to report violations that happened during a cross-process call. Loading