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.content.BroadcastReceiver; 2282e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.content.Context; 2382e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.content.Intent; 2482e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.content.IntentFilter; 2582e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.database.Cursor; 2682e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.net.ConnectivityManager; 2782e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.net.NetworkInfo; 2882e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.net.wifi.WifiManager; 2982e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.Environment; 30a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavineimport android.os.Handler; 31a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavineimport android.os.Looper; 3282e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.ParcelFileDescriptor; 3382e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.os.SystemClock; 3482e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.provider.Settings; 3582e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.test.InstrumentationTestCase; 3682e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport android.util.Log; 3782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 3882e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.HashSet; 3982e891b3259350a92b55969a6380ca1240ee0829Vasu Noriimport java.util.Set; 40b14ad8cc8cb0ed774072b077694b21fd0a6f33beJeff Sharkeyimport java.util.concurrent.TimeoutException; 4182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 4282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori/** 4382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Base class for Instrumented tests for the Download Manager. 4482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 4582e891b3259350a92b55969a6380ca1240ee0829Vasu Noripublic class DownloadManagerBaseTest extends InstrumentationTestCase { 4682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 4782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected DownloadManager mDownloadManager = null; 4882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected String mFileType = "text/plain"; 4982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected Context mContext = null; 5082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int DEFAULT_FILE_SIZE = 10 * 1024; // 10kb 5182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024; 5282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 5382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final String LOG_TAG = "android.net.DownloadManagerBaseTest"; 5482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int HTTP_OK = 200; 5582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int HTTP_REDIRECT = 307; 5682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int HTTP_PARTIAL_CONTENT = 206; 5782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int HTTP_NOT_FOUND = 404; 5882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int HTTP_SERVICE_UNAVAILABLE = 503; 5982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 6082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int DEFAULT_MAX_WAIT_TIME = 2 * 60 * 1000; // 2 minutes 6182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int DEFAULT_WAIT_POLL_TIME = 5 * 1000; // 5 seconds 6282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 6382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int WAIT_FOR_DOWNLOAD_POLL_TIME = 1 * 1000; // 1 second 6482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes 6582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes 6682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 67a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private DownloadFinishedListener mListener; 68a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private Thread mListenerThread; 6982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 7082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 7182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori public static class WiFiChangedReceiver extends BroadcastReceiver { 7282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori private Context mContext = null; 7382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 7482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 7582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Constructor 7682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 7782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Sets the current state of WiFi. 7882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 7982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param context The current app {@link Context}. 8082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 8182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori public WiFiChangedReceiver(Context context) { 8282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori mContext = context; 8382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 8482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 8582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 8682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * {@inheritDoc} 8782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 8882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori @Override 8982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori public void onReceive(Context context, Intent intent) { 9082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori if (intent.getAction().equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION)) { 9182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Log.i(LOG_TAG, "ConnectivityManager state change: " + intent.getAction()); 9282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori synchronized (this) { 9382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori this.notify(); 9482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 9582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 9682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 9782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 9882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 9982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Gets the current state of WiFi. 10082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 10182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @return Returns true if WiFi is on, false otherwise. 10282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 10382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori public boolean getWiFiIsOn() { 10482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori ConnectivityManager connManager = (ConnectivityManager)mContext.getSystemService( 10582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Context.CONNECTIVITY_SERVICE); 10682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori NetworkInfo info = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 10782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Log.i(LOG_TAG, "WiFi Connection state is currently: " + info.isConnected()); 10882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori return info.isConnected(); 10982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 11082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 11182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 11282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 113a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Broadcast receiver to listen for broadcast from DownloadManager indicating that downloads 114a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * are finished. 115a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine */ 116a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private class DownloadFinishedListener extends BroadcastReceiver implements Runnable { 117a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private Handler mHandler = null; 118a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private Looper mLooper; 119a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private Set<Long> mFinishedDownloads = new HashSet<Long>(); 120a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 121a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine /** 122a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Event loop for the thread that listens to broadcasts. 123a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine */ 124a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine @Override 125a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine public void run() { 126a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Looper.prepare(); 127a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine synchronized (this) { 128a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mLooper = Looper.myLooper(); 129a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mHandler = new Handler(); 130a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine notifyAll(); 131a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 132a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Looper.loop(); 133a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 134a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 135a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine /** 136a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Handles the incoming notifications from DownloadManager. 137a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine */ 138a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine @Override 139a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine public void onReceive(Context context, Intent intent) { 140a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { 141a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID); 142a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Log.i(LOG_TAG, "Received Notification for download: " + id); 143a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine synchronized (this) { 144a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if(!mFinishedDownloads.contains(id)) { 145a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mFinishedDownloads.add(id); 146a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine notifyAll(); 147a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } else { 148a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Log.i(LOG_TAG, 149a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine String.format("Notification for %d was already received", id)); 150a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 151a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 152a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 153a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 154a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 155a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine /** 156a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Returns the handler for this thread. Need this to make sure that the events are handled 157a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * in it is own thread and don't interfere with the instrumentation thread. 158a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @return Handler for the receiver thread. 159a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @throws InterruptedException 160a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine */ 161a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private Handler getHandler() throws InterruptedException { 162a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine synchronized (this) { 163a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (mHandler != null) return mHandler; 164a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine while (mHandler == null) { 165a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine wait(); 166a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 167a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return mHandler; 168a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 169a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 170a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 171a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine /** 172a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Stops the thread that receives notification from DownloadManager. 173a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine */ 174a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine public void cancel() { 175a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine synchronized(this) { 176a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (mLooper != null) { 177a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mLooper.quit(); 178a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 179a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 180a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 181a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 182a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine /** 183a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Waits for a given download to finish, or until the timeout expires. 184a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @param id id of the download to wait for. 185a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @param timeout maximum time to wait, in milliseconds 186a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @return true if the download finished, false otherwise. 187a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @throws InterruptedException 188a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine */ 189a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine public boolean waitForDownloadToFinish(long id, long timeout) throws InterruptedException { 190a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine long startTime = SystemClock.uptimeMillis(); 191a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine synchronized (this) { 192a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine while (!mFinishedDownloads.contains(id)) { 193a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (SystemClock.uptimeMillis() - startTime > timeout) { 194a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Log.i(LOG_TAG, String.format("Timeout while waiting for %d to finish", id)); 195a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return false; 196a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } else { 197a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine wait(timeout); 198a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 199a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 200a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return true; 201a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 202a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 203a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 204a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine /** 205a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Waits for multiple downloads to finish, or until timeout expires. 206a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @param ids ids of the downloads to wait for. 207a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @param timeout maximum time to wait, in milliseconds 208a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @return true of all the downloads finished, false otherwise. 209a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @throws InterruptedException 210a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine */ 211a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine public boolean waitForMultipleDownloadsToFinish(Set<Long> ids, long timeout) 212a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine throws InterruptedException { 213a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine long startTime = SystemClock.uptimeMillis(); 214a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine synchronized (this) { 215a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine while (!mFinishedDownloads.containsAll(ids)) { 216a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (SystemClock.uptimeMillis() - startTime > timeout) { 217a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Log.i(LOG_TAG, "Timeout waiting for multiple downloads to finish"); 218a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return false; 219a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } else { 220a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine wait(timeout); 221a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 222a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 223a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return true; 224a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 225a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 226a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 227a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 228a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine /** 22982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * {@inheritDoc} 23082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 23182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori @Override 23282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori public void setUp() throws Exception { 233a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine super.setUp(); 23482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori mContext = getInstrumentation().getContext(); 23582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); 236a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mListener = registerDownloadsListener(); 237a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 238a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine 239a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine @Override 240a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine public void tearDown() throws Exception { 241a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mContext.unregisterReceiver(mListener); 242a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mListener.cancel(); 243a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mListenerThread.join(); 244a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine super.tearDown(); 24582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 24682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 24782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 24882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Helper to verify the size of a file. 24982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 25082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param pfd The input file to compare the size of 25182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param size The expected size of the file 25282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 25382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected void verifyFileSize(ParcelFileDescriptor pfd, long size) { 25482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori assertEquals(pfd.getStatSize(), size); 25582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 25682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 25782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 25882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Helper to create and register a new MultipleDownloadCompletedReciever 25982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 26082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * This is used to track many simultaneous downloads by keeping count of all the downloads 26182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * that have completed. 26282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 26382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @return A new receiver that records and can be queried on how many downloads have completed. 264a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @throws InterruptedException 26582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 266a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine protected DownloadFinishedListener registerDownloadsListener() throws InterruptedException { 267a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine DownloadFinishedListener listener = new DownloadFinishedListener(); 268a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mListenerThread = new Thread(listener); 269a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mListenerThread.start(); 270a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine mContext.registerReceiver(listener, new IntentFilter( 271a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine DownloadManager.ACTION_DOWNLOAD_COMPLETE), null, listener.getHandler()); 272a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return listener; 27382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 27482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 27582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 27682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Enables or disables WiFi. 27782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 27882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Note: Needs the following permissions: 27982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * android.permission.ACCESS_WIFI_STATE 28082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * android.permission.CHANGE_WIFI_STATE 28182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param enable true if it should be enabled, false if it should be disabled 28282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 28382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected void setWiFiStateOn(boolean enable) throws Exception { 28482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Log.i(LOG_TAG, "Setting WiFi State to: " + enable); 28582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); 28682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 28782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori manager.setWifiEnabled(enable); 28882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 28982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori String timeoutMessage = "Timed out waiting for Wifi to be " 29082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori + (enable ? "enabled!" : "disabled!"); 29182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 29282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori WiFiChangedReceiver receiver = new WiFiChangedReceiver(mContext); 29382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori mContext.registerReceiver(receiver, new IntentFilter( 29482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori ConnectivityManager.CONNECTIVITY_ACTION)); 29582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 29682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori synchronized (receiver) { 29782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori long timeoutTime = SystemClock.elapsedRealtime() + DEFAULT_MAX_WAIT_TIME; 29882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori boolean timedOut = false; 29982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 30082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori while (receiver.getWiFiIsOn() != enable && !timedOut) { 30182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori try { 30282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori receiver.wait(DEFAULT_WAIT_POLL_TIME); 30382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 30482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori if (SystemClock.elapsedRealtime() > timeoutTime) { 30582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori timedOut = true; 30682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 30782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 30882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori catch (InterruptedException e) { 30982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori // ignore InterruptedExceptions 31082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 31182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 31282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori if (timedOut) { 31382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori fail(timeoutMessage); 31482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 31582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 31682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori assertEquals(enable, receiver.getWiFiIsOn()); 31782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 31882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 31982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 32082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Helper to enables or disables airplane mode. If successful, it also broadcasts an intent 32182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * indicating that the mode has changed. 32282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 32382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Note: Needs the following permission: 32482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * android.permission.WRITE_SETTINGS 32582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param enable true if airplane mode should be ON, false if it should be OFF 32682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 32782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected void setAirplaneModeOn(boolean enable) throws Exception { 32882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int state = enable ? 1 : 0; 32982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 33082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori // Change the system setting 33135fae68cc3eb21c15069c58d275a46537cc04f4aTsu Chiang Chuang Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 33282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori state); 33382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 33482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori String timeoutMessage = "Timed out waiting for airplane mode to be " + 33582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori (enable ? "enabled!" : "disabled!"); 33682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 33782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori // wait for airplane mode to change state 33882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int currentWaitTime = 0; 33982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori while (Settings.System.getInt(mContext.getContentResolver(), 34035fae68cc3eb21c15069c58d275a46537cc04f4aTsu Chiang Chuang Settings.Global.AIRPLANE_MODE_ON, -1) != state) { 34182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, DEFAULT_MAX_WAIT_TIME, 34282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori timeoutMessage); 34382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 34482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 34582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori // Post the intent 34682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 34782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori intent.putExtra("state", true); 34882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori mContext.sendBroadcast(intent); 34982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 35082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 35182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 352a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Helper to wait for a particular download to finish, or else a timeout to occur. 35382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 35482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param id The download id to query on (wait for) 35582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param poll The amount of time to wait 35682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete 35782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 358a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine protected boolean waitForDownload(long id, long timeoutMillis) 359a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine throws InterruptedException { 360a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return mListener.waitForDownloadToFinish(id, timeoutMillis); 36182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 36282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 363a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine protected boolean waitForMultipleDownloads(Set<Long> ids, long timeout) 364a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine throws InterruptedException { 365a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return mListener.waitForMultipleDownloadsToFinish(ids, timeout); 36682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 36782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 36882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 369a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Checks with the download manager if the give download is finished. 370a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @param id id of the download to check 371a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @return true if download is finished, false otherwise. 37282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 373a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private boolean hasDownloadFinished(long id) { 374a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Query q = new Query(); 375a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine q.setFilterById(id); 376a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine q.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL); 377a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Cursor cursor = mDownloadManager.query(q); 378a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine boolean finished = cursor.getCount() == 1; 379a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine cursor.close(); 380a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return finished; 38182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 38282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 38382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 38482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Helper function to synchronously wait, or timeout if the maximum threshold has been exceeded. 38582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 38682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param currentTotalWaitTime The total time waited so far 38782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param poll The amount of time to wait 38882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param maxTimeoutMillis The total wait time threshold; if we've waited more than this long, 38982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * we timeout and fail 39082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param timedOutMessage The message to display in the failure message if we timeout 39182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @return The new total amount of time we've waited so far 39282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @throws TimeoutException if timed out waiting for SD card to mount 39382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 39482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori private int timeoutWait(int currentTotalWaitTime, long poll, long maxTimeoutMillis, 39582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori String timedOutMessage) throws TimeoutException { 39682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori long now = SystemClock.elapsedRealtime(); 39782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori long end = now + poll; 39882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 39982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori // if we get InterruptedException's, ignore them and just keep sleeping 40082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori while (now < end) { 40182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori try { 40282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Thread.sleep(end - now); 40382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } catch (InterruptedException e) { 40482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori // ignore interrupted exceptions 40582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 40682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori now = SystemClock.elapsedRealtime(); 40782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 40882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 40982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori currentTotalWaitTime += poll; 41082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori if (currentTotalWaitTime > maxTimeoutMillis) { 41182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori throw new TimeoutException(timedOutMessage); 41282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 41382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori return currentTotalWaitTime; 41482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 41582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 41682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 41782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Synchronously waits for external store to be mounted (eg: SD Card). 41882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 41982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @throws InterruptedException if interrupted 42082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @throws Exception if timed out waiting for SD card to mount 42182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 42282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected void waitForExternalStoreMount() throws Exception { 42382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori String extStorageState = Environment.getExternalStorageState(); 42482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int currentWaitTime = 0; 42582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori while (!extStorageState.equals(Environment.MEDIA_MOUNTED)) { 42682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Log.i(LOG_TAG, "Waiting for SD card..."); 42782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori currentWaitTime = timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, 42882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori DEFAULT_MAX_WAIT_TIME, "Timed out waiting for SD Card to be ready!"); 42982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori extStorageState = Environment.getExternalStorageState(); 43082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 43182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 43282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 43382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 43482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Synchronously waits for a download to start. 43582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 43682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param dlRequest the download request id used by Download Manager to track the download. 43782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @throws Exception if timed out while waiting for SD card to mount 43882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 43982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected void waitForDownloadToStart(long dlRequest) throws Exception { 44082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Cursor cursor = getCursor(dlRequest); 44182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori try { 44282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS); 44382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int value = cursor.getInt(columnIndex); 44482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int currentWaitTime = 0; 44582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 44682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori while (value != DownloadManager.STATUS_RUNNING && 44782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori (value != DownloadManager.STATUS_FAILED) && 44882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori (value != DownloadManager.STATUS_SUCCESSFUL)) { 44982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Log.i(LOG_TAG, "Waiting for download to start..."); 45082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME, 45182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download to start!"); 45282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori cursor.requery(); 45382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori assertTrue(cursor.moveToFirst()); 45482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS); 45582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori value = cursor.getInt(columnIndex); 45682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 45782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori assertFalse("Download failed immediately after start", 45882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori value == DownloadManager.STATUS_FAILED); 45982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } finally { 46082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori cursor.close(); 46182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 46282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 46382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 46482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 465a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * Synchronously waits for the download manager to start incrementing the number of 466a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * bytes downloaded so far. 46782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 468a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @param id DownloadManager download id that needs to be checked. 469962e12883b6a07ff5b33bd9d269869e4da50b799Maxim Siniavine * @param bytesToReceive how many bytes do we need to wait to receive. 470a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine * @throws Exception if timed out while waiting for the file to grow in size. 47182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 472962e12883b6a07ff5b33bd9d269869e4da50b799Maxim Siniavine protected void waitToReceiveData(long id, long bytesToReceive) throws Exception { 47382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int currentWaitTime = 0; 474962e12883b6a07ff5b33bd9d269869e4da50b799Maxim Siniavine long expectedSize = getBytesDownloaded(id) + bytesToReceive; 475a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine long currentSize = 0; 476962e12883b6a07ff5b33bd9d269869e4da50b799Maxim Siniavine while ((currentSize = getBytesDownloaded(id)) <= expectedSize) { 477962e12883b6a07ff5b33bd9d269869e4da50b799Maxim Siniavine Log.i(LOG_TAG, String.format("expect: %d, cur: %d. Waiting for file to be written to...", 478962e12883b6a07ff5b33bd9d269869e4da50b799Maxim Siniavine expectedSize, currentSize)); 47982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME, 480a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be written to."); 48182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 48282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 48382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 484a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine private long getBytesDownloaded(long id) { 485a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine DownloadManager.Query q = new DownloadManager.Query(); 486a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine q.setFilterById(id); 487a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Cursor response = mDownloadManager.query(q); 488a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (response.getCount() < 1) { 489a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Log.i(LOG_TAG, String.format("Query to download manager returned nothing for id %d",id)); 490a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine response.close(); 491a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return -1; 49282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 493a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine while(response.moveToNext()) { 494a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine int index = response.getColumnIndex(DownloadManager.COLUMN_ID); 495a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (id == response.getLong(index)) { 496a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine break; 497a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 49882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 499a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine int index = response.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR); 500a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine if (index < 0) { 501a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine Log.i(LOG_TAG, String.format("No downloaded bytes for id %d", id)); 502a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine response.close(); 503a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return -1; 504a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine } 505a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine long size = response.getLong(index); 506a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine response.close(); 507a305d7229fb99a536293b5d52cdb9ce3c820d6c8Maxim Siniavine return size; 50882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 50982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 51082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 51182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Helper to remove all downloads that are registered with the DL Manager. 51282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 51382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Note: This gives us a clean slate b/c it includes downloads that are pending, running, 51482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * paused, or have completed. 51582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 51682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected void removeAllCurrentDownloads() { 51782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Log.i(LOG_TAG, "Removing all current registered downloads..."); 51882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Cursor cursor = mDownloadManager.query(new Query()); 51982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori try { 52082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori if (cursor.moveToFirst()) { 52182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori do { 52282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int index = cursor.getColumnIndex(DownloadManager.COLUMN_ID); 52382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori long downloadId = cursor.getLong(index); 52482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 52582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori mDownloadManager.remove(downloadId); 52682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } while (cursor.moveToNext()); 52782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 52882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } finally { 52982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori cursor.close(); 53082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 53182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 53282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 53382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori /** 53482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * Performs a query based on ID and returns a Cursor for the query. 53582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * 53682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @param id The id of the download in DL Manager; pass -1 to query all downloads 53782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori * @return A cursor for the query results 53882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori */ 53982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori protected Cursor getCursor(long id) throws Exception { 54082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Query query = new Query(); 54182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori if (id != -1) { 54282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori query.setFilterById(id); 54382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 54482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 54582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Cursor cursor = mDownloadManager.query(query); 54682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori int currentWaitTime = 0; 54782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori 54882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori try { 54982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori while (!cursor.moveToFirst()) { 55082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori Thread.sleep(DEFAULT_WAIT_POLL_TIME); 55182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori currentWaitTime += DEFAULT_WAIT_POLL_TIME; 55282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori if (currentWaitTime > DEFAULT_MAX_WAIT_TIME) { 55382e891b3259350a92b55969a6380ca1240ee0829Vasu Nori fail("timed out waiting for a non-null query result"); 55482e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 55582e891b3259350a92b55969a6380ca1240ee0829Vasu Nori cursor.requery(); 55682e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 55782e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } catch (Exception e) { 55882e891b3259350a92b55969a6380ca1240ee0829Vasu Nori cursor.close(); 55982e891b3259350a92b55969a6380ca1240ee0829Vasu Nori throw e; 56082e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 56182e891b3259350a92b55969a6380ca1240ee0829Vasu Nori return cursor; 56282e891b3259350a92b55969a6380ca1240ee0829Vasu Nori } 563fbfe6d971d63860c02a71d69c3c7c29a2e958734Neal Nguyen} 564