SntpClient periodically re-syncs the offset to NTP server

Many of the Android TV platforms do not report accurate `SystemClock.elapsedRealtime()`
In addition this drift is not consistant accross multiple boxes, so the time offset
between any pair of boxes will vary over time.

This variance will lead to a drift in the Live Offset calculation.

Fix is simple, inValidate the NTP server query after a period of time (10 minutes)
and re-issue the call
This commit is contained in:
Steve Mayhew 2023-10-04 13:55:38 -07:00 committed by Marc Baechinger
parent 1084c9ea98
commit 621a9aedba

View File

@ -49,6 +49,9 @@ public final class SntpClient {
/** The default maximum time, in milliseconds, to wait for the SNTP request to complete. */ /** The default maximum time, in milliseconds, to wait for the SNTP request to complete. */
public static final int DEFAULT_TIMEOUT_MS = 1_000; public static final int DEFAULT_TIMEOUT_MS = 1_000;
/** Max time to allow before re-initializing with NTP server, default is 10 minutes */
private static final long MAX_ELAPSED_MS_TILL_UPDATE = 60 * 10 * 1_000L;
/** Callback for calls to {@link #initialize(Loader, InitializationCallback)}. */ /** Callback for calls to {@link #initialize(Loader, InitializationCallback)}. */
public interface InitializationCallback { public interface InitializationCallback {
@ -96,6 +99,9 @@ public final class SntpClient {
@GuardedBy("valueLock") @GuardedBy("valueLock")
private static int timeoutMs = DEFAULT_TIMEOUT_MS; private static int timeoutMs = DEFAULT_TIMEOUT_MS;
@GuardedBy("valueLock")
private static long lastUpdateElapsedRealtime = C.TIME_UNSET;
private SntpClient() {} private SntpClient() {}
/** Returns the NTP host address used to retrieve {@link #getElapsedRealtimeOffsetMs()}. */ /** Returns the NTP host address used to retrieve {@link #getElapsedRealtimeOffsetMs()}. */
@ -120,6 +126,7 @@ public final class SntpClient {
if (!SntpClient.ntpHost.equals(ntpHost)) { if (!SntpClient.ntpHost.equals(ntpHost)) {
SntpClient.ntpHost = ntpHost; SntpClient.ntpHost = ntpHost;
isInitialized = false; isInitialized = false;
lastUpdateElapsedRealtime = C.TIME_UNSET;
} }
} }
} }
@ -156,6 +163,10 @@ public final class SntpClient {
*/ */
public static boolean isInitialized() { public static boolean isInitialized() {
synchronized (valueLock) { synchronized (valueLock) {
if (lastUpdateElapsedRealtime != C.TIME_UNSET) {
long deltaLastUpdate = SystemClock.elapsedRealtime() - lastUpdateElapsedRealtime;
isInitialized = isInitialized && deltaLastUpdate < MAX_ELAPSED_MS_TILL_UPDATE;
}
return isInitialized; return isInitialized;
} }
} }
@ -353,6 +364,7 @@ public final class SntpClient {
} }
long offsetMs = loadNtpTimeOffsetMs(); long offsetMs = loadNtpTimeOffsetMs();
synchronized (valueLock) { synchronized (valueLock) {
lastUpdateElapsedRealtime = SystemClock.elapsedRealtime();
elapsedRealtimeOffsetMs = offsetMs; elapsedRealtimeOffsetMs = offsetMs;
isInitialized = true; isInitialized = true;
} }