Adding mobile microbenchmark tests.

Change-Id: Ifcd67b0265045778965aeff8e213c3929da02c3d
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 9eee2f0..feea364 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -89,8 +89,27 @@
      * Ensure that downloading on wifi reports reasonable stats.
      */
     @LargeTest
-    public void testWifiDownload() {
-        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+    public void testWifiDownload() throws Exception {
+        assertTrue("Could not connect to wifi!", setDeviceWifiAndAirplaneMode(mSsid));
+        downloadFile();
+    }
+
+    /**
+     * Ensure that downloading on mobile reports reasonable stats.
+     */
+    @LargeTest
+    public void testMobileDownload() throws Exception {
+        // As part of the setup we disconnected from wifi; make sure we are connected to mobile and
+        // that we have data.
+        assertTrue("Do not have mobile data!", hasMobileData());
+        downloadFile();
+    }
+
+    /**
+     * Helper method that downloads a file using http connection from a test server and reports the
+     * data usage stats to instrumentation out.
+     */
+    protected void downloadFile() throws Exception {
         NetworkStats pre_test_stats = fetchDataFromProc(mUid);
         String ts = Long.toString(System.currentTimeMillis());
 
@@ -120,11 +139,28 @@
     }
 
     /**
-     * Ensure that downloading on wifi reports reasonable stats.
+     * Ensure that uploading on wifi reports reasonable stats.
      */
     @LargeTest
     public void testWifiUpload() {
         assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+        uploadFile();
+    }
+
+    /**
+     *  Ensure that uploading on wifi reports reasonable stats.
+     */
+    @LargeTest
+    public void testMobileUpload() throws Exception {
+        assertTrue(hasMobileData());
+        uploadFile();
+    }
+
+    /**
+     * Helper method that downloads a test file to upload. The stats reported to instrumentation out
+     * only include upload stats.
+     */
+    protected void uploadFile() throws Exception {
         // Download a file from the server.
         String ts = Long.toString(System.currentTimeMillis());
         String targetUrl = BandwidthTestUtil.buildDownloadUrl(
@@ -156,12 +192,30 @@
     }
 
     /**
-     * We want to make sure that if we use the Download Manager to download stuff,
+     * We want to make sure that if we use wifi and the  Download Manager to download stuff,
      * accounting still goes to the app making the call and that the numbers still make sense.
      */
     @LargeTest
     public void testWifiDownloadWithDownloadManager() {
         assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+        downloadFileUsingDownloadManager();
+    }
+
+    /**
+     * We want to make sure that if we use mobile data and the Download Manager to download stuff,
+     * accounting still goes to the app making the call and that the numbers still make sense.
+     */
+    @LargeTest
+    public void testMobileDownloadWithDownloadManager() throws Exception {
+        assertTrue(hasMobileData());
+        downloadFileUsingDownloadManager();
+    }
+
+    /**
+     * Helper method that downloads a file from a test server using the download manager and reports
+     * the stats to instrumentation out.
+     */
+    protected void downloadFileUsingDownloadManager() throws Exception {
         // If we are using the download manager, then the data that is written to /proc/uid_stat/
         // is accounted against download manager's uid, since it uses pre-ICS API.
         int downloadManagerUid = mConnectionUtil.downloadManagerUid();
@@ -195,6 +249,7 @@
 
     /**
      * Fetch network data from /proc/uid_stat/uid
+     *
      * @return populated {@link NetworkStats}
      */
     public NetworkStats fetchDataFromProc(int uid) {
@@ -210,7 +265,8 @@
     }
 
     /**
-     * Turn on Airplane mode and connect to the wifi
+     * Turn on Airplane mode and connect to the wifi.
+     *
      * @param ssid of the wifi to connect to
      * @return true if we successfully connected to a given network.
      */
@@ -219,12 +275,25 @@
         assertTrue(mConnectionUtil.connectToWifi(ssid));
         assertTrue(mConnectionUtil.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectionUtil.LONG_TIMEOUT));
-        return mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectionUtil.LONG_TIMEOUT);
+        assertTrue(mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
+                State.CONNECTED, ConnectionUtil.LONG_TIMEOUT));
+        return mConnectionUtil.hasData();
+    }
+
+    /**
+     * Helper method to make sure we are connected to mobile data.
+     *
+     * @return true if we successfully connect to mobile data.
+     */
+    public boolean hasMobileData() {
+        assertTrue("Not connected to mobile", mConnectionUtil.isConnectedToMobile());
+        assertFalse("Still connected to wifi.", mConnectionUtil.isConnectedToWifi());
+        return mConnectionUtil.hasData();
     }
 
     /**
      * Output the {@link NetworkStats} to Instrumentation out.
+     *
      * @param label to attach to this given stats.
      * @param stats {@link NetworkStats} to add.
      * @param results {@link Bundle} to be added to.
@@ -281,4 +350,4 @@
         }
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
index d663aad..a5e5ab0e 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
@@ -44,6 +44,8 @@
 import com.android.bandwidthtest.NetworkState.StateTransitionDirection;
 import com.android.internal.util.AsyncChannel;
 
+import java.io.IOException;
+import java.net.UnknownHostException;
 import java.util.List;
 
 /*
@@ -257,14 +259,14 @@
         mConnectivityState[networkType].recordState(networkState);
     }
 
-   /**
-    * Set the state transition criteria
-    *
-    * @param networkType
-    * @param initState
-    * @param transitionDir
-    * @param targetState
-    */
+    /**
+     * Set the state transition criteria
+     *
+     * @param networkType
+     * @param initState
+     * @param transitionDir
+     * @param targetState
+     */
     public void setStateTransitionCriteria(int networkType, State initState,
             StateTransitionDirection transitionDir, State targetState) {
         mConnectivityState[networkType].setStateTransitionCriteria(
@@ -495,7 +497,8 @@
      * @return true if connected to a mobile network, false otherwise.
      */
     public boolean isConnectedToMobile() {
-        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
+        NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        return networkInfo.isConnected();
     }
 
     /**
@@ -503,10 +506,10 @@
      * @return true if connected to wifi, false otherwise.
      */
     public boolean isConnectedToWifi() {
-        return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
+        NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        return networkInfo.isConnected();
     }
 
-
     /**
      * Associate the device to given SSID
      * If the device is already associated with a WiFi, disconnect and forget it,
@@ -681,4 +684,30 @@
         }
         Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
     }
+
+    /**
+     * Helper method used to test data connectivity by pinging a series of popular sites.
+     * @return true if device has data connectivity, false otherwise.
+     */
+    public boolean hasData() {
+        String[] hostList = {"www.google.com", "www.yahoo.com",
+                "www.bing.com", "www.facebook.com", "www.ask.com"};
+        try {
+            for (int i = 0; i < hostList.length; ++i) {
+                String host = hostList[i];
+                Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
+                int status = p.waitFor();
+                if (status == 0) {
+                    return true;
+                }
+            }
+        } catch (UnknownHostException e) {
+            Log.e(LOG_TAG, "Ping test Failed: Unknown Host");
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Ping test Failed: IOException");
+        } catch (InterruptedException e) {
+            Log.e(LOG_TAG, "Ping test Failed: InterruptedException");
+        }
+        return false;
+    }
 }
\ No newline at end of file