Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2ed1c6b authored by Neil Fuller's avatar Neil Fuller
Browse files

Add support for retaining / restoring NITZ signals

Add support for retaining NITZ for short periods when a network is
declared unavailable. When a network is declared available the NITZ may
be restored for use in time / time zone detection. An initial value of 5
minutes has been chosen.

This is an effort to improve time zone detection: some devices appear to
disconnect for short periods. Because carriers do not send NITZ signals
regularly, or if a device disconnects for a short period, this may help.
It may also cause problems: this reintroduces a call to
handleNetworkUnavailable() that was removed previously and there is no
guarantee that a retained / restored NITZ is from the same network as
the one the device is now attached to.

Bug: 204415203
Bug: 161967945
Test: atest tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
Test: treehugger
Change-Id: Id4694975fa6eb28fc07fab2192de7703dc701c67
parent f026f44c
Loading
Loading
Loading
Loading
+46 −14
Original line number Diff line number Diff line
@@ -89,17 +89,28 @@ public interface NitzStateMachine {
    interface DeviceState {

        /**
         * If elapsed time between two NITZ signals is less than this value then the second signal
         * can be ignored.
         * If the elapsed realtime between two NITZ signals is greater than this value then the
         * second signal cannot be ignored.
         */
        int getNitzUpdateSpacingMillis();

        /**
         * If UTC time between two NITZ signals is less than this value then the second signal can
         * be ignored.
         * If UTC time between two NITZ signals is greater than this value then the second signal
         * cannot be ignored.
         */
        int getNitzUpdateDiffMillis();

        /**
         * If the device connects to a telephony network and was disconnected from a telephony
         * network for less than this time, a previously received NITZ signal can be restored.
         *
         * <p>The restored NITZ may not be from the same network as the current network. It is
         * intended to be a relatively small value to allow for brief disconnections. Larger values
         * increase the likelihood that the device has moved to a different network and/or time
         * zone.
         */
        int getNitzNetworkDisconnectRetentionMillis();

        /**
         * Returns true if the {@code gsm.ignore-nitz} system property is set to "yes".
         */
@@ -122,32 +133,53 @@ public interface NitzStateMachine {
     * {@hide}
     */
    class DeviceStateImpl implements DeviceState {
        private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10;
        private final int mNitzUpdateSpacing;

        private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000;
        private final int mNitzUpdateDiff;
        /** The default value to use for {@link #getNitzUpdateSpacingMillis()}. 10 minutes. */
        private static final int NITZ_UPDATE_SPACING_MILLIS_DEFAULT = 1000 * 60 * 10;
        private final int mNitzUpdateSpacingMillis;

        /** The default value to use for {@link #getNitzUpdateDiffMillis()}. 2 seconds. */
        private static final int NITZ_UPDATE_DIFF_MILLIS_DEFAULT = 2000;
        private final int mNitzUpdateDiffMillis;

        /**
         * The default value to use for {@link #getNitzNetworkDisconnectRetentionMillis()}.
         * 5 minutes.
         */
        private static final int NITZ_NETWORK_DISCONNECT_RETENTION_MILLIS_DEFAULT = 1000 * 60 * 5;
        private final int mNitzNetworkDisconnectRetentionMillis;

        private final ContentResolver mCr;

        public DeviceStateImpl(Phone phone) {
            Context context = phone.getContext();
            mCr = context.getContentResolver();
            mNitzUpdateSpacing =
                    SystemProperties.getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT);
            mNitzUpdateDiff =
                    SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_DEFAULT);
            mNitzUpdateSpacingMillis =
                    SystemProperties.getInt("ro.nitz_update_spacing",
                            NITZ_UPDATE_SPACING_MILLIS_DEFAULT);
            mNitzUpdateDiffMillis =
                    SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_MILLIS_DEFAULT);
            mNitzNetworkDisconnectRetentionMillis =
                    SystemProperties.getInt("ro.nitz_network_disconnect_retention",
                            NITZ_NETWORK_DISCONNECT_RETENTION_MILLIS_DEFAULT);
        }

        @Override
        public int getNitzUpdateSpacingMillis() {
            return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_SPACING,
                    mNitzUpdateSpacing);
                    mNitzUpdateSpacingMillis);
        }

        @Override
        public int getNitzUpdateDiffMillis() {
            return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_DIFF, mNitzUpdateDiff);
            return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_DIFF,
                    mNitzUpdateDiffMillis);
        }

        @Override
        public int getNitzNetworkDisconnectRetentionMillis() {
            return Settings.Global.getInt(mCr, Settings.Global.NITZ_NETWORK_DISCONNECT_RETENTION,
                    mNitzNetworkDisconnectRetentionMillis);
        }

        @Override
+2 −0
Original line number Diff line number Diff line
@@ -3589,10 +3589,12 @@ public class ServiceStateTracker extends Handler {

        if (hasRegistered) {
            mNetworkAttachedRegistrants.notifyRegistrants();
            mNitzState.handleNetworkAvailable();
        }

        if (hasDeregistered) {
            mNetworkDetachedRegistrants.notifyRegistrants();
            mNitzState.handleNetworkUnavailable();
        }

        if (hasCssIndicatorChanged) {
+99 −52
Original line number Diff line number Diff line
@@ -98,14 +98,15 @@ public final class NitzStateMachineImpl implements NitzStateMachine {

    // Miscellaneous dependencies and helpers not related to detection state.
    private final int mSlotIndex;
    @NonNull private final DeviceState mDeviceState;
    /** Applied to NITZ signals during input filtering. */
    private final NitzSignalInputFilterPredicate mNitzSignalInputFilter;
    @NonNull private final NitzSignalInputFilterPredicate mNitzSignalInputFilter;
    /**
     * Creates a {@link TelephonyTimeZoneSuggestion} for passing to the time zone detection service.
     */
    private final TimeZoneSuggester mTimeZoneSuggester;
    @NonNull private final TimeZoneSuggester mTimeZoneSuggester;
    /** A facade to the time / time zone detection services. */
    private final TimeServiceHelper mTimeServiceHelper;
    @NonNull private final TimeServiceHelper mTimeServiceHelper;

    // Shared detection state.

@@ -114,8 +115,14 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
     * input filtering (e.g. rate limiting) and provides the NITZ information when time / time zone
     * needs to be recalculated when something else has changed.
     */
    @Nullable
    private NitzSignal mLatestNitzSignal;
    @Nullable private NitzSignal mLatestNitzSignal;

    /**
     * The last NITZ received, and the time when it was cleared. Used to restore the NITZ for
     * transient network disconnections. This can be null, but the value held when it isn't will not
     * be.
     */
    @Nullable private TimestampedValue<NitzSignal> mLastNitzSignalCleared;

    // Time Zone detection state.

@@ -124,7 +131,7 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
     * (lower case), empty (test network) or null (no country detected). A country code is required
     * to determine time zone except when on a test network.
     */
    private String mCountryIsoCode;
    @Nullable private String mCountryIsoCode;

    /**
     * Creates an instance for the supplied {@link Phone}.
@@ -141,7 +148,7 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        NitzSignalInputFilterPredicate nitzSignalFilter =
                NitzSignalInputFilterPredicateFactory.create(phone.getContext(), deviceState);
        return new NitzStateMachineImpl(
                slotIndex, nitzSignalFilter, timeZoneSuggester, newTimeServiceHelper);
                slotIndex, deviceState, nitzSignalFilter, timeZoneSuggester, newTimeServiceHelper);
    }

    /**
@@ -150,10 +157,12 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
     */
    @VisibleForTesting
    public NitzStateMachineImpl(int slotIndex,
            @NonNull DeviceState deviceState,
            @NonNull NitzSignalInputFilterPredicate nitzSignalInputFilter,
            @NonNull TimeZoneSuggester timeZoneSuggester,
            @NonNull TimeServiceHelper newTimeServiceHelper) {
        mSlotIndex = slotIndex;
        mDeviceState = Objects.requireNonNull(deviceState);
        mTimeZoneSuggester = Objects.requireNonNull(timeZoneSuggester);
        mTimeServiceHelper = Objects.requireNonNull(newTimeServiceHelper);
        mNitzSignalInputFilter = Objects.requireNonNull(nitzSignalInputFilter);
@@ -161,41 +170,14 @@ public final class NitzStateMachineImpl implements NitzStateMachine {

    @Override
    public void handleNetworkAvailable() {
        // We no longer do any useful work here: we assume handleNetworkUnavailable() is reliable.
        // TODO: Remove this method when all implementations do nothing.
        String reason = "handleNetworkAvailable";
        restoreNetworkStateAndRerunDetection(reason);
    }

    @Override
    public void handleNetworkUnavailable() {
        String reason = "handleNetworkUnavailable()";
        clearNetworkStateAndRerunDetection(reason);
    }

    private void clearNetworkStateAndRerunDetection(String reason) {
        if (mLatestNitzSignal == null) {
            // The network state is already empty so there's no need to do anything.
            if (DBG) {
                Rlog.d(LOG_TAG, reason + ": mLatestNitzSignal was already null. Nothing to do.");
            }
            return;
        }

        // The previous NITZ signal received is now invalid so clear it.
        mLatestNitzSignal = null;

        // countryIsoCode can be assigned null here, in which case the doTimeZoneDetection() call
        // below will do nothing, which is ok as nothing will have changed.
        String countryIsoCode = mCountryIsoCode;
        if (DBG) {
            Rlog.d(LOG_TAG, reason + ": countryIsoCode=" + countryIsoCode);
        }

        // Generate a new time zone suggestion (which could be an empty suggestion) and update the
        // service as needed.
        doTimeZoneDetection(countryIsoCode, null /* nitzSignal */, reason);

        // Generate a new time suggestion and update the service as needed.
        doTimeDetection(null /* nitzSignal */, reason);
        String reason = "handleNetworkUnavailable";
        clearNetworkStateAndRerunDetection(reason, false /* fullyClearNitz */);
    }

    @Override
@@ -224,19 +206,20 @@ public final class NitzStateMachineImpl implements NitzStateMachine {

        // Generate a new time zone suggestion and update the service as needed.
        doTimeZoneDetection(null /* countryIsoCode */, mLatestNitzSignal,
                "handleCountryUnavailable()");
                "handleCountryUnavailable");
    }

    @Override
    public void handleNitzReceived(@NonNull NitzSignal nitzSignal) {
        if (DBG) {
            Rlog.d(LOG_TAG, "handleNitzReceived: nitzSignal=" + nitzSignal);
        }
        Objects.requireNonNull(nitzSignal);

        // Perform input filtering to filter bad data and avoid processing signals too often.
        NitzSignal previousNitzSignal = mLatestNitzSignal;
        if (!mNitzSignalInputFilter.mustProcessNitzSignal(previousNitzSignal, nitzSignal)) {
            if (DBG) {
                Rlog.d(LOG_TAG, "handleNitzReceived: previousNitzSignal=" + previousNitzSignal
                        + ", nitzSignal=" + nitzSignal + ": NITZ filtered");
            }
            return;
        }

@@ -244,13 +227,7 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        mLatestNitzSignal = nitzSignal;

        String reason = "handleNitzReceived(" + nitzSignal + ")";

        // Generate a new time zone suggestion and update the service as needed.
        String countryIsoCode = mCountryIsoCode;
        doTimeZoneDetection(countryIsoCode, nitzSignal, reason);

        // Generate a new time suggestion and update the service as needed.
        doTimeDetection(nitzSignal, reason);
        runDetection(reason);
    }

    @Override
@@ -272,15 +249,84 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        mCountryIsoCode = null;

        String reason = "handleAirplaneModeChanged(" + on + ")";
        clearNetworkStateAndRerunDetection(reason);
        clearNetworkStateAndRerunDetection(reason, true /* fullyClearNitz */);
    }

    private void restoreNetworkStateAndRerunDetection(String reason) {
        // Restore the last NITZ signal if the network has been unavailable for only a short period.
        if (mLastNitzSignalCleared == null) {
            if (DBG) {
                Rlog.d(LOG_TAG, reason + ": mLastNitzSignalCleared is null.");
            }
            // Nothing has changed. No work to do.
            return;
        }

        long timeSinceNitzClearedMillis = mDeviceState.elapsedRealtimeMillis()
                - mLastNitzSignalCleared.getReferenceTimeMillis();
        boolean canRestoreNitz = timeSinceNitzClearedMillis
                < mDeviceState.getNitzNetworkDisconnectRetentionMillis();
        if (canRestoreNitz) {
            reason = reason + ", mLatestNitzSignal restored from mLastNitzSignalCleared="
                    + mLastNitzSignalCleared.getValue();
            mLatestNitzSignal = mLastNitzSignalCleared.getValue();

            runDetection(reason);
        } else {
            if (DBG) {
                Rlog.d(LOG_TAG, reason + ": mLastNitzSignalCleared is too old.");
            }
        }
    }

    private void clearNetworkStateAndRerunDetection(String reason, boolean fullyClearNitz) {
        if (mLatestNitzSignal == null) {
            if (fullyClearNitz) {
                mLastNitzSignalCleared = null;
            }

            // The network state is already empty so there's no need to do anything.
            if (DBG) {
                Rlog.d(LOG_TAG, reason + ": mLatestNitzSignal was already null. Nothing to do.");
            }
            return;
        }

        if (fullyClearNitz) {
            mLastNitzSignalCleared = null;
        } else {
            mLastNitzSignalCleared = new TimestampedValue<>(
                    mDeviceState.elapsedRealtimeMillis(), mLatestNitzSignal);
        }
        mLatestNitzSignal = null;

        runDetection(reason);
    }

    private void runDetection(String reason) {
        // countryIsoCode can be assigned null here, in which case the doTimeZoneDetection() call
        // below will do nothing.
        String countryIsoCode = mCountryIsoCode;

        NitzSignal nitzSignal = mLatestNitzSignal;
        if (DBG) {
            Rlog.d(LOG_TAG, "runDetection: reason=" + reason + ", countryIsoCode=" + countryIsoCode
                    + ", nitzSignal=" + nitzSignal);
        }

        // Generate a new time zone suggestion (which could be an empty suggestion) and update the
        // service as needed.
        doTimeZoneDetection(countryIsoCode, nitzSignal, reason);

        // Generate a new time suggestion and update the service as needed.
        doTimeDetection(nitzSignal, reason);
    }

    /**
     * Perform a round of time zone detection and notify the time zone detection service as needed.
     */
    private void doTimeZoneDetection(
            @Nullable String countryIsoCode, @Nullable NitzSignal
            nitzSignal,
            @Nullable String countryIsoCode, @Nullable NitzSignal nitzSignal,
            @NonNull String reason) {
        try {
            Objects.requireNonNull(reason);
@@ -348,6 +394,7 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        mTimeServiceHelper.dumpLogs(ipw);
    }

    @VisibleForTesting
    @Nullable
    public NitzData getCachedNitzData() {
        return mLatestNitzSignal != null ? mLatestNitzSignal.getNitzData() : null;
+106 −12
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        mRealTimeZoneSuggester = new TimeZoneSuggesterImpl(mFakeDeviceState, timeZoneLookupHelper);

        mNitzStateMachineImpl = new NitzStateMachineImpl(
                SLOT_INDEX, mFakeNitzSignalInputFilter, mRealTimeZoneSuggester,
                SLOT_INDEX, mFakeDeviceState, mFakeNitzSignalInputFilter, mRealTimeZoneSuggester,
                mFakeTimeServiceHelper);

        TelephonyTest.logd("NewNitzStateMachineImplTest -Setup!");
@@ -298,7 +298,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                expectedPreFlightTimeSuggestion, expectedPreFlightTimeZoneSuggestion);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(preFlightNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());

        // Boarded flight: Airplane mode turned on / time zone detection still enabled.
@@ -316,7 +316,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                EMPTY_TIME_SUGGESTION, EMPTY_TIME_ZONE_SUGGESTION);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertNull(mNitzStateMachineImpl.getCachedNitzData());

        // During flight: Airplane mode turned off / time zone detection still enabled.
@@ -332,7 +332,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        // Verify nothing was suggested: The last suggestion was empty so nothing has changed.
        script.verifyNothingWasSuggested();

        // Check the state that NitzStateMachine must expose.
        // Check the state that NitzStateMachineImpl exposes for tests.
        assertNull(mNitzStateMachineImpl.getCachedNitzData());

        // Post flight: Device has moved and receives new signals.
@@ -362,7 +362,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                expectedPostFlightTimeSuggestion, expectedPostFlightTimeZoneSuggestion);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(postFlightNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
    }

@@ -370,11 +370,15 @@ public class NitzStateMachineImplTest extends TelephonyTest {
     * Confirm losing the network / NITZ doesn't clear country state.
     */
    @Test
    public void test_handleNetworkUnavailableClearsNetworkState() throws Exception {
    public void test_handleNetworkUnavailableClearsNetworkState_noRetention() throws Exception {
        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1.mutableCopy();
        int timeStepMillis = (int) TimeUnit.HOURS.toMillis(3);
        String countryIsoCode = scenario.getNetworkCountryIsoCode();

        // Set retention threshold to zero to prevent NITZ being saved / restored when the network
        // becomes unavailable / available again.
        mFakeDeviceState.setNitzNetworkDisconnectRetentionMillis(0);

        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .networkAvailable();
@@ -396,7 +400,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());

        // Simulate the passage of time and update the device realtime clock.
@@ -413,7 +417,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                EMPTY_TIME_SUGGESTION, expectedMiddleTimeZoneSuggestion);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertNull(mNitzStateMachineImpl.getCachedNitzData());

        // Simulate the passage of time and update the device realtime clock.
@@ -424,7 +428,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.networkAvailable()
                .verifyNothingWasSuggested();

        // Check the state that NitzStateMachine must expose.
        // Check the state that NitzStateMachineImpl exposes for tests.
        assertNull(mNitzStateMachineImpl.getCachedNitzData());

        // Simulate the passage of time and update the device realtime clock.
@@ -446,7 +450,97 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                expectedFinalTimeSuggestion, expectedFinalTimeZoneSuggestion);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(finalNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
    }

    /**
     * Tests the NITZ retention / restore behavior when networkAvailable() is called after
     * networkUnavailable() inside the retention threshold.
     */
    @Test
    public void test_handleNetworkUnavailableClearsNetworkState_withinRetentionThreshold()
            throws Exception {
        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1.mutableCopy();
        int timeStepMillis = (int) TimeUnit.HOURS.toMillis(3);
        String countryIsoCode = scenario.getNetworkCountryIsoCode();

        // Set the retention threshold to effectively infinite.
        mFakeDeviceState.setNitzNetworkDisconnectRetentionMillis(Integer.MAX_VALUE);

        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .networkAvailable();

        // Simulate a device receiving signals that allow it to detect time and time zone.
        NitzSignal initialNitzSignal =
                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
        TelephonyTimeSuggestion expectedInitialTimeSuggestion =
                createTimeSuggestionFromNitzSignal(SLOT_INDEX, initialNitzSignal);

        // Simulate receiving the NITZ signal and country.
        script.nitzReceived(initialNitzSignal)
                .countryReceived(countryIsoCode);

        // Verify the state machine did the right thing.
        TelephonyTimeZoneSuggestion expectedInitialTimeZoneSuggestion =
                mRealTimeZoneSuggester.getTimeZoneSuggestion(
                        SLOT_INDEX, countryIsoCode, initialNitzSignal);
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);

        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());

        // Simulate the passage of time and update the device realtime clock.
        scenario.incrementTime(timeStepMillis);
        script.incrementTime(timeStepMillis);

        // Simulate network being lost.
        script.networkUnavailable();

        // Check the "no NITZ" time and time zone suggestions are made.
        TelephonyTimeZoneSuggestion expectedMiddleTimeZoneSuggestion =
                mRealTimeZoneSuggester.getTimeZoneSuggestion(
                        SLOT_INDEX, countryIsoCode, null /* nitzSignal */);
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                EMPTY_TIME_SUGGESTION, expectedMiddleTimeZoneSuggestion);

        // Check state that NitzStateMachineImpl exposes for tests.
        assertNull(mNitzStateMachineImpl.getCachedNitzData());

        // Simulate the passage of time and update the device realtime clock.
        scenario.incrementTime(timeStepMillis);
        script.incrementTime(timeStepMillis);

        // Simulate the network being found. As we are inside the NITZ retention threshold, the
        // initial NITZ signal should be restored, and the same suggestion made.
        script.networkAvailable()
                .verifyTimeAndTimeZoneSuggestedAndReset(
                        expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);

        // Check the state that NitzStateMachineImpl exposes for tests.
        assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());

        // Simulate the passage of time and update the device realtime clock.
        scenario.incrementTime(timeStepMillis);
        script.incrementTime(timeStepMillis);

        // Simulate the device receiving another NITZ signal.
        NitzSignal finalNitzSignal =
                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
        script.nitzReceived(finalNitzSignal);

        // Verify the state machine did the right thing.
        TelephonyTimeSuggestion expectedFinalTimeSuggestion =
                createTimeSuggestionFromNitzSignal(SLOT_INDEX, finalNitzSignal);
        TelephonyTimeZoneSuggestion expectedFinalTimeZoneSuggestion =
                mRealTimeZoneSuggester.getTimeZoneSuggestion(
                        SLOT_INDEX, countryIsoCode, finalNitzSignal);
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                expectedFinalTimeSuggestion, expectedFinalTimeZoneSuggestion);

        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(finalNitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
    }

@@ -477,7 +571,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                expectedTimeSuggestion, expectedTimeZoneSuggestion2);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());

        // Simulate the country becoming unavailable and verify the state machine does the right
@@ -488,7 +582,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
                        SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
        script.verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion3);

        // Check state that NitzStateMachine must expose.
        // Check state that NitzStateMachineImpl exposes for tests.
        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getCachedNitzData());
    }

+12 −0

File changed.

Preview size limit exceeded, changes collapsed.