Loading core/java/android/app/Activity.java +0 −1 Original line number Diff line number Diff line Loading @@ -859,7 +859,6 @@ 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/app/ActivityThread.java +4 −1 Original line number Diff line number Diff line Loading @@ -1616,6 +1616,7 @@ public final class ActivityThread { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); if (r.state != null) { r.state.setClassLoader(cl); Loading Loading @@ -2686,8 +2687,10 @@ public final class ActivityThread { private final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance) { ActivityClientRecord r = mActivities.get(token); Class activityClass = null; if (localLOGV) Slog.v(TAG, "Performing finish of " + r); if (r != null) { activityClass = r.activity.getClass(); r.activity.mConfigChangeFlags |= configChanges; if (finishing) { r.activity.mFinished = true; Loading Loading @@ -2765,7 +2768,7 @@ public final class ActivityThread { } } mActivities.remove(token); StrictMode.decrementExpectedActivityCount(activityClass); return r; } Loading core/java/android/os/StrictMode.java +70 −26 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** Loading Loading @@ -1370,8 +1371,9 @@ public final class StrictMode { } Runtime.getRuntime().gc(); // Note: classInstanceLimit is immutable, so this is lock-free for (Class klass : policy.classInstanceLimit.keySet()) { int limit = policy.classInstanceLimit.get(klass); for (Map.Entry<Class, Integer> entry : policy.classInstanceLimit.entrySet()) { Class klass = entry.getKey(); int limit = entry.getValue(); long instances = VMDebug.countInstancesOfClass(klass, false); if (instances <= limit) { continue; Loading @@ -1382,7 +1384,7 @@ public final class StrictMode { } private static long sLastInstanceCountCheckMillis = 0; private static boolean sIsIdlerRegistered = false; // guarded by sProcessIdleHandler private static boolean sIsIdlerRegistered = false; // guarded by StrictMode.class private static final MessageQueue.IdleHandler sProcessIdleHandler = new MessageQueue.IdleHandler() { public boolean queueIdle() { Loading @@ -1403,6 +1405,7 @@ public final class StrictMode { * @param policy the policy to put into place */ public static void setVmPolicy(final VmPolicy policy) { synchronized (StrictMode.class) { sVmPolicy = policy; sVmPolicyMask = policy.mask; setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); Loading @@ -1410,7 +1413,6 @@ public final class StrictMode { Looper looper = Looper.getMainLooper(); if (looper != null) { MessageQueue mq = looper.mQueue; synchronized (sProcessIdleHandler) { if (policy.classInstanceLimit.size() == 0) { mq.removeIdleHandler(sProcessIdleHandler); } else if (!sIsIdlerRegistered) { Loading @@ -1425,8 +1427,10 @@ public final class StrictMode { * Gets the current VM policy. */ public static VmPolicy getVmPolicy() { synchronized (StrictMode.class) { return sVmPolicy; } } /** * Enable the recommended StrictMode defaults, with violations just being logged. Loading Loading @@ -1480,6 +1484,11 @@ public final class StrictMode { final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0; final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); // 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 = 0; Loading @@ -1494,8 +1503,6 @@ public final class StrictMode { } } Log.d(TAG, "Time since last vm violation: " + timeSinceLastViolationMillis); if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { Log.e(TAG, message, originStack); } Loading Loading @@ -1799,18 +1806,57 @@ public final class StrictMode { ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); } // Guarded by StrictMode.class private static final HashMap<Class, Integer> sExpectedActivityInstanceCount = new HashMap<Class, Integer>(); /** * @hide */ public static void noteActivityClass(Class klass) { if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { public static void incrementExpectedActivityCount(Class klass) { if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { return; } if (sVmPolicy.classInstanceLimit.containsKey(klass)) { synchronized (StrictMode.class) { Integer expected = sExpectedActivityInstanceCount.get(klass); Integer newExpected = expected == null ? 1 : expected + 1; sExpectedActivityInstanceCount.put(klass, newExpected); // Note: adding 1 here to give some breathing room during // orientation changes. (shouldn't be necessary, though?) setExpectedClassInstanceCount(klass, newExpected + 1); } } /** * @hide */ public static void decrementExpectedActivityCount(Class klass) { if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { return; } // Note: capping at 2, not 1, to give some breathing room. setVmPolicy(new VmPolicy.Builder(sVmPolicy).setClassInstanceLimit(klass, 2).build()); synchronized (StrictMode.class) { Integer expected = sExpectedActivityInstanceCount.get(klass); Integer 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?) setExpectedClassInstanceCount(klass, newExpected + 1); } } /** * @hide */ public static void setExpectedClassInstanceCount(Class klass, int count) { synchronized (StrictMode.class) { setVmPolicy(new VmPolicy.Builder(sVmPolicy) .setClassInstanceLimit(klass, count) .build()); } } /** Loading Loading @@ -2020,15 +2066,13 @@ public final class StrictMode { final long mInstances; final int mLimit; private static final StackTraceElement[] FAKE_STACK = new StackTraceElement[1]; static { FAKE_STACK[0] = new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit", "StrictMode.java", 1); } private static final StackTraceElement[] FAKE_STACK = { new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit", "StrictMode.java", 1) }; public InstanceCountViolation(Class klass, long instances, int limit) { // Note: now including instances here, otherwise signatures would all be different. super(klass.toString() + "; limit=" + limit); super(klass.toString() + "; instances=" + instances + "; limit=" + limit); setStackTrace(FAKE_STACK); mClass = klass; mInstances = instances; Loading Loading
core/java/android/app/Activity.java +0 −1 Original line number Diff line number Diff line Loading @@ -859,7 +859,6 @@ 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/app/ActivityThread.java +4 −1 Original line number Diff line number Diff line Loading @@ -1616,6 +1616,7 @@ public final class ActivityThread { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); if (r.state != null) { r.state.setClassLoader(cl); Loading Loading @@ -2686,8 +2687,10 @@ public final class ActivityThread { private final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance) { ActivityClientRecord r = mActivities.get(token); Class activityClass = null; if (localLOGV) Slog.v(TAG, "Performing finish of " + r); if (r != null) { activityClass = r.activity.getClass(); r.activity.mConfigChangeFlags |= configChanges; if (finishing) { r.activity.mFinished = true; Loading Loading @@ -2765,7 +2768,7 @@ public final class ActivityThread { } } mActivities.remove(token); StrictMode.decrementExpectedActivityCount(activityClass); return r; } Loading
core/java/android/os/StrictMode.java +70 −26 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** Loading Loading @@ -1370,8 +1371,9 @@ public final class StrictMode { } Runtime.getRuntime().gc(); // Note: classInstanceLimit is immutable, so this is lock-free for (Class klass : policy.classInstanceLimit.keySet()) { int limit = policy.classInstanceLimit.get(klass); for (Map.Entry<Class, Integer> entry : policy.classInstanceLimit.entrySet()) { Class klass = entry.getKey(); int limit = entry.getValue(); long instances = VMDebug.countInstancesOfClass(klass, false); if (instances <= limit) { continue; Loading @@ -1382,7 +1384,7 @@ public final class StrictMode { } private static long sLastInstanceCountCheckMillis = 0; private static boolean sIsIdlerRegistered = false; // guarded by sProcessIdleHandler private static boolean sIsIdlerRegistered = false; // guarded by StrictMode.class private static final MessageQueue.IdleHandler sProcessIdleHandler = new MessageQueue.IdleHandler() { public boolean queueIdle() { Loading @@ -1403,6 +1405,7 @@ public final class StrictMode { * @param policy the policy to put into place */ public static void setVmPolicy(final VmPolicy policy) { synchronized (StrictMode.class) { sVmPolicy = policy; sVmPolicyMask = policy.mask; setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); Loading @@ -1410,7 +1413,6 @@ public final class StrictMode { Looper looper = Looper.getMainLooper(); if (looper != null) { MessageQueue mq = looper.mQueue; synchronized (sProcessIdleHandler) { if (policy.classInstanceLimit.size() == 0) { mq.removeIdleHandler(sProcessIdleHandler); } else if (!sIsIdlerRegistered) { Loading @@ -1425,8 +1427,10 @@ public final class StrictMode { * Gets the current VM policy. */ public static VmPolicy getVmPolicy() { synchronized (StrictMode.class) { return sVmPolicy; } } /** * Enable the recommended StrictMode defaults, with violations just being logged. Loading Loading @@ -1480,6 +1484,11 @@ public final class StrictMode { final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0; final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); // 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 = 0; Loading @@ -1494,8 +1503,6 @@ public final class StrictMode { } } Log.d(TAG, "Time since last vm violation: " + timeSinceLastViolationMillis); if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { Log.e(TAG, message, originStack); } Loading Loading @@ -1799,18 +1806,57 @@ public final class StrictMode { ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); } // Guarded by StrictMode.class private static final HashMap<Class, Integer> sExpectedActivityInstanceCount = new HashMap<Class, Integer>(); /** * @hide */ public static void noteActivityClass(Class klass) { if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { public static void incrementExpectedActivityCount(Class klass) { if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { return; } if (sVmPolicy.classInstanceLimit.containsKey(klass)) { synchronized (StrictMode.class) { Integer expected = sExpectedActivityInstanceCount.get(klass); Integer newExpected = expected == null ? 1 : expected + 1; sExpectedActivityInstanceCount.put(klass, newExpected); // Note: adding 1 here to give some breathing room during // orientation changes. (shouldn't be necessary, though?) setExpectedClassInstanceCount(klass, newExpected + 1); } } /** * @hide */ public static void decrementExpectedActivityCount(Class klass) { if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) { return; } // Note: capping at 2, not 1, to give some breathing room. setVmPolicy(new VmPolicy.Builder(sVmPolicy).setClassInstanceLimit(klass, 2).build()); synchronized (StrictMode.class) { Integer expected = sExpectedActivityInstanceCount.get(klass); Integer 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?) setExpectedClassInstanceCount(klass, newExpected + 1); } } /** * @hide */ public static void setExpectedClassInstanceCount(Class klass, int count) { synchronized (StrictMode.class) { setVmPolicy(new VmPolicy.Builder(sVmPolicy) .setClassInstanceLimit(klass, count) .build()); } } /** Loading Loading @@ -2020,15 +2066,13 @@ public final class StrictMode { final long mInstances; final int mLimit; private static final StackTraceElement[] FAKE_STACK = new StackTraceElement[1]; static { FAKE_STACK[0] = new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit", "StrictMode.java", 1); } private static final StackTraceElement[] FAKE_STACK = { new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit", "StrictMode.java", 1) }; public InstanceCountViolation(Class klass, long instances, int limit) { // Note: now including instances here, otherwise signatures would all be different. super(klass.toString() + "; limit=" + limit); super(klass.toString() + "; instances=" + instances + "; limit=" + limit); setStackTrace(FAKE_STACK); mClass = klass; mInstances = instances; Loading