use of com.android.internal.telephony.NitzData in project android_frameworks_opt_telephony by LineageOS.
the class TimeZoneLookupHelperTest method testLookupByNitzCountry_dstKnownAndUnknown.
@Test
public void testLookupByNitzCountry_dstKnownAndUnknown() {
// Historical dates are used to avoid the test breaking due to data changes.
// However, algorithm updates may change the exact time zone returned, though it shouldn't
// ever be a less exact match.
long nhSummerTimeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
long nhWinterTimeMillis = createUtcTime(2015, 1, 20, 1, 2, 3);
// A country in the northern hemisphere with one time zone.
// Andora
String adIso = "AD";
// 2015-06-20 01:02:03 UTC, UTC+2
String summerTimeNitzString = "15/06/20,01:02:03+8";
// 2015-01-20 01:02:03 UTC, UTC+1
String winterTimeNitzString = "15/01/20,01:02:03+4";
// Summer, known & correct DST state (DST == true).
{
String summerTimeNitzStringWithDst = summerTimeNitzString + ",1";
NitzData nitzData = NitzData.parse(summerTimeNitzStringWithDst);
int expectedUtcOffset = (int) TimeUnit.HOURS.toMillis(2);
Integer expectedDstOffset = (int) TimeUnit.HOURS.toMillis(1);
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
OffsetResult adSummerWithDstResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
OffsetResult expectedResult = new OffsetResult(zone("Europe/Andorra"), true);
assertEquals(expectedResult, adSummerWithDstResult);
assertOffsetResultZoneOffsets(nhSummerTimeMillis, expectedUtcOffset, expectedDstOffset, adSummerWithDstResult);
}
// Summer, known & incorrect DST state (DST == false)
{
String summerTimeNitzStringWithNoDst = summerTimeNitzString + ",0";
NitzData nitzData = NitzData.parse(summerTimeNitzStringWithNoDst);
OffsetResult adSummerWithNoDstResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
assertNull(adSummerWithNoDstResult);
}
// Winter, known & correct DST state (DST == false)
{
String winterTimeNitzStringWithNoDst = winterTimeNitzString + ",0";
NitzData nitzData = NitzData.parse(winterTimeNitzStringWithNoDst);
int expectedUtcOffset = (int) TimeUnit.HOURS.toMillis(1);
Integer expectedDstOffset = 0;
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
OffsetResult adWinterWithDstResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
OffsetResult expectedResult = new OffsetResult(zone("Europe/Andorra"), true);
assertEquals(expectedResult, adWinterWithDstResult);
assertOffsetResultZoneOffsets(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset, adWinterWithDstResult);
}
// Winter, known & incorrect DST state (DST == true)
{
String winterTimeNitzStringWithDst = winterTimeNitzString + ",1";
NitzData nitzData = NitzData.parse(winterTimeNitzStringWithDst);
OffsetResult adWinterWithDstResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
assertNull(adWinterWithDstResult);
}
// Summer, unknown DST state (will match any DST state with the correct offset).
{
NitzData nitzData = NitzData.parse(summerTimeNitzString);
int expectedUtcOffset = (int) TimeUnit.HOURS.toMillis(2);
// Unknown
Integer expectedDstOffset = null;
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
OffsetResult adSummerUnknownDstResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
OffsetResult expectedResult = new OffsetResult(zone("Europe/Andorra"), true);
assertEquals(expectedResult, adSummerUnknownDstResult);
assertOffsetResultZoneOffsets(nhSummerTimeMillis, expectedUtcOffset, expectedDstOffset, adSummerUnknownDstResult);
}
// Winter, unknown DST state (will match any DST state with the correct offset)
{
NitzData nitzData = NitzData.parse(winterTimeNitzString);
int expectedUtcOffset = (int) TimeUnit.HOURS.toMillis(1);
// Unknown
Integer expectedDstOffset = null;
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
OffsetResult adWinterUnknownDstResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
OffsetResult expectedResult = new OffsetResult(zone("Europe/Andorra"), true);
assertEquals(expectedResult, adWinterUnknownDstResult);
assertOffsetResultZoneOffsets(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset, adWinterUnknownDstResult);
}
}
use of com.android.internal.telephony.NitzData in project android_frameworks_opt_telephony by LineageOS.
the class TimeZoneLookupHelperTest method testDefaultBoostBehavior.
@Test
public void testDefaultBoostBehavior() {
long timeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
// An example known to be explicitly boosted. New Zealand has two zones but the vast
// majority of the population use one of them so Android's data file explicitly boosts the
// country default. If that changes in future this test will need to be changed to use
// another example.
String countryIsoCode = "nz";
CountryResult expectedResult = new CountryResult("Pacific/Auckland", QUALITY_DEFAULT_BOOSTED, ARBITRARY_DEBUG_INFO);
assertEquals(expectedResult, mTimeZoneLookupHelper.lookupByCountry(countryIsoCode, timeMillis));
// Data correct for the North and South Island.
int majorityWinterOffset = (int) TimeUnit.HOURS.toMillis(12);
NitzData majorityNitzData = NitzData.createForTests(majorityWinterOffset, 0, timeMillis, null);
// Boost doesn't directly affect lookupByNitzCountry()
OffsetResult majorityOffsetResult = mTimeZoneLookupHelper.lookupByNitzCountry(majorityNitzData, countryIsoCode);
assertEquals(zone("Pacific/Auckland"), majorityOffsetResult.getTimeZone());
assertTrue(majorityOffsetResult.isOnlyMatch());
// Data correct for the Chatham Islands.
int chathamWinterOffset = majorityWinterOffset + ((int) TimeUnit.MINUTES.toMillis(45));
NitzData chathamNitzData = NitzData.createForTests(chathamWinterOffset, 0, timeMillis, null);
OffsetResult chathamOffsetResult = mTimeZoneLookupHelper.lookupByNitzCountry(chathamNitzData, countryIsoCode);
assertEquals(zone("Pacific/Chatham"), chathamOffsetResult.getTimeZone());
assertTrue(chathamOffsetResult.isOnlyMatch());
// NITZ data that makes no sense for NZ results in no match.
int nonsenseOffset = (int) TimeUnit.HOURS.toMillis(5);
NitzData nonsenseNitzData = NitzData.createForTests(nonsenseOffset, 0, timeMillis, null);
OffsetResult nonsenseOffsetResult = mTimeZoneLookupHelper.lookupByNitzCountry(nonsenseNitzData, countryIsoCode);
assertNull(nonsenseOffsetResult);
}
use of com.android.internal.telephony.NitzData in project android_frameworks_opt_telephony by LineageOS.
the class TimeZoneLookupHelperTest method testNoDefaultBoostBehavior.
@Test
public void testNoDefaultBoostBehavior() {
long timeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
// An example known to not be explicitly boosted. Micronesia is spread out and there's no
// suitable default.
String countryIsoCode = "fm";
CountryResult expectedResult = new CountryResult("Pacific/Pohnpei", QUALITY_MULTIPLE_ZONES_DIFFERENT_OFFSETS, ARBITRARY_DEBUG_INFO);
assertEquals(expectedResult, mTimeZoneLookupHelper.lookupByCountry(countryIsoCode, timeMillis));
// Prove an OffsetResult can be found with the correct offset.
int chuukWinterOffset = (int) TimeUnit.HOURS.toMillis(10);
NitzData chuukNitzData = NitzData.createForTests(chuukWinterOffset, 0, timeMillis, null);
OffsetResult chuukOffsetResult = mTimeZoneLookupHelper.lookupByNitzCountry(chuukNitzData, countryIsoCode);
assertEquals(zone("Pacific/Chuuk"), chuukOffsetResult.getTimeZone());
assertTrue(chuukOffsetResult.isOnlyMatch());
// NITZ data that makes no sense for FM: no boost means we should get nothing.
int nonsenseOffset = (int) TimeUnit.HOURS.toMillis(5);
NitzData nonsenseNitzData = NitzData.createForTests(nonsenseOffset, 0, timeMillis, null);
OffsetResult nonsenseOffsetResult = mTimeZoneLookupHelper.lookupByNitzCountry(nonsenseNitzData, countryIsoCode);
assertNull(nonsenseOffsetResult);
}
use of com.android.internal.telephony.NitzData in project android_frameworks_opt_telephony by LineageOS.
the class NitzSignalInputFilterPredicateFactory method createRateLimitCheck.
/**
* Returns a {@link TrivalentPredicate} function that implements filtering using
* {@code oldSignal} and {@code newSignal}. The function can return {@code true} or
* {@code false} and so is intended as the final function in a chain.
*
* Function detail: if an NITZ signal received that is too similar to a previous one
* it should be disregarded if it's received within a configured time period.
* The general contract for {@link TrivalentPredicate} allows {@code previousSignal} to be
* {@code null}, but previous functions are expected to prevent it in this case.
*/
@VisibleForTesting
@NonNull
public static TrivalentPredicate createRateLimitCheck(@NonNull DeviceState deviceState) {
return new TrivalentPredicate() {
@Override
@NonNull
public Boolean mustProcessNitzSignal(@NonNull TimestampedValue<NitzData> previousSignal, @NonNull TimestampedValue<NitzData> newSignal) {
Objects.requireNonNull(newSignal);
Objects.requireNonNull(newSignal.getValue());
Objects.requireNonNull(previousSignal);
Objects.requireNonNull(previousSignal.getValue());
NitzData newNitzData = newSignal.getValue();
NitzData previousNitzData = previousSignal.getValue();
// was.
if (!offsetInfoIsTheSame(previousNitzData, newNitzData)) {
return true;
}
// Now check the continuous NitzData field (time) to see if it is sufficiently
// different.
int nitzUpdateSpacing = deviceState.getNitzUpdateSpacingMillis();
int nitzUpdateDiff = deviceState.getNitzUpdateDiffMillis();
// Calculate the elapsed time between the new signal and the last signal.
long elapsedRealtimeSinceLastSaved = newSignal.getReferenceTimeMillis() - previousSignal.getReferenceTimeMillis();
// Calculate the UTC difference between the time the two signals hold.
long utcTimeDifferenceMillis = newNitzData.getCurrentTimeInMillis() - previousNitzData.getCurrentTimeInMillis();
// Ideally the difference between elapsedRealtimeSinceLastSaved and
// utcTimeDifferenceMillis would be zero.
long millisGainedOrLost = Math.abs(utcTimeDifferenceMillis - elapsedRealtimeSinceLastSaved);
if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing || millisGainedOrLost > nitzUpdateDiff) {
return true;
}
if (DBG) {
Rlog.d(LOG_TAG, "mustProcessNitzSignal: NITZ signal filtered" + " previousSignal=" + previousSignal + ", newSignal=" + newSignal + ", nitzUpdateSpacing=" + nitzUpdateSpacing + ", nitzUpdateDiff=" + nitzUpdateDiff);
}
return false;
}
private boolean offsetInfoIsTheSame(NitzData one, NitzData two) {
return Objects.equals(two.getDstAdjustmentMillis(), one.getDstAdjustmentMillis()) && Objects.equals(two.getEmulatorHostTimeZone(), one.getEmulatorHostTimeZone()) && two.getLocalOffsetMillis() == one.getLocalOffsetMillis();
}
};
}
use of com.android.internal.telephony.NitzData in project android_frameworks_opt_telephony by LineageOS.
the class TimeZoneSuggesterImpl method findTimeZoneForTestNetwork.
/**
* Creates a {@link TelephonyTimeZoneSuggestion} using only NITZ. This happens when the device
* is attached to a test cell with an unrecognized MCC. In these cases we try to return a
* suggestion for an arbitrary time zone that matches the NITZ offset information.
*/
@NonNull
private TelephonyTimeZoneSuggestion findTimeZoneForTestNetwork(int slotIndex, @NonNull TimestampedValue<NitzData> nitzSignal) {
Objects.requireNonNull(nitzSignal);
NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue());
TelephonyTimeZoneSuggestion.Builder suggestionBuilder = new TelephonyTimeZoneSuggestion.Builder(slotIndex);
suggestionBuilder.addDebugInfo("findTimeZoneForTestNetwork: nitzSignal=" + nitzSignal);
OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitz(nitzData);
if (lookupResult == null) {
suggestionBuilder.addDebugInfo("findTimeZoneForTestNetwork: No zone found");
} else {
suggestionBuilder.setZoneId(lookupResult.getTimeZone().getID());
suggestionBuilder.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY);
int quality = lookupResult.isOnlyMatch() ? TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE : TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
suggestionBuilder.setQuality(quality);
suggestionBuilder.addDebugInfo("findTimeZoneForTestNetwork: lookupResult=" + lookupResult);
}
return suggestionBuilder.build();
}
Aggregations