Loading services/core/java/com/android/server/timedetector/ConfigurationInternal.java +125 −12 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE; import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED; import static android.app.time.Capabilities.CAPABILITY_POSSESSED; import static java.util.stream.Collectors.joining; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.time.Capabilities.CapabilityState; Loading @@ -29,6 +31,10 @@ import android.app.time.TimeCapabilitiesAndConfig; import android.app.time.TimeConfiguration; import android.os.UserHandle; import com.android.server.timedetector.TimeDetectorStrategy.Origin; import java.time.Instant; import java.util.Arrays; import java.util.Objects; /** Loading @@ -39,12 +45,20 @@ import java.util.Objects; public final class ConfigurationInternal { private final boolean mAutoDetectionSupported; private final int mSystemClockUpdateThresholdMillis; private final Instant mAutoTimeLowerBound; private final @Origin int[] mOriginPriorities; private final boolean mDeviceHasY2038Issue; private final boolean mAutoDetectionEnabledSetting; private final @UserIdInt int mUserId; private final boolean mUserConfigAllowed; private ConfigurationInternal(Builder builder) { mAutoDetectionSupported = builder.mAutoDetectionSupported; mSystemClockUpdateThresholdMillis = builder.mSystemClockUpdateThresholdMillis; mAutoTimeLowerBound = Objects.requireNonNull(builder.mAutoTimeLowerBound); mOriginPriorities = Objects.requireNonNull(builder.mOriginPriorities); mDeviceHasY2038Issue = builder.mDeviceHasY2038Issue; mAutoDetectionEnabledSetting = builder.mAutoDetectionEnabledSetting; mUserId = builder.mUserId; Loading @@ -56,6 +70,42 @@ public final class ConfigurationInternal { return mAutoDetectionSupported; } /** * Returns the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ public int getSystemClockUpdateThresholdMillis() { return mSystemClockUpdateThresholdMillis; } /** * Returns the lower bound for valid automatic times. It is guaranteed to be in the past, * i.e. it is unrelated to the current system clock time. * It holds no other meaning; it could be related to when the device system image was built, * or could be updated by a mainline module. */ @NonNull public Instant getAutoTimeLowerBound() { return mAutoTimeLowerBound; } /** * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ public @Origin int[] getAutoOriginPriorities() { return mOriginPriorities; } /** * Returns {@code true} if the device may be at risk of time_t overflow (because bionic * defines time_t as a 32-bit signed integer for 32-bit processes). */ public boolean getDeviceHasY2038Issue() { return mDeviceHasY2038Issue; } /** Returns the value of the auto time detection enabled setting. */ public boolean getAutoDetectionEnabledSetting() { return mAutoDetectionEnabledSetting; Loading Loading @@ -146,38 +196,61 @@ public final class ConfigurationInternal { @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; if (this == o) { return true; } if (!(o instanceof ConfigurationInternal)) { return false; } ConfigurationInternal that = (ConfigurationInternal) o; return mAutoDetectionSupported == that.mAutoDetectionSupported && mUserId == that.mUserId && mUserConfigAllowed == that.mUserConfigAllowed && mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting; && mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting && mUserId == that.mUserId && mUserConfigAllowed == that.mUserConfigAllowed && mSystemClockUpdateThresholdMillis == that.mSystemClockUpdateThresholdMillis && mAutoTimeLowerBound.equals(that.mAutoTimeLowerBound) && mDeviceHasY2038Issue == that.mDeviceHasY2038Issue && Arrays.equals(mOriginPriorities, that.mOriginPriorities); } @Override public int hashCode() { return Objects.hash(mAutoDetectionSupported, mUserId, mUserConfigAllowed, mAutoDetectionEnabledSetting); int result = Objects.hash(mAutoDetectionSupported, mAutoDetectionEnabledSetting, mUserId, mUserConfigAllowed, mSystemClockUpdateThresholdMillis, mAutoTimeLowerBound, mDeviceHasY2038Issue); result = 31 * result + Arrays.hashCode(mOriginPriorities); return result; } @Override public String toString() { String originPrioritiesString = Arrays.stream(mOriginPriorities) .mapToObj(TimeDetectorStrategy::originToString) .collect(joining(",", "[", "]")); return "ConfigurationInternal{" + "mAutoDetectionSupported=" + mAutoDetectionSupported + "mUserId=" + mUserId + ", mUserConfigAllowed=" + mUserConfigAllowed + ", mSystemClockUpdateThresholdMillis=" + mSystemClockUpdateThresholdMillis + ", mAutoTimeLowerBound=" + mAutoTimeLowerBound + "(" + mAutoTimeLowerBound.toEpochMilli() + ")" + ", mOriginPriorities=" + originPrioritiesString + ", mDeviceHasY2038Issue=" + mDeviceHasY2038Issue + ", mAutoDetectionEnabled=" + mAutoDetectionEnabledSetting + ", mUserId=" + mUserId + ", mUserConfigAllowed=" + mUserConfigAllowed + '}'; } static final class Builder { private final @UserIdInt int mUserId; private boolean mUserConfigAllowed; private boolean mAutoDetectionSupported; private int mSystemClockUpdateThresholdMillis; @NonNull private Instant mAutoTimeLowerBound; @NonNull private @Origin int[] mOriginPriorities; private boolean mDeviceHasY2038Issue; private boolean mAutoDetectionEnabledSetting; private final @UserIdInt int mUserId; private boolean mUserConfigAllowed; Builder(@UserIdInt int userId) { mUserId = userId; } Loading @@ -189,6 +262,10 @@ public final class ConfigurationInternal { this.mUserId = toCopy.mUserId; this.mUserConfigAllowed = toCopy.mUserConfigAllowed; this.mAutoDetectionSupported = toCopy.mAutoDetectionSupported; this.mSystemClockUpdateThresholdMillis = toCopy.mSystemClockUpdateThresholdMillis; this.mAutoTimeLowerBound = toCopy.mAutoTimeLowerBound; this.mOriginPriorities = toCopy.mOriginPriorities; this.mDeviceHasY2038Issue = toCopy.mDeviceHasY2038Issue; this.mAutoDetectionEnabledSetting = toCopy.mAutoDetectionEnabledSetting; } Loading @@ -208,6 +285,33 @@ public final class ConfigurationInternal { return this; } /** * Sets the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ public Builder setSystemClockUpdateThresholdMillis(int systemClockUpdateThresholdMillis) { mSystemClockUpdateThresholdMillis = systemClockUpdateThresholdMillis; return this; } /** * Sets the lower bound for valid automatic times. */ public Builder setAutoTimeLowerBound(@NonNull Instant autoTimeLowerBound) { mAutoTimeLowerBound = Objects.requireNonNull(autoTimeLowerBound); return this; } /** * Sets the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ public Builder setOriginPriorities(@NonNull @Origin int... originPriorities) { mOriginPriorities = Objects.requireNonNull(originPriorities); return this; } /** * Sets the value of the automatic time detection enabled setting for this device. */ Loading @@ -216,6 +320,15 @@ public final class ConfigurationInternal { return this; } /** * Returns {@code true} if the device may be at risk of time_t overflow (because bionic * defines time_t as a 32-bit signed integer for 32-bit processes). */ Builder setDeviceHasY2038Issue(boolean deviceHasY2038Issue) { mDeviceHasY2038Issue = deviceHasY2038Issue; return this; } /** Returns a new {@link ConfigurationInternal}. */ @NonNull ConfigurationInternal build() { Loading services/core/java/com/android/server/timedetector/EnvironmentImpl.java +0 −31 Original line number Diff line number Diff line Loading @@ -18,18 +18,14 @@ package com.android.server.timedetector; import android.annotation.NonNull; import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserManager; import android.util.Slog; import com.android.server.timezonedetector.ConfigurationChangeListener; import java.time.Instant; import java.util.Objects; /** Loading @@ -39,18 +35,13 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { private static final String LOG_TAG = TimeDetectorService.TAG; @NonNull private final Context mContext; @NonNull private final Handler mHandler; @NonNull private final ServiceConfigAccessor mServiceConfigAccessor; @NonNull private final ContentResolver mContentResolver; @NonNull private final PowerManager.WakeLock mWakeLock; @NonNull private final AlarmManager mAlarmManager; @NonNull private final UserManager mUserManager; EnvironmentImpl(@NonNull Context context, @NonNull Handler handler, @NonNull ServiceConfigAccessor serviceConfigAccessor) { mContext = Objects.requireNonNull(context); mContentResolver = Objects.requireNonNull(context.getContentResolver()); mHandler = Objects.requireNonNull(handler); mServiceConfigAccessor = Objects.requireNonNull(serviceConfigAccessor); Loading @@ -59,8 +50,6 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG)); mAlarmManager = Objects.requireNonNull(context.getSystemService(AlarmManager.class)); mUserManager = Objects.requireNonNull(context.getSystemService(UserManager.class)); } @Override Loading @@ -71,21 +60,6 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { mServiceConfigAccessor.addConfigurationInternalChangeListener(configurationChangeListener); } @Override public int systemClockUpdateThresholdMillis() { return mServiceConfigAccessor.systemClockUpdateThresholdMillis(); } @Override public Instant autoTimeLowerBound() { return mServiceConfigAccessor.autoTimeLowerBound(); } @Override public int[] autoOriginPriorities() { return mServiceConfigAccessor.getOriginPriorities(); } @Override public ConfigurationInternal getCurrentUserConfigurationInternal() { return mServiceConfigAccessor.getCurrentUserConfigurationInternal(); Loading Loading @@ -121,11 +95,6 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { mWakeLock.release(); } @Override public boolean deviceHasY2038Issue() { return Build.SUPPORTED_32_BIT_ABIS.length > 0; } private void checkWakeLockHeld() { if (!mWakeLock.isHeld()) { Slog.wtf(LOG_TAG, "WakeLock " + mWakeLock + " not held"); Loading services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java +0 −26 Original line number Diff line number Diff line Loading @@ -19,11 +19,8 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.time.TimeConfiguration; import com.android.server.timedetector.TimeDetectorStrategy.Origin; import com.android.server.timezonedetector.ConfigurationChangeListener; import java.time.Instant; /** * An interface that provides access to service configuration for time detection. This hides * how configuration is split between static, compile-time config, dynamic server-pushed flags and Loading Loading @@ -68,27 +65,4 @@ public interface ServiceConfigAccessor { */ @NonNull ConfigurationInternal getConfigurationInternal(@UserIdInt int userId); /** * Returns the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ int systemClockUpdateThresholdMillis(); /** * Returns a lower bound for valid automatic times. It is guaranteed to be in the past, * i.e. it is unrelated to the current system clock time. * It holds no other meaning; it could be related to when the device system image was built, * or could be updated by a mainline module. */ @NonNull Instant autoTimeLowerBound(); /** * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ @NonNull @Origin int[] getOriginPriorities(); } services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java +32 −27 Original line number Diff line number Diff line Loading @@ -182,33 +182,6 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { mConfigurationInternalListeners.remove(Objects.requireNonNull(listener)); } @Override @NonNull public @Origin int[] getOriginPriorities() { int[] serverFlagsValue = mServerFlagsOriginPrioritiesSupplier.get(); if (serverFlagsValue != null) { return serverFlagsValue; } int[] configValue = mConfigOriginPrioritiesSupplier.get(); if (configValue != null) { return configValue; } return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES; } @Override public int systemClockUpdateThresholdMillis() { return mSystemClockUpdateThresholdMillis; } @Override @NonNull public Instant autoTimeLowerBound() { return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE) .orElse(TIME_LOWER_BOUND_DEFAULT); } @Override @NonNull public synchronized ConfigurationInternal getCurrentUserConfigurationInternal() { Loading Loading @@ -268,6 +241,10 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { .setUserConfigAllowed(isUserConfigAllowed(userId)) .setAutoDetectionSupported(isAutoDetectionSupported()) .setAutoDetectionEnabledSetting(getAutoDetectionEnabledSetting()) .setSystemClockUpdateThresholdMillis(getSystemClockUpdateThresholdMillis()) .setAutoTimeLowerBound(getAutoTimeLowerBound()) .setOriginPriorities(getOriginPriorities()) .setDeviceHasY2038Issue(getDeviceHasY2038Issue()) .build(); } Loading Loading @@ -309,6 +286,34 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { return false; } private int getSystemClockUpdateThresholdMillis() { return mSystemClockUpdateThresholdMillis; } @NonNull private Instant getAutoTimeLowerBound() { return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE) .orElse(TIME_LOWER_BOUND_DEFAULT); } @NonNull private @Origin int[] getOriginPriorities() { @Origin int[] serverFlagsValue = mServerFlagsOriginPrioritiesSupplier.get(); if (serverFlagsValue != null) { return serverFlagsValue; } @Origin int[] configValue = mConfigOriginPrioritiesSupplier.get(); if (configValue != null) { return configValue; } return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES; } private boolean getDeviceHasY2038Issue() { return Build.SUPPORTED_32_BIT_ABIS.length > 0; } /** * A base supplier of an array of time origin integers in priority order. * It handles memoization of the result to avoid repeated string parsing when nothing has Loading services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +9 −47 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.server.timedetector; import static com.android.server.timedetector.TimeDetectorStrategy.originToString; import static java.util.stream.Collectors.joining; import android.annotation.CurrentTimeMillisLong; import android.annotation.ElapsedRealtimeLong; import android.annotation.NonNull; Loading Loading @@ -153,28 +151,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { /** Returns the {@link ConfigurationInternal} for the current user. */ @NonNull ConfigurationInternal getCurrentUserConfigurationInternal(); /** * Returns the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ int systemClockUpdateThresholdMillis(); /** * Returns a lower bound for valid automatic times. It is guaranteed to be in the past, * i.e. it is unrelated to the current system clock time. * It holds no other meaning; it could be related to when the device system image was built, * or could be updated by a mainline module. */ @NonNull Instant autoTimeLowerBound(); /** * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ @Origin int[] autoOriginPriorities(); /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); Loading @@ -191,12 +167,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { /** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */ void releaseWakeLock(); /** * Returns {@code true} if the device may be at risk of time_t overflow (because bionic * defines time_t as a 32-bit signed integer for 32-bit processes). */ boolean deviceHasY2038Issue(); } static TimeDetectorStrategy create( Loading Loading @@ -384,25 +354,13 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { ipw.println("mLastAutoSystemClockTimeSet=" + mLastAutoSystemClockTimeSet); ipw.println("mCurrentConfigurationInternal=" + mCurrentConfigurationInternal); ipw.println("[Capabilities=" + mCurrentConfigurationInternal.capabilitiesAndConfig() + "]"); ipw.println("[Capabilities=" + mCurrentConfigurationInternal.capabilitiesAndConfig() + "]"); long elapsedRealtimeMillis = mEnvironment.elapsedRealtimeMillis(); ipw.printf("mEnvironment.elapsedRealtimeMillis()=%s (%s)\n", Duration.ofMillis(elapsedRealtimeMillis), elapsedRealtimeMillis); long systemClockMillis = mEnvironment.systemClockMillis(); ipw.printf("mEnvironment.systemClockMillis()=%s (%s)\n", Instant.ofEpochMilli(systemClockMillis), systemClockMillis); ipw.println("mEnvironment.systemClockUpdateThresholdMillis()=" + mEnvironment.systemClockUpdateThresholdMillis()); Instant autoTimeLowerBound = mEnvironment.autoTimeLowerBound(); ipw.printf("mEnvironment.autoTimeLowerBound()=%s (%s)\n", autoTimeLowerBound, autoTimeLowerBound.toEpochMilli()); String priorities = Arrays.stream(mEnvironment.autoOriginPriorities()) .mapToObj(TimeDetectorStrategy::originToString) .collect(joining(",", "[", "]")); ipw.println("mEnvironment.autoOriginPriorities()=" + priorities); ipw.println("mEnvironment.deviceHasY2038Issue()=" + mEnvironment.deviceHasY2038Issue()); ipw.println("Time change log:"); ipw.increaseIndent(); // level 2 Loading Loading @@ -467,6 +425,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return true; } @GuardedBy("this") private boolean validateSuggestionTime( @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { if (newUnixEpochTime.getValue() == null) { Loading @@ -485,7 +444,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } if (newUnixEpochTime.getValue() > Y2038_LIMIT_IN_MILLIS && mEnvironment.deviceHasY2038Issue()) { && mCurrentConfigurationInternal.getDeviceHasY2038Issue()) { // This check won't prevent a device's system clock exceeding Integer.MAX_VALUE Unix // seconds through the normal passage of time, but it will stop it jumping above 2038 // because of a "bad" suggestion. b/204193177 Loading @@ -496,15 +455,17 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return true; } @GuardedBy("this") private boolean validateAutoSuggestionTime( @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { return validateSuggestionTime(newUnixEpochTime, suggestion) && validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion); } @GuardedBy("this") private boolean validateSuggestionAgainstLowerBound( @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { Instant lowerBound = mEnvironment.autoTimeLowerBound(); Instant lowerBound = mCurrentConfigurationInternal.getAutoTimeLowerBound(); // Suggestion is definitely wrong if it comes before lower time bound. if (lowerBound.isAfter(Instant.ofEpochMilli(newUnixEpochTime.getValue()))) { Loading @@ -524,7 +485,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } // Try the different origins one at a time. int[] originPriorities = mEnvironment.autoOriginPriorities(); int[] originPriorities = mCurrentConfigurationInternal.getAutoOriginPriorities(); for (int origin : originPriorities) { TimestampedValue<Long> newUnixEpochTime = null; String cause = null; Loading Loading @@ -814,7 +775,8 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { // Check if the new signal would make sufficient difference to the system clock. If it's // below the threshold then ignore it. long absTimeDifference = Math.abs(newSystemClockMillis - actualSystemClockMillis); long systemClockUpdateThreshold = mEnvironment.systemClockUpdateThresholdMillis(); long systemClockUpdateThreshold = mCurrentConfigurationInternal.getSystemClockUpdateThresholdMillis(); if (absTimeDifference < systemClockUpdateThreshold) { if (DBG) { Slog.d(LOG_TAG, "Not setting system clock. New time and" Loading Loading
services/core/java/com/android/server/timedetector/ConfigurationInternal.java +125 −12 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE; import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED; import static android.app.time.Capabilities.CAPABILITY_POSSESSED; import static java.util.stream.Collectors.joining; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.time.Capabilities.CapabilityState; Loading @@ -29,6 +31,10 @@ import android.app.time.TimeCapabilitiesAndConfig; import android.app.time.TimeConfiguration; import android.os.UserHandle; import com.android.server.timedetector.TimeDetectorStrategy.Origin; import java.time.Instant; import java.util.Arrays; import java.util.Objects; /** Loading @@ -39,12 +45,20 @@ import java.util.Objects; public final class ConfigurationInternal { private final boolean mAutoDetectionSupported; private final int mSystemClockUpdateThresholdMillis; private final Instant mAutoTimeLowerBound; private final @Origin int[] mOriginPriorities; private final boolean mDeviceHasY2038Issue; private final boolean mAutoDetectionEnabledSetting; private final @UserIdInt int mUserId; private final boolean mUserConfigAllowed; private ConfigurationInternal(Builder builder) { mAutoDetectionSupported = builder.mAutoDetectionSupported; mSystemClockUpdateThresholdMillis = builder.mSystemClockUpdateThresholdMillis; mAutoTimeLowerBound = Objects.requireNonNull(builder.mAutoTimeLowerBound); mOriginPriorities = Objects.requireNonNull(builder.mOriginPriorities); mDeviceHasY2038Issue = builder.mDeviceHasY2038Issue; mAutoDetectionEnabledSetting = builder.mAutoDetectionEnabledSetting; mUserId = builder.mUserId; Loading @@ -56,6 +70,42 @@ public final class ConfigurationInternal { return mAutoDetectionSupported; } /** * Returns the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ public int getSystemClockUpdateThresholdMillis() { return mSystemClockUpdateThresholdMillis; } /** * Returns the lower bound for valid automatic times. It is guaranteed to be in the past, * i.e. it is unrelated to the current system clock time. * It holds no other meaning; it could be related to when the device system image was built, * or could be updated by a mainline module. */ @NonNull public Instant getAutoTimeLowerBound() { return mAutoTimeLowerBound; } /** * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ public @Origin int[] getAutoOriginPriorities() { return mOriginPriorities; } /** * Returns {@code true} if the device may be at risk of time_t overflow (because bionic * defines time_t as a 32-bit signed integer for 32-bit processes). */ public boolean getDeviceHasY2038Issue() { return mDeviceHasY2038Issue; } /** Returns the value of the auto time detection enabled setting. */ public boolean getAutoDetectionEnabledSetting() { return mAutoDetectionEnabledSetting; Loading Loading @@ -146,38 +196,61 @@ public final class ConfigurationInternal { @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; if (this == o) { return true; } if (!(o instanceof ConfigurationInternal)) { return false; } ConfigurationInternal that = (ConfigurationInternal) o; return mAutoDetectionSupported == that.mAutoDetectionSupported && mUserId == that.mUserId && mUserConfigAllowed == that.mUserConfigAllowed && mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting; && mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting && mUserId == that.mUserId && mUserConfigAllowed == that.mUserConfigAllowed && mSystemClockUpdateThresholdMillis == that.mSystemClockUpdateThresholdMillis && mAutoTimeLowerBound.equals(that.mAutoTimeLowerBound) && mDeviceHasY2038Issue == that.mDeviceHasY2038Issue && Arrays.equals(mOriginPriorities, that.mOriginPriorities); } @Override public int hashCode() { return Objects.hash(mAutoDetectionSupported, mUserId, mUserConfigAllowed, mAutoDetectionEnabledSetting); int result = Objects.hash(mAutoDetectionSupported, mAutoDetectionEnabledSetting, mUserId, mUserConfigAllowed, mSystemClockUpdateThresholdMillis, mAutoTimeLowerBound, mDeviceHasY2038Issue); result = 31 * result + Arrays.hashCode(mOriginPriorities); return result; } @Override public String toString() { String originPrioritiesString = Arrays.stream(mOriginPriorities) .mapToObj(TimeDetectorStrategy::originToString) .collect(joining(",", "[", "]")); return "ConfigurationInternal{" + "mAutoDetectionSupported=" + mAutoDetectionSupported + "mUserId=" + mUserId + ", mUserConfigAllowed=" + mUserConfigAllowed + ", mSystemClockUpdateThresholdMillis=" + mSystemClockUpdateThresholdMillis + ", mAutoTimeLowerBound=" + mAutoTimeLowerBound + "(" + mAutoTimeLowerBound.toEpochMilli() + ")" + ", mOriginPriorities=" + originPrioritiesString + ", mDeviceHasY2038Issue=" + mDeviceHasY2038Issue + ", mAutoDetectionEnabled=" + mAutoDetectionEnabledSetting + ", mUserId=" + mUserId + ", mUserConfigAllowed=" + mUserConfigAllowed + '}'; } static final class Builder { private final @UserIdInt int mUserId; private boolean mUserConfigAllowed; private boolean mAutoDetectionSupported; private int mSystemClockUpdateThresholdMillis; @NonNull private Instant mAutoTimeLowerBound; @NonNull private @Origin int[] mOriginPriorities; private boolean mDeviceHasY2038Issue; private boolean mAutoDetectionEnabledSetting; private final @UserIdInt int mUserId; private boolean mUserConfigAllowed; Builder(@UserIdInt int userId) { mUserId = userId; } Loading @@ -189,6 +262,10 @@ public final class ConfigurationInternal { this.mUserId = toCopy.mUserId; this.mUserConfigAllowed = toCopy.mUserConfigAllowed; this.mAutoDetectionSupported = toCopy.mAutoDetectionSupported; this.mSystemClockUpdateThresholdMillis = toCopy.mSystemClockUpdateThresholdMillis; this.mAutoTimeLowerBound = toCopy.mAutoTimeLowerBound; this.mOriginPriorities = toCopy.mOriginPriorities; this.mDeviceHasY2038Issue = toCopy.mDeviceHasY2038Issue; this.mAutoDetectionEnabledSetting = toCopy.mAutoDetectionEnabledSetting; } Loading @@ -208,6 +285,33 @@ public final class ConfigurationInternal { return this; } /** * Sets the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ public Builder setSystemClockUpdateThresholdMillis(int systemClockUpdateThresholdMillis) { mSystemClockUpdateThresholdMillis = systemClockUpdateThresholdMillis; return this; } /** * Sets the lower bound for valid automatic times. */ public Builder setAutoTimeLowerBound(@NonNull Instant autoTimeLowerBound) { mAutoTimeLowerBound = Objects.requireNonNull(autoTimeLowerBound); return this; } /** * Sets the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ public Builder setOriginPriorities(@NonNull @Origin int... originPriorities) { mOriginPriorities = Objects.requireNonNull(originPriorities); return this; } /** * Sets the value of the automatic time detection enabled setting for this device. */ Loading @@ -216,6 +320,15 @@ public final class ConfigurationInternal { return this; } /** * Returns {@code true} if the device may be at risk of time_t overflow (because bionic * defines time_t as a 32-bit signed integer for 32-bit processes). */ Builder setDeviceHasY2038Issue(boolean deviceHasY2038Issue) { mDeviceHasY2038Issue = deviceHasY2038Issue; return this; } /** Returns a new {@link ConfigurationInternal}. */ @NonNull ConfigurationInternal build() { Loading
services/core/java/com/android/server/timedetector/EnvironmentImpl.java +0 −31 Original line number Diff line number Diff line Loading @@ -18,18 +18,14 @@ package com.android.server.timedetector; import android.annotation.NonNull; import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserManager; import android.util.Slog; import com.android.server.timezonedetector.ConfigurationChangeListener; import java.time.Instant; import java.util.Objects; /** Loading @@ -39,18 +35,13 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { private static final String LOG_TAG = TimeDetectorService.TAG; @NonNull private final Context mContext; @NonNull private final Handler mHandler; @NonNull private final ServiceConfigAccessor mServiceConfigAccessor; @NonNull private final ContentResolver mContentResolver; @NonNull private final PowerManager.WakeLock mWakeLock; @NonNull private final AlarmManager mAlarmManager; @NonNull private final UserManager mUserManager; EnvironmentImpl(@NonNull Context context, @NonNull Handler handler, @NonNull ServiceConfigAccessor serviceConfigAccessor) { mContext = Objects.requireNonNull(context); mContentResolver = Objects.requireNonNull(context.getContentResolver()); mHandler = Objects.requireNonNull(handler); mServiceConfigAccessor = Objects.requireNonNull(serviceConfigAccessor); Loading @@ -59,8 +50,6 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG)); mAlarmManager = Objects.requireNonNull(context.getSystemService(AlarmManager.class)); mUserManager = Objects.requireNonNull(context.getSystemService(UserManager.class)); } @Override Loading @@ -71,21 +60,6 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { mServiceConfigAccessor.addConfigurationInternalChangeListener(configurationChangeListener); } @Override public int systemClockUpdateThresholdMillis() { return mServiceConfigAccessor.systemClockUpdateThresholdMillis(); } @Override public Instant autoTimeLowerBound() { return mServiceConfigAccessor.autoTimeLowerBound(); } @Override public int[] autoOriginPriorities() { return mServiceConfigAccessor.getOriginPriorities(); } @Override public ConfigurationInternal getCurrentUserConfigurationInternal() { return mServiceConfigAccessor.getCurrentUserConfigurationInternal(); Loading Loading @@ -121,11 +95,6 @@ final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environment { mWakeLock.release(); } @Override public boolean deviceHasY2038Issue() { return Build.SUPPORTED_32_BIT_ABIS.length > 0; } private void checkWakeLockHeld() { if (!mWakeLock.isHeld()) { Slog.wtf(LOG_TAG, "WakeLock " + mWakeLock + " not held"); Loading
services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java +0 −26 Original line number Diff line number Diff line Loading @@ -19,11 +19,8 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.time.TimeConfiguration; import com.android.server.timedetector.TimeDetectorStrategy.Origin; import com.android.server.timezonedetector.ConfigurationChangeListener; import java.time.Instant; /** * An interface that provides access to service configuration for time detection. This hides * how configuration is split between static, compile-time config, dynamic server-pushed flags and Loading Loading @@ -68,27 +65,4 @@ public interface ServiceConfigAccessor { */ @NonNull ConfigurationInternal getConfigurationInternal(@UserIdInt int userId); /** * Returns the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ int systemClockUpdateThresholdMillis(); /** * Returns a lower bound for valid automatic times. It is guaranteed to be in the past, * i.e. it is unrelated to the current system clock time. * It holds no other meaning; it could be related to when the device system image was built, * or could be updated by a mainline module. */ @NonNull Instant autoTimeLowerBound(); /** * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ @NonNull @Origin int[] getOriginPriorities(); }
services/core/java/com/android/server/timedetector/ServiceConfigAccessorImpl.java +32 −27 Original line number Diff line number Diff line Loading @@ -182,33 +182,6 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { mConfigurationInternalListeners.remove(Objects.requireNonNull(listener)); } @Override @NonNull public @Origin int[] getOriginPriorities() { int[] serverFlagsValue = mServerFlagsOriginPrioritiesSupplier.get(); if (serverFlagsValue != null) { return serverFlagsValue; } int[] configValue = mConfigOriginPrioritiesSupplier.get(); if (configValue != null) { return configValue; } return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES; } @Override public int systemClockUpdateThresholdMillis() { return mSystemClockUpdateThresholdMillis; } @Override @NonNull public Instant autoTimeLowerBound() { return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE) .orElse(TIME_LOWER_BOUND_DEFAULT); } @Override @NonNull public synchronized ConfigurationInternal getCurrentUserConfigurationInternal() { Loading Loading @@ -268,6 +241,10 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { .setUserConfigAllowed(isUserConfigAllowed(userId)) .setAutoDetectionSupported(isAutoDetectionSupported()) .setAutoDetectionEnabledSetting(getAutoDetectionEnabledSetting()) .setSystemClockUpdateThresholdMillis(getSystemClockUpdateThresholdMillis()) .setAutoTimeLowerBound(getAutoTimeLowerBound()) .setOriginPriorities(getOriginPriorities()) .setDeviceHasY2038Issue(getDeviceHasY2038Issue()) .build(); } Loading Loading @@ -309,6 +286,34 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { return false; } private int getSystemClockUpdateThresholdMillis() { return mSystemClockUpdateThresholdMillis; } @NonNull private Instant getAutoTimeLowerBound() { return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE) .orElse(TIME_LOWER_BOUND_DEFAULT); } @NonNull private @Origin int[] getOriginPriorities() { @Origin int[] serverFlagsValue = mServerFlagsOriginPrioritiesSupplier.get(); if (serverFlagsValue != null) { return serverFlagsValue; } @Origin int[] configValue = mConfigOriginPrioritiesSupplier.get(); if (configValue != null) { return configValue; } return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES; } private boolean getDeviceHasY2038Issue() { return Build.SUPPORTED_32_BIT_ABIS.length > 0; } /** * A base supplier of an array of time origin integers in priority order. * It handles memoization of the result to avoid repeated string parsing when nothing has Loading
services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +9 −47 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.server.timedetector; import static com.android.server.timedetector.TimeDetectorStrategy.originToString; import static java.util.stream.Collectors.joining; import android.annotation.CurrentTimeMillisLong; import android.annotation.ElapsedRealtimeLong; import android.annotation.NonNull; Loading Loading @@ -153,28 +151,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { /** Returns the {@link ConfigurationInternal} for the current user. */ @NonNull ConfigurationInternal getCurrentUserConfigurationInternal(); /** * Returns the absolute threshold below which the system clock need not be updated. i.e. if * setting the system clock would adjust it by less than this (either backwards or forwards) * then it need not be set. */ int systemClockUpdateThresholdMillis(); /** * Returns a lower bound for valid automatic times. It is guaranteed to be in the past, * i.e. it is unrelated to the current system clock time. * It holds no other meaning; it could be related to when the device system image was built, * or could be updated by a mainline module. */ @NonNull Instant autoTimeLowerBound(); /** * Returns the order to look at time suggestions when automatically detecting time. * See {@code #ORIGIN_} constants */ @Origin int[] autoOriginPriorities(); /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); Loading @@ -191,12 +167,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { /** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */ void releaseWakeLock(); /** * Returns {@code true} if the device may be at risk of time_t overflow (because bionic * defines time_t as a 32-bit signed integer for 32-bit processes). */ boolean deviceHasY2038Issue(); } static TimeDetectorStrategy create( Loading Loading @@ -384,25 +354,13 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { ipw.println("mLastAutoSystemClockTimeSet=" + mLastAutoSystemClockTimeSet); ipw.println("mCurrentConfigurationInternal=" + mCurrentConfigurationInternal); ipw.println("[Capabilities=" + mCurrentConfigurationInternal.capabilitiesAndConfig() + "]"); ipw.println("[Capabilities=" + mCurrentConfigurationInternal.capabilitiesAndConfig() + "]"); long elapsedRealtimeMillis = mEnvironment.elapsedRealtimeMillis(); ipw.printf("mEnvironment.elapsedRealtimeMillis()=%s (%s)\n", Duration.ofMillis(elapsedRealtimeMillis), elapsedRealtimeMillis); long systemClockMillis = mEnvironment.systemClockMillis(); ipw.printf("mEnvironment.systemClockMillis()=%s (%s)\n", Instant.ofEpochMilli(systemClockMillis), systemClockMillis); ipw.println("mEnvironment.systemClockUpdateThresholdMillis()=" + mEnvironment.systemClockUpdateThresholdMillis()); Instant autoTimeLowerBound = mEnvironment.autoTimeLowerBound(); ipw.printf("mEnvironment.autoTimeLowerBound()=%s (%s)\n", autoTimeLowerBound, autoTimeLowerBound.toEpochMilli()); String priorities = Arrays.stream(mEnvironment.autoOriginPriorities()) .mapToObj(TimeDetectorStrategy::originToString) .collect(joining(",", "[", "]")); ipw.println("mEnvironment.autoOriginPriorities()=" + priorities); ipw.println("mEnvironment.deviceHasY2038Issue()=" + mEnvironment.deviceHasY2038Issue()); ipw.println("Time change log:"); ipw.increaseIndent(); // level 2 Loading Loading @@ -467,6 +425,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return true; } @GuardedBy("this") private boolean validateSuggestionTime( @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { if (newUnixEpochTime.getValue() == null) { Loading @@ -485,7 +444,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } if (newUnixEpochTime.getValue() > Y2038_LIMIT_IN_MILLIS && mEnvironment.deviceHasY2038Issue()) { && mCurrentConfigurationInternal.getDeviceHasY2038Issue()) { // This check won't prevent a device's system clock exceeding Integer.MAX_VALUE Unix // seconds through the normal passage of time, but it will stop it jumping above 2038 // because of a "bad" suggestion. b/204193177 Loading @@ -496,15 +455,17 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return true; } @GuardedBy("this") private boolean validateAutoSuggestionTime( @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { return validateSuggestionTime(newUnixEpochTime, suggestion) && validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion); } @GuardedBy("this") private boolean validateSuggestionAgainstLowerBound( @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { Instant lowerBound = mEnvironment.autoTimeLowerBound(); Instant lowerBound = mCurrentConfigurationInternal.getAutoTimeLowerBound(); // Suggestion is definitely wrong if it comes before lower time bound. if (lowerBound.isAfter(Instant.ofEpochMilli(newUnixEpochTime.getValue()))) { Loading @@ -524,7 +485,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } // Try the different origins one at a time. int[] originPriorities = mEnvironment.autoOriginPriorities(); int[] originPriorities = mCurrentConfigurationInternal.getAutoOriginPriorities(); for (int origin : originPriorities) { TimestampedValue<Long> newUnixEpochTime = null; String cause = null; Loading Loading @@ -814,7 +775,8 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { // Check if the new signal would make sufficient difference to the system clock. If it's // below the threshold then ignore it. long absTimeDifference = Math.abs(newSystemClockMillis - actualSystemClockMillis); long systemClockUpdateThreshold = mEnvironment.systemClockUpdateThresholdMillis(); long systemClockUpdateThreshold = mCurrentConfigurationInternal.getSystemClockUpdateThresholdMillis(); if (absTimeDifference < systemClockUpdateThreshold) { if (DBG) { Slog.d(LOG_TAG, "Not setting system clock. New time and" Loading