Merge changes from topic "wd-flags-master"
* changes: Update PackageWatchdogTest Make PackageWatchdog variables configurable
This commit is contained in:
committed by
Android (Google) Code Review
commit
d0565e7f80
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
// Flag to control whether explicit health checks are supported or not
|
||||
@GuardedBy("mLock")
|
||||
private boolean mIsHealthCheckEnabled = true;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mIsPackagesReady;
|
||||
// Flag to control whether explicit health checks are supported or not
|
||||
@GuardedBy("mLock")
|
||||
private boolean mIsHealthCheckEnabled = DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED;
|
||||
@GuardedBy("mLock")
|
||||
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,14 +351,13 @@ 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.
|
||||
* <p> If explicit health checks are disabled, pending explicit health check requests are
|
||||
* passed and the health check service is stopped.
|
||||
*/
|
||||
public void setExplicitHealthCheckEnabled(boolean enabled) {
|
||||
private void setExplicitHealthCheckEnabled(boolean enabled) {
|
||||
synchronized (mLock) {
|
||||
mIsHealthCheckEnabled = enabled;
|
||||
mHealthCheckController.setEnabled(enabled);
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,25 +18,27 @@ package com.android.server;
|
||||
|
||||
import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
|
||||
|
||||
import static com.android.server.PackageWatchdog.MonitoredPackage;
|
||||
import static com.android.server.PackageWatchdog.TRIGGER_FAILURE_COUNT;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.pm.VersionedPackage;
|
||||
import android.os.Handler;
|
||||
import android.os.test.TestLooper;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.AtomicFile;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import com.android.server.PackageWatchdog.MonitoredPackage;
|
||||
import com.android.server.PackageWatchdog.PackageHealthObserver;
|
||||
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -73,8 +75,13 @@ public class PackageWatchdogTest {
|
||||
public void setUp() throws Exception {
|
||||
new File(InstrumentationRegistry.getContext().getFilesDir(),
|
||||
"package-watchdog.xml").delete();
|
||||
adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG);
|
||||
mTestLooper = new TestLooper();
|
||||
mTestLooper.startAutoDispatch();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
dropShellPermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +211,7 @@ public class PackageWatchdogTest {
|
||||
// Verify random observer not saved returns null
|
||||
assertNull(watchdog2.getPackages(new TestObserver(OBSERVER_NAME_3)));
|
||||
|
||||
// Then regiser observer1
|
||||
// Then register observer1
|
||||
watchdog2.registerHealthObserver(observer1);
|
||||
watchdog2.registerHealthObserver(observer2);
|
||||
|
||||
@@ -231,7 +238,7 @@ public class PackageWatchdogTest {
|
||||
watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
|
||||
|
||||
// Then fail APP_A below the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT - 1; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount() - 1; i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
|
||||
}
|
||||
|
||||
@@ -258,7 +265,7 @@ public class PackageWatchdogTest {
|
||||
watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION);
|
||||
|
||||
// Then fail APP_C (not observed) above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)));
|
||||
}
|
||||
|
||||
@@ -292,7 +299,7 @@ public class PackageWatchdogTest {
|
||||
watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
|
||||
|
||||
// Then fail APP_A (different version) above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(
|
||||
new VersionedPackage(APP_A, differentVersionCode)));
|
||||
}
|
||||
@@ -331,7 +338,7 @@ public class PackageWatchdogTest {
|
||||
SHORT_DURATION);
|
||||
|
||||
// Then fail all apps above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
|
||||
new VersionedPackage(APP_B, VERSION_CODE),
|
||||
new VersionedPackage(APP_C, VERSION_CODE),
|
||||
@@ -384,7 +391,7 @@ public class PackageWatchdogTest {
|
||||
watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION);
|
||||
|
||||
// Then fail APP_A above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
|
||||
}
|
||||
// Run handler so package failures are dispatched to observers
|
||||
@@ -401,7 +408,7 @@ public class PackageWatchdogTest {
|
||||
observerSecond.mFailedPackages.clear();
|
||||
|
||||
// Then fail APP_A again above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
|
||||
}
|
||||
// Run handler so package failures are dispatched to observers
|
||||
@@ -418,7 +425,7 @@ public class PackageWatchdogTest {
|
||||
observerSecond.mFailedPackages.clear();
|
||||
|
||||
// Then fail APP_A again above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
|
||||
}
|
||||
// Run handler so package failures are dispatched to observers
|
||||
@@ -435,7 +442,7 @@ public class PackageWatchdogTest {
|
||||
observerSecond.mFailedPackages.clear();
|
||||
|
||||
// Then fail APP_A again above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
|
||||
}
|
||||
// Run handler so package failures are dispatched to observers
|
||||
@@ -462,7 +469,7 @@ public class PackageWatchdogTest {
|
||||
watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
|
||||
|
||||
// Then fail APP_A above the threshold
|
||||
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
|
||||
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
|
||||
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
|
||||
}
|
||||
|
||||
@@ -539,6 +546,10 @@ public class PackageWatchdogTest {
|
||||
*/
|
||||
@Test
|
||||
public void testExplicitHealthCheckStateChanges() throws Exception {
|
||||
adoptShellPermissions(
|
||||
Manifest.permission.WRITE_DEVICE_CONFIG,
|
||||
Manifest.permission.READ_DEVICE_CONFIG);
|
||||
|
||||
TestController controller = new TestController();
|
||||
PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */);
|
||||
TestObserver observer = new TestObserver(OBSERVER_NAME_1,
|
||||
@@ -559,7 +570,7 @@ public class PackageWatchdogTest {
|
||||
assertEquals(APP_B, requestedPackages.get(1));
|
||||
|
||||
// Disable explicit health checks (marks APP_A and APP_B as passed)
|
||||
watchdog.setExplicitHealthCheckEnabled(false);
|
||||
setExplicitHealthCheckEnabled(false);
|
||||
|
||||
// Run handler so requests/cancellations are dispatched to the controller
|
||||
mTestLooper.dispatchAll();
|
||||
@@ -575,7 +586,7 @@ public class PackageWatchdogTest {
|
||||
assertEquals(0, observer.mFailedPackages.size());
|
||||
|
||||
// Re-enable explicit health checks
|
||||
watchdog.setExplicitHealthCheckEnabled(true);
|
||||
setExplicitHealthCheckEnabled(true);
|
||||
|
||||
// Run handler so requests/cancellations are dispatched to the controller
|
||||
mTestLooper.dispatchAll();
|
||||
@@ -643,11 +654,13 @@ public class PackageWatchdogTest {
|
||||
/** Tests {@link MonitoredPackage} health check state transitions. */
|
||||
@Test
|
||||
public void testPackageHealthCheckStateTransitions() {
|
||||
MonitoredPackage m1 = new MonitoredPackage(APP_A, LONG_DURATION,
|
||||
TestController controller = new TestController();
|
||||
PackageWatchdog wd = createWatchdog(controller, true /* withPackagesReady */);
|
||||
MonitoredPackage m1 = wd.new MonitoredPackage(APP_A, LONG_DURATION,
|
||||
false /* hasPassedHealthCheck */);
|
||||
MonitoredPackage m2 = new MonitoredPackage(APP_B, LONG_DURATION, false);
|
||||
MonitoredPackage m3 = new MonitoredPackage(APP_C, LONG_DURATION, false);
|
||||
MonitoredPackage m4 = new MonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true);
|
||||
MonitoredPackage m2 = wd.new MonitoredPackage(APP_B, LONG_DURATION, false);
|
||||
MonitoredPackage m3 = wd.new MonitoredPackage(APP_C, LONG_DURATION, false);
|
||||
MonitoredPackage m4 = wd.new MonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true);
|
||||
|
||||
// Verify transition: inactive -> active -> passed
|
||||
// Verify initially inactive
|
||||
@@ -683,6 +696,32 @@ public class PackageWatchdogTest {
|
||||
assertEquals(MonitoredPackage.STATE_PASSED, m4.handleElapsedTimeLocked(LONG_DURATION));
|
||||
}
|
||||
|
||||
private void adoptShellPermissions(String... permissions) {
|
||||
InstrumentationRegistry
|
||||
.getInstrumentation()
|
||||
.getUiAutomation()
|
||||
.adoptShellPermissionIdentity(permissions);
|
||||
}
|
||||
|
||||
private void dropShellPermissions() {
|
||||
InstrumentationRegistry
|
||||
.getInstrumentation()
|
||||
.getUiAutomation()
|
||||
.dropShellPermissionIdentity();
|
||||
}
|
||||
|
||||
private void setExplicitHealthCheckEnabled(boolean enabled) {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
|
||||
PackageWatchdog.PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED,
|
||||
Boolean.toString(enabled), /*makeDefault*/false);
|
||||
//give time for DeviceConfig to broadcast the property value change
|
||||
try {
|
||||
Thread.sleep(SHORT_DURATION);
|
||||
} catch (InterruptedException e) {
|
||||
fail("Thread.sleep unexpectedly failed!");
|
||||
}
|
||||
}
|
||||
|
||||
private PackageWatchdog createWatchdog() {
|
||||
return createWatchdog(new TestController(), true /* withPackagesReady */);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user