Loading services/core/java/com/android/server/PackageWatchdog.java +39 −12 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.server.crashrecovery.CrashRecoveryUtils.dumpCrashRecov import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -91,6 +92,7 @@ import java.util.concurrent.TimeUnit; * Monitors the health of packages on the system and notifies interested observers when packages * fail. On failure, the registered observer with the least user impacting mitigation will * be notified. * @hide */ public class PackageWatchdog { private static final String TAG = "PackageWatchdog"; Loading @@ -108,13 +110,25 @@ public class PackageWatchdog { private static final long NUMBER_OF_NATIVE_CRASH_POLLS = 10; /** Reason for package failure could not be determined. */ public static final int FAILURE_REASON_UNKNOWN = 0; /** The package had a native crash. */ public static final int FAILURE_REASON_NATIVE_CRASH = 1; /** The package failed an explicit health check. */ public static final int FAILURE_REASON_EXPLICIT_HEALTH_CHECK = 2; /** The app crashed. */ public static final int FAILURE_REASON_APP_CRASH = 3; /** The app was not responding. */ public static final int FAILURE_REASON_APP_NOT_RESPONDING = 4; /** The device was boot looping. */ public static final int FAILURE_REASON_BOOT_LOOP = 5; /** @hide */ @IntDef(prefix = { "FAILURE_REASON_" }, value = { FAILURE_REASON_UNKNOWN, FAILURE_REASON_NATIVE_CRASH, Loading Loading @@ -186,7 +200,8 @@ public class PackageWatchdog { // aborted. private static final String METADATA_FILE = "/metadata/watchdog/mitigation_count.txt"; @GuardedBy("PackageWatchdog.class") private static final Object sPackageWatchdogLock = new Object(); @GuardedBy("sPackageWatchdogLock") private static PackageWatchdog sPackageWatchdog; private final Object mLock = new Object(); Loading Loading @@ -278,8 +293,8 @@ public class PackageWatchdog { } /** Creates or gets singleton instance of PackageWatchdog. */ public static PackageWatchdog getInstance(Context context) { synchronized (PackageWatchdog.class) { public static @NonNull PackageWatchdog getInstance(@NonNull Context context) { synchronized (sPackageWatchdogLock) { if (sPackageWatchdog == null) { new PackageWatchdog(context); } Loading @@ -290,6 +305,7 @@ public class PackageWatchdog { /** * Called during boot to notify when packages are ready on the device so we can start * binding. * @hide */ public void onPackagesReady() { synchronized (mLock) { Loading @@ -311,6 +327,7 @@ public class PackageWatchdog { * * <p>Observers are expected to call this on boot. It does not specify any packages but * it will resume observing any packages requested from a previous boot. * @hide */ public void registerHealthObserver(PackageHealthObserver observer) { synchronized (mLock) { Loading Loading @@ -344,6 +361,7 @@ public class PackageWatchdog { * * <p>If {@code durationMs} is less than 1, a default monitoring duration * {@link #DEFAULT_OBSERVING_DURATION_MS} will be used. * @hide */ public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames, long durationMs) { Loading Loading @@ -407,6 +425,7 @@ public class PackageWatchdog { * Unregisters {@code observer} from listening to package failure. * Additionally, this stops observing any packages that may have previously been observed * even from a previous boot. * @hide */ public void unregisterHealthObserver(PackageHealthObserver observer) { mLongTaskHandler.post(() -> { Loading @@ -425,7 +444,7 @@ public class PackageWatchdog { * * <p>This method could be called frequently if there is a severe problem on the device. */ public void onPackageFailure(List<VersionedPackage> packages, public void onPackageFailure(@NonNull List<VersionedPackage> packages, @FailureReasons int failureReason) { if (packages == null) { Slog.w(TAG, "Could not resolve a list of failing packages"); Loading Loading @@ -566,6 +585,7 @@ public class PackageWatchdog { * * Note: PackageWatchdog considers system_server restart loop as bootloop. Full reboots * are not counted in bootloop. * @hide */ @SuppressWarnings("GuardedBy") public void noteBoot() { Loading Loading @@ -620,7 +640,7 @@ public class PackageWatchdog { // TODO(b/120598832): Optimize write? Maybe only write a separate smaller file? Also // avoid holding lock? // This currently adds about 7ms extra to shutdown thread /** Writes the package information to file during shutdown. */ /** @hide Writes the package information to file during shutdown. */ public void writeNow() { synchronized (mLock) { // Must only run synchronous tasks as this runs on the ShutdownThread and no other Loading Loading @@ -674,6 +694,7 @@ public class PackageWatchdog { * Since this method can eventually trigger a rollback, it should be called * only once boot has completed {@code onBootCompleted} and not earlier, because the install * session must be entirely completed before we try to rollback. * @hide */ public void scheduleCheckAndMitigateNativeCrashes() { Slog.i(TAG, "Scheduling " + mNumberOfNativeCrashPollsRemaining + " polls to check " Loading @@ -695,7 +716,9 @@ public class PackageWatchdog { return mPackagesExemptFromImpactLevelThreshold; } /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */ /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. * @hide */ @Retention(SOURCE) @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_LEVEL_0, PackageHealthObserverImpact.USER_IMPACT_LEVEL_10, Loading Loading @@ -787,7 +810,7 @@ public class PackageWatchdog { * Identifier for the observer, should not change across device updates otherwise the * watchdog may drop observing packages with the old name. */ String getUniqueIdentifier(); @NonNull String getUniqueIdentifier(); /** * An observer will not be pruned if this is set, even if the observer is not explicitly Loading @@ -804,7 +827,7 @@ public class PackageWatchdog { * <p> A persistent observer may choose to start observing certain failing packages, even if * it has not explicitly asked to watch the package with {@link #startObservingHealth}. */ default boolean mayObservePackage(String packageName) { default boolean mayObservePackage(@NonNull String packageName) { return false; } } Loading Loading @@ -1240,7 +1263,7 @@ public class PackageWatchdog { } } /** Convert a {@code LongArrayQueue} to a String of comma-separated values. */ /** @hide Convert a {@code LongArrayQueue} to a String of comma-separated values. */ public static String longArrayQueueToString(LongArrayQueue queue) { if (queue.size() > 0) { StringBuilder sb = new StringBuilder(); Loading @@ -1254,7 +1277,7 @@ public class PackageWatchdog { return ""; } /** Parse a comma-separated String of longs into a LongArrayQueue. */ /** @hide Parse a comma-separated String of longs into a LongArrayQueue. */ public static LongArrayQueue parseLongArrayQueue(String commaSeparatedValues) { LongArrayQueue result = new LongArrayQueue(); if (!TextUtils.isEmpty(commaSeparatedValues)) { Loading @@ -1268,7 +1291,7 @@ public class PackageWatchdog { /** Dump status of every observer in mAllObservers. */ public void dump(PrintWriter pw) { public void dump(@NonNull PrintWriter pw) { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.println("Package Watchdog status"); ipw.increaseIndent(); Loading Loading @@ -1395,6 +1418,7 @@ public class PackageWatchdog { /** * Increments failure counts of {@code packageName}. * @returns {@code true} if failure threshold is exceeded, {@code false} otherwise * @hide */ @GuardedBy("mLock") public boolean onPackageFailureLocked(String packageName) { Loading Loading @@ -1514,6 +1538,7 @@ public class PackageWatchdog { } } /** @hide */ @Retention(SOURCE) @IntDef(value = { HealthCheckState.ACTIVE, Loading Loading @@ -1603,7 +1628,9 @@ public class PackageWatchdog { updateHealthCheckStateLocked(); } /** Writes the salient fields to disk using {@code out}. */ /** Writes the salient fields to disk using {@code out}. * @hide */ @GuardedBy("mLock") public void writeLocked(TypedXmlSerializer out) throws IOException { out.startTag(null, TAG_PACKAGE); Loading services/core/java/com/android/server/crashrecovery/CrashRecoveryModule.java +4 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,10 @@ import com.android.server.RescueParty; import com.android.server.SystemService; /** This class encapsulate the lifecycle methods of CrashRecovery module. */ /** This class encapsulate the lifecycle methods of CrashRecovery module. * * @hide */ public class CrashRecoveryModule { private static final String TAG = "CrashRecoveryModule"; Loading services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java +9 −6 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve // True if needing to roll back only rebootless apexes when native crash happens private boolean mTwoPhaseRollbackEnabled; /** @hide */ @VisibleForTesting public RollbackPackageHealthObserver(Context context, ApexManager apexManager) { mContext = context; Loading @@ -123,7 +124,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve } } RollbackPackageHealthObserver(Context context) { public RollbackPackageHealthObserver(@NonNull Context context) { this(context, ApexManager.getInstance()); } Loading Loading @@ -239,8 +240,8 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve return false; } @Override @NonNull public String getUniqueIdentifier() { return NAME; } Loading @@ -251,7 +252,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve } @Override public boolean mayObservePackage(String packageName) { public boolean mayObservePackage(@NonNull String packageName) { if (getAvailableRollbacks().isEmpty()) { return false; } Loading Loading @@ -281,12 +282,14 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve * This may cause {@code packages} to be rolled back if they crash too freqeuntly. */ @AnyThread void startObservingHealth(List<String> packages, long durationMs) { @NonNull public void startObservingHealth(@NonNull List<String> packages, @NonNull long durationMs) { PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs); } @AnyThread void notifyRollbackAvailable(RollbackInfo rollback) { @NonNull public void notifyRollbackAvailable(@NonNull RollbackInfo rollback) { mHandler.post(() -> { // Enable two-phase rollback when a rebootless apex rollback is made available. // We assume the rebootless apex is stable and is less likely to be the cause Loading Loading @@ -314,7 +317,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve * to check for native crashes and mitigate them if needed. */ @AnyThread void onBootCompletedAsync() { public void onBootCompletedAsync() { mHandler.post(()->onBootCompleted()); } Loading services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java +1 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import java.util.List; /** * This class handles the logic for logging Watchdog-triggered rollback events. * @hide */ public final class WatchdogRollbackLogger { private static final String TAG = "WatchdogRollbackLogger"; Loading Loading
services/core/java/com/android/server/PackageWatchdog.java +39 −12 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.server.crashrecovery.CrashRecoveryUtils.dumpCrashRecov import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -91,6 +92,7 @@ import java.util.concurrent.TimeUnit; * Monitors the health of packages on the system and notifies interested observers when packages * fail. On failure, the registered observer with the least user impacting mitigation will * be notified. * @hide */ public class PackageWatchdog { private static final String TAG = "PackageWatchdog"; Loading @@ -108,13 +110,25 @@ public class PackageWatchdog { private static final long NUMBER_OF_NATIVE_CRASH_POLLS = 10; /** Reason for package failure could not be determined. */ public static final int FAILURE_REASON_UNKNOWN = 0; /** The package had a native crash. */ public static final int FAILURE_REASON_NATIVE_CRASH = 1; /** The package failed an explicit health check. */ public static final int FAILURE_REASON_EXPLICIT_HEALTH_CHECK = 2; /** The app crashed. */ public static final int FAILURE_REASON_APP_CRASH = 3; /** The app was not responding. */ public static final int FAILURE_REASON_APP_NOT_RESPONDING = 4; /** The device was boot looping. */ public static final int FAILURE_REASON_BOOT_LOOP = 5; /** @hide */ @IntDef(prefix = { "FAILURE_REASON_" }, value = { FAILURE_REASON_UNKNOWN, FAILURE_REASON_NATIVE_CRASH, Loading Loading @@ -186,7 +200,8 @@ public class PackageWatchdog { // aborted. private static final String METADATA_FILE = "/metadata/watchdog/mitigation_count.txt"; @GuardedBy("PackageWatchdog.class") private static final Object sPackageWatchdogLock = new Object(); @GuardedBy("sPackageWatchdogLock") private static PackageWatchdog sPackageWatchdog; private final Object mLock = new Object(); Loading Loading @@ -278,8 +293,8 @@ public class PackageWatchdog { } /** Creates or gets singleton instance of PackageWatchdog. */ public static PackageWatchdog getInstance(Context context) { synchronized (PackageWatchdog.class) { public static @NonNull PackageWatchdog getInstance(@NonNull Context context) { synchronized (sPackageWatchdogLock) { if (sPackageWatchdog == null) { new PackageWatchdog(context); } Loading @@ -290,6 +305,7 @@ public class PackageWatchdog { /** * Called during boot to notify when packages are ready on the device so we can start * binding. * @hide */ public void onPackagesReady() { synchronized (mLock) { Loading @@ -311,6 +327,7 @@ public class PackageWatchdog { * * <p>Observers are expected to call this on boot. It does not specify any packages but * it will resume observing any packages requested from a previous boot. * @hide */ public void registerHealthObserver(PackageHealthObserver observer) { synchronized (mLock) { Loading Loading @@ -344,6 +361,7 @@ public class PackageWatchdog { * * <p>If {@code durationMs} is less than 1, a default monitoring duration * {@link #DEFAULT_OBSERVING_DURATION_MS} will be used. * @hide */ public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames, long durationMs) { Loading Loading @@ -407,6 +425,7 @@ public class PackageWatchdog { * Unregisters {@code observer} from listening to package failure. * Additionally, this stops observing any packages that may have previously been observed * even from a previous boot. * @hide */ public void unregisterHealthObserver(PackageHealthObserver observer) { mLongTaskHandler.post(() -> { Loading @@ -425,7 +444,7 @@ public class PackageWatchdog { * * <p>This method could be called frequently if there is a severe problem on the device. */ public void onPackageFailure(List<VersionedPackage> packages, public void onPackageFailure(@NonNull List<VersionedPackage> packages, @FailureReasons int failureReason) { if (packages == null) { Slog.w(TAG, "Could not resolve a list of failing packages"); Loading Loading @@ -566,6 +585,7 @@ public class PackageWatchdog { * * Note: PackageWatchdog considers system_server restart loop as bootloop. Full reboots * are not counted in bootloop. * @hide */ @SuppressWarnings("GuardedBy") public void noteBoot() { Loading Loading @@ -620,7 +640,7 @@ public class PackageWatchdog { // TODO(b/120598832): Optimize write? Maybe only write a separate smaller file? Also // avoid holding lock? // This currently adds about 7ms extra to shutdown thread /** Writes the package information to file during shutdown. */ /** @hide Writes the package information to file during shutdown. */ public void writeNow() { synchronized (mLock) { // Must only run synchronous tasks as this runs on the ShutdownThread and no other Loading Loading @@ -674,6 +694,7 @@ public class PackageWatchdog { * Since this method can eventually trigger a rollback, it should be called * only once boot has completed {@code onBootCompleted} and not earlier, because the install * session must be entirely completed before we try to rollback. * @hide */ public void scheduleCheckAndMitigateNativeCrashes() { Slog.i(TAG, "Scheduling " + mNumberOfNativeCrashPollsRemaining + " polls to check " Loading @@ -695,7 +716,9 @@ public class PackageWatchdog { return mPackagesExemptFromImpactLevelThreshold; } /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */ /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. * @hide */ @Retention(SOURCE) @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_LEVEL_0, PackageHealthObserverImpact.USER_IMPACT_LEVEL_10, Loading Loading @@ -787,7 +810,7 @@ public class PackageWatchdog { * Identifier for the observer, should not change across device updates otherwise the * watchdog may drop observing packages with the old name. */ String getUniqueIdentifier(); @NonNull String getUniqueIdentifier(); /** * An observer will not be pruned if this is set, even if the observer is not explicitly Loading @@ -804,7 +827,7 @@ public class PackageWatchdog { * <p> A persistent observer may choose to start observing certain failing packages, even if * it has not explicitly asked to watch the package with {@link #startObservingHealth}. */ default boolean mayObservePackage(String packageName) { default boolean mayObservePackage(@NonNull String packageName) { return false; } } Loading Loading @@ -1240,7 +1263,7 @@ public class PackageWatchdog { } } /** Convert a {@code LongArrayQueue} to a String of comma-separated values. */ /** @hide Convert a {@code LongArrayQueue} to a String of comma-separated values. */ public static String longArrayQueueToString(LongArrayQueue queue) { if (queue.size() > 0) { StringBuilder sb = new StringBuilder(); Loading @@ -1254,7 +1277,7 @@ public class PackageWatchdog { return ""; } /** Parse a comma-separated String of longs into a LongArrayQueue. */ /** @hide Parse a comma-separated String of longs into a LongArrayQueue. */ public static LongArrayQueue parseLongArrayQueue(String commaSeparatedValues) { LongArrayQueue result = new LongArrayQueue(); if (!TextUtils.isEmpty(commaSeparatedValues)) { Loading @@ -1268,7 +1291,7 @@ public class PackageWatchdog { /** Dump status of every observer in mAllObservers. */ public void dump(PrintWriter pw) { public void dump(@NonNull PrintWriter pw) { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.println("Package Watchdog status"); ipw.increaseIndent(); Loading Loading @@ -1395,6 +1418,7 @@ public class PackageWatchdog { /** * Increments failure counts of {@code packageName}. * @returns {@code true} if failure threshold is exceeded, {@code false} otherwise * @hide */ @GuardedBy("mLock") public boolean onPackageFailureLocked(String packageName) { Loading Loading @@ -1514,6 +1538,7 @@ public class PackageWatchdog { } } /** @hide */ @Retention(SOURCE) @IntDef(value = { HealthCheckState.ACTIVE, Loading Loading @@ -1603,7 +1628,9 @@ public class PackageWatchdog { updateHealthCheckStateLocked(); } /** Writes the salient fields to disk using {@code out}. */ /** Writes the salient fields to disk using {@code out}. * @hide */ @GuardedBy("mLock") public void writeLocked(TypedXmlSerializer out) throws IOException { out.startTag(null, TAG_PACKAGE); Loading
services/core/java/com/android/server/crashrecovery/CrashRecoveryModule.java +4 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,10 @@ import com.android.server.RescueParty; import com.android.server.SystemService; /** This class encapsulate the lifecycle methods of CrashRecovery module. */ /** This class encapsulate the lifecycle methods of CrashRecovery module. * * @hide */ public class CrashRecoveryModule { private static final String TAG = "CrashRecoveryModule"; Loading
services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java +9 −6 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve // True if needing to roll back only rebootless apexes when native crash happens private boolean mTwoPhaseRollbackEnabled; /** @hide */ @VisibleForTesting public RollbackPackageHealthObserver(Context context, ApexManager apexManager) { mContext = context; Loading @@ -123,7 +124,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve } } RollbackPackageHealthObserver(Context context) { public RollbackPackageHealthObserver(@NonNull Context context) { this(context, ApexManager.getInstance()); } Loading Loading @@ -239,8 +240,8 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve return false; } @Override @NonNull public String getUniqueIdentifier() { return NAME; } Loading @@ -251,7 +252,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve } @Override public boolean mayObservePackage(String packageName) { public boolean mayObservePackage(@NonNull String packageName) { if (getAvailableRollbacks().isEmpty()) { return false; } Loading Loading @@ -281,12 +282,14 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve * This may cause {@code packages} to be rolled back if they crash too freqeuntly. */ @AnyThread void startObservingHealth(List<String> packages, long durationMs) { @NonNull public void startObservingHealth(@NonNull List<String> packages, @NonNull long durationMs) { PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs); } @AnyThread void notifyRollbackAvailable(RollbackInfo rollback) { @NonNull public void notifyRollbackAvailable(@NonNull RollbackInfo rollback) { mHandler.post(() -> { // Enable two-phase rollback when a rebootless apex rollback is made available. // We assume the rebootless apex is stable and is less likely to be the cause Loading Loading @@ -314,7 +317,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve * to check for native crashes and mitigate them if needed. */ @AnyThread void onBootCompletedAsync() { public void onBootCompletedAsync() { mHandler.post(()->onBootCompleted()); } Loading
services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java +1 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import java.util.List; /** * This class handles the logic for logging Watchdog-triggered rollback events. * @hide */ public final class WatchdogRollbackLogger { private static final String TAG = "WatchdogRollbackLogger"; Loading