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

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

Modify tz detection logic on uninitialized devices

Make the tz detection more aggressive when the device's time zone
setting is uninitialized.

It is possible that bugs 141446564 & 141727033 were noticed as a result
of a behavior change between P and Q. Commit 325bce49
removed use of isTimeZoneSettingInitialized in one flow, which might
have had the side effect of setting the time zone on uninitialized
devices.

This commit adds explicit handling for devices with uninitialized time
zone settings. The impact should be limited because the paths should
only be followed once.

Bug: 141727033
Bug: 141740972
Bug: 141446564
Test: atest com.android.internal.telephony.NitzStateMachineImplTest
Change-Id: I84202c8db90f576e9d8ef9d6285570cdaa147029
parent f566eabe
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
        // TimeZone.getDefault() returns a default zone (GMT) even when time zone have never
        // been set which makes it difficult to tell if it's what the user / time zone detection
        // has chosen. isTimeZoneSettingInitialized() tells us whether the time zone of the
        // device has ever been explicit set by the user or code.
        // device has ever been explicitly set by the user or code.
        final boolean isTimeZoneSettingInitialized =
                mTimeServiceHelper.isTimeZoneSettingInitialized();

@@ -188,7 +188,8 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
                mTimeZoneLog.log(logMsg);

                zoneId = lookupResult != null ? lookupResult.getTimeZone().getID() : null;
            } else if (isNitzSignalOffsetInfoBogus(nitzSignal, isoCountryCode)) {
            } else if (isTimeZoneSettingInitialized
                    && isNitzSignalOffsetInfoBogus(nitzSignal, isoCountryCode)) {
                String logMsg = "updateTimeZoneFromCountryAndNitz: Received NITZ looks bogus, "
                        + " isoCountryCode=" + isoCountryCode
                        + " nitzSignal=" + nitzSignal;
@@ -519,12 +520,15 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
    private void updateTimeZoneFromNetworkCountryCode(String iso) {
        CountryResult lookupResult = mTimeZoneLookupHelper.lookupByCountry(
                iso, mDeviceState.currentTimeMillis());
        boolean isTimeZoneSettingInitialized = mTimeServiceHelper.isTimeZoneSettingInitialized();
        if (lookupResult != null
                && (lookupResult.quality == CountryResult.QUALITY_SINGLE_ZONE
                && (!isTimeZoneSettingInitialized
                        || lookupResult.quality == CountryResult.QUALITY_SINGLE_ZONE
                        || lookupResult.quality == CountryResult.QUALITY_DEFAULT_BOOSTED)) {
            String logMsg = "updateTimeZoneFromNetworkCountryCode: tz result found"
                    + " iso=" + iso
                    + " lookupResult=" + lookupResult;
                    + " lookupResult=" + lookupResult
                    + " isTimeZoneSettingInitialized=" + isTimeZoneSettingInitialized;

            String zoneId = lookupResult.zoneId;
            if (mTimeServiceHelper.isTimeZoneDetectionEnabled()) {
+98 −9
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static com.android.internal.telephony.NitzStateMachineTestSupport.NEW_ZEA
import static com.android.internal.telephony.NitzStateMachineTestSupport.UNIQUE_US_ZONE_SCENARIO1;
import static com.android.internal.telephony.NitzStateMachineTestSupport.UNIQUE_US_ZONE_SCENARIO2;
import static com.android.internal.telephony.NitzStateMachineTestSupport.UNITED_KINGDOM_SCENARIO;
import static com.android.internal.telephony.NitzStateMachineTestSupport.US_COUNTRY_DEFAULT_ZONE_ID;
import static com.android.internal.telephony.NitzStateMachineTestSupport.createTimeSignalFromNitzSignal;

import static org.junit.Assert.assertEquals;
@@ -81,7 +82,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null);
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        TimestampedValue<NitzData> nitzSignal =
                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
@@ -99,13 +100,101 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
    }

    @Test
    public void test_timeZoneUninitialized_countryOnly() throws Exception {
        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null /* uninitialized */);

        script.countryReceived(scenario.getNetworkCountryIsoCode())
                // Country alone *should* be enough on an uninitialized device.
                .verifyOnlyTimeZoneWasSetAndReset(US_COUNTRY_DEFAULT_ZONE_ID);
    }

    @Test
    public void test_timeZoneInitialized_countryOnly() throws Exception {
        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        script.countryReceived(scenario.getNetworkCountryIsoCode())
                // Country alone *should not* be enough on an initialized device.
                .verifyNothingWasSetAndReset();
    }

    @Test
    public void test_timeZoneUninitialized_nitzThenCountry() throws Exception {
        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;

        // Create a bad NITZ signal to send to the time zone detection code: Android always picks a
        // zone when there is one or more matching zones(regardless of whether the setting
        // setting is initialized), so we need to create a situation where no zones match to show it
        // still sets a time zone.
        TimestampedValue<NitzData> nitzSignal =
                CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());

        // Confirm there would be no match for this.
        OffsetResult result =
                mRealTimeZoneLookupHelper.lookupByNitzCountry(
                        nitzSignal.getValue(), scenario.getNetworkCountryIsoCode());
        assertNull(result);

        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null /* uninitialized */);

        script.nitzReceived(nitzSignal);
        TimestampedValue<Long> expectedTimeSignal = createTimeSignalFromNitzSignal(nitzSignal);
        script.verifyOnlyTimeWasSuggestedAndReset(expectedTimeSignal);

        script.countryReceived(scenario.getNetworkCountryIsoCode())
                // The code will use the country default zone because the setting is uninitialized.
                .verifyOnlyTimeZoneWasSetAndReset(US_COUNTRY_DEFAULT_ZONE_ID);
    }

    @Test
    public void test_timeZoneInitialized_nitzThenCountry() throws Exception {
        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;

        // Create a bad NITZ signal to send to the time zone detection code: Android always picks a
        // zone when there is one or more matching zones(regardless of whether the setting
        // is initialized), so we need to create a situation where no zones match to show it will
        // not set the time zone.
        TimestampedValue<NitzData> nitzSignal =
                CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());

        // Confirm there would be no match for this.
        OffsetResult result =
                mRealTimeZoneLookupHelper.lookupByNitzCountry(
                        nitzSignal.getValue(), scenario.getNetworkCountryIsoCode());
        assertNull(result);

        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        script.nitzReceived(nitzSignal);
        TimestampedValue<Long> expectedTimeSignal = createTimeSignalFromNitzSignal(nitzSignal);
        script.verifyOnlyTimeWasSuggestedAndReset(expectedTimeSignal);

        script.countryReceived(scenario.getNetworkCountryIsoCode())
                // The code will not set the zone because the setting is initialized.
                .verifyNothingWasSetAndReset();
    }

    @Test
    public void test_unitedKingdom_timeZoneEnabled_countryThenNitz() throws Exception {
        Scenario scenario = UNITED_KINGDOM_SCENARIO;
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null);
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        TimestampedValue<NitzData> nitzSignal =
                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
@@ -128,7 +217,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting("Europe/London");
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        // Demonstrate the defaultTimeZoneBoost behavior: we can get a zone only from the
        // countryIsoCode.
@@ -190,7 +279,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting("Europe/London");
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        // Demonstrate the behavior without default country boost for a country with multiple zones:
        // we cannot get a zone only from the countryIsoCode.
@@ -251,7 +340,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(false)
                .initializeTimeZoneSetting(null);
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        TimestampedValue<NitzData> nitzSignal =
                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
@@ -274,7 +363,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(false)
                .initializeTimeZoneSetting(null);
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        TimestampedValue<NitzData> nitzSignal =
                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
@@ -297,7 +386,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null);
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        // Simulate receiving an NITZ signal.
        TimestampedValue<NitzData> nitzSignal =
@@ -327,7 +416,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null);
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        // Simulate receiving an NITZ signal.
        TimestampedValue<NitzData> nitzSignal =
@@ -671,7 +760,7 @@ public class NitzStateMachineImplTest extends TelephonyTest {
        Script script = new Script()
                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                .initializeTimeZoneDetectionEnabled(true)
                .initializeTimeZoneSetting(null);
                .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);

        // Pre-flight: Simulate a device receiving signals that allow it to detect time and time
        // zone.