Merge "Allow for empty time suggestions"

This commit is contained in:
Neil Fuller
2019-11-27 09:45:53 +00:00
committed by Gerrit Code Review
5 changed files with 68 additions and 26 deletions

View File

@@ -29,7 +29,9 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* A time signal from a telephony source. The value consists of the number of milliseconds elapsed * A time signal from a telephony source. The value can be {@code null} to indicate that the
* telephony source has entered an "un-opinionated" state and any previously sent suggestions are
* being withdrawn. When not {@code null}, the value consists of the number of milliseconds elapsed
* since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number * since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number
* was established. The elapsed realtime clock is considered accurate but volatile, so time signals * was established. The elapsed realtime clock is considered accurate but volatile, so time signals
* must not be persisted across device resets. * must not be persisted across device resets.
@@ -50,20 +52,17 @@ public final class PhoneTimeSuggestion implements Parcelable {
}; };
private final int mPhoneId; private final int mPhoneId;
@NonNull @Nullable private TimestampedValue<Long> mUtcTime;
private final TimestampedValue<Long> mUtcTime; @Nullable private ArrayList<String> mDebugInfo;
@Nullable
private ArrayList<String> mDebugInfo;
public PhoneTimeSuggestion(int phoneId, @NonNull TimestampedValue<Long> utcTime) { public PhoneTimeSuggestion(int phoneId) {
mPhoneId = phoneId; mPhoneId = phoneId;
mUtcTime = Objects.requireNonNull(utcTime);
} }
private static PhoneTimeSuggestion createFromParcel(Parcel in) { private static PhoneTimeSuggestion createFromParcel(Parcel in) {
int phoneId = in.readInt(); int phoneId = in.readInt();
TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */); PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion(phoneId);
PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion(phoneId, utcTime); suggestion.setUtcTime(in.readParcelable(null /* classLoader */));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */); ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
suggestion.mDebugInfo = debugInfo; suggestion.mDebugInfo = debugInfo;
@@ -86,7 +85,11 @@ public final class PhoneTimeSuggestion implements Parcelable {
return mPhoneId; return mPhoneId;
} }
@NonNull public void setUtcTime(@Nullable TimestampedValue<Long> utcTime) {
mUtcTime = utcTime;
}
@Nullable
public TimestampedValue<Long> getUtcTime() { public TimestampedValue<Long> getUtcTime() {
return mUtcTime; return mUtcTime;
} }

View File

@@ -30,17 +30,22 @@ public class PhoneTimeSuggestionTest {
@Test @Test
public void testEquals() { public void testEquals() {
PhoneTimeSuggestion one = PhoneTimeSuggestion one = new PhoneTimeSuggestion(PHONE_ID);
new PhoneTimeSuggestion(PHONE_ID, new TimestampedValue<>(1111L, 2222L));
assertEquals(one, one); assertEquals(one, one);
PhoneTimeSuggestion two = PhoneTimeSuggestion two = new PhoneTimeSuggestion(PHONE_ID);
new PhoneTimeSuggestion(PHONE_ID, new TimestampedValue<>(1111L, 2222L));
assertEquals(one, two); assertEquals(one, two);
assertEquals(two, one); assertEquals(two, one);
PhoneTimeSuggestion three = one.setUtcTime(new TimestampedValue<>(1111L, 2222L));
new PhoneTimeSuggestion(PHONE_ID + 1, new TimestampedValue<>(1111L, 2222L)); assertEquals(one, one);
two.setUtcTime(new TimestampedValue<>(1111L, 2222L));
assertEquals(one, two);
assertEquals(two, one);
PhoneTimeSuggestion three = new PhoneTimeSuggestion(PHONE_ID + 1);
three.setUtcTime(new TimestampedValue<>(1111L, 2222L));
assertNotEquals(one, three); assertNotEquals(one, three);
assertNotEquals(three, one); assertNotEquals(three, one);
@@ -52,8 +57,10 @@ public class PhoneTimeSuggestionTest {
@Test @Test
public void testParcelable() { public void testParcelable() {
PhoneTimeSuggestion one = PhoneTimeSuggestion one = new PhoneTimeSuggestion(PHONE_ID);
new PhoneTimeSuggestion(PHONE_ID, new TimestampedValue<>(1111L, 2222L)); assertEquals(one, roundTripParcelable(one));
one.setUtcTime(new TimestampedValue<>(1111L, 2222L));
assertEquals(one, roundTripParcelable(one)); assertEquals(one, roundTripParcelable(one));
// DebugInfo should also be stored (but is not checked by equals() // DebugInfo should also be stored (but is not checked by equals()

View File

@@ -67,6 +67,11 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy {
public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion) { public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion) {
// NITZ logic // NITZ logic
// Empty suggestions are just ignored as we don't currently keep track of suggestion origin.
if (timeSuggestion.getUtcTime() == null) {
return;
}
boolean timeSuggestionIsValid = boolean timeSuggestionIsValid =
validateNewPhoneSuggestion(timeSuggestion, mLastPhoneSuggestion); validateNewPhoneSuggestion(timeSuggestion, mLastPhoneSuggestion);
if (!timeSuggestionIsValid) { if (!timeSuggestionIsValid) {

View File

@@ -70,6 +70,18 @@ public class SimpleTimeZoneDetectorStrategyTest {
.verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis); .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis);
} }
@Test
public void testSuggestPhoneTime_emptySuggestionIgnored() {
Scenario scenario = SCENARIO_1;
mScript.pokeFakeClocks(scenario)
.pokeTimeDetectionEnabled(true);
PhoneTimeSuggestion timeSuggestion = createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, null);
mScript.simulatePhoneTimeSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test @Test
public void testSuggestPhoneTime_systemClockThreshold() { public void testSuggestPhoneTime_systemClockThreshold() {
Scenario scenario = SCENARIO_1; Scenario scenario = SCENARIO_1;
@@ -99,7 +111,8 @@ public class SimpleTimeZoneDetectorStrategyTest {
TimestampedValue<Long> utcTime2 = new TimestampedValue<>( TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
mScript.peekElapsedRealtimeMillis(), mScript.peekElapsedRealtimeMillis(),
mScript.peekSystemClockMillis() + underThresholdMillis); mScript.peekSystemClockMillis() + underThresholdMillis);
PhoneTimeSuggestion timeSuggestion2 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2); PhoneTimeSuggestion timeSuggestion2 =
createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2);
mScript.simulateTimePassing(clockIncrement) mScript.simulateTimePassing(clockIncrement)
.simulatePhoneTimeSuggestion(timeSuggestion2) .simulatePhoneTimeSuggestion(timeSuggestion2)
.verifySystemClockWasNotSetAndResetCallTracking(); .verifySystemClockWasNotSetAndResetCallTracking();
@@ -109,7 +122,8 @@ public class SimpleTimeZoneDetectorStrategyTest {
mScript.peekElapsedRealtimeMillis(), mScript.peekElapsedRealtimeMillis(),
mScript.peekSystemClockMillis() + systemClockUpdateThresholdMillis); mScript.peekSystemClockMillis() + systemClockUpdateThresholdMillis);
PhoneTimeSuggestion timeSuggestion3 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime3); PhoneTimeSuggestion timeSuggestion3 =
createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime3);
mScript.simulateTimePassing(clockIncrement); mScript.simulateTimePassing(clockIncrement);
long expectSystemClockMillis3 = long expectSystemClockMillis3 =
@@ -158,7 +172,8 @@ public class SimpleTimeZoneDetectorStrategyTest {
long referenceTimeBeforeLastSignalMillis = utcTime1.getReferenceTimeMillis() - 1; long referenceTimeBeforeLastSignalMillis = utcTime1.getReferenceTimeMillis() - 1;
TimestampedValue<Long> utcTime2 = new TimestampedValue<>( TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
referenceTimeBeforeLastSignalMillis, validUtcTimeMillis); referenceTimeBeforeLastSignalMillis, validUtcTimeMillis);
PhoneTimeSuggestion timeSuggestion2 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2); PhoneTimeSuggestion timeSuggestion2 =
createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2);
mScript.simulatePhoneTimeSuggestion(timeSuggestion2) mScript.simulatePhoneTimeSuggestion(timeSuggestion2)
.verifySystemClockWasNotSetAndResetCallTracking(); .verifySystemClockWasNotSetAndResetCallTracking();
@@ -168,7 +183,8 @@ public class SimpleTimeZoneDetectorStrategyTest {
utcTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1; utcTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1;
TimestampedValue<Long> utcTime3 = new TimestampedValue<>( TimestampedValue<Long> utcTime3 = new TimestampedValue<>(
referenceTimeInFutureMillis, validUtcTimeMillis); referenceTimeInFutureMillis, validUtcTimeMillis);
PhoneTimeSuggestion timeSuggestion3 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime3); PhoneTimeSuggestion timeSuggestion3 =
createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime3);
mScript.simulatePhoneTimeSuggestion(timeSuggestion3) mScript.simulatePhoneTimeSuggestion(timeSuggestion3)
.verifySystemClockWasNotSetAndResetCallTracking(); .verifySystemClockWasNotSetAndResetCallTracking();
@@ -178,7 +194,8 @@ public class SimpleTimeZoneDetectorStrategyTest {
validReferenceTimeMillis, validUtcTimeMillis); validReferenceTimeMillis, validUtcTimeMillis);
long expectedSystemClockMillis4 = long expectedSystemClockMillis4 =
TimeDetectorStrategy.getTimeAt(utcTime4, mScript.peekElapsedRealtimeMillis()); TimeDetectorStrategy.getTimeAt(utcTime4, mScript.peekElapsedRealtimeMillis());
PhoneTimeSuggestion timeSuggestion4 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime4); PhoneTimeSuggestion timeSuggestion4 =
createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime4);
mScript.simulatePhoneTimeSuggestion(timeSuggestion4) mScript.simulatePhoneTimeSuggestion(timeSuggestion4)
.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4); .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4);
} }
@@ -223,7 +240,8 @@ public class SimpleTimeZoneDetectorStrategyTest {
TimestampedValue<Long> utcTime2 = new TimestampedValue<>( TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
mScript.peekElapsedRealtimeMillis(), mScript.peekElapsedRealtimeMillis(),
mScript.peekSystemClockMillis() + systemClockUpdateThreshold); mScript.peekSystemClockMillis() + systemClockUpdateThreshold);
PhoneTimeSuggestion timeSuggestion2 = new PhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2); PhoneTimeSuggestion timeSuggestion2 =
createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime2);
// Simulate more time passing. // Simulate more time passing.
mScript.simulateTimePassing(clockIncrementMillis); mScript.simulateTimePassing(clockIncrementMillis);
@@ -465,7 +483,7 @@ public class SimpleTimeZoneDetectorStrategyTest {
PhoneTimeSuggestion createPhoneTimeSuggestionForActual(int phoneId) { PhoneTimeSuggestion createPhoneTimeSuggestionForActual(int phoneId) {
TimestampedValue<Long> time = new TimestampedValue<>( TimestampedValue<Long> time = new TimestampedValue<>(
mInitialDeviceRealtimeMillis, mActualTimeMillis); mInitialDeviceRealtimeMillis, mActualTimeMillis);
return new PhoneTimeSuggestion(phoneId, time); return createPhoneTimeSuggestion(phoneId, time);
} }
static class Builder { static class Builder {
@@ -500,6 +518,13 @@ public class SimpleTimeZoneDetectorStrategyTest {
} }
} }
private static PhoneTimeSuggestion createPhoneTimeSuggestion(int phoneId,
TimestampedValue<Long> utcTime) {
PhoneTimeSuggestion timeSuggestion = new PhoneTimeSuggestion(phoneId);
timeSuggestion.setUtcTime(utcTime);
return timeSuggestion;
}
private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute, private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute,
int second) { int second) {
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC")); Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC"));

View File

@@ -117,8 +117,10 @@ public class TimeDetectorServiceTest {
private static PhoneTimeSuggestion createPhoneTimeSuggestion() { private static PhoneTimeSuggestion createPhoneTimeSuggestion() {
int phoneId = 1234; int phoneId = 1234;
PhoneTimeSuggestion suggestion = new PhoneTimeSuggestion(phoneId);
TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L); TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
return new PhoneTimeSuggestion(phoneId, timeValue); suggestion.setUtcTime(timeValue);
return suggestion;
} }
private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy { private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy {