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