Merge "Prepare to make time detection more configurable"
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ public class TimeDetectorServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleAutoTimeDetectionChanged() {
|
public void handleAutoTimeConfigChanged() {
|
||||||
mHandleAutoTimeDetectionChangedCalled = true;
|
mHandleAutoTimeDetectionChangedCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user