From 3c3c68eff8ee55b190dd6d172a033b30f2e4bb6b Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 16 Apr 2021 19:18:27 +0100 Subject: [PATCH] Add server flag for the lower bound Add a server flag for the lower bound time used by the time_detector to validate times in suggestions. This can be used during tests to confirm that suggestions are properly compared against the lower bound before being used, and to bypass the lower bound check when running tests with historical data. Note: Currently, the lower bound is used to validate / filter suggestions when they are received. Invalid suggestions are discarded, leaving old suggestions. Changing the lower bound will not cause the time_detector to discard / ignore already accepted suggestions if they now fall below the lower bound. Testing: adb shell dumpsys time_detector # Look at reported lower bound adb shell device_config put system_time \ time_detector_lower_bound_millis_override 0 adb shell dumpsys time_detector # Look at reported lower bound adb shell device_config delete system_time \ time_detector_lower_bound_millis_override adb shell dumpsys time_detector # Look at reported lower bound Bug: 172229867 Test: See above Change-Id: If1d5fd1aa09732c05808cc13dd257f2daeea6220 --- .../server/timedetector/ServerFlags.java | 31 +++++++++++++++++++ .../timedetector/ServiceConfigAccessor.java | 6 +++- .../TimeDetectorShellCommand.java | 4 +++ .../TimeDetectorStrategyImpl.java | 4 +-- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/timedetector/ServerFlags.java b/services/core/java/com/android/server/timedetector/ServerFlags.java index fda0e3cd947c6..7145f5ea4a645 100644 --- a/services/core/java/com/android/server/timedetector/ServerFlags.java +++ b/services/core/java/com/android/server/timedetector/ServerFlags.java @@ -30,7 +30,9 @@ import com.android.server.timezonedetector.ServiceConfigAccessor; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.time.DateTimeException; import java.time.Duration; +import java.time.Instant; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -62,6 +64,8 @@ public final class ServerFlags { KEY_LOCATION_TIME_ZONE_DETECTION_UNCERTAINTY_DELAY_MILLIS, KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE, KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT, + KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE, + KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE, }) @Retention(RetentionPolicy.SOURCE) @interface DeviceConfigKey {} @@ -144,6 +148,14 @@ public final class ServerFlags { public static final String KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE = "time_detector_origin_priorities_override"; + /** + * The key to override the time detector lower bound configuration. The values is the number of + * milliseconds since the beginning of the Unix epoch. + */ + @DeviceConfigKey + public static final String KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE = + "time_detector_lower_bound_millis_override"; + @GuardedBy("mListeners") private final ArrayMap> mListeners = new ArrayMap<>(); @@ -230,6 +242,25 @@ public final class ServerFlags { return Optional.of(string.get().split(",")); } + /** + * Returns an {@link Instant} from {@link DeviceConfig} from the system_time + * namespace, returns the {@code defaultValue} if the value is missing or invalid. + */ + @NonNull + public Optional getOptionalInstant(@DeviceConfigKey String key) { + String value = DeviceConfig.getProperty(NAMESPACE_SYSTEM_TIME, key); + if (value == null) { + return Optional.empty(); + } + + try { + long millis = Long.parseLong(value); + return Optional.of(Instant.ofEpochMilli(millis)); + } catch (DateTimeException | NumberFormatException e) { + return Optional.empty(); + } + } + /** * Returns an optional boolean value from {@link DeviceConfig} from the system_time * namespace, returns {@link Optional#empty()} if there is no explicit value set. diff --git a/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java index 381b77e5d1d2e..dac8a0a78edee 100644 --- a/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java +++ b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java @@ -15,6 +15,7 @@ */ package com.android.server.timedetector; +import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE; import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE; import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK; import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY; @@ -65,6 +66,7 @@ final class ServiceConfigAccessor { private static final Set SERVER_FLAGS_KEYS_TO_WATCH = Collections.unmodifiableSet( new ArraySet<>(new String[] { + KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE, KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE, })); @@ -137,8 +139,10 @@ final class ServiceConfigAccessor { return mSystemClockUpdateThresholdMillis; } + @NonNull Instant autoTimeLowerBound() { - return TIME_LOWER_BOUND_DEFAULT; + return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE) + .orElse(TIME_LOWER_BOUND_DEFAULT); } /** diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java index 3cb21aaf85ce7..233cc57fd71b8 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java @@ -18,6 +18,7 @@ package com.android.server.timedetector; import static android.app.timedetector.TimeDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED; import static android.provider.DeviceConfig.NAMESPACE_SYSTEM_TIME; +import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE; import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE; import android.os.ShellCommand; @@ -68,6 +69,9 @@ class TimeDetectorShellCommand extends ShellCommand { pw.println(); pw.printf("This service is also affected by the following device_config flags in the" + " %s namespace:\n", NAMESPACE_SYSTEM_TIME); + pw.printf(" %s - the lower bound used to validate time suggestions when they are" + + " received.\n", KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE); + pw.println(" Specified in milliseconds since the start of the Unix epoch."); pw.printf(" %s - [default=null], a comma separated list of origins. See" + " TimeDetectorStrategy for details\n", KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE); diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java index db8a59e0ab265..357c232226582 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java @@ -325,9 +325,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { ipw.println("mEnvironment.systemClockMillis()=" + mEnvironment.systemClockMillis()); ipw.println("mEnvironment.systemClockUpdateThresholdMillis()=" + mEnvironment.systemClockUpdateThresholdMillis()); + Instant autoTimeLowerBound = mEnvironment.autoTimeLowerBound(); ipw.printf("mEnvironment.autoTimeLowerBound()=%s(%s)\n", - mEnvironment.autoTimeLowerBound(), - mEnvironment.autoTimeLowerBound().toEpochMilli()); + autoTimeLowerBound, autoTimeLowerBound.toEpochMilli()); String priorities = Arrays.stream(mEnvironment.autoOriginPriorities()) .mapToObj(TimeDetectorStrategy::originToString)