Merge "Prepare to make time detection more configurable"

This commit is contained in:
Almaz Mingaleev
2020-11-27 18:36:25 +00:00
committed by Gerrit Code Review
6 changed files with 223 additions and 62 deletions

View File

@@ -125,7 +125,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub {
/** Internal method for handling the auto time setting being changed. */ /** Internal method for handling the auto time setting being changed. */
@VisibleForTesting @VisibleForTesting
public void handleAutoTimeDetectionChanged() { public void handleAutoTimeDetectionChanged() {
mHandler.post(mTimeDetectorStrategy::handleAutoTimeDetectionChanged); mHandler.post(mTimeDetectorStrategy::handleAutoTimeConfigChanged);
} }
@Override @Override

View File

@@ -16,6 +16,7 @@
package com.android.server.timedetector; package com.android.server.timedetector;
import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.ManualTimeSuggestion;
@@ -24,6 +25,8 @@ import android.app.timedetector.TelephonyTimeSuggestion;
import android.os.TimestampedValue; import android.os.TimestampedValue;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* The interface for the class that implements the time detection algorithm used by the * The interface for the class that implements the time detection algorithm used by the
@@ -37,22 +40,41 @@ import java.io.PrintWriter;
*/ */
public interface TimeDetectorStrategy { public interface TimeDetectorStrategy {
/** Process the suggested time from telephony sources. */ @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK })
@Retention(RetentionPolicy.SOURCE)
@interface Origin {}
/** Used when a time value originated from a telephony signal. */
@Origin
int ORIGIN_TELEPHONY = 1;
/** Used when a time value originated from a user / manual settings. */
@Origin
int ORIGIN_MANUAL = 2;
/** Used when a time value originated from a network signal. */
@Origin
int ORIGIN_NETWORK = 3;
/** Processes the suggested time from telephony sources. */
void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion); void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion);
/** /**
* Process the suggested manually entered time. Returns {@code false} if the suggestion was * Processes the suggested manually entered time. Returns {@code false} if the suggestion was
* invalid, or the device configuration prevented the suggestion being used, {@code true} if the * invalid, or the device configuration prevented the suggestion being used, {@code true} if the
* suggestion was accepted. A suggestion that is valid but does not change the time because it * suggestion was accepted. A suggestion that is valid but does not change the time because it
* matches the current device time is considered accepted. * matches the current device time is considered accepted.
*/ */
boolean suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion); boolean suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion);
/** Process the suggested time from network sources. */ /** Processes the suggested time from network sources. */
void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion); void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion);
/** Handle the auto-time setting being toggled on or off. */ /**
void handleAutoTimeDetectionChanged(); * Handles the auto-time configuration changing For example, when the auto-time setting is
* toggled on or off.
*/
void handleAutoTimeConfigChanged();
/** Dump debug information. */ /** Dump debug information. */
void dump(@NonNull PrintWriter pw, @Nullable String[] args); void dump(@NonNull PrintWriter pw, @Nullable String[] args);
@@ -67,4 +89,38 @@ public interface TimeDetectorStrategy {
return (referenceClockMillisNow - timeValue.getReferenceTimeMillis()) return (referenceClockMillisNow - timeValue.getReferenceTimeMillis())
+ timeValue.getValue(); + timeValue.getValue();
} }
/**
* Converts one of the {@code ORIGIN_} constants to a human readable string suitable for config
* and debug usage. Throws an {@link IllegalArgumentException} if the value is unrecognized.
*/
static String originToString(@Origin int origin) {
switch (origin) {
case ORIGIN_MANUAL:
return "manual";
case ORIGIN_NETWORK:
return "network";
case ORIGIN_TELEPHONY:
return "telephony";
default:
throw new IllegalArgumentException("origin=" + origin);
}
}
/**
* Converts a human readable config string to one of the {@code ORIGIN_} constants.
* Throws an {@link IllegalArgumentException} if the value is unrecognized.
*/
static @Origin int stringToOrigin(String originString) {
switch (originString) {
case "manual":
return ORIGIN_MANUAL;
case "network":
return ORIGIN_NETWORK;
case "telephony":
return ORIGIN_TELEPHONY;
default:
throw new IllegalArgumentException("originString=" + originString);
}
}
} }

View File

@@ -16,6 +16,8 @@
package com.android.server.timedetector; package com.android.server.timedetector;
import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.content.ContentResolver; import android.content.ContentResolver;
@@ -58,6 +60,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat
@NonNull private final ContentResolver mContentResolver; @NonNull private final ContentResolver mContentResolver;
@NonNull private final PowerManager.WakeLock mWakeLock; @NonNull private final PowerManager.WakeLock mWakeLock;
@NonNull private final AlarmManager mAlarmManager; @NonNull private final AlarmManager mAlarmManager;
@NonNull private final int[] mOriginPriorities;
public TimeDetectorStrategyCallbackImpl(@NonNull Context context) { public TimeDetectorStrategyCallbackImpl(@NonNull Context context) {
mContext = Objects.requireNonNull(context); mContext = Objects.requireNonNull(context);
@@ -72,6 +75,15 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat
mSystemClockUpdateThresholdMillis = mSystemClockUpdateThresholdMillis =
SystemProperties.getInt("ro.sys.time_detector_update_diff", SystemProperties.getInt("ro.sys.time_detector_update_diff",
SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT); SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
// TODO(b/172230856): Obtain these values from configuration.
String[] originStrings = { "telephony", "network" };
int[] origins = new int[originStrings.length];
for (int i = 0; i < originStrings.length; i++) {
int origin = stringToOrigin(originStrings[i]);
origins[i] = origin;
}
mOriginPriorities = origins;
} }
@Override @Override
@@ -93,6 +105,11 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat
return TIME_LOWER_BOUND; return TIME_LOWER_BOUND;
} }
@Override
public int[] getAutoOriginPriorities() {
return mOriginPriorities;
}
@Override @Override
public void acquireWakeLock() { public void acquireWakeLock() {
if (mWakeLock.isHeld()) { if (mWakeLock.isHeld()) {

View File

@@ -16,7 +16,8 @@
package com.android.server.timedetector; package com.android.server.timedetector;
import android.annotation.IntDef; import static com.android.server.timedetector.TimeDetectorStrategy.originToString;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.AlarmManager; import android.app.AlarmManager;
@@ -34,9 +35,8 @@ import com.android.server.timezonedetector.ArrayMapWithHistory;
import com.android.server.timezonedetector.ReferenceWithHistory; import com.android.server.timezonedetector.ReferenceWithHistory;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays;
/** /**
* An implementation of {@link TimeDetectorStrategy} that passes telephony and manual suggestions to * An implementation of {@link TimeDetectorStrategy} that passes telephony and manual suggestions to
@@ -64,22 +64,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
static final long MAX_UTC_TIME_AGE_MILLIS = static final long MAX_UTC_TIME_AGE_MILLIS =
TELEPHONY_BUCKET_COUNT * TELEPHONY_BUCKET_SIZE_MILLIS; TELEPHONY_BUCKET_COUNT * TELEPHONY_BUCKET_SIZE_MILLIS;
@IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK })
@Retention(RetentionPolicy.SOURCE)
public @interface Origin {}
/** Used when a time value originated from a telephony signal. */
@Origin
private static final int ORIGIN_TELEPHONY = 1;
/** Used when a time value originated from a user / manual settings. */
@Origin
private static final int ORIGIN_MANUAL = 2;
/** Used when a time value originated from a network signal. */
@Origin
private static final int ORIGIN_NETWORK = 3;
/** /**
* CLOCK_PARANOIA: The maximum difference allowed between the expected system clock time and the * CLOCK_PARANOIA: The maximum difference allowed between the expected system clock time and the
* actual system clock time before a warning is logged. Used to help identify situations where * actual system clock time before a warning is logged. Used to help identify situations where
@@ -153,6 +137,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
@NonNull @NonNull
Instant autoTimeLowerBound(); Instant autoTimeLowerBound();
/**
* Returns the order to look at time suggestions when automatically detecting time.
* See {@code #ORIGIN_} constants
*/
@Origin int[] getAutoOriginPriorities();
/** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */
void acquireWakeLock(); void acquireWakeLock();
@@ -237,12 +227,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
} }
@Override @Override
public synchronized void handleAutoTimeDetectionChanged() { public synchronized void handleAutoTimeConfigChanged() {
boolean enabled = mCallback.isAutoTimeDetectionEnabled(); boolean enabled = mCallback.isAutoTimeDetectionEnabled();
// When automatic time detection is enabled we update the system clock instantly if we can. // When automatic time detection is enabled we update the system clock instantly if we can.
// Conversely, when automatic time detection is disabled we leave the clock as it is. // Conversely, when automatic time detection is disabled we leave the clock as it is.
if (enabled) { if (enabled) {
String reason = "Auto time zone detection setting enabled."; String reason = "Auto time zone detection config changed.";
doAutoTimeDetection(reason); doAutoTimeDetection(reason);
} else { } else {
// CLOCK_PARANOIA: We are losing "control" of the system clock so we cannot predict what // CLOCK_PARANOIA: We are losing "control" of the system clock so we cannot predict what
@@ -365,33 +355,44 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
return; return;
} }
// Android devices currently prioritize any telephony over network signals. There are // Try the different origins one at a time.
// carrier compliance tests that would need to be changed before we could ignore NITZ or int[] originPriorities = mCallback.getAutoOriginPriorities();
// prefer NTP generally. This check is cheap on devices without telephony hardware. for (int origin : originPriorities) {
TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion(); TimestampedValue<Long> newUtcTime = null;
if (bestTelephonySuggestion != null) { String cause = null;
final TimestampedValue<Long> newUtcTime = bestTelephonySuggestion.getUtcTime(); if (origin == ORIGIN_TELEPHONY) {
String cause = "Found good telephony suggestion." TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion();
+ ", bestTelephonySuggestion=" + bestTelephonySuggestion if (bestTelephonySuggestion != null) {
+ ", detectionReason=" + detectionReason; newUtcTime = bestTelephonySuggestion.getUtcTime();
setSystemClockIfRequired(ORIGIN_TELEPHONY, newUtcTime, cause); cause = "Found good telephony suggestion."
return; + ", bestTelephonySuggestion=" + bestTelephonySuggestion
} + ", detectionReason=" + detectionReason;
}
} else if (origin == ORIGIN_NETWORK) {
NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion();
if (networkSuggestion != null) {
newUtcTime = networkSuggestion.getUtcTime();
cause = "Found good network suggestion."
+ ", networkSuggestion=" + networkSuggestion
+ ", detectionReason=" + detectionReason;
}
} else {
Slog.w(LOG_TAG, "Unknown or unsupported origin=" + origin
+ " in " + Arrays.toString(originPriorities)
+ ": Skipping");
}
// There is no good telephony suggestion, try network. // Update the system clock if a good suggestion has been found.
NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion(); if (newUtcTime != null) {
if (networkSuggestion != null) { setSystemClockIfRequired(origin, newUtcTime, cause);
final TimestampedValue<Long> newUtcTime = networkSuggestion.getUtcTime(); return;
String cause = "Found good network suggestion." }
+ ", networkSuggestion=" + networkSuggestion
+ ", detectionReason=" + detectionReason;
setSystemClockIfRequired(ORIGIN_NETWORK, newUtcTime, cause);
return;
} }
if (DBG) { if (DBG) {
Slog.d(LOG_TAG, "Could not determine time: No best telephony or network suggestion." Slog.d(LOG_TAG, "Could not determine time: No suggestion found in"
+ " detectionReason=" + detectionReason); + " originPriorities=" + Arrays.toString(originPriorities)
+ ", detectionReason=" + detectionReason);
} }
} }
@@ -476,7 +477,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
// Validate first. // Validate first.
TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime(); TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime();
if (!validateSuggestionUtcTime(elapsedRealtimeMillis, utcTime)) { if (!validateSuggestionUtcTime(elapsedRealtimeMillis, utcTime)) {
Slog.w(LOG_TAG, "Existing suggestion found to be invalid " Slog.w(LOG_TAG, "Existing suggestion found to be invalid"
+ " elapsedRealtimeMillis=" + elapsedRealtimeMillis + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
+ ", timeSuggestion=" + timeSuggestion); + ", timeSuggestion=" + timeSuggestion);
return TELEPHONY_INVALID_SCORE; return TELEPHONY_INVALID_SCORE;
@@ -525,7 +526,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
if (!mCallback.isAutoTimeDetectionEnabled()) { if (!mCallback.isAutoTimeDetectionEnabled()) {
if (DBG) { if (DBG) {
Slog.d(LOG_TAG, "Auto time detection is not enabled." Slog.d(LOG_TAG, "Auto time detection is not enabled."
+ " origin=" + origin + " origin=" + originToString(origin)
+ ", time=" + time + ", time=" + time
+ ", cause=" + cause); + ", cause=" + cause);
} }
@@ -535,7 +536,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
if (mCallback.isAutoTimeDetectionEnabled()) { if (mCallback.isAutoTimeDetectionEnabled()) {
if (DBG) { if (DBG) {
Slog.d(LOG_TAG, "Auto time detection is enabled." Slog.d(LOG_TAG, "Auto time detection is enabled."
+ " origin=" + origin + " origin=" + originToString(origin)
+ ", time=" + time + ", time=" + time
+ ", cause=" + cause); + ", cause=" + cause);
} }
@@ -557,7 +558,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
@GuardedBy("this") @GuardedBy("this")
private boolean setSystemClockUnderWakeLock( private boolean setSystemClockUnderWakeLock(
int origin, @NonNull TimestampedValue<Long> newTime, @NonNull Object cause) { @Origin int origin, @NonNull TimestampedValue<Long> newTime, @NonNull String cause) {
long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis(); long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
boolean isOriginAutomatic = isOriginAutomatic(origin); boolean isOriginAutomatic = isOriginAutomatic(origin);

View File

@@ -242,7 +242,7 @@ public class TimeDetectorServiceTest {
} }
@Override @Override
public void handleAutoTimeDetectionChanged() { public void handleAutoTimeConfigChanged() {
mHandleAutoTimeDetectionChangedCalled = true; mHandleAutoTimeDetectionChangedCalled = true;
} }

View File

@@ -16,6 +16,9 @@
package com.android.server.timedetector; package com.android.server.timedetector;
import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
@@ -29,6 +32,8 @@ import android.os.TimestampedValue;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import com.android.server.timedetector.TimeDetectorStrategy.Origin;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -48,6 +53,9 @@ public class TimeDetectorStrategyImplTest {
123456789L /* realtimeClockMillis */, 123456789L /* realtimeClockMillis */,
createUtcTime(2010, 5, 23, 12, 0, 0)); createUtcTime(2010, 5, 23, 12, 0, 0));
// This is the traditional ordering for time detection on Android.
private static final @Origin int [] PROVIDERS_PRIORITY = { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
/** /**
* An arbitrary time, very different from the {@link #ARBITRARY_CLOCK_INITIALIZATION_INFO} * An arbitrary time, very different from the {@link #ARBITRARY_CLOCK_INITIALIZATION_INFO}
* time. Can be used as the basis for time suggestions. * time. Can be used as the basis for time suggestions.
@@ -488,11 +496,8 @@ public class TimeDetectorStrategyImplTest {
.assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion); .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
} }
/**
* Manual suggestions should be ignored if auto time is enabled.
*/
@Test @Test
public void testSuggestManualTime_autoTimeEnabled() { public void manualTimeSuggestion_isIgnored_whenAutoTimeEnabled() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(true); .pokeAutoTimeDetectionEnabled(true);
@@ -505,7 +510,7 @@ public class TimeDetectorStrategyImplTest {
} }
@Test @Test
public void suggestManualTime_ignoresTimeLowerBound() { public void manualTimeSuggestion_ignoresTimeLowerBound() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(false); .pokeAutoTimeDetectionEnabled(false);
Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1));
@@ -658,6 +663,73 @@ public class TimeDetectorStrategyImplTest {
.assertLatestNetworkSuggestion(null); .assertLatestNetworkSuggestion(null);
} }
@Test
public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_lowerPriorityComesFirst() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(true);
Instant networkTime = ARBITRARY_TEST_TIME;
Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
NetworkTimeSuggestion networkTimeSuggestion =
mScript.generateNetworkTimeSuggestion(networkTime);
TelephonyTimeSuggestion telephonyTimeSuggestion =
mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime);
mScript.simulateNetworkTimeSuggestion(networkTimeSuggestion)
.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
.assertLatestNetworkSuggestion(networkTimeSuggestion)
.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli());
}
@Test
public void whenAllTimeSuggestionsAreAvailable_higherPriorityWins_higherPriorityComesFirst() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(true);
Instant networkTime = ARBITRARY_TEST_TIME;
Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30));
NetworkTimeSuggestion networkTimeSuggestion =
mScript.generateNetworkTimeSuggestion(networkTime);
TelephonyTimeSuggestion telephonyTimeSuggestion =
mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime);
mScript.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
.simulateNetworkTimeSuggestion(networkTimeSuggestion)
.assertLatestNetworkSuggestion(networkTimeSuggestion)
.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(telephonyTime.toEpochMilli());
}
@Test
public void whenHighestPrioritySuggestionIsNotAvailable_fallbacksToNext() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(true);
NetworkTimeSuggestion timeSuggestion =
mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME);
mScript.simulateNetworkTimeSuggestion(timeSuggestion)
.assertLatestNetworkSuggestion(timeSuggestion)
.verifySystemClockWasSetAndResetCallTracking(ARBITRARY_TEST_TIME.toEpochMilli());
}
@Test
public void suggestionsFromSourceNotListedInPrioritiesList_areIgnored() {
mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO)
.pokeAutoTimeDetectionEnabled(true)
.pokeAutoOriginPriorities(new int[]{ORIGIN_TELEPHONY});
NetworkTimeSuggestion timeSuggestion = mScript.generateNetworkTimeSuggestion(
ARBITRARY_TEST_TIME);
mScript.simulateNetworkTimeSuggestion(timeSuggestion)
.assertLatestNetworkSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
/** /**
* A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving
* like the real thing should, it also asserts preconditions. * like the real thing should, it also asserts preconditions.
@@ -668,6 +740,7 @@ public class TimeDetectorStrategyImplTest {
private long mElapsedRealtimeMillis; private long mElapsedRealtimeMillis;
private long mSystemClockMillis; private long mSystemClockMillis;
private int mSystemClockUpdateThresholdMillis = 2000; private int mSystemClockUpdateThresholdMillis = 2000;
private int[] mAutoOriginPriorities = PROVIDERS_PRIORITY;
// Tracking operations. // Tracking operations.
private boolean mSystemClockWasSet; private boolean mSystemClockWasSet;
@@ -687,6 +760,11 @@ public class TimeDetectorStrategyImplTest {
return TIME_LOWER_BOUND; return TIME_LOWER_BOUND;
} }
@Override
public int[] getAutoOriginPriorities() {
return mAutoOriginPriorities;
}
@Override @Override
public void acquireWakeLock() { public void acquireWakeLock() {
if (mWakeLockAcquired) { if (mWakeLockAcquired) {
@@ -736,6 +814,10 @@ public class TimeDetectorStrategyImplTest {
mAutoTimeDetectionEnabled = enabled; mAutoTimeDetectionEnabled = enabled;
} }
void pokeAutoOriginPriorities(@Origin int[] autoOriginPriorities) {
mAutoOriginPriorities = autoOriginPriorities;
}
long peekElapsedRealtimeMillis() { long peekElapsedRealtimeMillis() {
return mElapsedRealtimeMillis; return mElapsedRealtimeMillis;
} }
@@ -804,6 +886,11 @@ public class TimeDetectorStrategyImplTest {
return this; return this;
} }
Script pokeAutoOriginPriorities(@Origin int[] autoOriginPriorites) {
mFakeCallback.pokeAutoOriginPriorities(autoOriginPriorites);
return this;
}
long peekElapsedRealtimeMillis() { long peekElapsedRealtimeMillis() {
return mFakeCallback.peekElapsedRealtimeMillis(); return mFakeCallback.peekElapsedRealtimeMillis();
} }
@@ -836,7 +923,7 @@ public class TimeDetectorStrategyImplTest {
Script simulateAutoTimeDetectionToggle() { Script simulateAutoTimeDetectionToggle() {
mFakeCallback.simulateAutoTimeZoneDetectionToggle(); mFakeCallback.simulateAutoTimeZoneDetectionToggle();
mTimeDetectorStrategy.handleAutoTimeDetectionChanged(); mTimeDetectorStrategy.handleAutoTimeConfigChanged();
return this; return this;
} }
@@ -870,7 +957,7 @@ public class TimeDetectorStrategyImplTest {
Script assertLatestTelephonySuggestion(int slotIndex, TelephonyTimeSuggestion expected) { Script assertLatestTelephonySuggestion(int slotIndex, TelephonyTimeSuggestion expected) {
assertEquals( assertEquals(
"Expected to see " + expected + " at slotIndex=" + slotIndex + ", but got " "Expected to see " + expected + " at slotIndex=" + slotIndex + ", but got "
+ mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex), + mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex),
expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex)); expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex));
return this; return this;
} }