182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori/*
282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Copyright (C) 2010 The Android Open Source Project
382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori *
482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Licensed under the Apache License, Version 2.0 (the "License");
582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * you may not use this file except in compliance with the License.
682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * You may obtain a copy of the License at
782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori *
882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori *      http://www.apache.org/licenses/LICENSE-2.0
982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori *
1082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Unless required by applicable law or agreed to in writing, software
1182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * distributed under the License is distributed on an "AS IS" BASIS,
1282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * See the License for the specific language governing permissions and
1482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * limitations under the License.
1582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */
1682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
1782e891b3259350a92b55969a6380ca1240ee0829Vasu Noripackage com.android.frameworks.downloadmanagertests;
1882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
1982e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.app.DownloadManager;
2082e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.app.DownloadManager.Query;
2182e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.app.DownloadManager.Request;
2282e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.content.BroadcastReceiver;
2382e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.content.Context;
2482e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.content.Intent;
2582e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.content.IntentFilter;
2682e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.database.Cursor;
2782e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.net.ConnectivityManager;
2882e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.net.NetworkInfo;
2982e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.net.Uri;
3082e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.net.wifi.WifiManager;
3182e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.Bundle;
3282e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.Environment;
3382e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.ParcelFileDescriptor;
3482e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.SystemClock;
3582e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.ParcelFileDescriptor.AutoCloseInputStream;
3682e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.provider.Settings;
3782e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.test.InstrumentationTestCase;
3882e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.util.Log;
3982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
4082e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.io.DataInputStream;
4182e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.io.DataOutputStream;
4282e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.io.File;
4382e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.io.FileInputStream;
4482e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.io.FileOutputStream;
4582e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.io.IOException;
4682e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.net.URL;
4782e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.concurrent.TimeoutException;
4882e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.Collections;
4982e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.HashSet;
5082e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.Iterator;
5182e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.List;
5282e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.Random;
5382e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.Set;
5482e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.Vector;
5582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
5682e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport junit.framework.AssertionFailedError;
5782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
5882e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport coretestutils.http.MockResponse;
5982e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport coretestutils.http.MockWebServer;
6082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
6182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori/**
6282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Base class for Instrumented tests for the Download Manager.
6382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */
6482e891b3259350a92b55969a6380ca1240ee0829Vasu Noripublic class DownloadManagerBaseTest extends InstrumentationTestCase {
6582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
6682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected DownloadManager mDownloadManager = null;
6782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected MockWebServer mServer = null;
6882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected String mFileType = "text/plain";
6982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected Context mContext = null;
7082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected MultipleDownloadsCompletedReceiver mReceiver = null;
7182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int DEFAULT_FILE_SIZE = 10 * 1024;  // 10kb
7282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024;
7382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
7482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final String LOG_TAG = "android.net.DownloadManagerBaseTest";
7582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int HTTP_OK = 200;
7682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int HTTP_REDIRECT = 307;
7782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int HTTP_PARTIAL_CONTENT = 206;
7882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int HTTP_NOT_FOUND = 404;
7982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int HTTP_SERVICE_UNAVAILABLE = 503;
8082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected String DEFAULT_FILENAME = "somefile.txt";
8182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
8282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int DEFAULT_MAX_WAIT_TIME = 2 * 60 * 1000;  // 2 minutes
8382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int DEFAULT_WAIT_POLL_TIME = 5 * 1000;  // 5 seconds
8482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
8582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int WAIT_FOR_DOWNLOAD_POLL_TIME = 1 * 1000;  // 1 second
8682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
8782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes
8882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
8982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int DOWNLOAD_TO_SYSTEM_CACHE = 1;
9082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected static final int DOWNLOAD_TO_DOWNLOAD_CACHE_DIR = 2;
9182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
9282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    // Just a few popular file types used to return from a download
9382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected enum DownloadFileType {
9482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        PLAINTEXT,
9582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        APK,
9682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        GIF,
9782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        GARBAGE,
9882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        UNRECOGNIZED,
9982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        ZIP
10082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
10182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
10282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected enum DataType {
10382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        TEXT,
10482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        BINARY
10582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
10682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
10782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    public static class LoggingRng extends Random {
10882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
10982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
11082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Constructor
11182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         *
11282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Creates RNG with self-generated seed value.
11382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
11482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public LoggingRng() {
11582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            this(SystemClock.uptimeMillis());
11682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
11782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
11882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
11982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Constructor
12082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         *
12182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Creats RNG with given initial seed value
12282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
12382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * @param seed The initial seed value
12482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
12582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public LoggingRng(long seed) {
12682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            super(seed);
12782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            Log.i(LOG_TAG, "Seeding RNG with value: " + seed);
12882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
12982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
13082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
13182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
13282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        private volatile int mNumDownloadsCompleted = 0;
13382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());
13482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
13582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
13682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * {@inheritDoc}
13782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
13882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        @Override
13982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public void onReceive(Context context, Intent intent) {
14082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            if (intent.getAction().equalsIgnoreCase(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
14182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                synchronized(this) {
14282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
14382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    Log.i(LOG_TAG, "Received Notification for download: " + id);
14482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    if (!downloadIds.contains(id)) {
14582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        ++mNumDownloadsCompleted;
14682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
14782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                                intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
14882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        downloadIds.add(id);
14982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
15082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        DownloadManager dm = (DownloadManager)context.getSystemService(
15182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                                Context.DOWNLOAD_SERVICE);
15282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
15382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        Cursor cursor = dm.query(new Query().setFilterById(id));
15482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        try {
15582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                            if (cursor.moveToFirst()) {
15682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                                int status = cursor.getInt(cursor.getColumnIndex(
15782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                                        DownloadManager.COLUMN_STATUS));
15882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                                Log.i(LOG_TAG, "Download status is: " + status);
15982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                            } else {
16082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                                fail("No status found for completed download!");
16182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                            }
16282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        } finally {
16382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                            cursor.close();
16482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        }
16582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    } else {
16682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        Log.i(LOG_TAG, "Notification for id: " + id + " has already been made.");
16782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    }
16882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                }
16982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
17082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
17182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
17282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
17382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Gets the number of times the {@link #onReceive} callback has been called for the
17482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * {@link DownloadManager.ACTION_DOWNLOAD_COMPLETED} action, indicating the number of
17582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * downloads completed thus far.
17682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         *
17782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * @return the number of downloads completed so far.
17882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
17982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public int numDownloadsCompleted() {
18082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            return mNumDownloadsCompleted;
18182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
18282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
18382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
18482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Gets the list of download IDs.
18582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * @return A Set<Long> with the ids of the completed downloads.
18682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
18782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public Set<Long> getDownloadIds() {
18882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            synchronized(this) {
18982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                Set<Long> returnIds = new HashSet<Long>(downloadIds);
19082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                return returnIds;
19182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
19282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
19382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
19482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
19582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
19682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    public static class WiFiChangedReceiver extends BroadcastReceiver {
19782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        private Context mContext = null;
19882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
19982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
20082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Constructor
20182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         *
20282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Sets the current state of WiFi.
20382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         *
20482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * @param context The current app {@link Context}.
20582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
20682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public WiFiChangedReceiver(Context context) {
20782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            mContext = context;
20882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
20982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
21082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
21182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * {@inheritDoc}
21282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
21382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        @Override
21482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public void onReceive(Context context, Intent intent) {
21582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            if (intent.getAction().equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION)) {
21682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                Log.i(LOG_TAG, "ConnectivityManager state change: " + intent.getAction());
21782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                synchronized (this) {
21882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    this.notify();
21982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                }
22082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
22182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
22282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
22382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        /**
22482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * Gets the current state of WiFi.
22582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         *
22682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         * @return Returns true if WiFi is on, false otherwise.
22782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori         */
22882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        public boolean getWiFiIsOn() {
22982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            ConnectivityManager connManager = (ConnectivityManager)mContext.getSystemService(
23082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    Context.CONNECTIVITY_SERVICE);
23182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            NetworkInfo info = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
23282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            Log.i(LOG_TAG, "WiFi Connection state is currently: " + info.isConnected());
23382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            return info.isConnected();
23482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
23582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
23682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
23782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
23882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * {@inheritDoc}
23982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
24082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    @Override
24182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    public void setUp() throws Exception {
24282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mContext = getInstrumentation().getContext();
24382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
24482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mServer = new MockWebServer();
24582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mReceiver = registerNewMultipleDownloadsReceiver();
24682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // Note: callers overriding this should call mServer.play() with the desired port #
24782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
24882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
24982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
25082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to enqueue a response from the MockWebServer.
25182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
25282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param status The HTTP status code to return for this response
25382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param body The body to return in this response
25482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return Returns the mock web server response that was queued (which can be modified)
25582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
25682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private MockResponse enqueueResponse(int status, byte[] body) {
25782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return doEnqueueResponse(status).setBody(body);
25882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
25982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
26082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
26182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
26282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to enqueue a response from the MockWebServer.
26382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
26482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param status The HTTP status code to return for this response
26582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param bodyFile The body to return in this response
26682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return Returns the mock web server response that was queued (which can be modified)
26782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
26882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private MockResponse enqueueResponse(int status, File bodyFile) {
26982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return doEnqueueResponse(status).setBody(bodyFile);
27082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
27182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
27282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
27382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper for enqueue'ing a response from the MockWebServer.
27482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
27582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param status The HTTP status code to return for this response
27682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return Returns the mock web server response that was queued (which can be modified)
27782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
27882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private MockResponse doEnqueueResponse(int status) {
27982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        MockResponse response = new MockResponse().setResponseCode(status);
28082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        response.addHeader("Content-type", mFileType);
28182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mServer.enqueue(response);
28282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return response;
28382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
28482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
28582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
28682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to generate a random blob of bytes using a given RNG.
28782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
28882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param size The size of the data to generate
28982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param type The type of data to generate: currently, one of {@link DataType.TEXT} or
29082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *         {@link DataType.BINARY}.
29182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param rng (optional) The RNG to use; pass null to use
29282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return The random data that is generated.
29382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
29482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private byte[] generateData(int size, DataType type, Random rng) {
29582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int min = Byte.MIN_VALUE;
29682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int max = Byte.MAX_VALUE;
29782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
29882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // Only use chars in the HTTP ASCII printable character range for Text
29982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        if (type == DataType.TEXT) {
30082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            min = 32;
30182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            max = 126;
30282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
30382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        byte[] result = new byte[size];
30482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Log.i(LOG_TAG, "Generating data of size: " + size);
30582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
30682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        if (rng == null) {
30782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            rng = new LoggingRng();
30882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
30982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
31082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        for (int i = 0; i < size; ++i) {
31182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            result[i] = (byte) (min + rng.nextInt(max - min + 1));
31282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
31382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return result;
31482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
31582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
31682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
31782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to verify the size of a file.
31882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
31982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param pfd The input file to compare the size of
32082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param size The expected size of the file
32182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
32282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void verifyFileSize(ParcelFileDescriptor pfd, long size) {
32382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        assertEquals(pfd.getStatSize(), size);
32482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
32582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
32682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
32782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to verify the contents of a downloaded file versus a byte[].
32882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
32982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param actual The file of whose contents to verify
33082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param expected The data we expect to find in the aforementioned file
33182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @throws IOException if there was a problem reading from the file
33282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
33382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private void verifyFileContents(ParcelFileDescriptor actual, byte[] expected)
33482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            throws IOException {
33582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        AutoCloseInputStream input = new ParcelFileDescriptor.AutoCloseInputStream(actual);
33682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        long fileSize = actual.getStatSize();
33782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
33882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        assertTrue(fileSize <= Integer.MAX_VALUE);
33982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        assertEquals(expected.length, fileSize);
34082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
34182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        byte[] actualData = new byte[expected.length];
34282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        assertEquals(input.read(actualData), fileSize);
34382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        compareByteArrays(actualData, expected);
34482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
34582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
34682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
34782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to compare 2 byte arrays.
34882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
34982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param actual The array whose data we want to verify
35082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param expected The array of data we expect to see
35182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
35282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private void compareByteArrays(byte[] actual, byte[] expected) {
35382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        assertEquals(actual.length, expected.length);
35482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int length = actual.length;
35582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        for (int i = 0; i < length; ++i) {
35682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            // assert has a bit of overhead, so only do the assert when the values are not the same
35782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            if (actual[i] != expected[i]) {
35882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                fail("Byte arrays are not equal.");
35982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
36082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
36182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
36282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
36382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
36482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Gets the MIME content string for a given type
36582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
36682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param type The MIME type to return
36782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return the String representation of that MIME content type
36882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
36982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected String getMimeMapping(DownloadFileType type) {
37082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        switch (type) {
37182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            case APK:
37282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                return "application/vnd.android.package-archive";
37382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            case GIF:
37482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                return "image/gif";
37582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            case ZIP:
37682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                return "application/x-zip-compressed";
37782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            case GARBAGE:
37882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                return "zip\\pidy/doo/da";
37982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            case UNRECOGNIZED:
38082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                return "application/new.undefined.type.of.app";
38182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
38282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return "text/plain";
38382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
38482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
38582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
38682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Gets the Uri that should be used to access the mock server
38782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
38882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param filename The name of the file to try to retrieve from the mock server
38982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return the Uri to use for access the file on the mock server
39082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
39182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private Uri getServerUri(String filename) throws Exception {
39282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        URL url = mServer.getUrl("/" + filename);
39382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return Uri.parse(url.toString());
39482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
39582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
39682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
39782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to create and register a new MultipleDownloadCompletedReciever
39882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
39982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * This is used to track many simultaneous downloads by keeping count of all the downloads
40082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * that have completed.
40182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
40282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return A new receiver that records and can be queried on how many downloads have completed.
40382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
40482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected MultipleDownloadsCompletedReceiver registerNewMultipleDownloadsReceiver() {
40582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        MultipleDownloadsCompletedReceiver receiver = new MultipleDownloadsCompletedReceiver();
40682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mContext.registerReceiver(receiver, new IntentFilter(
40782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                DownloadManager.ACTION_DOWNLOAD_COMPLETE));
40882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return receiver;
40982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
41082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
41182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
41282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Enables or disables WiFi.
41382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
41482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Note: Needs the following permissions:
41582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *  android.permission.ACCESS_WIFI_STATE
41682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *  android.permission.CHANGE_WIFI_STATE
41782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param enable true if it should be enabled, false if it should be disabled
41882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
41982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void setWiFiStateOn(boolean enable) throws Exception {
42082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Log.i(LOG_TAG, "Setting WiFi State to: " + enable);
42182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
42282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
42382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        manager.setWifiEnabled(enable);
42482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
42582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        String timeoutMessage = "Timed out waiting for Wifi to be "
42682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            + (enable ? "enabled!" : "disabled!");
42782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
42882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        WiFiChangedReceiver receiver = new WiFiChangedReceiver(mContext);
42982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mContext.registerReceiver(receiver, new IntentFilter(
43082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                ConnectivityManager.CONNECTIVITY_ACTION));
43182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
43282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        synchronized (receiver) {
43382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            long timeoutTime = SystemClock.elapsedRealtime() + DEFAULT_MAX_WAIT_TIME;
43482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            boolean timedOut = false;
43582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
43682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            while (receiver.getWiFiIsOn() != enable && !timedOut) {
43782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                try {
43882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    receiver.wait(DEFAULT_WAIT_POLL_TIME);
43982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
44082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    if (SystemClock.elapsedRealtime() > timeoutTime) {
44182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        timedOut = true;
44282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    }
44382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                }
44482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                catch (InterruptedException e) {
44582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    // ignore InterruptedExceptions
44682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                }
44782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
44882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            if (timedOut) {
44982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                fail(timeoutMessage);
45082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
45182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
45282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        assertEquals(enable, receiver.getWiFiIsOn());
45382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
45482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
45582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
45682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to enables or disables airplane mode. If successful, it also broadcasts an intent
45782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * indicating that the mode has changed.
45882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
45982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Note: Needs the following permission:
46082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *  android.permission.WRITE_SETTINGS
46182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param enable true if airplane mode should be ON, false if it should be OFF
46282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
46382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void setAirplaneModeOn(boolean enable) throws Exception {
46482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int state = enable ? 1 : 0;
46582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
46682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // Change the system setting
46782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
46882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                state);
46982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
47082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        String timeoutMessage = "Timed out waiting for airplane mode to be " +
47182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                (enable ? "enabled!" : "disabled!");
47282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
47382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // wait for airplane mode to change state
47482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int currentWaitTime = 0;
47582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        while (Settings.System.getInt(mContext.getContentResolver(),
47682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                Settings.System.AIRPLANE_MODE_ON, -1) != state) {
47782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, DEFAULT_MAX_WAIT_TIME,
47882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    timeoutMessage);
47982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
48082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
48182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // Post the intent
48282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
48382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        intent.putExtra("state", true);
48482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        mContext.sendBroadcast(intent);
48582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
48682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
48782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
48882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to wait for a particular download to finish, or else a timeout to occur
48982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
49082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Does not wait for a receiver notification of the download.
49182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
49282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param id The download id to query on (wait for)
49382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
494fbfe6d971d63860c02a71d69c3c7c29a2e958734Neal Nguyen    protected void waitForDownloadOrTimeout_skipNotification(long id) throws TimeoutException,
49582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            InterruptedException {
496fbfe6d971d63860c02a71d69c3c7c29a2e958734Neal Nguyen        doWaitForDownloadsOrTimeout(new Query().setFilterById(id),
497fbfe6d971d63860c02a71d69c3c7c29a2e958734Neal Nguyen                WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
49882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
49982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
50082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
50182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to wait for a particular download to finish, or else a timeout to occur
50282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
50382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Also guarantees a notification has been posted for the download.
50482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
50582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param id The download id to query on (wait for)
50682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
50782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
50882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            InterruptedException {
509fbfe6d971d63860c02a71d69c3c7c29a2e958734Neal Nguyen        waitForDownloadOrTimeout(id, WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
51082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
51182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
51282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
51382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to wait for a particular download to finish, or else a timeout to occur
51482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
51582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Also guarantees a notification has been posted for the download.
51682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
51782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param id The download id to query on (wait for)
51882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param poll The amount of time to wait
51982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
52082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
52182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void waitForDownloadOrTimeout(long id, long poll, long timeoutMillis)
52282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            throws TimeoutException, InterruptedException {
52382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
52482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        waitForReceiverNotifications(1);
52582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
52682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
52782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
52882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to wait for all downloads to finish, or else a specified timeout to occur
52982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
53082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Makes no guaranee that notifications have been posted for all downloads.
53182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
53282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param poll The amount of time to wait
53382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
53482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
53582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void waitForDownloadsOrTimeout(long poll, long timeoutMillis) throws TimeoutException,
53682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            InterruptedException {
53782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        doWaitForDownloadsOrTimeout(new Query(), poll, timeoutMillis);
53882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
53982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
54082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
54182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to wait for all downloads to finish, or else a timeout to occur, but does not throw
54282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
54382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Also guarantees a notification has been posted for the download.
54482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
54582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param id The id of the download to query against
54682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param poll The amount of time to wait
54782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
54882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return true if download completed successfully (didn't timeout), false otherwise
54982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
55082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private boolean waitForDownloadOrTimeoutNoThrow(long id, long poll, long timeoutMillis) {
55182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        try {
55282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
55382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            waitForReceiverNotifications(1);
55482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        } catch (TimeoutException e) {
55582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            return false;
55682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
55782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return true;
55882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
55982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
56082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
56182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper function to synchronously wait, or timeout if the maximum threshold has been exceeded.
56282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
56382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param currentTotalWaitTime The total time waited so far
56482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param poll The amount of time to wait
56582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param maxTimeoutMillis The total wait time threshold; if we've waited more than this long,
56682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *          we timeout and fail
56782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param timedOutMessage The message to display in the failure message if we timeout
56882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return The new total amount of time we've waited so far
56982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @throws TimeoutException if timed out waiting for SD card to mount
57082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
57182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private int timeoutWait(int currentTotalWaitTime, long poll, long maxTimeoutMillis,
57282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            String timedOutMessage) throws TimeoutException {
57382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        long now = SystemClock.elapsedRealtime();
57482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        long end = now + poll;
57582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
57682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // if we get InterruptedException's, ignore them and just keep sleeping
57782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        while (now < end) {
57882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            try {
57982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                Thread.sleep(end - now);
58082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            } catch (InterruptedException e) {
58182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                // ignore interrupted exceptions
58282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
58382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            now = SystemClock.elapsedRealtime();
58482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
58582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
58682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        currentTotalWaitTime += poll;
58782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        if (currentTotalWaitTime > maxTimeoutMillis) {
58882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            throw new TimeoutException(timedOutMessage);
58982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
59082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return currentTotalWaitTime;
59182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
59282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
59382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
59482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to wait for all downloads to finish, or else a timeout to occur
59582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
59682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param query The query to pass to the download manager
59782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param poll The poll time to wait between checks
59882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param timeoutMillis The max amount of time (in ms) to wait for the download(s) to complete
59982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
60082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private void doWaitForDownloadsOrTimeout(Query query, long poll, long timeoutMillis)
60182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            throws TimeoutException {
60282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int currentWaitTime = 0;
60382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        while (true) {
60482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_PAUSED
60582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    | DownloadManager.STATUS_RUNNING);
60682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            Cursor cursor = mDownloadManager.query(query);
60782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
60882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            try {
60982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                if (cursor.getCount() == 0) {
61082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    Log.i(LOG_TAG, "All downloads should be done...");
61182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    break;
61282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                }
61382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
61482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        "Timed out waiting for all downloads to finish");
61582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            } finally {
61682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                cursor.close();
61782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
61882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
61982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
62082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
62182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
62282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Synchronously waits for external store to be mounted (eg: SD Card).
62382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
62482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @throws InterruptedException if interrupted
62582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @throws Exception if timed out waiting for SD card to mount
62682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
62782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void waitForExternalStoreMount() throws Exception {
62882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        String extStorageState = Environment.getExternalStorageState();
62982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int currentWaitTime = 0;
63082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        while (!extStorageState.equals(Environment.MEDIA_MOUNTED)) {
63182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            Log.i(LOG_TAG, "Waiting for SD card...");
63282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            currentWaitTime = timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME,
63382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    DEFAULT_MAX_WAIT_TIME, "Timed out waiting for SD Card to be ready!");
63482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            extStorageState = Environment.getExternalStorageState();
63582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
63682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
63782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
63882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
63982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Synchronously waits for a download to start.
64082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
64182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param dlRequest the download request id used by Download Manager to track the download.
64282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @throws Exception if timed out while waiting for SD card to mount
64382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
64482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void waitForDownloadToStart(long dlRequest) throws Exception {
64582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Cursor cursor = getCursor(dlRequest);
64682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        try {
64782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
64882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            int value = cursor.getInt(columnIndex);
64982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            int currentWaitTime = 0;
65082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
65182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            while (value != DownloadManager.STATUS_RUNNING &&
65282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    (value != DownloadManager.STATUS_FAILED) &&
65382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    (value != DownloadManager.STATUS_SUCCESSFUL)) {
65482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                Log.i(LOG_TAG, "Waiting for download to start...");
65582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
65682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                        MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download to start!");
65782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                cursor.requery();
65882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                assertTrue(cursor.moveToFirst());
65982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
66082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                value = cursor.getInt(columnIndex);
66182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
66282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            assertFalse("Download failed immediately after start",
66382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    value == DownloadManager.STATUS_FAILED);
66482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        } finally {
66582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            cursor.close();
66682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
66782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
66882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
66982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
67082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Synchronously waits for our receiver to receive notification for a given number of
67182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * downloads.
67282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
67382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param targetNumber The number of notifications for unique downloads to wait for; pass in
67482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *         -1 to not wait for notification.
67582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @throws Exception if timed out while waiting
67682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
67782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private void waitForReceiverNotifications(int targetNumber) throws TimeoutException {
67882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int count = mReceiver.numDownloadsCompleted();
67982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int currentWaitTime = 0;
68082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
68182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        while (count < targetNumber) {
68282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            Log.i(LOG_TAG, "Waiting for notification of downloads...");
68382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
68482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download notifications!"
68582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    + " Received " + count + "notifications.");
68682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            count = mReceiver.numDownloadsCompleted();
68782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
68882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
68982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
69082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
69182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Synchronously waits for a file to increase in size (such as to monitor that a download is
69282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * progressing).
69382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
69482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param file The file whose size to track.
69582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @throws Exception if timed out while waiting for the file to grow in size.
69682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
69782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void waitForFileToGrow(File file) throws Exception {
69882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int currentWaitTime = 0;
69982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
70082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // File may not even exist yet, so wait until it does (or we timeout)
70182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        while (!file.exists()) {
70282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            Log.i(LOG_TAG, "Waiting for file to exist...");
70382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
70482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be created.");
70582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
70682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
70782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // Get original file size...
70882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        long originalSize = file.length();
70982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
71082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        while (file.length() <= originalSize) {
71182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            Log.i(LOG_TAG, "Waiting for file to be written to...");
71282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
71382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be written to.");
71482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
71582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
71682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
71782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
71882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to remove all downloads that are registered with the DL Manager.
71982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
72082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Note: This gives us a clean slate b/c it includes downloads that are pending, running,
72182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * paused, or have completed.
72282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
72382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected void removeAllCurrentDownloads() {
72482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Log.i(LOG_TAG, "Removing all current registered downloads...");
72582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Cursor cursor = mDownloadManager.query(new Query());
72682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        try {
72782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            if (cursor.moveToFirst()) {
72882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                do {
72982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    int index = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
73082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    long downloadId = cursor.getLong(index);
73182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
73282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    mDownloadManager.remove(downloadId);
73382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                } while (cursor.moveToNext());
73482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
73582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        } finally {
73682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            cursor.close();
73782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
73882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
73982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
74082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
74182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to perform a standard enqueue of data to the mock server.
74282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * download is performed to the downloads cache dir (NOT systemcache dir)
74382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
74482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param body The body to return in the response from the server
74582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
74682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private long doStandardEnqueue(byte[] body) throws Exception {
74782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // Prepare the mock server with a standard response
74882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        enqueueResponse(HTTP_OK, body);
74982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return doCommonStandardEnqueue();
75082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
75182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
75282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
75382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to perform a standard enqueue of data to the mock server.
75482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
75582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param body The body to return in the response from the server, contained in the file
75682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
75782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private long doStandardEnqueue(File body) throws Exception {
75882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        // Prepare the mock server with a standard response
75982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        enqueueResponse(HTTP_OK, body);
76082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return doCommonStandardEnqueue();
76182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
76282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
76382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
76482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to do the additional steps (setting title and Uri of default filename) when
76582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * doing a standard enqueue request to the server.
76682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
76782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private long doCommonStandardEnqueue() throws Exception {
76882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Uri uri = getServerUri(DEFAULT_FILENAME);
76982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Request request = new Request(uri).setTitle(DEFAULT_FILENAME);
77082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return mDownloadManager.enqueue(request);
77182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
77282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
77382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
77482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Helper to verify an int value in a Cursor
77582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
77682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param cursor The cursor containing the query results
77782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param columnName The name of the column to query
77882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param expected The expected int value
77982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
78082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    private void verifyInt(Cursor cursor, String columnName, int expected) {
78182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int index = cursor.getColumnIndex(columnName);
78282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int actual = cursor.getInt(index);
78382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        assertEquals(expected, actual);
78482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
78582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
78682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    /**
78782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * Performs a query based on ID and returns a Cursor for the query.
78882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     *
78982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @param id The id of the download in DL Manager; pass -1 to query all downloads
79082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     * @return A cursor for the query results
79182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori     */
79282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    protected Cursor getCursor(long id) throws Exception {
79382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Query query = new Query();
79482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        if (id != -1) {
79582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            query.setFilterById(id);
79682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
79782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
79882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        Cursor cursor = mDownloadManager.query(query);
79982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        int currentWaitTime = 0;
80082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori
80182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        try {
80282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            while (!cursor.moveToFirst()) {
80382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                Thread.sleep(DEFAULT_WAIT_POLL_TIME);
80482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                currentWaitTime += DEFAULT_WAIT_POLL_TIME;
80582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                if (currentWaitTime > DEFAULT_MAX_WAIT_TIME) {
80682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                    fail("timed out waiting for a non-null query result");
80782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                }
80882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori                cursor.requery();
80982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            }
81082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        } catch (Exception e) {
81182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            cursor.close();
81282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori            throw e;
81382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        }
81482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori        return cursor;
81582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori    }
816fbfe6d971d63860c02a71d69c3c7c29a2e958734Neal Nguyen}
817