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