diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index 5672a13991d88..3fbb21e1bb48c 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -865,8 +865,8 @@ public class PackageWatchdog { MonitoredPackage p = it.next(); int oldState = p.getHealthCheckStateLocked(); int newState = p.handleElapsedTimeLocked(elapsedMs); - if (oldState != MonitoredPackage.STATE_FAILED - && newState == MonitoredPackage.STATE_FAILED) { + if (oldState != HealthCheckState.FAILED + && newState == HealthCheckState.FAILED) { Slog.i(TAG, "Package " + p.mName + " failed health check"); failedPackages.add(p); } @@ -941,6 +941,23 @@ public class PackageWatchdog { } } + @Retention(SOURCE) + @IntDef(value = { + HealthCheckState.ACTIVE, + HealthCheckState.INACTIVE, + HealthCheckState.PASSED, + HealthCheckState.FAILED}) + public @interface HealthCheckState { + // The package has not passed health check but has requested a health check + int ACTIVE = 0; + // The package has not passed health check and has not requested a health check + int INACTIVE = 1; + // The package has passed health check + int PASSED = 2; + // The package has failed health check + int FAILED = 3; + } + /** * Represents a package and its health check state along with the time * it should be monitored for. @@ -949,23 +966,12 @@ public class PackageWatchdog { * instances of this class. */ class MonitoredPackage { - // Health check states - // TODO(b/120598832): Prefix with HEALTH_CHECK - // mName has not passed health check but has requested a health check - public static final int STATE_ACTIVE = 0; - // mName has not passed health check and has not requested a health check - public static final int STATE_INACTIVE = 1; - // mName has passed health check - public static final int STATE_PASSED = 2; - // mName has failed health check - public static final int STATE_FAILED = 3; - //TODO(b/120598832): VersionedPackage? private final String mName; // One of STATE_[ACTIVE|INACTIVE|PASSED|FAILED]. Updated on construction and after // methods that could change the health check state: handleElapsedTimeLocked and // tryPassHealthCheckLocked - private int mHealthCheckState = STATE_INACTIVE; + private int mHealthCheckState = HealthCheckState.INACTIVE; // Whether an explicit health check has passed. // This value in addition with mHealthCheckDurationMs determines the health check state // of the package, see #getHealthCheckStateLocked @@ -1052,7 +1058,7 @@ public class PackageWatchdog { + ". Using total duration " + mDurationMs + "ms instead"); initialHealthCheckDurationMs = mDurationMs; } - if (mHealthCheckState == STATE_INACTIVE) { + if (mHealthCheckState == HealthCheckState.INACTIVE) { // Transitions to ACTIVE mHealthCheckDurationMs = initialHealthCheckDurationMs; } @@ -1072,7 +1078,7 @@ public class PackageWatchdog { } // Transitions to FAILED if now <= 0 and health check not passed mDurationMs -= elapsedMs; - if (mHealthCheckState == STATE_ACTIVE) { + if (mHealthCheckState == HealthCheckState.ACTIVE) { // We only update health check durations if we have #setHealthCheckActiveLocked // This ensures we don't leave the INACTIVE state for an unexpected elapsed time // Transitions to FAILED if now <= 0 and health check not passed @@ -1082,14 +1088,15 @@ public class PackageWatchdog { } /** - * Marks the health check as passed and transitions to {@link #STATE_PASSED} - * if not yet {@link #STATE_FAILED}. + * Marks the health check as passed and transitions to {@link HealthCheckState.PASSED} + * if not yet {@link HealthCheckState.FAILED}. * - * @return the new health check state + * @return the new {@link HealthCheckState health check state} */ @GuardedBy("mLock") + @HealthCheckState public int tryPassHealthCheckLocked() { - if (mHealthCheckState != STATE_FAILED) { + if (mHealthCheckState != HealthCheckState.FAILED) { // FAILED is a final state so only pass if we haven't failed // Transition to PASSED mHasPassedHealthCheck = true; @@ -1102,12 +1109,11 @@ public class PackageWatchdog { return mName; } - //TODO(b/120598832): IntDef /** - * Returns the current health check state, any of {@link #STATE_ACTIVE}, - * {@link #STATE_INACTIVE} or {@link #STATE_PASSED} + * Returns the current {@link HealthCheckState health check state}. */ @GuardedBy("mLock") + @HealthCheckState public int getHealthCheckStateLocked() { return mHealthCheckState; } @@ -1140,28 +1146,30 @@ public class PackageWatchdog { */ @GuardedBy("mLock") public boolean isPendingHealthChecksLocked() { - return mHealthCheckState == STATE_ACTIVE || mHealthCheckState == STATE_INACTIVE; + return mHealthCheckState == HealthCheckState.ACTIVE + || mHealthCheckState == HealthCheckState.INACTIVE; } /** * Updates the health check state based on {@link #mHasPassedHealthCheck} * and {@link #mHealthCheckDurationMs}. * - * @return the new health check state + * @return the new {@link HealthCheckState health check state} */ @GuardedBy("mLock") + @HealthCheckState private int updateHealthCheckStateLocked() { int oldState = mHealthCheckState; if (mHasPassedHealthCheck) { // Set final state first to avoid ambiguity - mHealthCheckState = STATE_PASSED; + mHealthCheckState = HealthCheckState.PASSED; } else if (mHealthCheckDurationMs <= 0 || mDurationMs <= 0) { // Set final state first to avoid ambiguity - mHealthCheckState = STATE_FAILED; + mHealthCheckState = HealthCheckState.FAILED; } else if (mHealthCheckDurationMs == Long.MAX_VALUE) { - mHealthCheckState = STATE_INACTIVE; + mHealthCheckState = HealthCheckState.INACTIVE; } else { - mHealthCheckState = STATE_ACTIVE; + mHealthCheckState = HealthCheckState.ACTIVE; } Slog.i(TAG, "Updated health check state for package " + mName + ": " + toString(oldState) + " -> " + toString(mHealthCheckState)); @@ -1169,15 +1177,15 @@ public class PackageWatchdog { } /** Returns a {@link String} representation of the current health check state. */ - private String toString(int state) { + private String toString(@HealthCheckState int state) { switch (state) { - case STATE_ACTIVE: + case HealthCheckState.ACTIVE: return "ACTIVE"; - case STATE_INACTIVE: + case HealthCheckState.INACTIVE: return "INACTIVE"; - case STATE_PASSED: + case HealthCheckState.PASSED: return "PASSED"; - case STATE_FAILED: + case HealthCheckState.FAILED: return "FAILED"; default: return "UNKNOWN"; diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 2d867f9d754fc..6c05bb8e86901 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -43,6 +43,7 @@ import android.util.AtomicFile; import androidx.test.InstrumentationRegistry; +import com.android.server.PackageWatchdog.HealthCheckState; import com.android.server.PackageWatchdog.MonitoredPackage; import com.android.server.PackageWatchdog.PackageHealthObserver; import com.android.server.PackageWatchdog.PackageHealthObserverImpact; @@ -687,36 +688,36 @@ public class PackageWatchdogTest { // Verify transition: inactive -> active -> passed // Verify initially inactive - assertEquals(MonitoredPackage.STATE_INACTIVE, m1.getHealthCheckStateLocked()); + assertEquals(HealthCheckState.INACTIVE, m1.getHealthCheckStateLocked()); // Verify still inactive, until we #setHealthCheckActiveLocked - assertEquals(MonitoredPackage.STATE_INACTIVE, m1.handleElapsedTimeLocked(SHORT_DURATION)); + assertEquals(HealthCheckState.INACTIVE, m1.handleElapsedTimeLocked(SHORT_DURATION)); // Verify now active - assertEquals(MonitoredPackage.STATE_ACTIVE, m1.setHealthCheckActiveLocked(SHORT_DURATION)); + assertEquals(HealthCheckState.ACTIVE, m1.setHealthCheckActiveLocked(SHORT_DURATION)); // Verify now passed - assertEquals(MonitoredPackage.STATE_PASSED, m1.tryPassHealthCheckLocked()); + assertEquals(HealthCheckState.PASSED, m1.tryPassHealthCheckLocked()); // Verify transition: inactive -> active -> failed // Verify initially inactive - assertEquals(MonitoredPackage.STATE_INACTIVE, m2.getHealthCheckStateLocked()); + assertEquals(HealthCheckState.INACTIVE, m2.getHealthCheckStateLocked()); // Verify now active - assertEquals(MonitoredPackage.STATE_ACTIVE, m2.setHealthCheckActiveLocked(SHORT_DURATION)); + assertEquals(HealthCheckState.ACTIVE, m2.setHealthCheckActiveLocked(SHORT_DURATION)); // Verify now failed - assertEquals(MonitoredPackage.STATE_FAILED, m2.handleElapsedTimeLocked(SHORT_DURATION)); + assertEquals(HealthCheckState.FAILED, m2.handleElapsedTimeLocked(SHORT_DURATION)); // Verify transition: inactive -> failed // Verify initially inactive - assertEquals(MonitoredPackage.STATE_INACTIVE, m3.getHealthCheckStateLocked()); + assertEquals(HealthCheckState.INACTIVE, m3.getHealthCheckStateLocked()); // Verify now failed because package expired - assertEquals(MonitoredPackage.STATE_FAILED, m3.handleElapsedTimeLocked(LONG_DURATION)); + assertEquals(HealthCheckState.FAILED, m3.handleElapsedTimeLocked(LONG_DURATION)); // Verify remains failed even when asked to pass - assertEquals(MonitoredPackage.STATE_FAILED, m3.tryPassHealthCheckLocked()); + assertEquals(HealthCheckState.FAILED, m3.tryPassHealthCheckLocked()); // Verify transition: passed - assertEquals(MonitoredPackage.STATE_PASSED, m4.getHealthCheckStateLocked()); + assertEquals(HealthCheckState.PASSED, m4.getHealthCheckStateLocked()); // Verify remains passed even if health check fails - assertEquals(MonitoredPackage.STATE_PASSED, m4.handleElapsedTimeLocked(SHORT_DURATION)); + assertEquals(HealthCheckState.PASSED, m4.handleElapsedTimeLocked(SHORT_DURATION)); // Verify remains passed even if package expires - assertEquals(MonitoredPackage.STATE_PASSED, m4.handleElapsedTimeLocked(LONG_DURATION)); + assertEquals(HealthCheckState.PASSED, m4.handleElapsedTimeLocked(LONG_DURATION)); } @Test