mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Retry alternative addresses on timeout in SNTP client
Changed the default timeout for SNTP requests to 1 second. Issue: androidx/media#1540 PiperOrigin-RevId: 652897579
This commit is contained in:
parent
7f304092ae
commit
ded66debc3
@ -24,8 +24,8 @@
|
||||
* `MediaCodecVideoRenderer` avoids decoding samples that are neither
|
||||
rendered nor used as reference by other samples.
|
||||
* Add `BasePreloadManager.Listener` to propagate preload events to apps.
|
||||
* Allow changing SNTP client timeout
|
||||
([#1540](https://github.com/androidx/media/issues/1540)).
|
||||
* Allow changing SNTP client timeout and retry alternative addresses on
|
||||
timeout ([#1540](https://github.com/androidx/media/issues/1540)).
|
||||
* Remove `MediaCodecAdapter.Configuration.flags` as the field was always
|
||||
zero.
|
||||
* Transformer:
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer.util;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -27,6 +29,7 @@ import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Arrays;
|
||||
import java.util.ConcurrentModificationException;
|
||||
|
||||
@ -44,7 +47,7 @@ public final class SntpClient {
|
||||
public static final String DEFAULT_NTP_HOST = "time.android.com";
|
||||
|
||||
/** The default maximum time, in milliseconds, to wait for the SNTP request to complete. */
|
||||
public static final int DEFAULT_TIMEOUT_MS = 5_000;
|
||||
public static final int DEFAULT_TIMEOUT_MS = 1_000;
|
||||
|
||||
/** Callback for calls to {@link #initialize(Loader, InitializationCallback)}. */
|
||||
public interface InitializationCallback {
|
||||
@ -60,6 +63,7 @@ public final class SntpClient {
|
||||
void onInitializationFailed(IOException error);
|
||||
}
|
||||
|
||||
private static final int MAX_RETRY_COUNT = 10;
|
||||
private static final int ORIGINATE_TIME_OFFSET = 24;
|
||||
private static final int RECEIVE_TIME_OFFSET = 32;
|
||||
private static final int TRANSMIT_TIME_OFFSET = 40;
|
||||
@ -191,14 +195,18 @@ public final class SntpClient {
|
||||
}
|
||||
|
||||
private static long loadNtpTimeOffsetMs() throws IOException {
|
||||
InetAddress address = InetAddress.getByName(getNtpHost());
|
||||
try (DatagramSocket socket = new DatagramSocket()) {
|
||||
socket.setSoTimeout(getTimeoutMs());
|
||||
|
||||
int retryCount = 0;
|
||||
SocketTimeoutException timeoutException = null;
|
||||
InetAddress[] addresses = InetAddress.getAllByName(getNtpHost());
|
||||
for (InetAddress address : addresses) {
|
||||
byte[] buffer = new byte[NTP_PACKET_SIZE];
|
||||
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
|
||||
|
||||
// Set mode = 3 (client) and version = 3. Mode is in low 3 bits of the first byte and Version
|
||||
// is in bits 3-5 of the first byte.
|
||||
// Set mode = 3 (client) and version = 3. Mode is in low 3 bits of the first byte and
|
||||
// Version is in bits 3-5 of the first byte.
|
||||
buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);
|
||||
|
||||
// Get current time and write it to the request packet.
|
||||
@ -210,7 +218,22 @@ public final class SntpClient {
|
||||
|
||||
// Read the response.
|
||||
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
|
||||
try {
|
||||
socket.receive(response);
|
||||
} catch (SocketTimeoutException e) {
|
||||
// Store the timeout exception and try the next address if we have not reached retry limit
|
||||
if (timeoutException == null) {
|
||||
timeoutException = e;
|
||||
} else {
|
||||
timeoutException.addSuppressed(e);
|
||||
}
|
||||
if (retryCount++ < MAX_RETRY_COUNT) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final long responseTicks = SystemClock.elapsedRealtime();
|
||||
final long responseTime = requestTime + (responseTicks - requestTicks);
|
||||
|
||||
@ -235,13 +258,16 @@ public final class SntpClient {
|
||||
// = (2 * skew)/2 = skew
|
||||
long clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime)) / 2;
|
||||
|
||||
// Save our results using the times on this side of the network latency (i.e. response rather
|
||||
// than request time)
|
||||
// Save our results using the times on this side of the network latency (i.e. response
|
||||
// rather than request time)
|
||||
long ntpTime = responseTime + clockOffset;
|
||||
long ntpTimeReference = responseTicks;
|
||||
|
||||
return ntpTime - ntpTimeReference;
|
||||
}
|
||||
// If no response is received from any of the addresses, throw an exception.
|
||||
throw checkNotNull(timeoutException);
|
||||
}
|
||||
}
|
||||
|
||||
private static long readTimestamp(byte[] buffer, int offset) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user