From 8e9abc5b2e13abe9305e203592e7c3426ba99e07 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Wed, 16 Feb 2011 10:37:50 -0800 Subject: [PATCH] Fix wifi watchdog to use InetAddress Supports IPv6 and stops using deprectated DhcpInfo. Change-Id: I0590dbcd50f56e15d9b95327ad9435cdbfc8a78d --- .../android/server/WifiWatchdogService.java | 100 +++++++++--------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/services/java/com/android/server/WifiWatchdogService.java b/services/java/com/android/server/WifiWatchdogService.java index 46d6befc0c0ed..94531bbb8e2c1 100644 --- a/services/java/com/android/server/WifiWatchdogService.java +++ b/services/java/com/android/server/WifiWatchdogService.java @@ -22,8 +22,9 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; +import android.net.ConnectivityManager; +import android.net.LinkProperties; import android.net.NetworkInfo; -import android.net.DhcpInfo; import android.net.wifi.ScanResult; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -42,6 +43,7 @@ import java.net.InetAddress; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; +import java.util.Collection; import java.util.List; import java.util.Random; @@ -77,7 +79,8 @@ public class WifiWatchdogService { private Context mContext; private ContentResolver mContentResolver; private WifiManager mWifiManager; - + private ConnectivityManager mConnectivityManager; + /** * The main watchdog thread. */ @@ -310,19 +313,26 @@ public class WifiWatchdogService { } /** - * Gets the DNS of the current AP. + * Gets the first DNS of the current AP. * - * @return The DNS of the current AP. + * @return The first DNS of the current AP. */ - private int getDns() { - DhcpInfo addressInfo = mWifiManager.getDhcpInfo(); - if (addressInfo != null) { - return addressInfo.dns1; - } else { - return -1; + private InetAddress getDns() { + if (mConnectivityManager == null) { + mConnectivityManager = (ConnectivityManager)mContext.getSystemService( + Context.CONNECTIVITY_SERVICE); } + + LinkProperties linkProperties = mConnectivityManager.getLinkProperties( + ConnectivityManager.TYPE_WIFI); + if (linkProperties == null) return null; + + Collection dnses = linkProperties.getDnses(); + if (dnses == null || dnses.size() == 0) return null; + + return dnses.iterator().next(); } - + /** * Checks whether the DNS can be reached using multiple attempts according * to the current setting values. @@ -330,29 +340,28 @@ public class WifiWatchdogService { * @return Whether the DNS is reachable */ private boolean checkDnsConnectivity() { - int dns = getDns(); - if (dns == -1) { + InetAddress dns = getDns(); + if (dns == null) { if (V) { myLogV("checkDnsConnectivity: Invalid DNS, returning false"); } return false; } - + if (V) { - myLogV("checkDnsConnectivity: Checking 0x" + - Integer.toHexString(Integer.reverseBytes(dns)) + " for connectivity"); + myLogV("checkDnsConnectivity: Checking " + dns.getHostAddress() + " for connectivity"); } int numInitialIgnoredPings = getInitialIgnoredPingCount(); int numPings = getPingCount(); int pingDelay = getPingDelayMs(); int acceptableLoss = getAcceptablePacketLossPercentage(); - + /** See {@link Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} */ int ignoredPingCounter = 0; int pingCounter = 0; int successCounter = 0; - + // No connectivity check needed if (numPings == 0) { return true; @@ -371,20 +380,20 @@ public class WifiWatchdogService { pingCounter++; successCounter++; } - + if (V) { Slog.v(TAG, (dnsAlive ? " +" : " Ignored: -")); } if (shouldCancel()) return false; - + try { Thread.sleep(pingDelay); } catch (InterruptedException e) { Slog.w(TAG, "Interrupted while pausing between pings", e); } } - + // Do the pings that we use to measure packet loss for (; pingCounter < numPings; pingCounter++) { if (shouldCancel()) return false; @@ -401,40 +410,41 @@ public class WifiWatchdogService { } if (shouldCancel()) return false; - + try { Thread.sleep(pingDelay); } catch (InterruptedException e) { Slog.w(TAG, "Interrupted while pausing between pings", e); } } - + int packetLossPercentage = 100 * (numPings - successCounter) / numPings; if (D) { Slog.d(TAG, packetLossPercentage + "% packet loss (acceptable is " + acceptableLoss + "%)"); } - + return !shouldCancel() && (packetLossPercentage <= acceptableLoss); } private boolean backgroundCheckDnsConnectivity() { - int dns = getDns(); - if (false && V) { - myLogV("backgroundCheckDnsConnectivity: Background checking " + dns + - " for connectivity"); - } - - if (dns == -1) { + InetAddress dns = getDns(); + + if (dns == null) { if (V) { myLogV("backgroundCheckDnsConnectivity: DNS is empty, returning false"); } return false; } - + + if (false && V) { + myLogV("backgroundCheckDnsConnectivity: Background checking " + + dns.getHostAddress() + " for connectivity"); + } + return DnsPinger.isDnsReachable(dns, getBackgroundCheckTimeoutMs()); } - + /** * Signals the current action to cancel. */ @@ -1207,43 +1217,37 @@ public class WifiWatchdogService { /** Used to generate IDs */ private static Random sRandom = new Random(); - - static boolean isDnsReachable(int dns, int timeout) { + + static boolean isDnsReachable(InetAddress dnsAddress, int timeout) { DatagramSocket socket = null; try { socket = new DatagramSocket(); - + // Set some socket properties socket.setSoTimeout(timeout); - + byte[] buf = new byte[DNS_QUERY_BASE_SIZE]; fillQuery(buf); - - // Send the DNS query - byte parts[] = new byte[4]; - parts[0] = (byte)(dns & 0xff); - parts[1] = (byte)((dns >> 8) & 0xff); - parts[2] = (byte)((dns >> 16) & 0xff); - parts[3] = (byte)((dns >> 24) & 0xff); - InetAddress dnsAddress = InetAddress.getByAddress(parts); + // Send the DNS query + DatagramPacket packet = new DatagramPacket(buf, buf.length, dnsAddress, DNS_PORT); socket.send(packet); - + // Wait for reply (blocks for the above timeout) DatagramPacket replyPacket = new DatagramPacket(buf, buf.length); socket.receive(replyPacket); // If a timeout occurred, an exception would have been thrown. We got a reply! return true; - + } catch (SocketException e) { if (V) { Slog.v(TAG, "DnsPinger.isReachable received SocketException", e); } return false; - + } catch (UnknownHostException e) { if (V) { Slog.v(TAG, "DnsPinger.isReachable is unable to resolve the DNS host", e);