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;
3933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
4033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang/**
4133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Test that downloads files from a test server and reports the bandwidth metrics collected.
4233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */
4333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangpublic class BandwidthTest extends InstrumentationTestCase {
4433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
4533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private static final String LOG_TAG = "BandwidthTest";
4633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String PROF_LABEL = "PROF_";
4733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String PROC_LABEL = "PROC_";
4833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static int INSTRUMENTATION_IN_PROGRESS = 2;
4933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
5033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String BASE_DIR =
5133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            Environment.getExternalStorageDirectory().getAbsolutePath();
5233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final static String TMP_FILENAME = "tmp.dat";
5333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    // Download 10.486 * 106 bytes (+ headers) from app engine test server.
5433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private final int FILE_SIZE = 10485613;
5533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private Context mContext;
5633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private ConnectionUtil mConnectionUtil;
5733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private TelephonyManager mTManager;
5833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private int mUid;
5933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private String mSsid;
6033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private String mTestServer;
6133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private String mDeviceId;
6233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private BandwidthTestRunner mRunner;
6333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
6433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
6533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @Override
6633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    protected void setUp() throws Exception {
6733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        super.setUp();
6833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mRunner = (BandwidthTestRunner) getInstrumentation();
6933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mSsid = mRunner.mSsid;
7033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mTestServer = mRunner.mTestServer;
7133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mContext = mRunner.getTargetContext();
7233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil = new ConnectionUtil(mContext);
7333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil.initialize();
7433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Log.v(LOG_TAG, "Initialized mConnectionUtil");
7533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mUid = Process.myUid();
7633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mTManager = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
7733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mDeviceId = mTManager.getDeviceId();
7833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
7933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
8033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @Override
8133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    protected void tearDown() throws Exception {
8233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil.cleanUp();
8333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        super.tearDown();
8433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
8533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
8633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
8733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Ensure that downloading on wifi reports reasonable stats.
8833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
8933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    @LargeTest
90163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    public void testWifiDownload() throws Exception {
91a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        mConnectionUtil.wifiTestInit();
92212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Could not connect to wifi!", setDeviceWifiAndAirplaneMode(mSsid));
93212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFile();
94212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
95212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
96212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
97212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Ensure that downloading on mobile reports reasonable stats.
98212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
99212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
100212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileDownload() throws Exception {
101212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        // As part of the setup we disconnected from wifi; make sure we are connected to mobile and
102212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        // that we have data.
103212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Do not have mobile data!", hasMobileData());
104212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFile();
105212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
106212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
107212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
108212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a file using http connection from a test server and reports the
109212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * data usage stats to instrumentation out.
110212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
111212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void downloadFile() throws Exception {
11233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(mUid);
11333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
11433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
11533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
11633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
11733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
11833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
11933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
12033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
1216951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
12233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
12333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(mUid);
12433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
12533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
12633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
127e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // the server.
128e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        Bundle results = new Bundle();
129e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putString("device_id", mDeviceId);
130e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putString("timestamp", ts);
131e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
132ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        addStatsToResults(PROF_LABEL, prof_stats, results, mUid);
133ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        addStatsToResults(PROC_LABEL, proc_stats, results, mUid);
134e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
135e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
136e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        // Clean up.
137e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
138e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    }
139e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang
140e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    /**
141212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Ensure that uploading on wifi reports reasonable stats.
142e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang     */
143e888685bf6f443b7d69601796a7896240a7fc4eeTsu Chiang Chuang    @LargeTest
144163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    public void testWifiUpload() throws Exception {
145a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        mConnectionUtil.wifiTestInit();
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);
186ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        addStatsToResults(PROF_LABEL, prof_stats, results, mUid);
187ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        addStatsToResults(PROC_LABEL, proc_stats, results, mUid);
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 {
200a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        mConnectionUtil.wifiTestInit();
20133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
202212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFileUsingDownloadManager();
203212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
204212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
205212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
206212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * We want to make sure that if we use mobile data and the Download Manager to download stuff,
207212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * accounting still goes to the app making the call and that the numbers still make sense.
208212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
209212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    @LargeTest
210212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public void testMobileDownloadWithDownloadManager() throws Exception {
211212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(hasMobileData());
212212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        downloadFileUsingDownloadManager();
213212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
214212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
215212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
216212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method that downloads a file from a test server using the download manager and reports
217212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * the stats to instrumentation out.
218212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
219212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    protected void downloadFileUsingDownloadManager() throws Exception {
22033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // If we are using the download manager, then the data that is written to /proc/uid_stat/
22133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // is accounted against download manager's uid, since it uses pre-ICS API.
22233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int downloadManagerUid = mConnectionUtil.downloadManagerUid();
22333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(downloadManagerUid >= 0);
22433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats pre_test_stats = fetchDataFromProc(downloadManagerUid);
22533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // start profiling
22633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        TrafficStats.startDataProfiling(mContext);
22733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String ts = Long.toString(System.currentTimeMillis());
22833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
22933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                mTestServer, FILE_SIZE, mDeviceId, ts);
23033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Log.v(LOG_TAG, "Download url: " + targetUrl);
23133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
23233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.startDownloadAndWait(targetUrl, 500000));
23333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
23433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats post_test_stats = fetchDataFromProc(downloadManagerUid);
23533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
2366951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        Log.d(LOG_TAG, prof_stats.toString());
23733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Output measurements to instrumentation out, so that it can be compared to that of
23833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // the server.
23933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        Bundle results = new Bundle();
24033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("device_id", mDeviceId);
24133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putString("timestamp", ts);
24233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        results.putInt("size", FILE_SIZE);
243ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        addStatsToResults(PROF_LABEL, prof_stats, results, mUid);
244ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        // remember to use download manager uid for proc stats
245ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        addStatsToResults(PROC_LABEL, proc_stats, results, downloadManagerUid);
24633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
24733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
24833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        // Clean up.
24933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(cleanUpFile(tmpSaveFile));
25033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
25133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
25233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
25333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Fetch network data from /proc/uid_stat/uid
254212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
25533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return populated {@link NetworkStats}
25633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
25733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public NetworkStats fetchDataFromProc(int uid) {
25833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        String root_filepath = "/proc/uid_stat/" + uid + "/";
25933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File rcv_stat = new File (root_filepath + "tcp_rcv");
26033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int rx = BandwidthTestUtil.parseIntValueFromFile(rcv_stat);
26133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        File snd_stat = new File (root_filepath + "tcp_snd");
26233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
26333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
264b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
265b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                NetworkStats.TAG_NONE, rx, 0, tx, 0, 0);
26633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        return stats;
26733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
26833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
26933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
270212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Turn on Airplane mode and connect to the wifi.
271212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
27233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param ssid of the wifi to connect to
27333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return true if we successfully connected to a given network.
27433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
27533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    public boolean setDeviceWifiAndAirplaneMode(String ssid) {
27633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        mConnectionUtil.setAirplaneMode(mContext, true);
27733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.connectToWifi(ssid));
27833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        assertTrue(mConnectionUtil.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
27933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang                ConnectionUtil.LONG_TIMEOUT));
280212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue(mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
281212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang                State.CONNECTED, ConnectionUtil.LONG_TIMEOUT));
282212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        return mConnectionUtil.hasData();
283212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    }
284212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang
285212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    /**
286212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * Helper method to make sure we are connected to mobile data.
287212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
288212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     * @return true if we successfully connect to mobile data.
289212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     */
290212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang    public boolean hasMobileData() {
291a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang        assertTrue(mConnectionUtil.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
292a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang                State.CONNECTED, ConnectionUtil.LONG_TIMEOUT));
293212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertTrue("Not connected to mobile", mConnectionUtil.isConnectedToMobile());
294212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        assertFalse("Still connected to wifi.", mConnectionUtil.isConnectedToWifi());
295212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang        return mConnectionUtil.hasData();
29633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
29733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
29833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
29933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Output the {@link NetworkStats} to Instrumentation out.
300212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang     *
30133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param label to attach to this given stats.
30233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param stats {@link NetworkStats} to add.
30333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param results {@link Bundle} to be added to.
304ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine     * @param uid for which to report the results.
30533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
306ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine    public void addStatsToResults(String label, NetworkStats stats, Bundle results, int uid){
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        }
311ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        Entry totalStats = null;
31233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        for (int i = 0; i < stats.size(); ++i) {
3136951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            Entry statsEntry = stats.getValues(i, null);
3146951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            // We are only interested in the all inclusive stats.
3156951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            if (statsEntry.tag != 0) {
3166951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang                continue;
3176951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            }
318ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine            // skip stats for other uids
319ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine            if (statsEntry.uid != uid) {
320ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine                continue;
321ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine            }
322ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine            if (totalStats == null || statsEntry.set == NetworkStats.SET_ALL) {
323ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine                totalStats = statsEntry;
3246951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            } else {
325ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine                totalStats.rxBytes += statsEntry.rxBytes;
326ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine                totalStats.txBytes += statsEntry.txBytes;
3276951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang            }
3286951b1b421fc39b85b0d7010f9b0da291228ef8fTsu Chiang Chuang        }
329ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        // Output merged stats to bundle.
330ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        results.putInt(label + "uid", totalStats.uid);
331ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        results.putLong(label + "tx", totalStats.txBytes);
332ca76692417aad438f816a9a57059e9aea445f2d4Maxim Siniavine        results.putLong(label + "rx", totalStats.rxBytes);
33333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
33433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang
33533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    /**
33633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * Remove file if it exists.
33733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @param file {@link File} to delete.
33833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     * @return true if successfully deleted the file.
33933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang     */
34033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    private boolean cleanUpFile(File file) {
34133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        if (file.exists()) {
34233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang            return file.delete();
34333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        }
34433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang        return true;
34533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang    }
346287353a78eb7b3a9b092efa7cbc77f7cb350d0f1Tsu Chiang Chuang}
347