140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen/*
240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * Copyright (C) 2010 The Android Open Source Project
340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *
440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * Licensed under the Apache License, Version 2.0 (the "License");
540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * you may not use this file except in compliance with the License.
640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * You may obtain a copy of the License at
740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *
840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *      http://www.apache.org/licenses/LICENSE-2.0
940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *
1040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * Unless required by applicable law or agreed to in writing, software
1140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * distributed under the License is distributed on an "AS IS" BASIS,
1240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * See the License for the specific language governing permissions and
1440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * limitations under the License.
1540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen */
1640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenpackage com.android.frameworks.downloadmanagertests;
1740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
1831fd85f39b554e09b2e6c1c2ccf5c186859880faSteve Howardimport android.app.DownloadManager;
1931fd85f39b554e09b2e6c1c2ccf5c186859880faSteve Howardimport android.app.DownloadManager.Request;
2040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.database.Cursor;
2140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.net.Uri;
2240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.os.Environment;
2340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.os.ParcelFileDescriptor;
2440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.util.Log;
2540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
2640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport java.io.DataInputStream;
2740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport java.io.DataOutputStream;
2840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport java.io.File;
2940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport java.io.FileInputStream;
3040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport java.io.FileOutputStream;
31df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyenimport java.util.HashSet;
3240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
3340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen/**
3440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * Class to test downloading files from a real (not mock) external server.
3540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen */
3640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenpublic class DownloadManagerTestApp extends DownloadManagerBaseTest {
3740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static String DOWNLOAD_STARTED_FLAG = "DMTEST_DOWNLOAD_STARTED";
3840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static String LOG_TAG =
3940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
4040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
4140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static String DOWNLOAD_500K_FILENAME = "External541kb.apk";
4240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static long DOWNLOAD_500K_FILESIZE = 570927;
4340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static String DOWNLOAD_1MB_FILENAME = "External1mb.apk";
4440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static long DOWNLOAD_1MB_FILESIZE = 1041262;
4565c36e6133be04e008bc164b62d42884ff06a13aNeal Nguyen    protected static String DOWNLOAD_5MB_FILENAME = "External5mb.apk";
4665c36e6133be04e008bc164b62d42884ff06a13aNeal Nguyen    protected static long DOWNLOAD_5MB_FILESIZE = 5138700;
4740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static String DOWNLOAD_10MB_FILENAME = "External10mb.apk";
4840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected static long DOWNLOAD_10MB_FILESIZE = 10258741;
4940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
50df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    private static final String FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX = "file";
51df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    private static final String FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION = ".bin";
52df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    protected static long CONCURRENT_DOWNLOAD_FILESIZE = 1000000;
53df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen
5440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    // Values to be obtained from TestRunner
5540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    private String externalDownloadUriValue = null;
56df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    private String externalLargeDownloadUriValue = null;
5740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
5840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
5940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * {@inheritDoc }
6040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
6140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    @Override
6240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void setUp() throws Exception {
6340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        super.setUp();
6440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation();
65df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        externalDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
6640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        assertNotNull(externalDownloadUriValue);
6740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
68df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        externalLargeDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
69df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        assertNotNull(externalLargeDownloadUriValue);
70df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    }
71df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen
72df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    /**
73df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     * Normalizes a uri to ensure it ends with a "/"
74df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     *
75df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     * @param uri The uri to normalize (or null)
76df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     * @return The normalized uri, or null if null was passed in
77df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     */
78df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    public String normalizeUri(String uri) {
79df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        if (uri != null && !uri.endsWith("/")) {
80df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen            uri += "/";
8140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
82df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        return uri;
8340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
8440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
8540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
8640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Gets the external URL of the file to download
8740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
8840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @return the Uri of the external file to download
8940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
9040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    private Uri getExternalFileUri(String file) {
9140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        return Uri.parse(externalDownloadUriValue + file);
9240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
9340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
9440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
9540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Gets the path to the file that flags that a download has started. The file contains the
9640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * DownloadManager id of the download being trackted between reboot sessions.
9740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
9840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @return The path of the file tracking that a download has started
9940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws InterruptedException if interrupted
10040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws Exception if timed out while waiting for SD card to mount
10140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
10240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected String getDownloadStartedFilePath() {
10340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String path = Environment.getExternalStorageDirectory().getPath();
10440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        return path + File.separatorChar + DOWNLOAD_STARTED_FLAG;
10540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
10640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
10740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
10840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Common setup steps for downloads.
10940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
11040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Note that these are not included in setUp, so that individual tests can control their own
11140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * state between reboots, etc.
11240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
11340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    protected void doCommonDownloadSetup() throws Exception {
11440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        setWiFiStateOn(true);
11540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        setAirplaneModeOn(false);
11640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        waitForExternalStoreMount();
11740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        removeAllCurrentDownloads();
11840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
11940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
12040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
12140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Initiates a download.
12240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
12340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Queues up a download to the download manager, and saves the DownloadManager's assigned
12440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * download ID for this download to a file.
12540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
12640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws Exception if unsuccessful
12740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
12840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void initiateDownload() throws Exception {
12965c36e6133be04e008bc164b62d42884ff06a13aNeal Nguyen        String filename = DOWNLOAD_5MB_FILENAME;
13040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
13140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        FileOutputStream fileOutput = mContext.openFileOutput(DOWNLOAD_STARTED_FLAG, 0);
13240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        DataOutputStream outputFile = null;
13340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        doCommonDownloadSetup();
13440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
13540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
13640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            long dlRequest = -1;
13740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
13840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Make sure there are no pending downloads currently going on
13940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            removeAllCurrentDownloads();
14040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
14140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Uri remoteUri = getExternalFileUri(filename);
14240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Request request = new Request(remoteUri);
14340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
14440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            dlRequest = mDownloadManager.enqueue(request);
14540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadToStart(dlRequest);
14640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            assertTrue(dlRequest != -1);
14740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
14840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Store ID of download for later retrieval
14940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            outputFile = new DataOutputStream(fileOutput);
15040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            outputFile.writeLong(dlRequest);
15140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
15240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (outputFile != null) {
15340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                outputFile.flush();
15440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                outputFile.close();
15540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
15640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
15740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
15840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
15940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
16040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Waits for a previously-initiated download and verifies it has completed successfully.
16140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
16240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws Exception if unsuccessful
16340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
16440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void verifyFileDownloadSucceeded() throws Exception {
16565c36e6133be04e008bc164b62d42884ff06a13aNeal Nguyen        String filename = DOWNLOAD_5MB_FILENAME;
16665c36e6133be04e008bc164b62d42884ff06a13aNeal Nguyen        long filesize = DOWNLOAD_5MB_FILESIZE;
16740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long dlRequest = -1;
16840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        boolean rebootMarkerValid = false;
16940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        DataInputStream dataInputFile = null;
17040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
17140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        setWiFiStateOn(true);
17240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        setAirplaneModeOn(false);
17340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
17440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
17540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            FileInputStream inFile = mContext.openFileInput(DOWNLOAD_STARTED_FLAG);
17640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            dataInputFile = new DataInputStream(inFile);
17740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            dlRequest = dataInputFile.readLong();
17840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } catch (Exception e) {
17940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // The file was't valid so we just leave the flag false
18040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Unable to determine initial download id.");
18140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            throw e;
18240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
18340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (dataInputFile != null) {
18440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                dataInputFile.close();
18540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
18640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
18740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
18840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
18940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        assertTrue(dlRequest != -1);
19040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        Cursor cursor = getCursor(dlRequest);
19140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        ParcelFileDescriptor pfd = null;
19240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
19340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            assertTrue("Unable to query last initiated download!", cursor.moveToFirst());
19440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
19540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
19640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            int status = cursor.getInt(columnIndex);
19740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            int currentWaitTime = 0;
19840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
19965c36e6133be04e008bc164b62d42884ff06a13aNeal Nguyen            // Wait until the download finishes; don't wait for a notification b/c
20065c36e6133be04e008bc164b62d42884ff06a13aNeal Nguyen            // the download may well have been completed before the last reboot.
201fbfe6d971d63860c02a71d69c3c7c29a2e958734Neal Nguyen            waitForDownloadOrTimeout_skipNotification(dlRequest);
20240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
20340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Verifying download information...");
20440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Verify specific info about the file (size, name, etc)...
20540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            pfd = mDownloadManager.openDownloadedFile(dlRequest);
20640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyFileSize(pfd, filesize);
20740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } catch (Exception e) {
20840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "error: " + e.toString());
20940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            throw e;
21040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
21140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Clean up...
21240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            cursor.close();
21340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            mDownloadManager.remove(dlRequest);
21440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (pfd != null) {
21540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                pfd.close();
21640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
21740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
21840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
21940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
22040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
22140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Tests downloading a large file over WiFi (~10 Mb).
22240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
22340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws Exception if unsuccessful
22440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
22540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void runLargeDownloadOverWiFi() throws Exception {
22640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String filename = DOWNLOAD_10MB_FILENAME;
22740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long filesize = DOWNLOAD_10MB_FILESIZE;
22840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long dlRequest = -1;
22940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        doCommonDownloadSetup();
23040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
23140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        // Make sure there are no pending downloads currently going on
23240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        removeAllCurrentDownloads();
23340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
23440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        Uri remoteUri = getExternalFileUri(filename);
23540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        Request request = new Request(remoteUri);
236b14ad8cc8cb0ed774072b077694b21fd0a6f33beJeff Sharkey        request.setMimeType("application/vnd.android.package-archive");
23740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
23840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        dlRequest = mDownloadManager.enqueue(request);
23940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
24040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        // Rather large file, so wait up to 15 mins...
24140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        waitForDownloadOrTimeout(dlRequest, WAIT_FOR_DOWNLOAD_POLL_TIME, 15 * 60 * 1000);
24240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
24340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        Cursor cursor = getCursor(dlRequest);
24440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        ParcelFileDescriptor pfd = null;
24540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
24640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Verifying download information...");
24740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Verify specific info about the file (size, name, etc)...
24840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            pfd = mDownloadManager.openDownloadedFile(dlRequest);
24940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyFileSize(pfd, filesize);
25040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
25140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (pfd != null) {
25240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                pfd.close();
25340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
25440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            mDownloadManager.remove(dlRequest);
25540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            cursor.close();
25640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
25740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
25840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
25940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
26040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Tests that downloads resume when switching back and forth from having connectivity to
26140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * having no connectivity using both WiFi and airplane mode.
26240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
26340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Note: Device has no mobile access when running this test.
26440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
26540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws Exception if unsuccessful
26640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
26740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void runDownloadMultipleSwitching() throws Exception {
26840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String filename = DOWNLOAD_500K_FILENAME;
26940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long filesize = DOWNLOAD_500K_FILESIZE;
27040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        doCommonDownloadSetup();
27140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
27240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
27340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        File downloadedFile = new File(localDownloadDirectory, filename);
27440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
27540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long dlRequest = -1;
27640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
27740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            downloadedFile.delete();
27840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
27940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Make sure there are no pending downloads currently going on
28040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            removeAllCurrentDownloads();
28140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
28240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Uri remoteUri = getExternalFileUri(filename);
28340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Request request = new Request(remoteUri);
28440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
28540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Local destination of downloaded file
28640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Uri localUri = Uri.fromFile(downloadedFile);
28740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
28840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            request.setDestinationUri(localUri);
28940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
29040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);
29140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
29240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            dlRequest = mDownloadManager.enqueue(request);
29340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadToStart(dlRequest);
29440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // make sure we're starting to download some data...
29540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForFileToGrow(downloadedFile);
29640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
29740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download disable
29840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(false);
29940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
30040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download disable
30140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning on airplane mode...");
30240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setAirplaneModeOn(true);
30340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(30 * 1000);  // wait 30 secs
30440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
30540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download disable
30640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(true);
30740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(30 * 1000);  // wait 30 secs
30840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
30940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download enable
31040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning off airplane mode...");
31140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setAirplaneModeOn(false);
31240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(5 * 1000);  // wait 5 seconds
31340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
31440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download disable
31540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning off WiFi...");
31640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(false);
31740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(30 * 1000);  // wait 30 secs
31840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
31940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // finally, turn WiFi back on and finish up the download
32040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning on WiFi...");
32140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(true);
32240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
32340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
32440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
32540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyFileSize(pfd, filesize);
32640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
32740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Cleaning up files...");
32840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (dlRequest != -1) {
32940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                mDownloadManager.remove(dlRequest);
33040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
33140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            downloadedFile.delete();
33240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
33340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
33440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
33540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
33640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Tests that downloads resume when switching on/off WiFi at various intervals.
33740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
33840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Note: Device has no mobile access when running this test.
33940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
34040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws Exception if unsuccessful
34140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
34240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void runDownloadMultipleWiFiEnableDisable() throws Exception {
34340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String filename = DOWNLOAD_500K_FILENAME;
34440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long filesize = DOWNLOAD_500K_FILESIZE;
34540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        doCommonDownloadSetup();
34640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
34740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
34840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        File downloadedFile = new File(localDownloadDirectory, filename);
34940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long dlRequest = -1;
35040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
35140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            downloadedFile.delete();
35240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
35340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Make sure there are no pending downloads currently going on
35440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            removeAllCurrentDownloads();
35540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
35640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Uri remoteUri = getExternalFileUri(filename);
35740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Request request = new Request(remoteUri);
35840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
35940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Local destination of downloaded file
36040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Uri localUri = Uri.fromFile(downloadedFile);
36140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
36240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            request.setDestinationUri(localUri);
36340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
36440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
36540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
36640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            dlRequest = mDownloadManager.enqueue(request);
36740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadToStart(dlRequest);
36840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // are we making any progress?
36940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForFileToGrow(downloadedFile);
37040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
37140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download disable
37240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning off WiFi...");
37340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(false);
37440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(40 * 1000);  // wait 40 seconds
37540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
37640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // enable download...
37740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning on WiFi again...");
37840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(true);
37940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForFileToGrow(downloadedFile);
38040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
38140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download disable
38240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning off WiFi...");
38340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(false);
38440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(20 * 1000);  // wait 20 seconds
38540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
38640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // enable download...
38740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning on WiFi again...");
38840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setWiFiStateOn(true);
38940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
39040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
39140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
39240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
39340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyFileSize(pfd, filesize);
39440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
39540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Cleaning up files...");
39640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (dlRequest != -1) {
39740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                mDownloadManager.remove(dlRequest);
39840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
39940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            downloadedFile.delete();
40040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
40140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
40240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
40340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
40440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Tests that downloads resume when switching on/off Airplane mode numerous times at
40540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * various intervals.
40640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
40740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Note: Device has no mobile access when running this test.
40840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     *
40940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * @throws Exception if unsuccessful
41040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
41140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void runDownloadMultipleAirplaneModeEnableDisable() throws Exception {
41240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String filename = DOWNLOAD_500K_FILENAME;
41340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long filesize = DOWNLOAD_500K_FILESIZE;
41440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        // make sure WiFi is enabled, and airplane mode is not on
41540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        doCommonDownloadSetup();
41640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
41740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
41840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        File downloadedFile = new File(localDownloadDirectory, filename);
41940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long dlRequest = -1;
42040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
42140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            downloadedFile.delete();
42240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
42340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Make sure there are no pending downloads currently going on
42440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            removeAllCurrentDownloads();
42540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
42640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Uri remoteUri = getExternalFileUri(filename);
42740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Request request = new Request(remoteUri);
42840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
42940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Local destination of downloaded file
43040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Uri localUri = Uri.fromFile(downloadedFile);
43140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
43240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            request.setDestinationUri(localUri);
43340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
43440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
43540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
43640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            dlRequest = mDownloadManager.enqueue(request);
43740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadToStart(dlRequest);
43840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // are we making any progress?
43940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForFileToGrow(downloadedFile);
44040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
44140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download disable
44240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning on Airplane mode...");
44340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setAirplaneModeOn(true);
44440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(60 * 1000);  // wait 1 minute
44540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
44640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // download enable
44740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning off Airplane mode...");
44840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setAirplaneModeOn(false);
44940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // make sure we're starting to download some data...
45040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForFileToGrow(downloadedFile);
45140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
45240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // reenable the connection to start up the download again
45340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning on Airplane mode again...");
45440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setAirplaneModeOn(true);
45540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Thread.sleep(20 * 1000);  // wait 20 seconds
45640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
45740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Finish up the download...
45840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Turning off Airplane mode again...");
45940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            setAirplaneModeOn(false);
46040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
46140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Waiting up to 3 minutes for donwload to complete...");
46240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadsOrTimeout(dlRequest, 180 * 1000);  // wait up to 3 mins before timeout
46340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
46440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyFileSize(pfd, filesize);
46540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
46640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Cleaning up files...");
46740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (dlRequest != -1) {
46840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                mDownloadManager.remove(dlRequest);
46940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
47040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            downloadedFile.delete();
47140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
47240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
473df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen
474df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    /**
475df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     * Tests 15 concurrent downloads of 1,000,000-byte files.
476df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     *
477df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     * @throws Exception if test failed
478df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen     */
479df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    public void runDownloadMultipleSimultaneously() throws Exception {
480df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        final int TOTAL_DOWNLOADS = 15;
481df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        HashSet<Long> downloadIds = new HashSet<Long>(TOTAL_DOWNLOADS);
482df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
483df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen
484df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        // Make sure there are no pending downloads currently going on
485df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        removeAllCurrentDownloads();
486df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen
487df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        try {
488df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen            for (int i = 0; i < TOTAL_DOWNLOADS; ++i) {
489df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                long dlRequest = -1;
490df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                String filename = FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX + i
491df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                        + FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION;
492df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                Uri remoteUri = getExternalFileUri(filename);
493df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                Request request = new Request(remoteUri);
494df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                request.setTitle(filename);
495df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                dlRequest = mDownloadManager.enqueue(request);
496df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                assertTrue(dlRequest != -1);
497df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen                downloadIds.add(dlRequest);
498df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen            }
499df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen
500df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen            waitForDownloadsOrTimeout(DEFAULT_WAIT_POLL_TIME, 15 * 60 * 2000);  // wait 15 mins max
501df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen            assertEquals(TOTAL_DOWNLOADS, receiver.numDownloadsCompleted());
502df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        } finally {
503df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen            removeAllCurrentDownloads();
504df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen        }
505df7a865bbf45b57c60d294d5ac721e67e69a2dd6Neal Nguyen    }
50640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen}
507