Merge "Centralize upper/lower time bound logic"

This commit is contained in:
Neil Fuller
2022-07-21 09:22:33 +00:00
committed by Android (Google) Code Review
7 changed files with 581 additions and 169 deletions

View File

@@ -0,0 +1,158 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.timedetector;
import android.annotation.NonNull;
import android.os.Build;
import java.time.Instant;
/**
* A utility class for fundamental time detector-related logic that doesn't need to communicate with
* the time detector service, i.e. because it can use SDK APIs or hard-coded facts, and doesn't need
* permissions or singleton state. Putting logic here avoids the need to expose binder-based calls
* or to duplicate code to share related logic (since android.app.timedetector classes are visible
* to all processes).
*
* @hide
*/
// Not final for easy replacement / mocking during tests.
public class TimeDetectorHelper {
/**
* See {@link #getManualDateSelectionYearMin()}. Chosen to produce Unix epoch times be greater
* than {@link #MANUAL_SUGGESTION_LOWER_BOUND}.
*/
private static final int MANUAL_SUGGESTION_YEAR_MIN = 2008;
/**
* The maximum gregorian calendar year to allow for manual date selection on devices unlikely to
* have Y2038 issues. This serves as a sensible UI-enforced limit though the system server may
* support a larger upper bound. Users besides future archeologists are unlikely to need higher
* values, for a few years at least.
*/
private static final int MANUAL_SUGGESTION_YEAR_MAX_WITHOUT_Y2038_ISSUE = 2100;
/**
* The maximum gregorian calendar year to allow for manual date selection on devices that may
* have Y2038 issues. This serves as a sensible UI-enforced limit though the system server may
* support a larger upper bound. That is, the signed 32-bit milliseconds value is
* 03:14:07 UTC on 19 January 2038, but this constant means users can only enter dates up to
* 2037-12-31. See {@link #MANUAL_SUGGESTION_YEAR_MAX_WITH_Y2038_ISSUE}.
*
* <p>Note: This UI limit also doesn't prevent devices reaching the Y2038 roll-over time through
* the natural passage of time, it just prevents users potentially causing issues in the years
* leading up to it accidentally via the UI.
*/
private static final int MANUAL_SUGGESTION_YEAR_MAX_WITH_Y2038_ISSUE = 2037;
/**
* The upper bound for valid suggestions when the Y2038 issue is a risk. This is the instant
* when the Y2038 issue occurs.
*/
private static final Instant SUGGESTION_UPPER_BOUND_WITH_Y2038_ISSUE =
Instant.ofEpochMilli(1000L * Integer.MAX_VALUE);
/**
* The upper bound for valid suggestions when the Y2038 issue is not a risk. This values means
* there is no practical upper bound.
*
* <p>Make sure this value remains in the value representable as a signed int64 Unix epoch
* millis value as in various places {@link Instant#toEpochMilli()} is called, and that throws
* an exception if the value is too large.
*/
private static final Instant SUGGESTION_UPPER_BOUND_WIITHOUT_Y2038_ISSUE =
Instant.ofEpochMilli(Long.MAX_VALUE);
/** See {@link #getManualSuggestionLowerBound()}. */
private static final Instant MANUAL_SUGGESTION_LOWER_BOUND =
Instant.ofEpochMilli(1194220800000L); // Nov 5, 2007, 0:00 UTC
/**
* The lowest value in Unix epoch milliseconds that is considered a valid automatic suggestion.
* See also {@link #MANUAL_SUGGESTION_LOWER_BOUND}.
*
* <p>Note that this is a default value. The lower value enforced can be overridden to be
* lower in the system server with flags for testing.
*/
private static final Instant AUTO_SUGGESTION_LOWER_BOUND_DEFAULT = Instant.ofEpochMilli(
Long.max(android.os.Environment.getRootDirectory().lastModified(), Build.TIME));
/** The singleton instance of this class. */
public static final TimeDetectorHelper INSTANCE = new TimeDetectorHelper();
/** Constructor present for subclassing in tests. Use {@link #INSTANCE} in production code. */
protected TimeDetectorHelper() {}
/**
* Returns the minimum gregorian calendar year to offer for manual date selection. This serves
* as a sensible UI-enforced lower limit, the system server may support a smaller lower bound.
*/
public int getManualDateSelectionYearMin() {
return MANUAL_SUGGESTION_YEAR_MIN;
}
/**
* Returns the maximum gregorian calendar year to offer for manual date selection. This serves
* as a sensible UI-enforced lower limit, the system server may support a larger upper bound.
*/
public int getManualDateSelectionYearMax() {
return getDeviceHasY2038Issue()
? MANUAL_SUGGESTION_YEAR_MAX_WITH_Y2038_ISSUE
: MANUAL_SUGGESTION_YEAR_MAX_WITHOUT_Y2038_ISSUE;
}
/**
* Returns the lowest value in Unix epoch milliseconds that is considered a valid manual
* suggestion. For historical reasons Android has a different lower limit for manual input than
* automatic. This may change in the future to align with automatic suggestions, but has been
* kept initially to avoid breaking manual tests that are hard-coded with old dates real users
* will never want to use.
*/
@NonNull
public Instant getManualSuggestionLowerBound() {
return MANUAL_SUGGESTION_LOWER_BOUND;
}
/**
* Returns the lowest value in Unix epoch milliseconds that is considered a valid automatic
* suggestion. See also {@link #MANUAL_SUGGESTION_LOWER_BOUND}.
*
* <p>Note that this is a default value. The lower value enforced can be overridden to be
* different in the system server with server flags.
*/
@NonNull
public Instant getAutoSuggestionLowerBoundDefault() {
return AUTO_SUGGESTION_LOWER_BOUND_DEFAULT;
}
/** Returns the upper bound to enforce for all time suggestions (manual and automatic). */
@NonNull
public Instant getSuggestionUpperBound() {
return getDeviceHasY2038Issue()
? SUGGESTION_UPPER_BOUND_WITH_Y2038_ISSUE
: SUGGESTION_UPPER_BOUND_WIITHOUT_Y2038_ISSUE;
}
/**
* 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).
*/
private boolean getDeviceHasY2038Issue() {
return Build.SUPPORTED_32_BIT_ABIS.length > 0;
}
}

View File

@@ -46,9 +46,10 @@ public final class ConfigurationInternal {
private final boolean mAutoDetectionSupported;
private final int mSystemClockUpdateThresholdMillis;
private final Instant mAutoTimeLowerBound;
private final Instant mAutoSuggestionLowerBound;
private final Instant mManualSuggestionLowerBound;
private final Instant mSuggestionUpperBound;
private final @Origin int[] mOriginPriorities;
private final boolean mDeviceHasY2038Issue;
private final boolean mAutoDetectionEnabledSetting;
private final @UserIdInt int mUserId;
private final boolean mUserConfigAllowed;
@@ -56,9 +57,10 @@ public final class ConfigurationInternal {
private ConfigurationInternal(Builder builder) {
mAutoDetectionSupported = builder.mAutoDetectionSupported;
mSystemClockUpdateThresholdMillis = builder.mSystemClockUpdateThresholdMillis;
mAutoTimeLowerBound = Objects.requireNonNull(builder.mAutoTimeLowerBound);
mAutoSuggestionLowerBound = Objects.requireNonNull(builder.mAutoSuggestionLowerBound);
mManualSuggestionLowerBound = Objects.requireNonNull(builder.mManualSuggestionLowerBound);
mSuggestionUpperBound = Objects.requireNonNull(builder.mSuggestionUpperBound);
mOriginPriorities = Objects.requireNonNull(builder.mOriginPriorities);
mDeviceHasY2038Issue = builder.mDeviceHasY2038Issue;
mAutoDetectionEnabledSetting = builder.mAutoDetectionEnabledSetting;
mUserId = builder.mUserId;
@@ -80,14 +82,31 @@ public final class ConfigurationInternal {
}
/**
* 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.
* Returns the lower bound for valid automatic time suggestions. 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;
public Instant getAutoSuggestionLowerBound() {
return mAutoSuggestionLowerBound;
}
/**
* Returns the lower bound for valid manual time suggestions. It is guaranteed to be in the
* past, i.e. it is unrelated to the current system clock time.
*/
@NonNull
public Instant getManualSuggestionLowerBound() {
return mManualSuggestionLowerBound;
}
/**
* Returns the upper bound for valid time suggestions (manual and automatic).
*/
@NonNull
public Instant getSuggestionUpperBound() {
return mSuggestionUpperBound;
}
/**
@@ -98,14 +117,6 @@ public final class ConfigurationInternal {
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;
@@ -207,16 +218,17 @@ public final class ConfigurationInternal {
&& mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting
&& mUserId == that.mUserId && mUserConfigAllowed == that.mUserConfigAllowed
&& mSystemClockUpdateThresholdMillis == that.mSystemClockUpdateThresholdMillis
&& mAutoTimeLowerBound.equals(that.mAutoTimeLowerBound)
&& mDeviceHasY2038Issue == that.mDeviceHasY2038Issue
&& mAutoSuggestionLowerBound.equals(that.mAutoSuggestionLowerBound)
&& mManualSuggestionLowerBound.equals(that.mManualSuggestionLowerBound)
&& mSuggestionUpperBound.equals(that.mSuggestionUpperBound)
&& Arrays.equals(mOriginPriorities, that.mOriginPriorities);
}
@Override
public int hashCode() {
int result = Objects.hash(mAutoDetectionSupported, mAutoDetectionEnabledSetting, mUserId,
mUserConfigAllowed, mSystemClockUpdateThresholdMillis, mAutoTimeLowerBound,
mDeviceHasY2038Issue);
mUserConfigAllowed, mSystemClockUpdateThresholdMillis, mAutoSuggestionLowerBound,
mManualSuggestionLowerBound, mSuggestionUpperBound);
result = 31 * result + Arrays.hashCode(mOriginPriorities);
return result;
}
@@ -230,10 +242,13 @@ public final class ConfigurationInternal {
return "ConfigurationInternal{"
+ "mAutoDetectionSupported=" + mAutoDetectionSupported
+ ", mSystemClockUpdateThresholdMillis=" + mSystemClockUpdateThresholdMillis
+ ", mAutoTimeLowerBound=" + mAutoTimeLowerBound
+ "(" + mAutoTimeLowerBound.toEpochMilli() + ")"
+ ", mAutoSuggestionLowerBound=" + mAutoSuggestionLowerBound
+ "(" + mAutoSuggestionLowerBound.toEpochMilli() + ")"
+ ", mManualSuggestionLowerBound=" + mManualSuggestionLowerBound
+ "(" + mManualSuggestionLowerBound.toEpochMilli() + ")"
+ ", mSuggestionUpperBound=" + mSuggestionUpperBound
+ "(" + mSuggestionUpperBound.toEpochMilli() + ")"
+ ", mOriginPriorities=" + originPrioritiesString
+ ", mDeviceHasY2038Issue=" + mDeviceHasY2038Issue
+ ", mAutoDetectionEnabled=" + mAutoDetectionEnabledSetting
+ ", mUserId=" + mUserId
+ ", mUserConfigAllowed=" + mUserConfigAllowed
@@ -243,9 +258,10 @@ public final class ConfigurationInternal {
static final class Builder {
private boolean mAutoDetectionSupported;
private int mSystemClockUpdateThresholdMillis;
@NonNull private Instant mAutoTimeLowerBound;
@NonNull private Instant mAutoSuggestionLowerBound;
@NonNull private Instant mManualSuggestionLowerBound;
@NonNull private Instant mSuggestionUpperBound;
@NonNull private @Origin int[] mOriginPriorities;
private boolean mDeviceHasY2038Issue;
private boolean mAutoDetectionEnabledSetting;
private final @UserIdInt int mUserId;
@@ -263,9 +279,10 @@ public final class ConfigurationInternal {
this.mUserConfigAllowed = toCopy.mUserConfigAllowed;
this.mAutoDetectionSupported = toCopy.mAutoDetectionSupported;
this.mSystemClockUpdateThresholdMillis = toCopy.mSystemClockUpdateThresholdMillis;
this.mAutoTimeLowerBound = toCopy.mAutoTimeLowerBound;
this.mAutoSuggestionLowerBound = toCopy.mAutoSuggestionLowerBound;
this.mManualSuggestionLowerBound = toCopy.mManualSuggestionLowerBound;
this.mSuggestionUpperBound = toCopy.mSuggestionUpperBound;
this.mOriginPriorities = toCopy.mOriginPriorities;
this.mDeviceHasY2038Issue = toCopy.mDeviceHasY2038Issue;
this.mAutoDetectionEnabledSetting = toCopy.mAutoDetectionEnabledSetting;
}
@@ -296,10 +313,26 @@ public final class ConfigurationInternal {
}
/**
* Sets the lower bound for valid automatic times.
* Sets the lower bound for valid automatic time suggestions.
*/
public Builder setAutoTimeLowerBound(@NonNull Instant autoTimeLowerBound) {
mAutoTimeLowerBound = Objects.requireNonNull(autoTimeLowerBound);
public Builder setAutoSuggestionLowerBound(@NonNull Instant autoSuggestionLowerBound) {
mAutoSuggestionLowerBound = Objects.requireNonNull(autoSuggestionLowerBound);
return this;
}
/**
* Sets the lower bound for valid manual time suggestions.
*/
public Builder setManualSuggestionLowerBound(@NonNull Instant manualSuggestionLowerBound) {
mManualSuggestionLowerBound = Objects.requireNonNull(manualSuggestionLowerBound);
return this;
}
/**
* Sets the upper bound for valid time suggestions (manual and automatic).
*/
public Builder setSuggestionUpperBound(@NonNull Instant suggestionUpperBound) {
mSuggestionUpperBound = Objects.requireNonNull(suggestionUpperBound);
return this;
}
@@ -320,15 +353,6 @@ 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() {

View File

@@ -31,6 +31,7 @@ import android.app.ActivityManagerInternal;
import android.app.time.TimeCapabilities;
import android.app.time.TimeCapabilitiesAndConfig;
import android.app.time.TimeConfiguration;
import android.app.timedetector.TimeDetectorHelper;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -38,7 +39,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.os.Build;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -74,13 +74,6 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
private static final @Origin int[]
DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES = { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
/**
* Time in the past. If an automatic time suggestion is before this point, it is sure to be
* incorrect.
*/
private static final Instant TIME_LOWER_BOUND_DEFAULT = Instant.ofEpochMilli(
Long.max(android.os.Environment.getRootDirectory().lastModified(), Build.TIME));
/** Device config keys that affect the {@link TimeDetectorService}. */
private static final Set<String> SERVER_FLAGS_KEYS_TO_WATCH = Set.of(
KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE,
@@ -237,14 +230,16 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
@Override
@NonNull
public synchronized ConfigurationInternal getConfigurationInternal(@UserIdInt int userId) {
TimeDetectorHelper timeDetectorHelper = TimeDetectorHelper.INSTANCE;
return new ConfigurationInternal.Builder(userId)
.setUserConfigAllowed(isUserConfigAllowed(userId))
.setAutoDetectionSupported(isAutoDetectionSupported())
.setAutoDetectionEnabledSetting(getAutoDetectionEnabledSetting())
.setSystemClockUpdateThresholdMillis(getSystemClockUpdateThresholdMillis())
.setAutoTimeLowerBound(getAutoTimeLowerBound())
.setAutoSuggestionLowerBound(getAutoSuggestionLowerBound())
.setManualSuggestionLowerBound(timeDetectorHelper.getManualSuggestionLowerBound())
.setSuggestionUpperBound(timeDetectorHelper.getSuggestionUpperBound())
.setOriginPriorities(getOriginPriorities())
.setDeviceHasY2038Issue(getDeviceHasY2038Issue())
.build();
}
@@ -291,9 +286,9 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
}
@NonNull
private Instant getAutoTimeLowerBound() {
private Instant getAutoSuggestionLowerBound() {
return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE)
.orElse(TIME_LOWER_BOUND_DEFAULT);
.orElse(TimeDetectorHelper.INSTANCE.getAutoSuggestionLowerBoundDefault());
}
@NonNull
@@ -310,10 +305,6 @@ final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
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

View File

@@ -84,9 +84,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
*/
private static final int KEEP_SUGGESTION_HISTORY_SIZE = 10;
/** The value in Unix epoch milliseconds of the Y2038 issue. */
private static final long Y2038_LIMIT_IN_MILLIS = 1000L * Integer.MAX_VALUE;
/**
* A log that records the decisions / decision metadata that affected the device's system clock
* time. This is logged in bug reports to assist with debugging issues with detection.
@@ -248,7 +245,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
final TimestampedValue<Long> newUnixEpochTime = suggestion.getUnixEpochTime();
if (!validateSuggestionTime(newUnixEpochTime, suggestion)) {
if (!validateManualSuggestionTime(newUnixEpochTime, suggestion)) {
return false;
}
@@ -424,7 +421,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
}
@GuardedBy("this")
private boolean validateSuggestionTime(
private boolean validateSuggestionCommon(
@NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
if (newUnixEpochTime.getValue() == null) {
Slog.w(LOG_TAG, "Suggested time value is null. suggestion=" + suggestion);
@@ -441,8 +438,8 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
return false;
}
if (newUnixEpochTime.getValue() > Y2038_LIMIT_IN_MILLIS
&& mCurrentConfigurationInternal.getDeviceHasY2038Issue()) {
if (newUnixEpochTime.getValue()
> mCurrentConfigurationInternal.getSuggestionUpperBound().toEpochMilli()) {
// 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
@@ -453,20 +450,40 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
return true;
}
/**
* Returns {@code true} if an automatic time suggestion time is valid.
* See also {@link #validateManualSuggestionTime(TimestampedValue, Object)}.
*/
@GuardedBy("this")
private boolean validateAutoSuggestionTime(
@NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
return validateSuggestionTime(newUnixEpochTime, suggestion)
&& validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion);
Instant lowerBound = mCurrentConfigurationInternal.getAutoSuggestionLowerBound();
return validateSuggestionCommon(newUnixEpochTime, suggestion)
&& validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion,
lowerBound);
}
/**
* Returns {@code true} if a manual time suggestion time is valid.
* See also {@link #validateAutoSuggestionTime(TimestampedValue, Object)}.
*/
@GuardedBy("this")
private boolean validateManualSuggestionTime(
@NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
Instant lowerBound = mCurrentConfigurationInternal.getManualSuggestionLowerBound();
// Suggestion is definitely wrong if it comes before lower time bound.
return validateSuggestionCommon(newUnixEpochTime, suggestion)
&& validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion, lowerBound);
}
@GuardedBy("this")
private boolean validateSuggestionAgainstLowerBound(
@NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
Instant lowerBound = mCurrentConfigurationInternal.getAutoTimeLowerBound();
@NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion,
@NonNull Instant lowerBound) {
// Suggestion is definitely wrong if it comes before lower time bound.
if (lowerBound.isAfter(Instant.ofEpochMilli(newUnixEpochTime.getValue()))) {
if (lowerBound.toEpochMilli() > newUnixEpochTime.getValue()) {
Slog.w(LOG_TAG, "Suggestion points to time before lower bound, skipping it. "
+ "suggestion=" + suggestion + ", lower bound=" + lowerBound);
return false;

View File

@@ -45,7 +45,9 @@ public class ConfigurationInternalTest {
private static final int ARBITRARY_USER_ID = 99999;
private static final int ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS = 1234;
private static final Instant ARBITRARY_AUTO_TIME_LOWER_BOUND = Instant.ofEpochMilli(0);
private static final Instant ARBITRARY_SUGGESTION_LOWER_BOUND = Instant.ofEpochMilli(0);
private static final Instant ARBITRARY_SUGGESTION_UPPER_BOUND =
Instant.ofEpochMilli(Long.MAX_VALUE);
private static final @Origin int[] ARBITRARY_ORIGIN_PRIORITIES = { ORIGIN_NETWORK };
/**
@@ -59,9 +61,10 @@ public class ConfigurationInternalTest {
.setUserConfigAllowed(true)
.setAutoDetectionSupported(true)
.setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
.setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
.setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
.setDeviceHasY2038Issue(true)
.setAutoDetectionEnabledSetting(true)
.build();
{
@@ -110,9 +113,10 @@ public class ConfigurationInternalTest {
.setUserConfigAllowed(false)
.setAutoDetectionSupported(true)
.setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
.setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
.setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
.setDeviceHasY2038Issue(true)
.setAutoDetectionEnabledSetting(true)
.build();
{
@@ -159,9 +163,10 @@ public class ConfigurationInternalTest {
.setUserConfigAllowed(true)
.setAutoDetectionSupported(false)
.setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
.setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
.setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
.setDeviceHasY2038Issue(true)
.setAutoDetectionEnabledSetting(true)
.build();
{

View File

@@ -69,7 +69,9 @@ public class TimeDetectorServiceTest {
private static final int ARBITRARY_USER_ID = 9999;
private static final int ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS = 1234;
private static final Instant ARBITRARY_AUTO_TIME_LOWER_BOUND = Instant.ofEpochMilli(0);
private static final Instant ARBITRARY_SUGGESTION_LOWER_BOUND = Instant.ofEpochMilli(0);
private static final Instant ARBITRARY_SUGGESTION_UPPER_BOUND =
Instant.ofEpochMilli(Long.MAX_VALUE);
private static final int[] ARBITRARY_ORIGIN_PRIORITIES = { ORIGIN_NETWORK };
private Context mMockContext;
@@ -444,9 +446,10 @@ public class TimeDetectorServiceTest {
.setUserConfigAllowed(true)
.setAutoDetectionSupported(true)
.setSystemClockUpdateThresholdMillis(ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoTimeLowerBound(ARBITRARY_AUTO_TIME_LOWER_BOUND)
.setAutoSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setManualSuggestionLowerBound(ARBITRARY_SUGGESTION_LOWER_BOUND)
.setSuggestionUpperBound(ARBITRARY_SUGGESTION_UPPER_BOUND)
.setOriginPriorities(ARBITRARY_ORIGIN_PRIORITIES)
.setDeviceHasY2038Issue(true)
.setAutoDetectionEnabledSetting(autoDetectionEnabled)
.build();
}

View File

@@ -53,7 +53,16 @@ public class TimeDetectorStrategyImplTest {
private static final @UserIdInt int ARBITRARY_USER_ID = 9876;
private static final int ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS = 1234;
private static final Instant TIME_LOWER_BOUND = createUnixEpochTime(2009, 1, 1, 12, 0, 0);
private static final Instant DEFAULT_SUGGESTION_LOWER_BOUND =
createUnixEpochTime(2005, 1, 1, 1, 0, 0);
/** A value after {@link #DEFAULT_SUGGESTION_LOWER_BOUND} */
private static final Instant TEST_SUGGESTION_LOWER_BOUND =
createUnixEpochTime(2006, 1, 1, 1, 0, 0);
private static final Instant DEFAULT_SUGGESTION_UPPER_BOUND =
createUnixEpochTime(2099, 12, 1, 1, 0, 0);
/** A value before {@link #DEFAULT_SUGGESTION_UPPER_BOUND} */
private static final Instant TEST_SUGGESTION_UPPER_BOUND =
createUnixEpochTime(2037, 12, 1, 1, 0, 0);
private static final TimestampedValue<Instant> ARBITRARY_CLOCK_INITIALIZATION_INFO =
new TimestampedValue<>(
@@ -77,9 +86,10 @@ public class TimeDetectorStrategyImplTest {
.setAutoDetectionSupported(true)
.setSystemClockUpdateThresholdMillis(
ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoTimeLowerBound(TIME_LOWER_BOUND)
.setAutoSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
.setManualSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
.setSuggestionUpperBound(DEFAULT_SUGGESTION_UPPER_BOUND)
.setOriginPriorities(ORIGIN_PRIORITIES)
.setDeviceHasY2038Issue(true)
.setAutoDetectionEnabledSetting(false)
.build();
@@ -89,9 +99,10 @@ public class TimeDetectorStrategyImplTest {
.setAutoDetectionSupported(true)
.setSystemClockUpdateThresholdMillis(
ARBITRARY_SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS)
.setAutoTimeLowerBound(TIME_LOWER_BOUND)
.setAutoSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
.setManualSuggestionLowerBound(DEFAULT_SUGGESTION_LOWER_BOUND)
.setSuggestionUpperBound(DEFAULT_SUGGESTION_UPPER_BOUND)
.setOriginPriorities(ORIGIN_PRIORITIES)
.setDeviceHasY2038Issue(true)
.setAutoDetectionEnabledSetting(true)
.build();
@@ -343,22 +354,6 @@ public class TimeDetectorStrategyImplTest {
.assertLatestTelephonySuggestion(slotIndex, timeSuggestion4);
}
@Test
public void telephonyTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_ENABLED);
int slotIndex = ARBITRARY_SLOT_INDEX;
Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
TelephonyTimeSuggestion timeSuggestion =
script.generateTelephonyTimeSuggestion(
slotIndex, suggestedTime);
script.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking()
.assertLatestTelephonySuggestion(slotIndex, null);
}
@Test
public void testSuggestTelephonyTime_timeDetectionToggled() {
final int clockIncrementMillis = 100;
@@ -452,6 +447,70 @@ public class TimeDetectorStrategyImplTest {
script.assertLatestTelephonySuggestion(slotIndex, telephonySuggestion);
}
@Test
public void testSuggestTelephonyTime_rejectedBelowLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
TelephonyTimeSuggestion timeSuggestion =
script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, belowLowerBound);
script.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestTelephonyTime_notRejectedAboveLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
TelephonyTimeSuggestion timeSuggestion =
script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, aboveLowerBound);
script.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
}
@Test
public void testSuggestTelephonyTime_rejectedAboveUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
TelephonyTimeSuggestion timeSuggestion =
script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, aboveUpperBound);
script.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestTelephonyTime_notRejectedBelowUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
TelephonyTimeSuggestion timeSuggestion =
script.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, belowUpperBound);
script.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
}
@Test
public void testSuggestManualTime_autoTimeDisabled() {
Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_DISABLED);
@@ -530,7 +589,7 @@ public class TimeDetectorStrategyImplTest {
}
@Test
public void manualTimeSuggestion_isIgnored_whenAutoTimeEnabled() {
public void testSuggestManualTime_isIgnored_whenAutoTimeEnabled() {
Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_ENABLED);
ManualTimeSuggestion timeSuggestion =
@@ -543,16 +602,63 @@ public class TimeDetectorStrategyImplTest {
}
@Test
public void manualTimeSuggestion_ignoresTimeLowerBound() {
Script script = new Script().simulateConfigurationInternalChange(CONFIG_AUTO_DISABLED);
Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
ManualTimeSuggestion timeSuggestion =
script.generateManualTimeSuggestion(suggestedTime);
public void testSuggestManualTime_rejectedAboveUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(aboveUpperBound);
script.simulateManualTimeSuggestion(
ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
.verifySystemClockWasSetAndResetCallTracking(suggestedTime.toEpochMilli());
ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestManualTime_notRejectedBelowUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(belowUpperBound);
script.simulateManualTimeSuggestion(
ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
.verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
}
@Test
public void testSuggestManualTime_rejectedBelowLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
.setManualSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(belowLowerBound);
script.simulateManualTimeSuggestion(
ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestManualTimes_notRejectedAboveLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
.setManualSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(aboveLowerBound);
script.simulateManualTimeSuggestion(
ARBITRARY_USER_ID, timeSuggestion, true /* expectedResult */)
.verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
}
@Test
@@ -591,20 +697,67 @@ public class TimeDetectorStrategyImplTest {
}
@Test
public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
public void testSuggestNetworkTime_rejectedBelowLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_NETWORK)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(suggestedTime);
script.generateNetworkTimeSuggestion(belowLowerBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking()
.assertLatestNetworkSuggestion(null);
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestNetworkTime_notRejectedAboveLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_NETWORK)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(aboveLowerBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
}
@Test
public void testSuggestNetworkTime_rejectedAboveUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_NETWORK)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(aboveUpperBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestNetworkTime_notRejectedBelowUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_NETWORK)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(belowUpperBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
}
@Test
@@ -642,6 +795,70 @@ public class TimeDetectorStrategyImplTest {
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestGnssTime_rejectedBelowLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_GNSS)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
GnssTimeSuggestion timeSuggestion =
script.generateGnssTimeSuggestion(belowLowerBound);
script.simulateGnssTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestGnssTime_notRejectedAboveLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_GNSS)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
GnssTimeSuggestion timeSuggestion =
script.generateGnssTimeSuggestion(aboveLowerBound);
script.simulateGnssTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
}
@Test
public void testSuggestGnssTime_rejectedAboveUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_GNSS)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
GnssTimeSuggestion timeSuggestion =
script.generateGnssTimeSuggestion(aboveUpperBound);
script.simulateGnssTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestGnssTime_notRejectedBelowUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_GNSS)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
GnssTimeSuggestion timeSuggestion =
script.generateGnssTimeSuggestion(belowUpperBound);
script.simulateGnssTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
}
@Test
public void testSuggestExternalTime_autoTimeEnabled() {
ConfigurationInternal configInternal =
@@ -678,20 +895,67 @@ public class TimeDetectorStrategyImplTest {
}
@Test
public void externalTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() {
public void testSuggestExternalTime_rejectedBelowLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_EXTERNAL)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
Instant belowLowerBound = TEST_SUGGESTION_LOWER_BOUND.minusSeconds(1);
ExternalTimeSuggestion timeSuggestion =
script.generateExternalTimeSuggestion(suggestedTime);
script.generateExternalTimeSuggestion(belowLowerBound);
script.simulateExternalTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking()
.assertLatestExternalSuggestion(null);
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestExternalTime_notRejectedAboveLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_EXTERNAL)
.setAutoSuggestionLowerBound(TEST_SUGGESTION_LOWER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveLowerBound = TEST_SUGGESTION_LOWER_BOUND.plusSeconds(1);
ExternalTimeSuggestion timeSuggestion =
script.generateExternalTimeSuggestion(aboveLowerBound);
script.simulateExternalTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
}
@Test
public void testSuggestExternalTime_rejectedAboveUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_EXTERNAL)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant aboveUpperBound = TEST_SUGGESTION_UPPER_BOUND.plusSeconds(1);
ExternalTimeSuggestion timeSuggestion =
script.generateExternalTimeSuggestion(aboveUpperBound);
script.simulateExternalTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void testSuggestExternalTime_notRejectedBelowUpperBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_EXTERNAL)
.setSuggestionUpperBound(TEST_SUGGESTION_UPPER_BOUND)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant belowUpperBound = TEST_SUGGESTION_UPPER_BOUND.minusSeconds(1);
ExternalTimeSuggestion timeSuggestion =
script.generateExternalTimeSuggestion(belowUpperBound);
script.simulateExternalTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
}
@Test
@@ -1198,56 +1462,6 @@ public class TimeDetectorStrategyImplTest {
.verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli());
}
@Test
public void manualY2038SuggestionsAreRejectedOnAffectedDevices() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
.setDeviceHasY2038Issue(true)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
ManualTimeSuggestion timeSuggestion = script.generateManualTimeSuggestion(y2038IssueTime);
script.simulateManualTimeSuggestion(
ARBITRARY_USER_ID, timeSuggestion, false /* expectedResult */)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void telephonyY2038SuggestionsAreRejectedOnAffectedDevices() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
.setDeviceHasY2038Issue(true)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
final int slotIndex = 0;
Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
TelephonyTimeSuggestion timeSuggestion =
script.generateTelephonyTimeSuggestion(slotIndex, y2038IssueTime);
script.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
public void telephonyY2038SuggestionsAreNotRejectedOnUnaffectedDevices() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
.setDeviceHasY2038Issue(false)
.build();
Script script = new Script().simulateConfigurationInternalChange(configInternal);
final int slotIndex = 0;
Instant y2038IssueTime = Instant.ofEpochMilli((1L + Integer.MAX_VALUE) * 1000L);
TelephonyTimeSuggestion timeSuggestion =
script.generateTelephonyTimeSuggestion(slotIndex, y2038IssueTime);
script.simulateTelephonyTimeSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(y2038IssueTime.toEpochMilli());
}
/**
* A fake implementation of {@link TimeDetectorStrategyImpl.Environment}. Besides tracking
* changes and behaving like the real thing should, it also asserts preconditions.