BandwidthTest.java revision a8c57bf6adf3bdd477ce4d6ed8cca031c66830cd
133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang/*
233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Copyright (C) 2011, The Android Open Source Project
333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang *
433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Licensed under the Apache License, Version 2.0 (the "License");
533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * you may not use this file except in compliance with the License.
633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * You may obtain a copy of the License at
733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang *
833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang *      http://www.apache.org/licenses/LICENSE-2.0
933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang *
1033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Unless required by applicable law or agreed to in writing, software
1133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * distributed under the License is distributed on an "AS IS" BASIS,
1233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * See the License for the specific language governing permissions and
1433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * limitations under the License.
1533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */
1633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
1733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangpackage com.android.bandwidthtest;
1833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
1933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.Context;
2033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.ConnectivityManager;
2133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.NetworkInfo.State;
2233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.NetworkStats;
236951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuangimport android.net.NetworkStats.Entry;
2433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.TrafficStats;
2533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.wifi.WifiManager;
2633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.os.Bundle;
2733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.os.Environment;
2833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.os.Process;
2933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.os.SystemClock;
3033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.telephony.TelephonyManager;
3133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.test.InstrumentationTestCase;
3233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.test.suitebuilder.annotation.LargeTest;
3333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.util.Log;
3433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
3533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport com.android.bandwidthtest.util.BandwidthTestUtil;
3633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport com.android.bandwidthtest.util.ConnectionUtil;
3733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
3833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport java.io.File;
396951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuangimport java.util.HashMap;
406951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuangimport java.util.Map;
4133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
4233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang/**
4333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Test that downloads files from a test server and reports the bandwidth metrics collected.
4433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */
4533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangpublic class BandwidthTest extends InstrumentationTestCase {
4633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
4733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private static final String LOG_TAG = "BandwidthTest";
4833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String PROF_LABEL = "PROF_";
4933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String PROC_LABEL = "PROC_";
5033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static int INSTRUMENTATION_IN_PROGRESS = 2;
5133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
5233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String BASE_DIR =
5333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            Environment.getExternalStorageDirectory().getAbsolutePath();
5433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String TMP_FILENAME = "tmp.dat";
5533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    // Download 10.486 * 106 bytes (+ headers) from app engine test server.
5633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final int FILE_SIZE = 10485613;
5733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private Context mContext;
5833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private ConnectionUtil mConnectionUtil;
5933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private TelephonyManager mTManager;
6033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private int mUid;
6133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private String mSsid;
6233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private String mTestServer;
6333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private String mDeviceId;
6433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private BandwidthTestRunner mRunner;
6533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
6633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
6733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @Override
6833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    protected void setUp() throws Exception {
6933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        super.setUp();
7033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mRunner = (BandwidthTestRunner) getInstrumentation();
7133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mSsid = mRunner.mSsid;
7233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mTestServer = mRunner.mTestServer;
7333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mContext = mRunner.getTargetContext();
7433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil = new ConnectionUtil(mContext);
7533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil.initialize();
7633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Log.v(LOG_TAG, "Initialized mConnectionUtil");
7733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mUid = Process.myUid();
7833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mTManager = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
7933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mDeviceId = mTManager.getDeviceId();
8033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
8133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
8233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @Override
8333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    protected void tearDown() throws Exception {
8433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil.cleanUp();
8533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        super.tearDown();
8633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
8733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
8833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
8933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Ensure that downloading on wifi reports reasonable stats.
9033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
9133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @LargeTest
92163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    public void testWifiDownload() throws Exception {
93a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        mConnectionUtil.wifiTestInit();
94212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Could not connect to wifi!", setDeviceWifiAndAirplaneMode(mSsid));
95212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFile();
96212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
97212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
98212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
99212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Ensure that downloading on mobile reports reasonable stats.
100212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
101212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
102212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileDownload() throws Exception {
103212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        // As part of the setup we disconnected from wifi; make sure we are connected to mobile and
104212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        // that we have data.
105212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Do not have mobile data!", hasMobileData());
106212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFile();
107212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
108212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
109212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
110212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a file using http connection from a test server and reports the
111212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * data usage stats to instrumentation out.
112212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
113212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void downloadFile() throws Exception {
11433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(mUid);
11533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
11633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
11733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
11833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
11933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
12033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
12133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
12233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
1236951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
12433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
12533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(mUid);
12633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
12733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
12833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
129e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // the server.
130e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        Bundle results = new Bundle();
131e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putString("device_id", mDeviceId);
132e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putString("timestamp", ts);
133e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
134e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        AddStatsToResults(PROF_LABEL, prof_stats, results);
135e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        AddStatsToResults(PROC_LABEL, proc_stats, results);
136e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
137e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
138e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // Clean up.
139e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
140e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    }
141e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
142e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    /**
143212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Ensure that uploading on wifi reports reasonable stats.
144e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang     */
145e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    @LargeTest
146163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    public void testWifiUpload() throws Exception {
147a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        mConnectionUtil.wifiTestInit();
148e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
149212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        uploadFile();
150212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
151212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
152212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
153212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *  Ensure that uploading on wifi reports reasonable stats.
154212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
155212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
156212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileUpload() throws Exception {
157212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(hasMobileData());
158212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        uploadFile();
159212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
160212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
161212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
162212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a test file to upload. The stats reported to instrumentation out
163212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * only include upload stats.
164212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
165212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void uploadFile() throws Exception {
166e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // Download a file from the server.
167e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
168e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
169e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
170e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
171e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
172e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
173e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        ts = Long.toString(System.currentTimeMillis());
174e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(mUid);
175e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
176e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(BandwidthTestUtil.postFileToServer(mTestServer, mDeviceId, ts, tmpSaveFile));
177e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
178e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
179e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(mUid);
180e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
181e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
182e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
18333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // the server.
18433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Bundle results = new Bundle();
18533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("device_id", mDeviceId);
18633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("timestamp", ts);
18733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
18833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROF_LABEL, prof_stats, results);
18933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROC_LABEL, proc_stats, results);
19033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
19133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
19233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Clean up.
19333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
19433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
19533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
19633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
197212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * We want to make sure that if we use wifi and the  Download Manager to download stuff,
19833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * accounting still goes to the app making the call and that the numbers still make sense.
19933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
20033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @LargeTest
201163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    public void testWifiDownloadWithDownloadManager() throws Exception {
202a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        mConnectionUtil.wifiTestInit();
20333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
204212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFileUsingDownloadManager();
205212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
206212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
207212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
208212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * We want to make sure that if we use mobile data and the Download Manager to download stuff,
209212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * accounting still goes to the app making the call and that the numbers still make sense.
210212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
211212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
212212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileDownloadWithDownloadManager() throws Exception {
213212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(hasMobileData());
214212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFileUsingDownloadManager();
215212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
216212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
217212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
218212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a file from a test server using the download manager and reports
219212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * the stats to instrumentation out.
220212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
221212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void downloadFileUsingDownloadManager() throws Exception {
22233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // If we are using the download manager, then the data that is written to /proc/uid_stat/
22333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // is accounted against download manager's uid, since it uses pre-ICS API.
22433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int downloadManagerUid = mConnectionUtil.downloadManagerUid();
22533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(downloadManagerUid >= 0);
22633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(downloadManagerUid);
22733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // start profiling
22833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
22933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
23033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
23133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
23233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Log.v(LOG_TAG, "Download url: " + targetUrl);
23333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
23433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.startDownloadAndWait(targetUrl, 500000));
23533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
23633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(downloadManagerUid);
23733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
2386951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
23933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
24033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // the server.
24133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Bundle results = new Bundle();
24233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("device_id", mDeviceId);
24333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("timestamp", ts);
24433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
24533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROF_LABEL, prof_stats, results);
24633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROC_LABEL, proc_stats, results);
24733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
24833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
24933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Clean up.
25033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
25133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
25233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
25333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
25433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Fetch network data from /proc/uid_stat/uid
255212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
25633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return populated {@link NetworkStats}
25733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
25833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public NetworkStats fetchDataFromProc(int uid) {
25933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String root_filepath = "/proc/uid_stat/" + uid + "/";
26033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File rcv_stat = new File (root_filepath + "tcp_rcv");
26133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int rx = BandwidthTestUtil.parseIntValueFromFile(rcv_stat);
26233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File snd_stat = new File (root_filepath + "tcp_snd");
26333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
26433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
265b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
266b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                NetworkStats.TAG_NONE, rx, 0, tx, 0, 0);
26733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        return stats;
26833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
26933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
27033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
271212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Turn on Airplane mode and connect to the wifi.
272212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
27333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param ssid of the wifi to connect to
27433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return true if we successfully connected to a given network.
27533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
27633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public boolean setDeviceWifiAndAirplaneMode(String ssid) {
27733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil.setAirplaneMode(mContext, true);
27833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.connectToWifi(ssid));
27933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
28033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                ConnectionUtil.LONG_TIMEOUT));
281212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
282212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang                State.CONNECTED, ConnectionUtil.LONG_TIMEOUT));
283212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        return mConnectionUtil.hasData();
284212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
285212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
286212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
287212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method to make sure we are connected to mobile data.
288212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
289212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * @return true if we successfully connect to mobile data.
290212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
291212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public boolean hasMobileData() {
292a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        assertTrue(mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
293a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang                State.CONNECTED, ConnectionUtil.LONG_TIMEOUT));
294212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Not connected to mobile", mConnectionUtil.isConnectedToMobile());
295212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertFalse("Still connected to wifi.", mConnectionUtil.isConnectedToWifi());
296212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        return mConnectionUtil.hasData();
29733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
29833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
29933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
30033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Output the {@link NetworkStats} to Instrumentation out.
301212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
30233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param label to attach to this given stats.
30333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param stats {@link NetworkStats} to add.
30433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param results {@link Bundle} to be added to.
30533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
30633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public void AddStatsToResults(String label, NetworkStats stats, Bundle results){
30733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        if (results == null || results.isEmpty()) {
30833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            Log.e(LOG_TAG, "Empty bundle provided.");
30933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            return;
31033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        }
3116951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        // Merge stats across all sets.
3126951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Map<Integer, Entry> totalStats = new HashMap<Integer, Entry>();
31333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        for (int i = 0; i < stats.size(); ++i) {
3146951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            Entry statsEntry = stats.getValues(i, null);
3156951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            // We are only interested in the all inclusive stats.
3166951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            if (statsEntry.tag != 0) {
3176951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                continue;
3186951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            }
3196951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            Entry mapEntry = null;
3206951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            if (totalStats.containsKey(statsEntry.uid)) {
3216951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                mapEntry = totalStats.get(statsEntry.uid);
3226951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                switch (statsEntry.set) {
3236951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    case NetworkStats.SET_ALL:
3246951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.rxBytes = statsEntry.rxBytes;
3256951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.txBytes = statsEntry.txBytes;
3266951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        break;
3276951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    case NetworkStats.SET_DEFAULT:
3286951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    case NetworkStats.SET_FOREGROUND:
3296951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.rxBytes += statsEntry.rxBytes;
3306951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.txBytes += statsEntry.txBytes;
3316951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        break;
3326951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    default:
3336951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        Log.w(LOG_TAG, "Invalid state found in NetworkStats.");
3346951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                }
3356951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            } else {
3366951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                totalStats.put(statsEntry.uid, statsEntry);
3376951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            }
3386951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        }
3396951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        // Ouput merged stats to bundle.
3406951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        for (Entry entry : totalStats.values()) {
34133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            results.putInt(label + "uid", entry.uid);
34233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            results.putLong(label + "tx", entry.txBytes);
34333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            results.putLong(label + "rx", entry.rxBytes);
34433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        }
34533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
34633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
34733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
34833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Remove file if it exists.
34933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param file {@link File} to delete.
35033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return true if successfully deleted the file.
35133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
35233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private boolean cleanUpFile(File file) {
35333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        if (file.exists()) {
35433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            return file.delete();
35533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        }
35633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        return true;
35733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
358287353a78eb7b3a9b092efa7cbc77f7cb350d0f1Tsu Chiang Chuang}
359