Merge changes Ieb0a5d24,I44df6668
* changes: Fix SntpClientTest failures with no active network Allow specifying a network for SNTP time sync
This commit is contained in:
@@ -80,25 +80,27 @@ public class SntpClient {
|
|||||||
*
|
*
|
||||||
* @param host host name of the server.
|
* @param host host name of the server.
|
||||||
* @param timeout network timeout in milliseconds.
|
* @param timeout network timeout in milliseconds.
|
||||||
|
* @param network network over which to send the request.
|
||||||
* @return true if the transaction was successful.
|
* @return true if the transaction was successful.
|
||||||
*/
|
*/
|
||||||
public boolean requestTime(String host, int timeout) {
|
public boolean requestTime(String host, int timeout, Network network) {
|
||||||
InetAddress address = null;
|
InetAddress address = null;
|
||||||
try {
|
try {
|
||||||
address = InetAddress.getByName(host);
|
address = network.getByName(host);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
EventLogTags.writeNtpFailure(host, e.toString());
|
EventLogTags.writeNtpFailure(host, e.toString());
|
||||||
if (DBG) Log.d(TAG, "request time failed: " + e);
|
if (DBG) Log.d(TAG, "request time failed: " + e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return requestTime(address, NTP_PORT, timeout);
|
return requestTime(address, NTP_PORT, timeout, network);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requestTime(InetAddress address, int port, int timeout) {
|
public boolean requestTime(InetAddress address, int port, int timeout, Network network) {
|
||||||
DatagramSocket socket = null;
|
DatagramSocket socket = null;
|
||||||
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_NTP);
|
final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_NTP);
|
||||||
try {
|
try {
|
||||||
socket = new DatagramSocket();
|
socket = new DatagramSocket();
|
||||||
|
network.bindSocket(socket);
|
||||||
socket.setSoTimeout(timeout);
|
socket.setSoTimeout(timeout);
|
||||||
byte[] buffer = new byte[NTP_PACKET_SIZE];
|
byte[] buffer = new byte[NTP_PACKET_SIZE];
|
||||||
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, port);
|
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, port);
|
||||||
@@ -168,6 +170,12 @@ public class SntpClient {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public boolean requestTime(String host, int timeout) {
|
||||||
|
Log.w(TAG, "Shame on you for calling the hidden API requestTime()!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the time computed from the NTP transaction.
|
* Returns the time computed from the NTP transaction.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.Network;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.SntpClient;
|
import android.net.SntpClient;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
@@ -80,6 +81,18 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean forceRefresh() {
|
public boolean forceRefresh() {
|
||||||
|
// We can't do this at initialization time: ConnectivityService might not be running yet.
|
||||||
|
synchronized (this) {
|
||||||
|
if (mCM == null) {
|
||||||
|
mCM = sContext.getSystemService(ConnectivityManager.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Network network = mCM == null ? null : mCM.getActiveNetwork();
|
||||||
|
return forceRefresh(network);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean forceRefresh(Network network) {
|
||||||
if (TextUtils.isEmpty(mServer)) {
|
if (TextUtils.isEmpty(mServer)) {
|
||||||
// missing server, so no trusted time available
|
// missing server, so no trusted time available
|
||||||
return false;
|
return false;
|
||||||
@@ -88,11 +101,11 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
// We can't do this at initialization time: ConnectivityService might not be running yet.
|
// We can't do this at initialization time: ConnectivityService might not be running yet.
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mCM == null) {
|
if (mCM == null) {
|
||||||
mCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
mCM = sContext.getSystemService(ConnectivityManager.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final NetworkInfo ni = mCM == null ? null : mCM.getActiveNetworkInfo();
|
final NetworkInfo ni = mCM == null ? null : mCM.getNetworkInfo(network);
|
||||||
if (ni == null || !ni.isConnected()) {
|
if (ni == null || !ni.isConnected()) {
|
||||||
if (LOGD) Log.d(TAG, "forceRefresh: no connectivity");
|
if (LOGD) Log.d(TAG, "forceRefresh: no connectivity");
|
||||||
return false;
|
return false;
|
||||||
@@ -101,7 +114,7 @@ public class NtpTrustedTime implements TrustedTime {
|
|||||||
|
|
||||||
if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
|
if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
|
||||||
final SntpClient client = new SntpClient();
|
final SntpClient client = new SntpClient();
|
||||||
if (client.requestTime(mServer, (int) mTimeout)) {
|
if (client.requestTime(mServer, (int) mTimeout, network)) {
|
||||||
mHasCache = true;
|
mHasCache = true;
|
||||||
mCachedNtpTime = client.getNtpTime();
|
mCachedNtpTime = client.getNtpTime();
|
||||||
mCachedNtpElapsedRealtime = client.getNtpTimeReference();
|
mCachedNtpElapsedRealtime = client.getNtpTimeReference();
|
||||||
|
|||||||
@@ -16,20 +16,28 @@
|
|||||||
|
|
||||||
package android.net;
|
package android.net;
|
||||||
|
|
||||||
import android.net.SntpClient;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertFalse;
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import libcore.util.HexEncoding;
|
import libcore.util.HexEncoding;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class SntpClientTest extends TestCase {
|
public class SntpClientTest {
|
||||||
private static final String TAG = "SntpClientTest";
|
private static final String TAG = "SntpClientTest";
|
||||||
|
|
||||||
private static final int ORIGINATE_TIME_OFFSET = 24;
|
private static final int ORIGINATE_TIME_OFFSET = 24;
|
||||||
@@ -58,36 +66,50 @@ public class SntpClientTest extends TestCase {
|
|||||||
"d9ca945194bd3fff" +
|
"d9ca945194bd3fff" +
|
||||||
"d9ca945194bd4001";
|
"d9ca945194bd4001";
|
||||||
|
|
||||||
private final SntpTestServer mServer = new SntpTestServer();
|
private SntpTestServer mServer;
|
||||||
private final SntpClient mClient = new SntpClient();
|
private SntpClient mClient;
|
||||||
|
private Network mNetwork;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
// NETID_UNSET allows the test to run, with a loopback server, even w/o external networking
|
||||||
|
mNetwork = new Network(ConnectivityManager.NETID_UNSET);
|
||||||
|
mServer = new SntpTestServer();
|
||||||
|
mClient = new SntpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testBasicWorkingSntpClientQuery() throws Exception {
|
public void testBasicWorkingSntpClientQuery() throws Exception {
|
||||||
mServer.setServerReply(HexEncoding.decode(WORKING_VERSION4.toCharArray(), false));
|
mServer.setServerReply(HexEncoding.decode(WORKING_VERSION4.toCharArray(), false));
|
||||||
assertTrue(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500));
|
assertTrue(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork));
|
||||||
assertEquals(1, mServer.numRequestsReceived());
|
assertEquals(1, mServer.numRequestsReceived());
|
||||||
assertEquals(1, mServer.numRepliesSent());
|
assertEquals(1, mServer.numRepliesSent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testDnsResolutionFailure() throws Exception {
|
public void testDnsResolutionFailure() throws Exception {
|
||||||
assertFalse(mClient.requestTime("ntp.server.doesnotexist.example", 5000));
|
assertFalse(mClient.requestTime("ntp.server.doesnotexist.example", 5000, mNetwork));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testTimeoutFailure() throws Exception {
|
public void testTimeoutFailure() throws Exception {
|
||||||
mServer.clearServerReply();
|
mServer.clearServerReply();
|
||||||
assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500));
|
assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork));
|
||||||
assertEquals(1, mServer.numRequestsReceived());
|
assertEquals(1, mServer.numRequestsReceived());
|
||||||
assertEquals(0, mServer.numRepliesSent());
|
assertEquals(0, mServer.numRepliesSent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testIgnoreLeapNoSync() throws Exception {
|
public void testIgnoreLeapNoSync() throws Exception {
|
||||||
final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
|
final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
|
||||||
reply[0] |= (byte) 0xc0;
|
reply[0] |= (byte) 0xc0;
|
||||||
mServer.setServerReply(reply);
|
mServer.setServerReply(reply);
|
||||||
assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500));
|
assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork));
|
||||||
assertEquals(1, mServer.numRequestsReceived());
|
assertEquals(1, mServer.numRequestsReceived());
|
||||||
assertEquals(1, mServer.numRepliesSent());
|
assertEquals(1, mServer.numRepliesSent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testAcceptOnlyServerAndBroadcastModes() throws Exception {
|
public void testAcceptOnlyServerAndBroadcastModes() throws Exception {
|
||||||
final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
|
final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
|
||||||
for (int i = 0; i <= 7; i++) {
|
for (int i = 0; i <= 7; i++) {
|
||||||
@@ -95,7 +117,8 @@ public class SntpClientTest extends TestCase {
|
|||||||
reply[0] &= (byte) 0xf8;
|
reply[0] &= (byte) 0xf8;
|
||||||
reply[0] |= (byte) i;
|
reply[0] |= (byte) i;
|
||||||
mServer.setServerReply(reply);
|
mServer.setServerReply(reply);
|
||||||
final boolean rval = mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500);
|
final boolean rval = mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500,
|
||||||
|
mNetwork);
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case NTP_MODE_SERVER:
|
case NTP_MODE_SERVER:
|
||||||
case NTP_MODE_BROADCAST:
|
case NTP_MODE_BROADCAST:
|
||||||
@@ -110,6 +133,7 @@ public class SntpClientTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testAcceptableStrataOnly() throws Exception {
|
public void testAcceptableStrataOnly() throws Exception {
|
||||||
final int STRATUM_MIN = 1;
|
final int STRATUM_MIN = 1;
|
||||||
final int STRATUM_MAX = 15;
|
final int STRATUM_MAX = 15;
|
||||||
@@ -119,7 +143,8 @@ public class SntpClientTest extends TestCase {
|
|||||||
final String logMsg = "stratum: " + i;
|
final String logMsg = "stratum: " + i;
|
||||||
reply[1] = (byte) i;
|
reply[1] = (byte) i;
|
||||||
mServer.setServerReply(reply);
|
mServer.setServerReply(reply);
|
||||||
final boolean rval = mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500);
|
final boolean rval = mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500,
|
||||||
|
mNetwork);
|
||||||
if (STRATUM_MIN <= i && i <= STRATUM_MAX) {
|
if (STRATUM_MIN <= i && i <= STRATUM_MAX) {
|
||||||
assertTrue(logMsg, rval);
|
assertTrue(logMsg, rval);
|
||||||
} else {
|
} else {
|
||||||
@@ -130,11 +155,12 @@ public class SntpClientTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testZeroTransmitTime() throws Exception {
|
public void testZeroTransmitTime() throws Exception {
|
||||||
final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
|
final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
|
||||||
Arrays.fill(reply, TRANSMIT_TIME_OFFSET, TRANSMIT_TIME_OFFSET + 8, (byte) 0x00);
|
Arrays.fill(reply, TRANSMIT_TIME_OFFSET, TRANSMIT_TIME_OFFSET + 8, (byte) 0x00);
|
||||||
mServer.setServerReply(reply);
|
mServer.setServerReply(reply);
|
||||||
assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500));
|
assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork));
|
||||||
assertEquals(1, mServer.numRequestsReceived());
|
assertEquals(1, mServer.numRequestsReceived());
|
||||||
assertEquals(1, mServer.numRepliesSent());
|
assertEquals(1, mServer.numRepliesSent());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,10 @@
|
|||||||
package com.android.tests.bandwidthenforcement;
|
package com.android.tests.bandwidthenforcement;
|
||||||
|
|
||||||
import android.app.IntentService;
|
import android.app.IntentService;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.Network;
|
||||||
import android.net.SntpClient;
|
import android.net.SntpClient;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -55,7 +58,7 @@ public class BandwidthEnforcementTestService extends IntentService {
|
|||||||
String outputFile = intent.getStringExtra(OUTPUT_FILE);
|
String outputFile = intent.getStringExtra(OUTPUT_FILE);
|
||||||
dumpResult("testUrlConnection", testUrlConnection(), outputFile);
|
dumpResult("testUrlConnection", testUrlConnection(), outputFile);
|
||||||
dumpResult("testUrlConnectionv6", testUrlConnectionv6(), outputFile);
|
dumpResult("testUrlConnectionv6", testUrlConnectionv6(), outputFile);
|
||||||
dumpResult("testSntp", testSntp(), outputFile);
|
dumpResult("testSntp", testSntp(getApplicationContext()), outputFile);
|
||||||
dumpResult("testDns", testDns(), outputFile);
|
dumpResult("testDns", testDns(), outputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,9 +141,12 @@ public class BandwidthEnforcementTestService extends IntentService {
|
|||||||
* Tests to connect via sntp.
|
* Tests to connect via sntp.
|
||||||
* @return true if it was able to connect, false otherwise.
|
* @return true if it was able to connect, false otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean testSntp() {
|
public static boolean testSntp(Context context) {
|
||||||
final SntpClient client = new SntpClient();
|
final SntpClient client = new SntpClient();
|
||||||
if (client.requestTime("0.pool.ntp.org", 10000)) {
|
final ConnectivityManager mCM = context.getSystemService(ConnectivityManager.class);
|
||||||
|
final Network network = mCM.getActiveNetwork();
|
||||||
|
|
||||||
|
if (client.requestTime("0.pool.ntp.org", 10000, network)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user