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

Commit 169ca55d authored by Neil Fuller's avatar Neil Fuller
Browse files

Re-run detection under more conditions

handleAirplaneModeChanged() would only rerun time / time zone detection
if the network state (NITZ) was cleared. It should be run if the country
state was cleared too so that a proper "uncertain" suggestion will be
made in all cases.

This also adds a regression test to confirm this case is covered.

Bug: 227047106
Test: atest ./tests/telephonytests/src/com/android/internal/telephony/nitz
Merged-In: I444ce448029c09a99e41d06bb7a478958f849d15
Change-Id: I444ce448029c09a99e41d06bb7a478958f849d15
(cherry picked from commit 05810cf5)
parent bfb2ebe2
Loading
Loading
Loading
Loading
+18 −21
Original line number Diff line number Diff line
@@ -178,8 +178,11 @@ public final class NitzStateMachineImpl implements NitzStateMachine {

    @Override
    public void handleNetworkUnavailable() {
        boolean networkStateChanged = clearNetworkState(false /* fullyClearNitz */);
        if (networkStateChanged) {
            String reason = "handleNetworkUnavailable";
        clearNetworkStateAndRerunDetection(reason, false /* fullyClearNitz */);
            runDetection(reason);
        }
    }

    @Override
@@ -246,15 +249,20 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        // while in airplane mode from influencing behavior afterwards.
        //
        // After clearing detection state, the time zone detection should work out from first
        // principles what the time / time zone is. This assumes calls like handleNetworkAvailable()
        // will be made after airplane mode is re-enabled as the device re-establishes network
        // principles what the time zone is. This assumes calls like handleNetworkAvailable() will
        // be made after airplane mode is re-enabled as the device re-establishes network
        // connectivity.

        // Clear country detection state.
        boolean countryStateChanged = mCountryIsoCode != null;
        mCountryIsoCode = null;

        boolean networkStateChanged = clearNetworkState(true /* fullyClearNitz */);

        if (countryStateChanged || networkStateChanged) {
            String reason = "handleAirplaneModeChanged(" + on + ")";
        clearNetworkStateAndRerunDetection(reason, true /* fullyClearNitz */);
            runDetection(reason);
        }
    }

    private void restoreNetworkStateAndRerunDetection(String reason) {
@@ -289,28 +297,17 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        }
    }

    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;
        }

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

        runDetection(reason);
        boolean networkStateChanged = mLatestNitzSignal != null;
        mLatestNitzSignal = null;
        return networkStateChanged;
    }

    private void runDetection(String reason) {
+53 −1
Original line number Diff line number Diff line
@@ -316,7 +316,8 @@ public class NitzStateMachineImplTest {
        script.toggleAirplaneMode(true);

        // Verify the state machine did the right thing.
        // Check the time zone suggestion was withdrawn (time is not currently withdrawn).
        // Check the previous time and time zone suggestions based on cleared signals were
        // withdrawn.
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                EMPTY_TIME_SUGGESTION, EMPTY_TIME_ZONE_SUGGESTION);

@@ -373,6 +374,57 @@ public class NitzStateMachineImplTest {
        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
    }

    /**
     * Regression test for b/227047106: If only country state was actually cleared (i.e. if there
     * was no NITZ signal to clear) then the existing tz suggestion wasn't withdrawn. Simulates a
     * flight from the UK to the US.
     */
    @Test
    public void test_airplaneModeClearsState_onlyCountryCleared_b227047106() throws Exception {
        Scenario scenario = UNITED_KINGDOM_SCENARIO.mutableCopy();
        int timeStepMillis = (int) TimeUnit.HOURS.toMillis(3);

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

        // Pre-flight: Simulate a device receiving signals that allow it to detect the time zone.
        String preFlightCountryIsoCode = scenario.getNetworkCountryIsoCode();

        // Simulate receiving the country.
        script.countryReceived(preFlightCountryIsoCode);

        // Verify the state machine did the right thing.
        TelephonyTimeZoneSuggestion expectedPreFlightTimeZoneSuggestion =
                mRealTimeZoneSuggester.getTimeZoneSuggestion(
                        SLOT_INDEX, preFlightCountryIsoCode, null);
        script.verifyOnlyTimeZoneWasSuggestedAndReset(expectedPreFlightTimeZoneSuggestion);

        // Check NitzStateMachineImpl internal state exposed for tests.
        assertNull(mNitzStateMachineImpl.getLatestNitzData());
        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());

        // Boarded flight: Airplane mode turned on / time zone detection still enabled.
        // The NitzStateMachine must lose all state and stop having an opinion about time zone.

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

        // Simulate airplane mode being turned on.
        script.toggleAirplaneMode(true);

        // Verify the state machine did the right thing. Check the previous time zone suggestion
        // was withdrawn. An empty time suggestion is also made, but this is for simplicity in the
        // implementation, not a requirement.
        script.verifyTimeAndTimeZoneSuggestedAndReset(
                EMPTY_TIME_SUGGESTION, EMPTY_TIME_ZONE_SUGGESTION);

        // Check NitzStateMachineImpl internal state exposed for tests.
        assertNull(mNitzStateMachineImpl.getLatestNitzData());
        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
    }

    /**
     * Confirm losing the network / NITZ doesn't clear country state.
     */