Loading src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java +18 −21 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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) { Loading tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java +53 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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. */ Loading Loading
src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java +18 −21 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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) { Loading
tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java +53 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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. */ Loading