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 {
93212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Could not connect to wifi!", setDeviceWifiAndAirplaneMode(mSsid));
94212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFile();
95212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
96212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
97212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
98212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Ensure that downloading on mobile reports reasonable stats.
99212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
100212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
101212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileDownload() throws Exception {
102212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        // As part of the setup we disconnected from wifi; make sure we are connected to mobile and
103212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        // that we have data.
104212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Do not have mobile data!", hasMobileData());
105212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFile();
106212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
107212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
108212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
109212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a file using http connection from a test server and reports the
110212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * data usage stats to instrumentation out.
111212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
112212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void downloadFile() throws Exception {
11333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(mUid);
11433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
11533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
11633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
11733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
11833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
11933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
12033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
12133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
1226951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
12333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
12433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(mUid);
12533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
12633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
12733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
128e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // the server.
129e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        Bundle results = new Bundle();
130e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putString("device_id", mDeviceId);
131e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putString("timestamp", ts);
132e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
133e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        AddStatsToResults(PROF_LABEL, prof_stats, results);
134e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        AddStatsToResults(PROC_LABEL, proc_stats, results);
135e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
136e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
137e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // Clean up.
138e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
139e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    }
140e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
141e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    /**
142212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Ensure that uploading on wifi reports reasonable stats.
143e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang     */
144e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    @LargeTest
145163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    public void testWifiUpload() throws Exception {
146e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
147212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        uploadFile();
148212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
149212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
150212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
151212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *  Ensure that uploading on wifi reports reasonable stats.
152212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
153212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
154212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileUpload() throws Exception {
155212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(hasMobileData());
156212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        uploadFile();
157212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
158212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
159212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
160212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a test file to upload. The stats reported to instrumentation out
161212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * only include upload stats.
162212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
163212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void uploadFile() throws Exception {
164e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // Download a file from the server.
165e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
166e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
167e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
168e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
169e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
170e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
171e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        ts = Long.toString(System.currentTimeMillis());
172e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(mUid);
173e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
174e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(BandwidthTestUtil.postFileToServer(mTestServer, mDeviceId, ts, tmpSaveFile));
175e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
176e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
177e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(mUid);
178e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
179e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
180e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
18133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // the server.
18233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Bundle results = new Bundle();
18333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("device_id", mDeviceId);
18433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("timestamp", ts);
18533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
18633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROF_LABEL, prof_stats, results);
18733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROC_LABEL, proc_stats, results);
18833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
18933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
19033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Clean up.
19133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
19233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
19333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
19433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
195212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * We want to make sure that if we use wifi and the  Download Manager to download stuff,
19633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * accounting still goes to the app making the call and that the numbers still make sense.
19733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
19833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @LargeTest
199163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    public void testWifiDownloadWithDownloadManager() throws Exception {
20033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
201212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFileUsingDownloadManager();
202212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
203212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
204212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
205212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * We want to make sure that if we use mobile data and the Download Manager to download stuff,
206212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * accounting still goes to the app making the call and that the numbers still make sense.
207212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
208212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
209212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileDownloadWithDownloadManager() throws Exception {
210212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(hasMobileData());
211212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFileUsingDownloadManager();
212212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
213212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
214212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
215212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a file from a test server using the download manager and reports
216212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * the stats to instrumentation out.
217212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
218212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void downloadFileUsingDownloadManager() throws Exception {
21933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // If we are using the download manager, then the data that is written to /proc/uid_stat/
22033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // is accounted against download manager's uid, since it uses pre-ICS API.
22133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int downloadManagerUid = mConnectionUtil.downloadManagerUid();
22233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(downloadManagerUid >= 0);
22333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(downloadManagerUid);
22433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // start profiling
22533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
22633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
22733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
22833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
22933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Log.v(LOG_TAG, "Download url: " + targetUrl);
23033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
23133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.startDownloadAndWait(targetUrl, 500000));
23233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
23333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(downloadManagerUid);
23433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
2356951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
23633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
23733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // the server.
23833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Bundle results = new Bundle();
23933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("device_id", mDeviceId);
24033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("timestamp", ts);
24133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
24233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROF_LABEL, prof_stats, results);
24333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        AddStatsToResults(PROC_LABEL, proc_stats, results);
24433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
24533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
24633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Clean up.
24733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
24833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
24933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
25033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
25133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Fetch network data from /proc/uid_stat/uid
252212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
25333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return populated {@link NetworkStats}
25433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
25533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public NetworkStats fetchDataFromProc(int uid) {
25633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String root_filepath = "/proc/uid_stat/" + uid + "/";
25733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File rcv_stat = new File (root_filepath + "tcp_rcv");
25833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int rx = BandwidthTestUtil.parseIntValueFromFile(rcv_stat);
25933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File snd_stat = new File (root_filepath + "tcp_snd");
26033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
26133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
262b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
263b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                NetworkStats.TAG_NONE, rx, 0, tx, 0, 0);
26433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        return stats;
26533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
26633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
26733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
268212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Turn on Airplane mode and connect to the wifi.
269212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
27033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param ssid of the wifi to connect to
27133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return true if we successfully connected to a given network.
27233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
27333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public boolean setDeviceWifiAndAirplaneMode(String ssid) {
27433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil.setAirplaneMode(mContext, true);
27533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.connectToWifi(ssid));
27633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
27733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                ConnectionUtil.LONG_TIMEOUT));
278212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
279212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang                State.CONNECTED, ConnectionUtil.LONG_TIMEOUT));
280212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        return mConnectionUtil.hasData();
281212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
282212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
283212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
284212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method to make sure we are connected to mobile data.
285212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
286212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * @return true if we successfully connect to mobile data.
287212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
288212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public boolean hasMobileData() {
289212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Not connected to mobile", mConnectionUtil.isConnectedToMobile());
290212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertFalse("Still connected to wifi.", mConnectionUtil.isConnectedToWifi());
291212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        return mConnectionUtil.hasData();
29233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
29333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
29433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
29533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Output the {@link NetworkStats} to Instrumentation out.
296212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
29733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param label to attach to this given stats.
29833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param stats {@link NetworkStats} to add.
29933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param results {@link Bundle} to be added to.
30033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
30133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public void AddStatsToResults(String label, NetworkStats stats, Bundle results){
30233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        if (results == null || results.isEmpty()) {
30333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            Log.e(LOG_TAG, "Empty bundle provided.");
30433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            return;
30533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        }
3066951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        // Merge stats across all sets.
3076951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Map<Integer, Entry> totalStats = new HashMap<Integer, Entry>();
30833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        for (int i = 0; i < stats.size(); ++i) {
3096951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            Entry statsEntry = stats.getValues(i, null);
3106951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            // We are only interested in the all inclusive stats.
3116951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            if (statsEntry.tag != 0) {
3126951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                continue;
3136951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            }
3146951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            Entry mapEntry = null;
3156951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            if (totalStats.containsKey(statsEntry.uid)) {
3166951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                mapEntry = totalStats.get(statsEntry.uid);
3176951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                switch (statsEntry.set) {
3186951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    case NetworkStats.SET_ALL:
3196951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.rxBytes = statsEntry.rxBytes;
3206951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.txBytes = statsEntry.txBytes;
3216951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        break;
3226951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    case NetworkStats.SET_DEFAULT:
3236951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    case NetworkStats.SET_FOREGROUND:
3246951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.rxBytes += statsEntry.rxBytes;
3256951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        mapEntry.txBytes += statsEntry.txBytes;
3266951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        break;
3276951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                    default:
3286951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                        Log.w(LOG_TAG, "Invalid state found in NetworkStats.");
3296951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                }
3306951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            } else {
3316951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                totalStats.put(statsEntry.uid, statsEntry);
3326951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            }
3336951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        }
3346951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        // Ouput merged stats to bundle.
3356951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        for (Entry entry : totalStats.values()) {
33633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            results.putInt(label + "uid", entry.uid);
33733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            results.putLong(label + "tx", entry.txBytes);
33833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            results.putLong(label + "rx", entry.rxBytes);
33933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        }
34033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
34133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
34233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
34333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Remove file if it exists.
34433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param file {@link File} to delete.
34533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return true if successfully deleted the file.
34633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
34733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private boolean cleanUpFile(File file) {
34833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        if (file.exists()) {
34933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            return file.delete();
35033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        }
35133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        return true;
35233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
353287353a78eb7b3a9b092efa7cbc77f7cb350d0f1Tsu Chiang Chuang}
354