Merge "Allow for empty time suggestions"
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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"));
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user