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

Commit cf61e69b authored by Neil Fuller's avatar Neil Fuller Committed by Gerrit Code Review
Browse files

Merge "Allow NITZ signals > year 2037"

parents 694586e2 0ffc5b2c
Loading
Loading
Loading
Loading
+24 −11
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK
import com.android.internal.annotations.VisibleForTesting;
import com.android.telephony.Rlog;

import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;
@@ -39,9 +40,6 @@ public final class NitzData {
    private static final int MS_PER_QUARTER_HOUR = 15 * 60 * 1000;
    private static final int MS_PER_HOUR = 60 * 60 * 1000;

    /* Time stamp after 19 January 2038 is not supported under 32 bit */
    private static final int MAX_NITZ_YEAR = 2037;

    private static final Pattern NITZ_SPLIT_PATTERN = Pattern.compile("[/:,+-]");

    // Stored For logging / debugging only.
@@ -77,22 +75,37 @@ public final class NitzData {
        try {
            String[] nitzSubs = NITZ_SPLIT_PATTERN.split(nitz);

            int year = 2000 + Integer.parseInt(nitzSubs[0]);
            if (year > MAX_NITZ_YEAR) {
                if (ServiceStateTracker.DBG) {
                    Rlog.e(LOG_TAG, "NITZ year: " + year + " exceeds limit, skip NITZ time update");
                }
                return null;
            int year = Integer.parseInt(nitzSubs[0]);
            if (year < 1 || year > 99) {
                // 0 > year > 99 imply an invalid string.
                //
                // At the time of this comment (year 2023), a zero year is considered invalid and
                // assumed to be the result of invalid data being converted to zero in the code that
                // turns the binary NITZ into a string. For the next few decades at least, Android
                // devices should not need to interpret zero. Hopefully, NITZ will be replaced by
                // the time that's not true, or folks dealing the Y2K1 issue can handle it.
                //
                // DateTimeException is also thrown by LocalDateTime below if the values are out of
                // range and will be handled in the catch block.
                throw new DateTimeException("Invalid NITZ year == 0");
            }

            // Values < {current year} could be considered invalid but are used in test code, so no
            // window is applied to adjust low values < {current year} with "+ 2100" (and would also
            // need to consider zero as valid). Code that processes the NitzData is in a better
            // position to log and discard obviously invalid NITZ signals from past years.
            year += 2000;

            int month = Integer.parseInt(nitzSubs[1]);
            int date = Integer.parseInt(nitzSubs[2]);
            int hour = Integer.parseInt(nitzSubs[3]);
            int minute = Integer.parseInt(nitzSubs[4]);
            int second = Integer.parseInt(nitzSubs[5]);

            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
             * offset as well (which we won't worry about until later) */
            // NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
            // offset as well (which we won't worry about until later).
            // The LocalDateTime.of() will throw DateTimeException for values outside the allowed
            // range for the Gregorian calendar.
            long epochMillis = LocalDateTime.of(year, month, date, hour, minute, second)
                    .toInstant(ZoneOffset.UTC)
                    .toEpochMilli();
+12 −3
Original line number Diff line number Diff line
@@ -29,8 +29,17 @@ import java.util.concurrent.TimeUnit;
public class NitzDataTest {

    @Test
    public void testParse_dateOutsideAllowedRange() {
        assertNull(NitzData.parse("38/06/20,00:00:00+0"));
    public void testParse_invalidYear() {
        assertNull(NitzData.parse("00/06/20,00:00:00+0,0"));
    }

    @Test
    public void testParse_beyond2038() {
        NitzData nitz = NitzData.parse("40/06/20,01:02:03+4,1");
        assertEquals(createUnixEpochTime(2040, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
        assertEquals(TimeUnit.MINUTES.toMillis(4 * 15), nitz.getLocalOffsetMillis());
        assertEquals(TimeUnit.MINUTES.toMillis(60), nitz.getDstAdjustmentMillis().longValue());
        assertNull(nitz.getEmulatorHostTimeZone());
    }

    @Test
@@ -38,7 +47,7 @@ public class NitzDataTest {
        // "yy/mm/dd,hh:mm:ss(+/-)tz[,dt[,tzid]]"

        // No tz field.
        assertNull(NitzData.parse("38/06/20,00:00:00"));
        assertNull(NitzData.parse("22/06/20,00:00:00"));
    }

    @Test
+0 −13
Original line number Diff line number Diff line
@@ -1813,12 +1813,6 @@ public class ServiceStateTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testSetTimeFromNITZStr_withoutAge() throws Exception {
        {
            // Mock sending incorrect nitz str from RIL
            mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0");
            waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
            verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
        }
        {
            // Mock sending correct nitz str from RIL with a zero ageMs
            String nitzStr = "15/06/20,00:00:00+0";
@@ -1843,13 +1837,6 @@ public class ServiceStateTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testSetTimeFromNITZStr_withAge() throws Exception {
        {
            // Mock sending incorrect nitz str from RIL with a non-zero ageMs
            long ageMs = 60 * 1000;
            mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0", ageMs);
            waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
            verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
        }
        {
            // Mock sending correct nitz str from RIL with a non-zero ageMs
            String nitzStr = "21/08/15,00:00:00+0";