OSDN Git Service

Allow specifying a network for SNTP time sync
authorKurt Marcinkiewicz <kurdt@google.com>
Mon, 5 Mar 2018 22:45:04 +0000 (14:45 -0800)
committerKurt Marcinkiewicz <kurdt@google.com>
Thu, 22 Mar 2018 20:43:25 +0000 (13:43 -0700)
Permits syncing over a specific network instead of the default for
the process. This was causing an issue with Android Wear devices
paired with iOS where the default network is bluetooth
(see b/32663274).

This CL is in support of ag/3776564

Bug: 32663274

Test: adb shell am instrument -e class android.net.SntpClientTest -w \
com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner

Change-Id: Ic9fc169cf75457810d4992121d85d7642e350b90

config/hiddenapi-vendor-list.txt
core/java/android/net/SntpClient.java
core/java/android/util/NtpTrustedTime.java
core/tests/coretests/src/android/net/SntpClientTest.java
tests/BandwidthTests/src/com/android/tests/bandwidthenforcement/BandwidthEnforcementTestService.java

index fe9a5db..bc2d747 100644 (file)
@@ -309,7 +309,6 @@ Landroid/net/RouteInfo;->selectBestRoute(Ljava/util/Collection;Ljava/net/InetAdd
 Landroid/net/SntpClient;->getNtpTime()J
 Landroid/net/SntpClient;->getNtpTimeReference()J
 Landroid/net/SntpClient;->getRoundTripTime()J
-Landroid/net/SntpClient;->requestTime(Ljava/lang/String;I)Z
 Landroid/net/StaticIpConfiguration;->dnsServers:Ljava/util/ArrayList;
 Landroid/net/StaticIpConfiguration;->domains:Ljava/lang/String;
 Landroid/net/StaticIpConfiguration;->gateway:Ljava/net/InetAddress;
index ffc735c..66cdc99 100644 (file)
@@ -80,25 +80,27 @@ public class SntpClient {
      *
      * @param host host name of the server.
      * @param timeout network timeout in milliseconds.
+     * @param network network over which to send the request.
      * @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;
         try {
-            address = InetAddress.getByName(host);
+            address = network.getByName(host);
         } catch (Exception e) {
             EventLogTags.writeNtpFailure(host, e.toString());
             if (DBG) Log.d(TAG, "request time failed: " + e);
             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;
         final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_NTP);
         try {
             socket = new DatagramSocket();
+            network.bindSocket(socket);
             socket.setSoTimeout(timeout);
             byte[] buffer = new byte[NTP_PACKET_SIZE];
             DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, port);
@@ -168,6 +170,12 @@ public class SntpClient {
         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.
      *
index ed2d3c6..30d7b6c 100644 (file)
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.Network;
 import android.net.NetworkInfo;
 import android.net.SntpClient;
 import android.os.SystemClock;
@@ -80,6 +81,18 @@ public class NtpTrustedTime implements TrustedTime {
 
     @Override
     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)) {
             // missing server, so no trusted time available
             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.
         synchronized (this) {
             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 (LOGD) Log.d(TAG, "forceRefresh: no connectivity");
             return false;
@@ -101,7 +114,7 @@ public class NtpTrustedTime implements TrustedTime {
 
         if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
         final SntpClient client = new SntpClient();
-        if (client.requestTime(mServer, (int) mTimeout)) {
+        if (client.requestTime(mServer, (int) mTimeout, network)) {
             mHasCache = true;
             mCachedNtpTime = client.getNtpTime();
             mCachedNtpElapsedRealtime = client.getNtpTimeReference();
index 8b8cf67..63d4080 100644 (file)
@@ -16,7 +16,8 @@
 
 package android.net;
 
-import android.net.SntpClient;
+import android.content.Context;
+import android.test.AndroidTestCase;
 import android.util.Log;
 import libcore.util.HexEncoding;
 
@@ -26,10 +27,9 @@ import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.SocketException;
 import java.util.Arrays;
-import junit.framework.TestCase;
 
 
-public class SntpClientTest extends TestCase {
+public class SntpClientTest extends AndroidTestCase {
     private static final String TAG = "SntpClientTest";
 
     private static final int ORIGINATE_TIME_OFFSET = 24;
@@ -61,20 +61,29 @@ public class SntpClientTest extends TestCase {
     private final SntpTestServer mServer = new SntpTestServer();
     private final SntpClient mClient = new SntpClient();
 
+    private Network mNetwork;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        ConnectivityManager mCM = getContext().getSystemService(ConnectivityManager.class);
+        mNetwork = mCM.getActiveNetwork();
+    }
+
     public void testBasicWorkingSntpClientQuery() throws Exception {
         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.numRepliesSent());
     }
 
     public void testDnsResolutionFailure() throws Exception {
-        assertFalse(mClient.requestTime("ntp.server.doesnotexist.example", 5000));
+        assertFalse(mClient.requestTime("ntp.server.doesnotexist.example", 5000, mNetwork));
     }
 
     public void testTimeoutFailure() throws Exception {
         mServer.clearServerReply();
-        assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500));
+        assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500, mNetwork));
         assertEquals(1, mServer.numRequestsReceived());
         assertEquals(0, mServer.numRepliesSent());
     }
@@ -83,7 +92,7 @@ public class SntpClientTest extends TestCase {
         final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
         reply[0] |= (byte) 0xc0;
         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.numRepliesSent());
     }
@@ -95,7 +104,8 @@ public class SntpClientTest extends TestCase {
             reply[0] &= (byte) 0xf8;
             reply[0] |= (byte) i;
             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) {
                 case NTP_MODE_SERVER:
                 case NTP_MODE_BROADCAST:
@@ -119,7 +129,8 @@ public class SntpClientTest extends TestCase {
             final String logMsg = "stratum: " + i;
             reply[1] = (byte) i;
             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) {
                 assertTrue(logMsg, rval);
             } else {
@@ -134,7 +145,7 @@ public class SntpClientTest extends TestCase {
         final byte[] reply = HexEncoding.decode(WORKING_VERSION4.toCharArray(), false);
         Arrays.fill(reply, TRANSMIT_TIME_OFFSET, TRANSMIT_TIME_OFFSET + 8, (byte) 0x00);
         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.numRepliesSent());
     }
index a2427f5..35f1e58 100644 (file)
 package com.android.tests.bandwidthenforcement;
 
 import android.app.IntentService;
+import android.content.Context;
 import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
 import android.net.SntpClient;
 import android.os.Environment;
 import android.util.Log;
@@ -55,7 +58,7 @@ public class BandwidthEnforcementTestService extends IntentService {
         String outputFile = intent.getStringExtra(OUTPUT_FILE);
         dumpResult("testUrlConnection", testUrlConnection(), outputFile);
         dumpResult("testUrlConnectionv6", testUrlConnectionv6(), outputFile);
-        dumpResult("testSntp", testSntp(), outputFile);
+        dumpResult("testSntp", testSntp(getApplicationContext()), outputFile);
         dumpResult("testDns", testDns(), outputFile);
     }
 
@@ -138,9 +141,12 @@ public class BandwidthEnforcementTestService extends IntentService {
      * Tests to connect via sntp.
      * @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();
-        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 false;