Use ping to check connectivity.

Installing WifiUtil only to check connectivity is overkill and can cause unnecessary failures if package manager or activity manager is not working correctly. Using ping for connectivity checks would help TF to avoid this kind of failures.

Bug: 17692677

Change-Id: I6f19ecb1cb1beab5a5c92bb5076c30a58ef73e62
diff --git a/src/com/android/tradefed/device/TestDevice.java b/src/com/android/tradefed/device/TestDevice.java
index abe3310..45b8b70 100644
--- a/src/com/android/tradefed/device/TestDevice.java
+++ b/src/com/android/tradefed/device/TestDevice.java
@@ -80,6 +80,8 @@
     private static final String TEST_INPUT_CMD = "dumpsys input";
     static final String LIST_PACKAGES_CMD = "pm list packages -f";
     private static final Pattern PACKAGE_REGEX = Pattern.compile("package:(.*)=(.*)");
+    private static final Pattern PING_REGEX = Pattern.compile(
+            "(?<send>\\d+) packets transmitted, (?<recv>\\d+) received, (?<loss>\\d+)% packet loss");
     /** regex to match input dispatch readiness line **/
     static final Pattern INPUT_DISPATCH_STATE_REGEX =
             Pattern.compile("DispatchEnabled:\\s?([01])");
@@ -1743,12 +1745,23 @@
     }
 
     /**
-     * Check that device has network connectivity.
+     * {@inheritDoc}
      */
     @Override
     public boolean checkConnectivity() throws DeviceNotAvailableException {
-        final IWifiHelper wifi = createWifiHelper();
-        return wifi.checkConnectivity(mOptions.getConnCheckUrl());
+        final int pingLoss = getPingLoss();
+        return (0 <= pingLoss && pingLoss < 100);
+    }
+
+    int getPingLoss() throws DeviceNotAvailableException {
+        final String output = executeShellCommand(
+                "ping -c 1 -w 5 -s 1024 " + mOptions.getPingIpOrHost());
+        final Matcher stat = PING_REGEX.matcher(output);
+        if (stat.find()) {
+            return Integer.parseInt(stat.group("loss"));
+        }
+        // Return -1 if we failed to parse output.
+        return -1;
     }
 
     /**
diff --git a/tests/src/com/android/tradefed/device/TestDeviceTest.java b/tests/src/com/android/tradefed/device/TestDeviceTest.java
index 524874f..32619a6 100644
--- a/tests/src/com/android/tradefed/device/TestDeviceTest.java
+++ b/tests/src/com/android/tradefed/device/TestDeviceTest.java
@@ -1169,5 +1169,45 @@
         assertNotNull(mTestDevice.handleAllocationEvent(DeviceEvent.FREE_UNKNOWN));
         assertEquals(DeviceAllocationState.Unknown, mTestDevice.getAllocationState());
     }
+
+    public void testGetPingLoss() throws Exception {
+        final String pingCommand = "ping -c 1 -w 5 -s 1024 www.google.com";
+        injectShellResponse(pingCommand, ArrayUtil.join("\r\n",
+                "PING www.google.com (0.0.0.0) 1024(1052) bytes of data.",
+                "1032 bytes from www.google.com (0.0.0.0):" +
+                        "icmp_seq=1 ttl=52 time=74.1 ms",
+                "",
+                "--- www.google.com ping statistics ---",
+                "2 packets transmitted, 1 received, 50% packet loss, time 0ms"
+                ));
+        replayMocks();
+        assertEquals(50, mTestDevice.getPingLoss());
+    }
+
+    public void testCheckConnectivity() throws Exception {
+        final String pingCommand = "ping -c 1 -w 5 -s 1024 www.google.com";
+        injectShellResponse(pingCommand, ArrayUtil.join("\r\n",
+                "PING www.google.com (0.0.0.0) 1024(1052) bytes of data.",
+                "1032 bytes from www.google.com (0.0.0.0):" +
+                        "icmp_seq=1 ttl=52 time=74.1 ms",
+                "",
+                "--- www.google.com ping statistics ---",
+                "1 packets transmitted, 1 received, 0% packet loss, time 0ms"
+                ));
+        replayMocks();
+        assertTrue(mTestDevice.checkConnectivity());
+    }
+
+    public void testCheckConnectivity_NoConnectivity() throws Exception {
+        final String pingCommand = "ping -c 1 -w 5 -s 1024 www.google.com";
+        injectShellResponse(pingCommand, ArrayUtil.join("\r\n",
+                "PING www.google.com (0.0.0.0) 1024(1052) bytes of data.",
+                "",
+                "--- www.google.com ping statistics ---",
+                "1 packets transmitted, 0 received, 100% packet loss, time 0ms"
+                ));
+        replayMocks();
+        assertFalse(mTestDevice.checkConnectivity());
+    }
 }