Loading tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineImplTest.java +35 −204 Original line number Diff line number Diff line Loading @@ -16,18 +16,21 @@ package com.android.internal.telephony; import static com.android.internal.telephony.NitzStateMachineTestSupport.createTimeSignalFromNitzSignal; import static com.android.internal.telephony.NitzStateMachineTestSupport.createUtcTime; import static com.android.internal.telephony.NitzStateMachineTestSupport.zone; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.icu.util.Calendar; import android.icu.util.GregorianCalendar; import android.icu.util.TimeZone; import android.util.TimestampedValue; import com.android.internal.telephony.NitzStateMachine.DeviceState; import com.android.internal.telephony.NitzStateMachineTestSupport.FakeDeviceState; import com.android.internal.telephony.NitzStateMachineTestSupport.Scenario; import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult; import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult; Loading Loading @@ -748,63 +751,6 @@ public class NitzStateMachineImplTest extends TelephonyTest { TimeZone.getTimeZone(zoneId2).getOffset(timeMillis)); } private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC")); cal.clear(); cal.set(year, monthInYear - 1, day, hourOfDay, minute, second); return cal.getTimeInMillis(); } /** Some piece of state that tests want to track. */ private static class TestState<T> { private T mInitialValue; private LinkedList<T> mValues = new LinkedList<>(); void init(T value) { mValues.clear(); mInitialValue = value; } void set(T value) { mValues.addFirst(value); } boolean hasBeenSet() { return mValues.size() > 0; } void assertHasNotBeenSet() { assertFalse(hasBeenSet()); } void assertHasBeenSet() { assertTrue(hasBeenSet()); } void commitLatest() { if (hasBeenSet()) { mInitialValue = mValues.getLast(); mValues.clear(); } } void assertLatestEquals(T expected) { assertEquals(expected, getLatest()); } void assertChangeCount(int expectedCount) { assertEquals(expectedCount, mValues.size()); } public T getLatest() { if (hasBeenSet()) { return mValues.getFirst(); } return mInitialValue; } } /** * A "fluent" helper class allowing reuse of logic for test state initialization, simulation of * events, and verification of device state changes with self-describing method names. Loading Loading @@ -924,129 +870,56 @@ public class NitzStateMachineImplTest extends TelephonyTest { } } private static TimestampedValue<Long> createTimeSignalFromNitzSignal( TimestampedValue<NitzData> nitzSignal) { return new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); } /** * A scenario used during tests. Describes a fictional reality. */ static class Scenario { private final boolean mFrozen; private TimeZone mZone; private String mNetworkCountryIsoCode; private long mElapsedRealtimeMillis; private long mActualTimeMillis; Scenario(boolean frozen, long elapsedRealtimeMillis, long timeMillis, String zoneId, String countryIsoCode) { mFrozen = frozen; mActualTimeMillis = timeMillis; mElapsedRealtimeMillis = elapsedRealtimeMillis; mZone = zone(zoneId); mNetworkCountryIsoCode = countryIsoCode; } /** Creates an NITZ signal to match the scenario. */ TimestampedValue<NitzData> createNitzSignal() { int[] offsets = new int[2]; mZone.getOffset(mActualTimeMillis, false /* local */, offsets); int zoneOffsetMillis = offsets[0] + offsets[1]; NitzData nitzData = NitzData.createForTests( zoneOffsetMillis, offsets[1], mActualTimeMillis, null /* emulatorHostTimeZone */); return new TimestampedValue<>(mElapsedRealtimeMillis, nitzData); } /** Creates a time signal to match the scenario. */ TimestampedValue<Long> createTimeSignal() { return new TimestampedValue<>(mElapsedRealtimeMillis, mActualTimeMillis); } long getDeviceRealTimeMillis() { return mElapsedRealtimeMillis; } String getNetworkCountryIsoCode() { return mNetworkCountryIsoCode; } String getTimeZoneId() { return mZone.getID(); } /** Some piece of state that tests want to track. */ private static class TestState<T> { private T mInitialValue; private LinkedList<T> mValues = new LinkedList<>(); long getActualTimeMillis() { return mActualTimeMillis; void init(T value) { mValues.clear(); mInitialValue = value; } Scenario incrementTime(long timeIncrementMillis) { checkFrozen(); mElapsedRealtimeMillis += timeIncrementMillis; mActualTimeMillis += timeIncrementMillis; return this; void set(T value) { mValues.addFirst(value); } Scenario changeCountry(String timeZoneId, String networkCountryIsoCode) { checkFrozen(); mZone = zone(timeZoneId); mNetworkCountryIsoCode = networkCountryIsoCode; return this; boolean hasBeenSet() { return mValues.size() > 0; } Scenario mutableCopy() { return new Scenario( false /* frozen */, mElapsedRealtimeMillis, mActualTimeMillis, mZone.getID(), mNetworkCountryIsoCode); void assertHasNotBeenSet() { assertFalse(hasBeenSet()); } private void checkFrozen() { if (mFrozen) { throw new IllegalStateException("Scenario is frozen. Copy first"); } void assertHasBeenSet() { assertTrue(hasBeenSet()); } static class Builder { private long mInitialDeviceRealtimeMillis; private long mActualTimeMillis; private String mZoneId; private String mCountryIsoCode; Builder setDeviceRealtimeMillis(long realtimeMillis) { mInitialDeviceRealtimeMillis = realtimeMillis; return this; void commitLatest() { if (hasBeenSet()) { mInitialValue = mValues.getLast(); mValues.clear(); } Builder setActualTimeUtc(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { mActualTimeMillis = createUtcTime(year, monthInYear, day, hourOfDay, minute, second); return this; } Builder setTimeZone(String zoneId) { mZoneId = zoneId; return this; void assertLatestEquals(T expected) { assertEquals(expected, getLatest()); } Builder setCountryIso(String isoCode) { mCountryIsoCode = isoCode; return this; void assertChangeCount(int expectedCount) { assertEquals(expectedCount, mValues.size()); } Scenario buildFrozen() { return new Scenario( true /* frozen */, mInitialDeviceRealtimeMillis, mActualTimeMillis, mZoneId, mCountryIsoCode); public T getLatest() { if (hasBeenSet()) { return mValues.getFirst(); } return mInitialValue; } } private class FakeTimeServiceHelper implements TimeServiceHelper { private static class FakeTimeServiceHelper implements TimeServiceHelper { public TimeServiceHelper.Listener listener; public boolean timeZoneDetectionEnabled; Loading Loading @@ -1093,46 +966,4 @@ public class NitzStateMachineImplTest extends TelephonyTest { suggestedTime.commitLatest(); } } private static class FakeDeviceState implements DeviceState { public boolean ignoreNitz; public int nitzUpdateDiffMillis; public int nitzUpdateSpacingMillis; public String networkCountryIsoForPhone; public long elapsedRealtime; @Override public int getNitzUpdateSpacingMillis() { return nitzUpdateSpacingMillis; } @Override public int getNitzUpdateDiffMillis() { return nitzUpdateDiffMillis; } @Override public boolean getIgnoreNitz() { return ignoreNitz; } @Override public String getNetworkCountryIsoForPhone() { return networkCountryIsoForPhone; } @Override public long elapsedRealtime() { return elapsedRealtime; } } private static TimeZone zone(String zoneId) { TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId); if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) { fail(zoneId + " is not a valid zone"); } return timeZone; } } tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTestSupport.java 0 → 100644 +207 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony; import static org.junit.Assert.fail; import android.icu.util.Calendar; import android.icu.util.GregorianCalendar; import android.icu.util.TimeZone; import android.util.TimestampedValue; import com.android.internal.telephony.NitzStateMachine.DeviceState; /** * An assortment of methods and classes for testing {@link NitzStateMachine} implementations. */ final class NitzStateMachineTestSupport { /** * A scenario used during tests. Describes a fictional reality. */ static class Scenario { private final boolean mFrozen; private TimeZone mZone; private String mNetworkCountryIsoCode; private long mElapsedRealtimeMillis; private long mActualTimeMillis; Scenario(boolean frozen, long elapsedRealtimeMillis, long timeMillis, String zoneId, String countryIsoCode) { mFrozen = frozen; mActualTimeMillis = timeMillis; mElapsedRealtimeMillis = elapsedRealtimeMillis; mZone = zone(zoneId); mNetworkCountryIsoCode = countryIsoCode; } /** Creates an NITZ signal to match the scenario. */ TimestampedValue<NitzData> createNitzSignal() { int[] offsets = new int[2]; mZone.getOffset(mActualTimeMillis, false /* local */, offsets); int zoneOffsetMillis = offsets[0] + offsets[1]; NitzData nitzData = NitzData.createForTests( zoneOffsetMillis, offsets[1], mActualTimeMillis, null /* emulatorHostTimeZone */); return new TimestampedValue<>(mElapsedRealtimeMillis, nitzData); } /** Creates a time signal to match the scenario. */ TimestampedValue<Long> createTimeSignal() { return new TimestampedValue<>(mElapsedRealtimeMillis, mActualTimeMillis); } long getDeviceRealTimeMillis() { return mElapsedRealtimeMillis; } String getNetworkCountryIsoCode() { return mNetworkCountryIsoCode; } String getTimeZoneId() { return mZone.getID(); } long getActualTimeMillis() { return mActualTimeMillis; } Scenario incrementTime(long timeIncrementMillis) { checkFrozen(); mElapsedRealtimeMillis += timeIncrementMillis; mActualTimeMillis += timeIncrementMillis; return this; } Scenario changeCountry(String timeZoneId, String networkCountryIsoCode) { checkFrozen(); mZone = zone(timeZoneId); mNetworkCountryIsoCode = networkCountryIsoCode; return this; } Scenario mutableCopy() { return new Scenario( false /* frozen */, mElapsedRealtimeMillis, mActualTimeMillis, mZone.getID(), mNetworkCountryIsoCode); } private void checkFrozen() { if (mFrozen) { throw new IllegalStateException("Scenario is frozen. Copy first"); } } static class Builder { private long mInitialDeviceRealtimeMillis; private long mActualTimeMillis; private String mZoneId; private String mCountryIsoCode; Builder setDeviceRealtimeMillis(long realtimeMillis) { mInitialDeviceRealtimeMillis = realtimeMillis; return this; } Builder setActualTimeUtc(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { mActualTimeMillis = createUtcTime(year, monthInYear, day, hourOfDay, minute, second); return this; } Builder setTimeZone(String zoneId) { mZoneId = zoneId; return this; } Builder setCountryIso(String isoCode) { mCountryIsoCode = isoCode; return this; } Scenario buildFrozen() { return new Scenario( true /* frozen */, mInitialDeviceRealtimeMillis, mActualTimeMillis, mZoneId, mCountryIsoCode); } } } /** A fake implementation of {@link DeviceState}. */ static class FakeDeviceState implements DeviceState { public boolean ignoreNitz; public int nitzUpdateDiffMillis; public int nitzUpdateSpacingMillis; public String networkCountryIsoForPhone; public long elapsedRealtime; @Override public int getNitzUpdateSpacingMillis() { return nitzUpdateSpacingMillis; } @Override public int getNitzUpdateDiffMillis() { return nitzUpdateDiffMillis; } @Override public boolean getIgnoreNitz() { return ignoreNitz; } @Override public String getNetworkCountryIsoForPhone() { return networkCountryIsoForPhone; } @Override public long elapsedRealtime() { return elapsedRealtime; } } private NitzStateMachineTestSupport() {} static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { Calendar cal = new GregorianCalendar(zone("Etc/UTC")); cal.clear(); cal.set(year, monthInYear - 1, day, hourOfDay, minute, second); return cal.getTimeInMillis(); } static TimestampedValue<Long> createTimeSignalFromNitzSignal( TimestampedValue<NitzData> nitzSignal) { return new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); } static TimeZone zone(String zoneId) { TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId); if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) { fail(zoneId + " is not a valid zone"); } return timeZone; } } Loading
tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineImplTest.java +35 −204 Original line number Diff line number Diff line Loading @@ -16,18 +16,21 @@ package com.android.internal.telephony; import static com.android.internal.telephony.NitzStateMachineTestSupport.createTimeSignalFromNitzSignal; import static com.android.internal.telephony.NitzStateMachineTestSupport.createUtcTime; import static com.android.internal.telephony.NitzStateMachineTestSupport.zone; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.icu.util.Calendar; import android.icu.util.GregorianCalendar; import android.icu.util.TimeZone; import android.util.TimestampedValue; import com.android.internal.telephony.NitzStateMachine.DeviceState; import com.android.internal.telephony.NitzStateMachineTestSupport.FakeDeviceState; import com.android.internal.telephony.NitzStateMachineTestSupport.Scenario; import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult; import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult; Loading Loading @@ -748,63 +751,6 @@ public class NitzStateMachineImplTest extends TelephonyTest { TimeZone.getTimeZone(zoneId2).getOffset(timeMillis)); } private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC")); cal.clear(); cal.set(year, monthInYear - 1, day, hourOfDay, minute, second); return cal.getTimeInMillis(); } /** Some piece of state that tests want to track. */ private static class TestState<T> { private T mInitialValue; private LinkedList<T> mValues = new LinkedList<>(); void init(T value) { mValues.clear(); mInitialValue = value; } void set(T value) { mValues.addFirst(value); } boolean hasBeenSet() { return mValues.size() > 0; } void assertHasNotBeenSet() { assertFalse(hasBeenSet()); } void assertHasBeenSet() { assertTrue(hasBeenSet()); } void commitLatest() { if (hasBeenSet()) { mInitialValue = mValues.getLast(); mValues.clear(); } } void assertLatestEquals(T expected) { assertEquals(expected, getLatest()); } void assertChangeCount(int expectedCount) { assertEquals(expectedCount, mValues.size()); } public T getLatest() { if (hasBeenSet()) { return mValues.getFirst(); } return mInitialValue; } } /** * A "fluent" helper class allowing reuse of logic for test state initialization, simulation of * events, and verification of device state changes with self-describing method names. Loading Loading @@ -924,129 +870,56 @@ public class NitzStateMachineImplTest extends TelephonyTest { } } private static TimestampedValue<Long> createTimeSignalFromNitzSignal( TimestampedValue<NitzData> nitzSignal) { return new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); } /** * A scenario used during tests. Describes a fictional reality. */ static class Scenario { private final boolean mFrozen; private TimeZone mZone; private String mNetworkCountryIsoCode; private long mElapsedRealtimeMillis; private long mActualTimeMillis; Scenario(boolean frozen, long elapsedRealtimeMillis, long timeMillis, String zoneId, String countryIsoCode) { mFrozen = frozen; mActualTimeMillis = timeMillis; mElapsedRealtimeMillis = elapsedRealtimeMillis; mZone = zone(zoneId); mNetworkCountryIsoCode = countryIsoCode; } /** Creates an NITZ signal to match the scenario. */ TimestampedValue<NitzData> createNitzSignal() { int[] offsets = new int[2]; mZone.getOffset(mActualTimeMillis, false /* local */, offsets); int zoneOffsetMillis = offsets[0] + offsets[1]; NitzData nitzData = NitzData.createForTests( zoneOffsetMillis, offsets[1], mActualTimeMillis, null /* emulatorHostTimeZone */); return new TimestampedValue<>(mElapsedRealtimeMillis, nitzData); } /** Creates a time signal to match the scenario. */ TimestampedValue<Long> createTimeSignal() { return new TimestampedValue<>(mElapsedRealtimeMillis, mActualTimeMillis); } long getDeviceRealTimeMillis() { return mElapsedRealtimeMillis; } String getNetworkCountryIsoCode() { return mNetworkCountryIsoCode; } String getTimeZoneId() { return mZone.getID(); } /** Some piece of state that tests want to track. */ private static class TestState<T> { private T mInitialValue; private LinkedList<T> mValues = new LinkedList<>(); long getActualTimeMillis() { return mActualTimeMillis; void init(T value) { mValues.clear(); mInitialValue = value; } Scenario incrementTime(long timeIncrementMillis) { checkFrozen(); mElapsedRealtimeMillis += timeIncrementMillis; mActualTimeMillis += timeIncrementMillis; return this; void set(T value) { mValues.addFirst(value); } Scenario changeCountry(String timeZoneId, String networkCountryIsoCode) { checkFrozen(); mZone = zone(timeZoneId); mNetworkCountryIsoCode = networkCountryIsoCode; return this; boolean hasBeenSet() { return mValues.size() > 0; } Scenario mutableCopy() { return new Scenario( false /* frozen */, mElapsedRealtimeMillis, mActualTimeMillis, mZone.getID(), mNetworkCountryIsoCode); void assertHasNotBeenSet() { assertFalse(hasBeenSet()); } private void checkFrozen() { if (mFrozen) { throw new IllegalStateException("Scenario is frozen. Copy first"); } void assertHasBeenSet() { assertTrue(hasBeenSet()); } static class Builder { private long mInitialDeviceRealtimeMillis; private long mActualTimeMillis; private String mZoneId; private String mCountryIsoCode; Builder setDeviceRealtimeMillis(long realtimeMillis) { mInitialDeviceRealtimeMillis = realtimeMillis; return this; void commitLatest() { if (hasBeenSet()) { mInitialValue = mValues.getLast(); mValues.clear(); } Builder setActualTimeUtc(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { mActualTimeMillis = createUtcTime(year, monthInYear, day, hourOfDay, minute, second); return this; } Builder setTimeZone(String zoneId) { mZoneId = zoneId; return this; void assertLatestEquals(T expected) { assertEquals(expected, getLatest()); } Builder setCountryIso(String isoCode) { mCountryIsoCode = isoCode; return this; void assertChangeCount(int expectedCount) { assertEquals(expectedCount, mValues.size()); } Scenario buildFrozen() { return new Scenario( true /* frozen */, mInitialDeviceRealtimeMillis, mActualTimeMillis, mZoneId, mCountryIsoCode); public T getLatest() { if (hasBeenSet()) { return mValues.getFirst(); } return mInitialValue; } } private class FakeTimeServiceHelper implements TimeServiceHelper { private static class FakeTimeServiceHelper implements TimeServiceHelper { public TimeServiceHelper.Listener listener; public boolean timeZoneDetectionEnabled; Loading Loading @@ -1093,46 +966,4 @@ public class NitzStateMachineImplTest extends TelephonyTest { suggestedTime.commitLatest(); } } private static class FakeDeviceState implements DeviceState { public boolean ignoreNitz; public int nitzUpdateDiffMillis; public int nitzUpdateSpacingMillis; public String networkCountryIsoForPhone; public long elapsedRealtime; @Override public int getNitzUpdateSpacingMillis() { return nitzUpdateSpacingMillis; } @Override public int getNitzUpdateDiffMillis() { return nitzUpdateDiffMillis; } @Override public boolean getIgnoreNitz() { return ignoreNitz; } @Override public String getNetworkCountryIsoForPhone() { return networkCountryIsoForPhone; } @Override public long elapsedRealtime() { return elapsedRealtime; } } private static TimeZone zone(String zoneId) { TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId); if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) { fail(zoneId + " is not a valid zone"); } return timeZone; } }
tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTestSupport.java 0 → 100644 +207 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony; import static org.junit.Assert.fail; import android.icu.util.Calendar; import android.icu.util.GregorianCalendar; import android.icu.util.TimeZone; import android.util.TimestampedValue; import com.android.internal.telephony.NitzStateMachine.DeviceState; /** * An assortment of methods and classes for testing {@link NitzStateMachine} implementations. */ final class NitzStateMachineTestSupport { /** * A scenario used during tests. Describes a fictional reality. */ static class Scenario { private final boolean mFrozen; private TimeZone mZone; private String mNetworkCountryIsoCode; private long mElapsedRealtimeMillis; private long mActualTimeMillis; Scenario(boolean frozen, long elapsedRealtimeMillis, long timeMillis, String zoneId, String countryIsoCode) { mFrozen = frozen; mActualTimeMillis = timeMillis; mElapsedRealtimeMillis = elapsedRealtimeMillis; mZone = zone(zoneId); mNetworkCountryIsoCode = countryIsoCode; } /** Creates an NITZ signal to match the scenario. */ TimestampedValue<NitzData> createNitzSignal() { int[] offsets = new int[2]; mZone.getOffset(mActualTimeMillis, false /* local */, offsets); int zoneOffsetMillis = offsets[0] + offsets[1]; NitzData nitzData = NitzData.createForTests( zoneOffsetMillis, offsets[1], mActualTimeMillis, null /* emulatorHostTimeZone */); return new TimestampedValue<>(mElapsedRealtimeMillis, nitzData); } /** Creates a time signal to match the scenario. */ TimestampedValue<Long> createTimeSignal() { return new TimestampedValue<>(mElapsedRealtimeMillis, mActualTimeMillis); } long getDeviceRealTimeMillis() { return mElapsedRealtimeMillis; } String getNetworkCountryIsoCode() { return mNetworkCountryIsoCode; } String getTimeZoneId() { return mZone.getID(); } long getActualTimeMillis() { return mActualTimeMillis; } Scenario incrementTime(long timeIncrementMillis) { checkFrozen(); mElapsedRealtimeMillis += timeIncrementMillis; mActualTimeMillis += timeIncrementMillis; return this; } Scenario changeCountry(String timeZoneId, String networkCountryIsoCode) { checkFrozen(); mZone = zone(timeZoneId); mNetworkCountryIsoCode = networkCountryIsoCode; return this; } Scenario mutableCopy() { return new Scenario( false /* frozen */, mElapsedRealtimeMillis, mActualTimeMillis, mZone.getID(), mNetworkCountryIsoCode); } private void checkFrozen() { if (mFrozen) { throw new IllegalStateException("Scenario is frozen. Copy first"); } } static class Builder { private long mInitialDeviceRealtimeMillis; private long mActualTimeMillis; private String mZoneId; private String mCountryIsoCode; Builder setDeviceRealtimeMillis(long realtimeMillis) { mInitialDeviceRealtimeMillis = realtimeMillis; return this; } Builder setActualTimeUtc(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { mActualTimeMillis = createUtcTime(year, monthInYear, day, hourOfDay, minute, second); return this; } Builder setTimeZone(String zoneId) { mZoneId = zoneId; return this; } Builder setCountryIso(String isoCode) { mCountryIsoCode = isoCode; return this; } Scenario buildFrozen() { return new Scenario( true /* frozen */, mInitialDeviceRealtimeMillis, mActualTimeMillis, mZoneId, mCountryIsoCode); } } } /** A fake implementation of {@link DeviceState}. */ static class FakeDeviceState implements DeviceState { public boolean ignoreNitz; public int nitzUpdateDiffMillis; public int nitzUpdateSpacingMillis; public String networkCountryIsoForPhone; public long elapsedRealtime; @Override public int getNitzUpdateSpacingMillis() { return nitzUpdateSpacingMillis; } @Override public int getNitzUpdateDiffMillis() { return nitzUpdateDiffMillis; } @Override public boolean getIgnoreNitz() { return ignoreNitz; } @Override public String getNetworkCountryIsoForPhone() { return networkCountryIsoForPhone; } @Override public long elapsedRealtime() { return elapsedRealtime; } } private NitzStateMachineTestSupport() {} static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { Calendar cal = new GregorianCalendar(zone("Etc/UTC")); cal.clear(); cal.set(year, monthInYear - 1, day, hourOfDay, minute, second); return cal.getTimeInMillis(); } static TimestampedValue<Long> createTimeSignalFromNitzSignal( TimestampedValue<NitzData> nitzSignal) { return new TimestampedValue<>( nitzSignal.getReferenceTimeMillis(), nitzSignal.getValue().getCurrentTimeInMillis()); } static TimeZone zone(String zoneId) { TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId); if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) { fail(zoneId + " is not a valid zone"); } return timeZone; } }