DownloadManagerTestApp.java revision a305d7229fb99a536293b5d52cdb9ce3c820d6c8
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.frameworks.downloadmanagertests; 17 18import android.app.DownloadManager; 19import android.app.DownloadManager.Request; 20import android.database.Cursor; 21import android.net.Uri; 22import android.os.Environment; 23import android.os.ParcelFileDescriptor; 24import android.util.Log; 25 26import java.io.DataInputStream; 27import java.io.DataOutputStream; 28import java.io.File; 29import java.io.FileInputStream; 30import java.io.FileOutputStream; 31import java.util.HashSet; 32 33/** 34 * Class to test downloading files from a real (not mock) external server. 35 */ 36public class DownloadManagerTestApp extends DownloadManagerBaseTest { 37 protected static String DOWNLOAD_STARTED_FLAG = "DMTEST_DOWNLOAD_STARTED"; 38 protected static String LOG_TAG = 39 "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp"; 40 41 protected static final String DOWNLOAD_FILENAME = "External93mb.apk"; 42 protected static final long DOWNLOAD_FILESIZE = 95251708; 43 44 private static final String FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX = "file"; 45 private static final String FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION = ".bin"; 46 protected static long CONCURRENT_DOWNLOAD_FILESIZE = 1000000; 47 48 // Values to be obtained from TestRunner 49 private String externalDownloadUriValue = null; 50 private String externalLargeDownloadUriValue = null; 51 52 /** 53 * {@inheritDoc } 54 */ 55 @Override 56 public void setUp() throws Exception { 57 super.setUp(); 58 DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation(); 59 externalDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue); 60 assertNotNull(externalDownloadUriValue); 61 62 externalLargeDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue); 63 assertNotNull(externalLargeDownloadUriValue); 64 } 65 66 /** 67 * Normalizes a uri to ensure it ends with a "/" 68 * 69 * @param uri The uri to normalize (or null) 70 * @return The normalized uri, or null if null was passed in 71 */ 72 public String normalizeUri(String uri) { 73 if (uri != null && !uri.endsWith("/")) { 74 uri += "/"; 75 } 76 return uri; 77 } 78 79 /** 80 * Gets the external URL of the file to download 81 * 82 * @return the Uri of the external file to download 83 */ 84 private Uri getExternalFileUri(String file) { 85 return Uri.parse(externalDownloadUriValue + file); 86 } 87 88 /** 89 * Gets the path to the file that flags that a download has started. The file contains the 90 * DownloadManager id of the download being trackted between reboot sessions. 91 * 92 * @return The path of the file tracking that a download has started 93 * @throws InterruptedException if interrupted 94 * @throws Exception if timed out while waiting for SD card to mount 95 */ 96 protected String getDownloadStartedFilePath() { 97 String path = Environment.getExternalStorageDirectory().getPath(); 98 return path + File.separatorChar + DOWNLOAD_STARTED_FLAG; 99 } 100 101 /** 102 * Common setup steps for downloads. 103 * 104 * Note that these are not included in setUp, so that individual tests can control their own 105 * state between reboots, etc. 106 */ 107 protected void doCommonDownloadSetup() throws Exception { 108 setWiFiStateOn(true); 109 setAirplaneModeOn(false); 110 waitForExternalStoreMount(); 111 removeAllCurrentDownloads(); 112 } 113 114 /** 115 * Initiates a download. 116 * 117 * Queues up a download to the download manager, and saves the DownloadManager's assigned 118 * download ID for this download to a file. 119 * 120 * @throws Exception if unsuccessful 121 */ 122 public void initiateDownload() throws Exception { 123 String filename = DOWNLOAD_FILENAME; 124 mContext.deleteFile(DOWNLOAD_STARTED_FLAG); 125 FileOutputStream fileOutput = mContext.openFileOutput(DOWNLOAD_STARTED_FLAG, 0); 126 DataOutputStream outputFile = null; 127 doCommonDownloadSetup(); 128 129 try { 130 long dlRequest = -1; 131 132 // Make sure there are no pending downloads currently going on 133 removeAllCurrentDownloads(); 134 135 Uri remoteUri = getExternalFileUri(filename); 136 Request request = new Request(remoteUri); 137 138 dlRequest = mDownloadManager.enqueue(request); 139 waitForDownloadToStart(dlRequest); 140 assertTrue(dlRequest != -1); 141 142 // Store ID of download for later retrieval 143 outputFile = new DataOutputStream(fileOutput); 144 outputFile.writeLong(dlRequest); 145 } finally { 146 if (outputFile != null) { 147 outputFile.flush(); 148 outputFile.close(); 149 } 150 } 151 } 152 153 /** 154 * Waits for a previously-initiated download and verifies it has completed successfully. 155 * 156 * @throws Exception if unsuccessful 157 */ 158 public void verifyFileDownloadSucceeded() throws Exception { 159 String filename = DOWNLOAD_FILENAME; 160 long filesize = DOWNLOAD_FILESIZE; 161 long dlRequest = -1; 162 boolean rebootMarkerValid = false; 163 DataInputStream dataInputFile = null; 164 165 setWiFiStateOn(true); 166 setAirplaneModeOn(false); 167 168 try { 169 FileInputStream inFile = mContext.openFileInput(DOWNLOAD_STARTED_FLAG); 170 dataInputFile = new DataInputStream(inFile); 171 dlRequest = dataInputFile.readLong(); 172 } catch (Exception e) { 173 // The file was't valid so we just leave the flag false 174 Log.i(LOG_TAG, "Unable to determine initial download id."); 175 throw e; 176 } finally { 177 if (dataInputFile != null) { 178 dataInputFile.close(); 179 } 180 mContext.deleteFile(DOWNLOAD_STARTED_FLAG); 181 } 182 183 assertTrue(dlRequest != -1); 184 Cursor cursor = getCursor(dlRequest); 185 ParcelFileDescriptor pfd = null; 186 try { 187 assertTrue("Unable to query last initiated download!", cursor.moveToFirst()); 188 189 int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS); 190 int status = cursor.getInt(columnIndex); 191 int currentWaitTime = 0; 192 193 assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000)); 194 195 Log.i(LOG_TAG, "Verifying download information..."); 196 // Verify specific info about the file (size, name, etc)... 197 pfd = mDownloadManager.openDownloadedFile(dlRequest); 198 verifyFileSize(pfd, filesize); 199 } catch (Exception e) { 200 Log.i(LOG_TAG, "error: " + e.toString()); 201 throw e; 202 } finally { 203 // Clean up... 204 cursor.close(); 205 mDownloadManager.remove(dlRequest); 206 if (pfd != null) { 207 pfd.close(); 208 } 209 } 210 } 211 212 /** 213 * Tests downloading a large file over WiFi (~10 Mb). 214 * 215 * @throws Exception if unsuccessful 216 */ 217 public void runLargeDownloadOverWiFi() throws Exception { 218 String filename = DOWNLOAD_FILENAME; 219 long filesize = DOWNLOAD_FILESIZE; 220 long dlRequest = -1; 221 doCommonDownloadSetup(); 222 223 // Make sure there are no pending downloads currently going on 224 removeAllCurrentDownloads(); 225 226 Uri remoteUri = getExternalFileUri(filename); 227 Request request = new Request(remoteUri); 228 request.setMimeType("application/vnd.android.package-archive"); 229 230 dlRequest = mDownloadManager.enqueue(request); 231 232 // Rather large file, so wait up to 15 mins... 233 assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000)); 234 235 Cursor cursor = getCursor(dlRequest); 236 ParcelFileDescriptor pfd = null; 237 try { 238 Log.i(LOG_TAG, "Verifying download information..."); 239 // Verify specific info about the file (size, name, etc)... 240 pfd = mDownloadManager.openDownloadedFile(dlRequest); 241 verifyFileSize(pfd, filesize); 242 } finally { 243 if (pfd != null) { 244 pfd.close(); 245 } 246 mDownloadManager.remove(dlRequest); 247 cursor.close(); 248 } 249 } 250 251 /** 252 * Tests that downloads resume when switching back and forth from having connectivity to 253 * having no connectivity using both WiFi and airplane mode. 254 * 255 * Note: Device has no mobile access when running this test. 256 * 257 * @throws Exception if unsuccessful 258 */ 259 public void runDownloadMultipleSwitching() throws Exception { 260 String filename = DOWNLOAD_FILENAME; 261 long filesize = DOWNLOAD_FILESIZE; 262 doCommonDownloadSetup(); 263 264 String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath(); 265 File downloadedFile = new File(localDownloadDirectory, filename); 266 267 long dlRequest = -1; 268 try { 269 downloadedFile.delete(); 270 271 // Make sure there are no pending downloads currently going on 272 removeAllCurrentDownloads(); 273 274 Uri remoteUri = getExternalFileUri(filename); 275 Request request = new Request(remoteUri); 276 277 // Local destination of downloaded file 278 Uri localUri = Uri.fromFile(downloadedFile); 279 Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath()); 280 request.setDestinationUri(localUri); 281 282 request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI); 283 284 dlRequest = mDownloadManager.enqueue(request); 285 waitForDownloadToStart(dlRequest); 286 // make sure we're starting to download some data... 287 waitToReceiveData(dlRequest); 288 289 // download disable 290 setWiFiStateOn(false); 291 292 // download disable 293 Log.i(LOG_TAG, "Turning on airplane mode..."); 294 setAirplaneModeOn(true); 295 Thread.sleep(30 * 1000); // wait 30 secs 296 297 // download disable 298 setWiFiStateOn(true); 299 Thread.sleep(30 * 1000); // wait 30 secs 300 301 // download enable 302 Log.i(LOG_TAG, "Turning off airplane mode..."); 303 setAirplaneModeOn(false); 304 Thread.sleep(5 * 1000); // wait 5 seconds 305 306 // download disable 307 Log.i(LOG_TAG, "Turning off WiFi..."); 308 setWiFiStateOn(false); 309 Thread.sleep(30 * 1000); // wait 30 secs 310 311 // finally, turn WiFi back on and finish up the download 312 Log.i(LOG_TAG, "Turning on WiFi..."); 313 setWiFiStateOn(true); 314 Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete..."); 315 assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000)); 316 ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest); 317 verifyFileSize(pfd, filesize); 318 } finally { 319 Log.i(LOG_TAG, "Cleaning up files..."); 320 if (dlRequest != -1) { 321 mDownloadManager.remove(dlRequest); 322 } 323 downloadedFile.delete(); 324 } 325 } 326 327 /** 328 * Tests that downloads resume when switching on/off WiFi at various intervals. 329 * 330 * Note: Device has no mobile access when running this test. 331 * 332 * @throws Exception if unsuccessful 333 */ 334 public void runDownloadMultipleWiFiEnableDisable() throws Exception { 335 String filename = DOWNLOAD_FILENAME; 336 long filesize = DOWNLOAD_FILESIZE; 337 doCommonDownloadSetup(); 338 339 String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath(); 340 File downloadedFile = new File(localDownloadDirectory, filename); 341 long dlRequest = -1; 342 try { 343 downloadedFile.delete(); 344 345 // Make sure there are no pending downloads currently going on 346 removeAllCurrentDownloads(); 347 348 Uri remoteUri = getExternalFileUri(filename); 349 Request request = new Request(remoteUri); 350 351 // Local destination of downloaded file 352 Uri localUri = Uri.fromFile(downloadedFile); 353 Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath()); 354 request.setDestinationUri(localUri); 355 356 request.setAllowedNetworkTypes(Request.NETWORK_WIFI); 357 358 dlRequest = mDownloadManager.enqueue(request); 359 waitForDownloadToStart(dlRequest); 360 // are we making any progress? 361 waitToReceiveData(dlRequest); 362 363 // download disable 364 Log.i(LOG_TAG, "Turning off WiFi..."); 365 setWiFiStateOn(false); 366 Thread.sleep(40 * 1000); // wait 40 seconds 367 368 // enable download... 369 Log.i(LOG_TAG, "Turning on WiFi again..."); 370 setWiFiStateOn(true); 371 waitToReceiveData(dlRequest); 372 373 // download disable 374 Log.i(LOG_TAG, "Turning off WiFi..."); 375 setWiFiStateOn(false); 376 Thread.sleep(20 * 1000); // wait 20 seconds 377 378 // enable download... 379 Log.i(LOG_TAG, "Turning on WiFi again..."); 380 setWiFiStateOn(true); 381 382 Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete..."); 383 assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000)); 384 ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest); 385 verifyFileSize(pfd, filesize); 386 } finally { 387 Log.i(LOG_TAG, "Cleaning up files..."); 388 if (dlRequest != -1) { 389 mDownloadManager.remove(dlRequest); 390 } 391 downloadedFile.delete(); 392 } 393 } 394 395 /** 396 * Tests that downloads resume when switching on/off Airplane mode numerous times at 397 * various intervals. 398 * 399 * Note: Device has no mobile access when running this test. 400 * 401 * @throws Exception if unsuccessful 402 */ 403 public void runDownloadMultipleAirplaneModeEnableDisable() throws Exception { 404 String filename = DOWNLOAD_FILENAME; 405 long filesize = DOWNLOAD_FILESIZE; 406 // make sure WiFi is enabled, and airplane mode is not on 407 doCommonDownloadSetup(); 408 409 String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath(); 410 File downloadedFile = new File(localDownloadDirectory, filename); 411 long dlRequest = -1; 412 try { 413 downloadedFile.delete(); 414 415 // Make sure there are no pending downloads currently going on 416 removeAllCurrentDownloads(); 417 418 Uri remoteUri = getExternalFileUri(filename); 419 Request request = new Request(remoteUri); 420 421 // Local destination of downloaded file 422 Uri localUri = Uri.fromFile(downloadedFile); 423 Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath()); 424 request.setDestinationUri(localUri); 425 426 request.setAllowedNetworkTypes(Request.NETWORK_WIFI); 427 428 dlRequest = mDownloadManager.enqueue(request); 429 waitForDownloadToStart(dlRequest); 430 // are we making any progress? 431 waitToReceiveData(dlRequest); 432 433 // download disable 434 Log.i(LOG_TAG, "Turning on Airplane mode..."); 435 setAirplaneModeOn(true); 436 Thread.sleep(60 * 1000); // wait 1 minute 437 438 // download enable 439 Log.i(LOG_TAG, "Turning off Airplane mode..."); 440 setAirplaneModeOn(false); 441 // make sure we're starting to download some data... 442 waitToReceiveData(dlRequest); 443 444 // reenable the connection to start up the download again 445 Log.i(LOG_TAG, "Turning on Airplane mode again..."); 446 setAirplaneModeOn(true); 447 Thread.sleep(20 * 1000); // wait 20 seconds 448 449 // Finish up the download... 450 Log.i(LOG_TAG, "Turning off Airplane mode again..."); 451 setAirplaneModeOn(false); 452 453 Log.i(LOG_TAG, "Waiting up to 3 minutes for donwload to complete..."); 454 assertTrue(waitForDownload(dlRequest, 180 * 1000)); // wait up to 3 mins before timeout 455 ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest); 456 verifyFileSize(pfd, filesize); 457 } finally { 458 Log.i(LOG_TAG, "Cleaning up files..."); 459 if (dlRequest != -1) { 460 mDownloadManager.remove(dlRequest); 461 } 462 downloadedFile.delete(); 463 } 464 } 465 466 /** 467 * Tests 15 concurrent downloads of 1,000,000-byte files. 468 * 469 * @throws Exception if test failed 470 */ 471 public void runDownloadMultipleSimultaneously() throws Exception { 472 final int TOTAL_DOWNLOADS = 15; 473 HashSet<Long> downloadIds = new HashSet<Long>(TOTAL_DOWNLOADS); 474 475 // Make sure there are no pending downloads currently going on 476 removeAllCurrentDownloads(); 477 478 try { 479 for (int i = 0; i < TOTAL_DOWNLOADS; ++i) { 480 long dlRequest = -1; 481 String filename = FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX + i 482 + FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION; 483 Uri remoteUri = getExternalFileUri(filename); 484 Request request = new Request(remoteUri); 485 request.setTitle(filename); 486 dlRequest = mDownloadManager.enqueue(request); 487 assertTrue(dlRequest != -1); 488 downloadIds.add(dlRequest); 489 } 490 491 assertTrue(waitForMultipleDownloads(downloadIds, 15 * 60 * 2000)); // wait 15 mins max 492 } finally { 493 removeAllCurrentDownloads(); 494 } 495 } 496} 497