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

Commit 4ff403e2 authored by Neil Fuller's avatar Neil Fuller Committed by android-build-merger
Browse files

Merge "Clear NITZ state when entering airplane mode" am: 65283370 am: 86ff6b4b am: 4146fba3

am: 4bdaa7a7

Change-Id: I80afb9d84b24488e1c7a20df580bc3c08e3231ae
parents bc144a84 4bdaa7a7
Loading
Loading
Loading
Loading
+32 −3
Original line number Original line Diff line number Diff line
@@ -305,8 +305,24 @@ public final class NitzStateMachineImpl implements NitzStateMachine {


    @Override
    @Override
    public void handleAirplaneModeChanged(boolean on) {
    public void handleAirplaneModeChanged(boolean on) {
        if (DBG) {
            Rlog.d(LOG_TAG, "handleAirplaneModeChanged: on=" + on);
            Rlog.d(LOG_TAG, "handleAirplaneModeChanged: on=" + on);
        // TODO
        }

        // Treat entry / exit from airplane mode as a strong signal that the user wants to clear
        // cached state. If the user really is boarding a plane they won't want cached state from
        // before their flight influencing behavior.
        //
        // State is cleared on entry AND exit: on entry because the detection code shouldn't be
        // opinionated while in airplane mode, and on exit to avoid any unexpected signals received
        // 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
        // connectivity.
        clearTimeDetectionState();
        clearTimeZoneDetectionState();
    }
    }


    private void updateTimeFromNitz() {
    private void updateTimeFromNitz() {
@@ -399,6 +415,11 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        }
        }
    }
    }


    private void clearTimeDetectionState() {
        mSavedNitzTime = null;
        mTimeZoneLog.log("clearTimeZoneDetectionState: All time detection state cleared.");
    }

    private void setAndBroadcastNetworkSetTimeZone(String zoneId, String logMessage) {
    private void setAndBroadcastNetworkSetTimeZone(String zoneId, String logMessage) {
        logMessage += " [Setting device time zone to zoneId=" + zoneId + "]";
        logMessage += " [Setting device time zone to zoneId=" + zoneId + "]";
        if (DBG) {
        if (DBG) {
@@ -497,6 +518,15 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        }
        }
    }
    }


    private void clearTimeZoneDetectionState() {
        mLatestNitzSignal = null;
        mGotCountryCode = false;
        mSavedTimeZoneId = null;
        mNitzTimeZoneDetectionSuccessful = false;
        mTimeZoneLog.log("clearTimeZoneDetectionState: All time zone detection state cleared.");
    }

    // VisibleForTesting
    public boolean getNitzTimeZoneDetectionSuccessful() {
    public boolean getNitzTimeZoneDetectionSuccessful() {
        return mNitzTimeZoneDetectionSuccessful;
        return mNitzTimeZoneDetectionSuccessful;
    }
    }
@@ -510,5 +540,4 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
    public String getSavedTimeZoneId() {
    public String getSavedTimeZoneId() {
        return mSavedTimeZoneId;
        return mSavedTimeZoneId;
    }
    }

}
}
+96 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.Test;


import java.util.LinkedList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;


public class NitzStateMachineImplTest extends TelephonyTest {
public class NitzStateMachineImplTest extends TelephonyTest {


@@ -631,6 +632,101 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
        assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
    }
    }


    @Test
    public void test_airplaneModeClearsState() throws Exception {
        Scenario scenario = UNITED_KINGDOM_SCENARIO.mutableCopy();
        long timeStepMillis = TimeUnit.HOURS.toMillis(3);

        Script script = new Script()
                .setRealtimeClockFromScenario(scenario)
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null);

        // Pre-flight: Simulate a device receiving signals that allow it to detect time and time
        // zone.
        TimestampedValue<NitzData> preflightNitzSignal = scenario.createNitzSignal();
        script.nitzReceived(preflightNitzSignal)
                .countryReceived(scenario.getNetworkCountryIsoCode())
                .verifyTimeSuggestedAndZoneSetAndReset(
                        scenario.createTimeSignal(), scenario.getTimeZoneId());

        // Demonstrate the NitzStateMachineImpl is "opinionated" about time zone: toggling auto-time
        // zone on should cause it to set the last known time zone again.
        // Note: Historically Android telephony time detection hasn't retained an opinion about time
        // so only the time zone is set. Also, NitzStateMachine doesn't pay attention to whether
        // auto-time is enabled; it is left to the system server service to decide whether to act on
        // the time suggestion if the settings allow.
        script.toggleTimeZoneDetectionEnabled(false)
                .verifyNothingWasSetAndReset()
                .toggleTimeZoneDetectionEnabled(true)
                .verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId());

        // Check state that NitzStateMachine must expose.
        assertEquals(preflightNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
        assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());

        // Boarded flight: Airplane mode turned on / time zone detection still enabled.
        // The NitzStateMachineImpl 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.setRealtimeClockFromScenario(scenario);

        script.toggleAirplaneMode(true);

        // Check state that NitzStateMachine must expose.
        assertNull(mNitzStateMachine.getCachedNitzData());
        assertNull(mNitzStateMachine.getSavedTimeZoneId());

        // Verify there's no time zone opinion by toggling auto time zone off and on.
        script.toggleTimeZoneDetectionEnabled(false)
                .verifyNothingWasSetAndReset()
                .toggleTimeZoneDetectionEnabled(true)
                .verifyNothingWasSetAndReset();

        // During flight: Airplane mode turned off / time zone detection still enabled.
        // The NitzStateMachineImpl still must not have an opinion about time zone / hold any state.

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

        script.toggleAirplaneMode(false);

        // Verify there's still no opinion by toggling auto time zone off and on.
        script.toggleTimeZoneDetectionEnabled(false)
                .verifyNothingWasSetAndReset()
                .toggleTimeZoneDetectionEnabled(true)
                .verifyNothingWasSetAndReset();

        // Check the state that NitzStateMachine must expose.
        assertNull(mNitzStateMachine.getCachedNitzData());
        assertNull(mNitzStateMachine.getSavedTimeZoneId());

        // Post flight: Device has moved and receives new signals.

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

        // Simulate the movement to the destination.
        scenario.changeCountry(UNIQUE_US_ZONE_SCENARIO.getTimeZoneId(),
                UNIQUE_US_ZONE_SCENARIO.getNetworkCountryIsoCode());

        // Simulate the device receiving NITZ signals again after the flight. Now the
        // NitzStateMachineImpl is opinionated again.
        TimestampedValue<NitzData> postFlightNitzSignal = scenario.createNitzSignal();
        script.countryReceived(scenario.getNetworkCountryIsoCode())
                .nitzReceived(postFlightNitzSignal)
                .verifyTimeSuggestedAndZoneSetAndReset(
                        scenario.createTimeSignal(), scenario.getTimeZoneId());

        // Check state that NitzStateMachine must expose.
        assertEquals(postFlightNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
        assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
    }

    /**
    /**
     * Asserts a test scenario has the properties we expect for NITZ-only lookup. There are
     * Asserts a test scenario has the properties we expect for NITZ-only lookup. There are
     * usually multiple zones that will share the same UTC offset so we get a low quality / low
     * usually multiple zones that will share the same UTC offset so we get a low quality / low