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

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

Start using NitzSignal.ageMillis

Start using NitzSignal.ageMillis in time detection. The main functional
change is one line in NitzStateMachineImpl.

The NITZ filtering has been updated, with some refactoring to try to
make things clearer:
1) The receipt time (ignoring age) is still used to tell if NITZ signals
are arriving too closely together. Arguments could be made both ways for
this, but it seems unimportant.
2) The UTC time check does take into the account the age, since it is
required to understand what UTC time the NITZ signal encodes.

Time zone detection logic is unaffected except for NITZ filtering.

Bug: 203638508
Test: atest tests/telephonytests/src/com/android/internal/telephony/nitz/
Test: atest tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java
Test: treehugger
Change-Id: I868543a87bed8e8d7ff0a8b09e126f56cdbd2380
parent 1c36e39e
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.telephony;
import android.annotation.DurationMillisLong;
import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.os.TimestampedValue;

import java.time.Duration;
import java.util.Objects;
@@ -76,6 +77,28 @@ public final class NitzSignal {
        return mAgeMillis;
    }

    /**
     * Returns a derived property of {@code receiptElapsedMillis - ageMillis}, i.e. the time
     * according to the elapsed realtime clock when the NITZ signal was actually received by this
     * device taking into time it was cached by layers before the RIL.
     */
    @ElapsedRealtimeLong
    public long getAgeAdjustedElapsedRealtimeMillis() {
        return mReceiptElapsedMillis - mAgeMillis;
    }

    /**
     * Creates a {@link android.os.TimestampedValue} containing the UTC time as the number of
     * milliseconds since the start of the Unix epoch. The reference time is the time according to
     * the elapsed realtime clock when that would have been the time, accounting for receipt time
     * and age.
     */
    public TimestampedValue<Long> createTimeSignal() {
        return new TimestampedValue<>(
                getAgeAdjustedElapsedRealtimeMillis(),
                getNitzData().getCurrentTimeInMillis());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
@@ -85,7 +108,8 @@ public final class NitzSignal {
            return false;
        }
        NitzSignal that = (NitzSignal) o;
        return mReceiptElapsedMillis == that.mReceiptElapsedMillis && mAgeMillis == that.mAgeMillis
        return mReceiptElapsedMillis == that.mReceiptElapsedMillis
                && mAgeMillis == that.mAgeMillis
                && mNitzData.equals(that.mNitzData);
    }

+6 −6
Original line number Diff line number Diff line
@@ -89,14 +89,14 @@ public interface NitzStateMachine {
    interface DeviceState {

        /**
         * If time between NITZ updates is less than {@link #getNitzUpdateSpacingMillis()} the
         * update may be ignored.
         * If elapsed time between two NITZ signals is less than this value then the second signal
         * can be ignored.
         */
        int getNitzUpdateSpacingMillis();

        /**
         * If {@link #getNitzUpdateSpacingMillis()} hasn't been exceeded but update is >
         * {@link #getNitzUpdateDiffMillis()} do the update
         * If UTC time between two NITZ signals is less than this value then the second signal can
         * be ignored.
         */
        int getNitzUpdateDiffMillis();

@@ -108,7 +108,7 @@ public interface NitzStateMachine {
        /**
         * Returns the same value as {@link SystemClock#elapsedRealtime()}.
         */
        long elapsedRealtime();
        long elapsedRealtimeMillis();

        /**
         * Returns the same value as {@link System#currentTimeMillis()}.
@@ -157,7 +157,7 @@ public interface NitzStateMachine {
        }

        @Override
        public long elapsedRealtime() {
        public long elapsedRealtimeMillis() {
            return SystemClock.elapsedRealtime();
        }

+25 −15
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ public final class NitzSignalInputFilterPredicateFactory {
                // Acquire the wake lock as we are reading the elapsed realtime clock below.
                wakeLock.acquire();

                long elapsedRealtime = deviceState.elapsedRealtime();
                long elapsedRealtime = deviceState.elapsedRealtimeMillis();
                long millisSinceNitzReceived =
                        elapsedRealtime - newSignal.getReceiptElapsedRealtimeMillis();
                if (millisSinceNitzReceived < 0 || millisSinceNitzReceived > Integer.MAX_VALUE) {
@@ -196,26 +196,36 @@ public final class NitzSignalInputFilterPredicateFactory {
                    return true;
                }

                // Now check the continuous NitzData field (time) to see if it is sufficiently
                // different.
                int nitzUpdateSpacing = deviceState.getNitzUpdateSpacingMillis();
                int nitzUpdateDiff = deviceState.getNitzUpdateDiffMillis();
                // Check the time-related NitzData fields to see if they are sufficiently different.

                // Calculate the elapsed time between the new signal and the last signal.
                // See if the NITZ signals have been received sufficiently far apart. If yes, we
                // want to process the new one.
                int nitzUpdateSpacing = deviceState.getNitzUpdateSpacingMillis();
                long elapsedRealtimeSinceLastSaved = newSignal.getReceiptElapsedRealtimeMillis()
                        - previousSignal.getReceiptElapsedRealtimeMillis();
                if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing) {
                    return true;
                }

                // Calculate the UTC difference between the time the two signals hold.
                // See if the NITZ signals have sufficiently different encoded UTC times. If yes,
                // then we want to process the new one.
                int nitzUpdateDiff = deviceState.getNitzUpdateDiffMillis();

                // Calculate the UTC difference between the time the two signals hold, accounting
                // for any difference in receipt time and age.
                long utcTimeDifferenceMillis = newNitzData.getCurrentTimeInMillis()
                        - previousNitzData.getCurrentTimeInMillis();

                // Ideally the difference between elapsedRealtimeSinceLastSaved and
                // utcTimeDifferenceMillis would be zero.
                long millisGainedOrLost = Math
                        .abs(utcTimeDifferenceMillis - elapsedRealtimeSinceLastSaved);

                if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing
                        || millisGainedOrLost > nitzUpdateDiff) {
                long ageAdjustedElapsedRealtimeDifferenceMillis =
                        newSignal.getAgeAdjustedElapsedRealtimeMillis()
                                - previousSignal.getAgeAdjustedElapsedRealtimeMillis();

                // In ideal conditions, the difference between
                // ageAdjustedElapsedRealtimeSinceLastSaved and utcTimeDifferenceMillis will be zero
                // if two NITZ signals are consistent and if the elapsed realtime clock is ticking
                // at the correct rate.
                long millisGainedOrLost = Math.abs(
                        utcTimeDifferenceMillis - ageAdjustedElapsedRealtimeDifferenceMillis);
                if (millisGainedOrLost > nitzUpdateDiff) {
                    return true;
                }

+1 −3
Original line number Diff line number Diff line
@@ -319,9 +319,7 @@ public final class NitzStateMachineImpl implements NitzStateMachine {
                builder.addDebugInfo("Clearing time suggestion"
                        + " reason=" + reason);
            } else {
                TimestampedValue<Long> newNitzTime = new TimestampedValue<>(
                        nitzSignal.getReceiptElapsedRealtimeMillis(),
                        nitzSignal.getNitzData().getCurrentTimeInMillis());
                TimestampedValue<Long> newNitzTime = nitzSignal.createTimeSignal();
                builder.setUtcTime(newNitzTime);
                builder.addDebugInfo("Sending new time suggestion"
                        + " nitzSignal=" + nitzSignal
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import org.junit.Test;

public class NitzSignalTest {

    /** Sample cases for equals() and hashCode(). Not exhaustive. */
    @Test
    public void testEqualsAndHashCode() {
        long receiptElapsedMillis1 = 1111;
        NitzData nitzData1 = NitzData.createForTests(0, 0, 1234, null);
        long ageMillis1 = 11;
        NitzSignal nitzSignal1 = new NitzSignal(receiptElapsedMillis1, nitzData1, ageMillis1);
        assertEquals(nitzSignal1, nitzSignal1);
        assertEquals(nitzSignal1.hashCode(), nitzSignal1.hashCode());

        NitzSignal nitzSignal1v2 = new NitzSignal(receiptElapsedMillis1, nitzData1, ageMillis1);
        assertEquals(nitzSignal1, nitzSignal1v2);
        assertEquals(nitzSignal1v2, nitzSignal1);
        assertEquals(nitzSignal1.hashCode(), nitzSignal1v2.hashCode());

        long receiptElapsedMillis2 = 2222;
        NitzData nitzData2 = NitzData.createForTests(0, 0, 2345, null);
        long ageMillis2 = 11;
        NitzSignal nitzSignal2 = new NitzSignal(receiptElapsedMillis2, nitzData2, ageMillis2);
        assertNotEquals(nitzSignal1, nitzSignal2);
        assertNotEquals(nitzSignal2, nitzSignal1);
    }

    @Test
    public void testGetAgeAdjustedRealtimeMillis_zeroAge() {
        NitzData nitzData = NitzData.createForTests(0, 0, 1234, null);
        long receiptElapsedRealtimeMillis = 1111;
        long ageMillis = 0;
        NitzSignal nitzSignal =
                new NitzSignal(receiptElapsedRealtimeMillis, nitzData, ageMillis);
        assertEquals(receiptElapsedRealtimeMillis,
                nitzSignal.getReceiptElapsedRealtimeMillis());
        assertEquals(ageMillis, nitzSignal.getAgeMillis());
        assertEquals(receiptElapsedRealtimeMillis - ageMillis,
                nitzSignal.getAgeAdjustedElapsedRealtimeMillis());
    }

    @Test
    public void testGetAgeAdjustedRealtimeMillis_withAge() {
        NitzData nitzData = NitzData.createForTests(0, 0, 1234, null);
        long receiptElapsedRealtimeMillis = 1111;
        long ageMillis = 5000;
        NitzSignal nitzSignal =
                new NitzSignal(receiptElapsedRealtimeMillis, nitzData, ageMillis);
        assertEquals(receiptElapsedRealtimeMillis,
                nitzSignal.getReceiptElapsedRealtimeMillis());
        assertEquals(ageMillis, nitzSignal.getAgeMillis());
        assertEquals(receiptElapsedRealtimeMillis - ageMillis,
                nitzSignal.getAgeAdjustedElapsedRealtimeMillis());
    }
}
Loading