Loading src/java/com/android/internal/telephony/NitzSignal.java +25 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); } Loading src/java/com/android/internal/telephony/NitzStateMachine.java +6 −6 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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()}. Loading Loading @@ -157,7 +157,7 @@ public interface NitzStateMachine { } @Override public long elapsedRealtime() { public long elapsedRealtimeMillis() { return SystemClock.elapsedRealtime(); } Loading src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java +25 −15 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java +1 −3 Original line number Diff line number Diff line Loading @@ -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 Loading tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java 0 → 100644 +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
src/java/com/android/internal/telephony/NitzSignal.java +25 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); } Loading
src/java/com/android/internal/telephony/NitzStateMachine.java +6 −6 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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()}. Loading Loading @@ -157,7 +157,7 @@ public interface NitzStateMachine { } @Override public long elapsedRealtime() { public long elapsedRealtimeMillis() { return SystemClock.elapsedRealtime(); } Loading
src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java +25 −15 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading
src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java +1 −3 Original line number Diff line number Diff line Loading @@ -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 Loading
tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java 0 → 100644 +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()); } }