summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/service/watchdog/ExplicitHealthCheckService.java1
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java96
2 files changed, 81 insertions, 16 deletions
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
index eeefb4ae10fa..dc9c85808240 100644
--- a/core/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -183,7 +183,6 @@ public abstract class ExplicitHealthCheckService extends Service {
*/
@SystemApi
public static final class PackageConfig implements Parcelable {
- // TODO: Receive from DeviceConfig flag
private static final long DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(1);
private final String mPackageName;
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index b44009fd6880..e383c522f474 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -29,6 +29,7 @@ import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
+import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -61,6 +62,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
/**
* Monitors the health of packages on the system and notifies interested observers when packages
@@ -69,10 +71,22 @@ import java.util.Set;
*/
public class PackageWatchdog {
private static final String TAG = "PackageWatchdog";
+
+ static final String PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS =
+ "watchdog_trigger_failure_duration_millis";
+ static final String PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT =
+ "watchdog_trigger_failure_count";
+ static final String PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED =
+ "watchdog_explicit_health_check_enabled";
+
// Duration to count package failures before it resets to 0
- private static final int TRIGGER_DURATION_MS = 60000;
+ private static final int DEFAULT_TRIGGER_FAILURE_DURATION_MS =
+ (int) TimeUnit.MINUTES.toMillis(1);
// Number of package failures within the duration above before we notify observers
- static final int TRIGGER_FAILURE_COUNT = 5;
+ private static final int DEFAULT_TRIGGER_FAILURE_COUNT = 5;
+ // Whether explicit health checks are enabled or not
+ private static final boolean DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED = true;
+
private static final int DB_VERSION = 1;
private static final String TAG_PACKAGE_WATCHDOG = "package-watchdog";
private static final String TAG_PACKAGE = "package";
@@ -83,6 +97,7 @@ public class PackageWatchdog {
private static final String ATTR_EXPLICIT_HEALTH_CHECK_DURATION = "health-check-duration";
private static final String ATTR_PASSED_HEALTH_CHECK = "passed-health-check";
+ @GuardedBy("PackageWatchdog.class")
private static PackageWatchdog sPackageWatchdog;
private final Object mLock = new Object();
@@ -100,11 +115,15 @@ public class PackageWatchdog {
// File containing the XML data of monitored packages /data/system/package-watchdog.xml
private final AtomicFile mPolicyFile;
private final ExplicitHealthCheckController mHealthCheckController;
+ @GuardedBy("mLock")
+ private boolean mIsPackagesReady;
// Flag to control whether explicit health checks are supported or not
@GuardedBy("mLock")
- private boolean mIsHealthCheckEnabled = true;
+ private boolean mIsHealthCheckEnabled = DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED;
@GuardedBy("mLock")
- private boolean mIsPackagesReady;
+ private int mTriggerFailureDurationMs = DEFAULT_TRIGGER_FAILURE_DURATION_MS;
+ @GuardedBy("mLock")
+ private int mTriggerFailureCount = DEFAULT_TRIGGER_FAILURE_COUNT;
// SystemClock#uptimeMillis when we last executed #syncState
// 0 if no prune is scheduled.
@GuardedBy("mLock")
@@ -153,8 +172,8 @@ public class PackageWatchdog {
mHealthCheckController.setCallbacks(packageName -> onHealthCheckPassed(packageName),
packages -> onSupportedPackages(packages),
() -> syncRequestsAsync());
- // Controller is initially disabled until here where we may enable it and sync our state
- setExplicitHealthCheckEnabled(mIsHealthCheckEnabled);
+ setPropertyChangedListenerLocked();
+ updateConfigs();
}
}
@@ -332,7 +351,6 @@ public class PackageWatchdog {
}
}
- // TODO(b/120598832): Set depending on DeviceConfig flag
/**
* Enables or disables explicit health checks.
* <p> If explicit health checks are enabled, the health check service is started.
@@ -390,6 +408,12 @@ public class PackageWatchdog {
String getName();
}
+ long getTriggerFailureCount() {
+ synchronized (mLock) {
+ return mTriggerFailureCount;
+ }
+ }
+
/**
* Serializes and syncs health check requests with the {@link ExplicitHealthCheckController}.
*/
@@ -646,7 +670,7 @@ public class PackageWatchdog {
XmlUtils.beginDocument(parser, TAG_PACKAGE_WATCHDOG);
int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
- ObserverInternal observer = ObserverInternal.read(parser);
+ ObserverInternal observer = ObserverInternal.read(parser, this);
if (observer != null) {
mAllObservers.put(observer.mName, observer);
}
@@ -661,6 +685,48 @@ public class PackageWatchdog {
}
}
+ /** Adds a {@link DeviceConfig#OnPropertyChangedListener}. */
+ private void setPropertyChangedListenerLocked() {
+ DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ mContext.getMainExecutor(),
+ (namespace, name, value) -> {
+ if (!DeviceConfig.NAMESPACE_ROLLBACK.equals(namespace)) {
+ return;
+ }
+ updateConfigs();
+ });
+ }
+
+ /**
+ * Health check is enabled or disabled after reading the flags
+ * from DeviceConfig.
+ */
+ private void updateConfigs() {
+ synchronized (mLock) {
+ mTriggerFailureCount = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
+ DEFAULT_TRIGGER_FAILURE_COUNT);
+ if (mTriggerFailureCount <= 0) {
+ mTriggerFailureCount = DEFAULT_TRIGGER_FAILURE_COUNT;
+ }
+
+ mTriggerFailureDurationMs = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS,
+ DEFAULT_TRIGGER_FAILURE_DURATION_MS);
+ if (mTriggerFailureDurationMs <= 0) {
+ mTriggerFailureDurationMs = DEFAULT_TRIGGER_FAILURE_COUNT;
+ }
+
+ setExplicitHealthCheckEnabled(DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_ROLLBACK,
+ PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED,
+ DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED));
+ }
+ }
+
/**
* Persists mAllObservers to file. Threshold information is ignored.
*/
@@ -805,7 +871,7 @@ public class PackageWatchdog {
* #loadFromFile which in turn is only called on construction of the
* singleton PackageWatchdog.
**/
- public static ObserverInternal read(XmlPullParser parser) {
+ public static ObserverInternal read(XmlPullParser parser, PackageWatchdog watchdog) {
String observerName = null;
if (TAG_OBSERVER.equals(parser.getName())) {
observerName = parser.getAttributeValue(null, ATTR_NAME);
@@ -829,7 +895,7 @@ public class PackageWatchdog {
boolean hasPassedHealthCheck = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_PASSED_HEALTH_CHECK));
if (!TextUtils.isEmpty(packageName)) {
- packages.add(new MonitoredPackage(packageName, duration,
+ packages.add(watchdog.new MonitoredPackage(packageName, duration,
healthCheckDuration, hasPassedHealthCheck));
}
} catch (NumberFormatException e) {
@@ -856,7 +922,7 @@ public class PackageWatchdog {
* <p> Note, the PackageWatchdog#mLock must always be held when reading or writing
* instances of this class.
*/
- static class MonitoredPackage {
+ class MonitoredPackage {
// Health check states
// TODO(b/120598832): Prefix with HEALTH_CHECK
// mName has not passed health check but has requested a health check
@@ -931,7 +997,7 @@ public class PackageWatchdog {
public boolean onFailureLocked() {
final long now = SystemClock.uptimeMillis();
final long duration = now - mUptimeStartMs;
- if (duration > TRIGGER_DURATION_MS) {
+ if (duration > mTriggerFailureDurationMs) {
// TODO(b/120598832): Reseting to 1 is not correct
// because there may be more than 1 failure in the last trigger window from now
// This is the RescueParty impl, will leave for now
@@ -940,7 +1006,7 @@ public class PackageWatchdog {
} else {
mFailures++;
}
- boolean failed = mFailures >= TRIGGER_FAILURE_COUNT;
+ boolean failed = mFailures >= mTriggerFailureCount;
if (failed) {
mFailures = 0;
}
@@ -1065,7 +1131,7 @@ public class PackageWatchdog {
}
/** Returns a {@link String} representation of the current health check state. */
- private static String toString(int state) {
+ private String toString(int state) {
switch (state) {
case STATE_ACTIVE:
return "ACTIVE";
@@ -1081,7 +1147,7 @@ public class PackageWatchdog {
}
/** Returns {@code value} if it is greater than 0 or {@link Long#MAX_VALUE} otherwise. */
- private static long toPositive(long value) {
+ private long toPositive(long value) {
return value > 0 ? value : Long.MAX_VALUE;
}
}