Loading services/core/java/com/android/server/PackageWatchdog.java +26 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,12 @@ public class PackageWatchdog { static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10); // Time needed to apply mitigation private static final String MITIGATION_WINDOW_MS = "persist.device_config.configuration.mitigation_window_ms"; @VisibleForTesting static final long DEFAULT_MITIGATION_WINDOW_MS = TimeUnit.SECONDS.toMillis(5); // Threshold level at which or above user might experience significant disruption. private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD = "persist.device_config.configuration.major_user_impact_level_threshold"; Loading Loading @@ -210,6 +216,9 @@ public class PackageWatchdog { @GuardedBy("mLock") private boolean mSyncRequired = false; @GuardedBy("mLock") private long mLastMitigation = -1000000; @FunctionalInterface @VisibleForTesting interface SystemClock { Loading Loading @@ -400,6 +409,16 @@ public class PackageWatchdog { Slog.w(TAG, "Could not resolve a list of failing packages"); return; } synchronized (mLock) { final long now = mSystemClock.uptimeMillis(); if (Flags.recoverabilityDetection()) { if (now >= mLastMitigation && (now - mLastMitigation) < getMitigationWindowMs()) { Slog.i(TAG, "Skipping onPackageFailure mitigation"); return; } } } mLongTaskHandler.post(() -> { synchronized (mLock) { if (mAllObservers.isEmpty()) { Loading Loading @@ -500,10 +519,17 @@ public class PackageWatchdog { int currentObserverImpact, int mitigationCount) { if (currentObserverImpact < getUserImpactLevelLimit()) { synchronized (mLock) { mLastMitigation = mSystemClock.uptimeMillis(); } currentObserverToNotify.execute(versionedPackage, failureReason, mitigationCount); } } private long getMitigationWindowMs() { return SystemProperties.getLong(MITIGATION_WINDOW_MS, DEFAULT_MITIGATION_WINDOW_MS); } /** * Called when the system server boots. If the system server is detected to be in a boot loop, Loading tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +7 −3 Original line number Diff line number Diff line Loading @@ -101,8 +101,8 @@ public class PackageWatchdogTest { private static final String OBSERVER_NAME_2 = "observer2"; private static final String OBSERVER_NAME_3 = "observer3"; private static final String OBSERVER_NAME_4 = "observer4"; private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(1); private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(5); private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(10); private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(50); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); Loading Loading @@ -1453,7 +1453,8 @@ public class PackageWatchdogTest { raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN); moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS); moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS - TimeUnit.MINUTES.toMillis(1)); // The first failure will be outside the threshold. raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A, Loading Loading @@ -1712,6 +1713,9 @@ public class PackageWatchdogTest { watchdog.onPackageFailure(packages, failureReason); } mTestLooper.dispatchAll(); if (Flags.recoverabilityDetection()) { moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS); } } private PackageWatchdog createWatchdog() { Loading Loading
services/core/java/com/android/server/PackageWatchdog.java +26 −0 Original line number Diff line number Diff line Loading @@ -138,6 +138,12 @@ public class PackageWatchdog { static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10); // Time needed to apply mitigation private static final String MITIGATION_WINDOW_MS = "persist.device_config.configuration.mitigation_window_ms"; @VisibleForTesting static final long DEFAULT_MITIGATION_WINDOW_MS = TimeUnit.SECONDS.toMillis(5); // Threshold level at which or above user might experience significant disruption. private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD = "persist.device_config.configuration.major_user_impact_level_threshold"; Loading Loading @@ -210,6 +216,9 @@ public class PackageWatchdog { @GuardedBy("mLock") private boolean mSyncRequired = false; @GuardedBy("mLock") private long mLastMitigation = -1000000; @FunctionalInterface @VisibleForTesting interface SystemClock { Loading Loading @@ -400,6 +409,16 @@ public class PackageWatchdog { Slog.w(TAG, "Could not resolve a list of failing packages"); return; } synchronized (mLock) { final long now = mSystemClock.uptimeMillis(); if (Flags.recoverabilityDetection()) { if (now >= mLastMitigation && (now - mLastMitigation) < getMitigationWindowMs()) { Slog.i(TAG, "Skipping onPackageFailure mitigation"); return; } } } mLongTaskHandler.post(() -> { synchronized (mLock) { if (mAllObservers.isEmpty()) { Loading Loading @@ -500,10 +519,17 @@ public class PackageWatchdog { int currentObserverImpact, int mitigationCount) { if (currentObserverImpact < getUserImpactLevelLimit()) { synchronized (mLock) { mLastMitigation = mSystemClock.uptimeMillis(); } currentObserverToNotify.execute(versionedPackage, failureReason, mitigationCount); } } private long getMitigationWindowMs() { return SystemProperties.getLong(MITIGATION_WINDOW_MS, DEFAULT_MITIGATION_WINDOW_MS); } /** * Called when the system server boots. If the system server is detected to be in a boot loop, Loading
tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +7 −3 Original line number Diff line number Diff line Loading @@ -101,8 +101,8 @@ public class PackageWatchdogTest { private static final String OBSERVER_NAME_2 = "observer2"; private static final String OBSERVER_NAME_3 = "observer3"; private static final String OBSERVER_NAME_4 = "observer4"; private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(1); private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(5); private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(10); private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(50); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); Loading Loading @@ -1453,7 +1453,8 @@ public class PackageWatchdogTest { raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN); moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS); moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS - TimeUnit.MINUTES.toMillis(1)); // The first failure will be outside the threshold. raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A, Loading Loading @@ -1712,6 +1713,9 @@ public class PackageWatchdogTest { watchdog.onPackageFailure(packages, failureReason); } mTestLooper.dispatchAll(); if (Flags.recoverabilityDetection()) { moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS); } } private PackageWatchdog createWatchdog() { Loading