blob: 4a5385256923a270515b4ced6c13c563fc58aef3 [file] [log] [blame]
Neal Nguyen40ef0f42010-08-09 14:08:26 -07001/*
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 */
16
Steve Howard31fd85f2010-09-27 16:32:39 -070017package android.app;
Neal Nguyen40ef0f42010-08-09 14:08:26 -070018
Steve Howard31fd85f2010-09-27 16:32:39 -070019import android.app.DownloadManager.Query;
20import android.app.DownloadManager.Request;
Neal Nguyen40ef0f42010-08-09 14:08:26 -070021import android.database.Cursor;
Steve Howard31fd85f2010-09-27 16:32:39 -070022import android.net.Uri;
Neal Nguyen40ef0f42010-08-09 14:08:26 -070023import android.os.Environment;
24import android.os.ParcelFileDescriptor;
Neal Nguyen40ef0f42010-08-09 14:08:26 -070025import android.test.suitebuilder.annotation.LargeTest;
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -070026import com.google.mockwebserver.MockResponse;
27
Neal Nguyen40ef0f42010-08-09 14:08:26 -070028import java.io.File;
Md Haquec6272b92016-03-08 14:51:33 -080029import java.util.concurrent.TimeoutException;
Neal Nguyendf7a8652010-09-09 14:54:26 -070030import java.util.Iterator;
Neal Nguyendf7a8652010-09-09 14:54:26 -070031import java.util.Set;
Neal Nguyen40ef0f42010-08-09 14:08:26 -070032
Neal Nguyen40ef0f42010-08-09 14:08:26 -070033/**
34 * Integration tests of the DownloadManager API.
35 */
Vasu Nori82e891b2010-12-15 14:42:30 -080036public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
37 private static final String TAG = "DownloadManagerFunctionalTest";
Neal Nguyendf7a8652010-09-09 14:54:26 -070038 private final static String CACHE_DIR =
39 Environment.getDownloadCacheDirectory().getAbsolutePath();
Vasu Nori82e891b2010-12-15 14:42:30 -080040 private final static String PROHIBITED_DIRECTORY =
41 Environment.getRootDirectory().getAbsolutePath();
Neal Nguyen40ef0f42010-08-09 14:08:26 -070042
43 /**
44 * {@inheritDoc}
45 */
46 @Override
47 public void setUp() throws Exception {
48 super.setUp();
49 setWiFiStateOn(true);
Neal Nguyen40ef0f42010-08-09 14:08:26 -070050 removeAllCurrentDownloads();
Neal Nguyen40ef0f42010-08-09 14:08:26 -070051 }
52
53 /**
54 * {@inheritDoc}
55 */
56 @Override
57 public void tearDown() throws Exception {
58 super.tearDown();
59 setWiFiStateOn(true);
Neal Nguyendf7a8652010-09-09 14:54:26 -070060 removeAllCurrentDownloads();
Neal Nguyen40ef0f42010-08-09 14:08:26 -070061
62 if (mReceiver != null) {
63 mContext.unregisterReceiver(mReceiver);
64 mReceiver = null;
Neal Nguyen40ef0f42010-08-09 14:08:26 -070065 }
66 }
67
68 /**
Neal Nguyendf7a8652010-09-09 14:54:26 -070069 * Verifies a particular error code was received from a download
70 *
71 * @param uri The uri to enqueue to the DownloadManager
72 * @param error The error code expected
Vasu Nori82e891b2010-12-15 14:42:30 -080073 * @throws Exception if the test fails
Neal Nguyendf7a8652010-09-09 14:54:26 -070074 */
Neal Nguyendf7a8652010-09-09 14:54:26 -070075 public void doErrorTest(Uri uri, int error) throws Exception {
76 Request request = new Request(uri);
77 request.setTitle(DEFAULT_FILENAME);
78
79 long dlRequest = mDownloadManager.enqueue(request);
Md Haquec6272b92016-03-08 14:51:33 -080080 try {
81 waitForDownloadOrTimeout(dlRequest);
82 } catch (TimeoutException ex) {
83 // it is expected to timeout as download never finishes
84 }
Neal Nguyendf7a8652010-09-09 14:54:26 -070085
86 Cursor cursor = getCursor(dlRequest);
87 try {
Steve Howard3e8c1d32010-09-29 17:03:32 -070088 verifyInt(cursor, DownloadManager.COLUMN_REASON, error);
Neal Nguyendf7a8652010-09-09 14:54:26 -070089 } finally {
90 cursor.close();
91 }
Neal Nguyen40ef0f42010-08-09 14:08:26 -070092 }
93
94 /**
95 * Test a basic download of a binary file 500k in size.
96 */
Md Haque0ef9faf2016-03-10 10:48:49 -080097 @LargeTest
Vasu Nori82e891b2010-12-15 14:42:30 -080098 public void testBinaryDownloadToSystemCache() throws Exception {
99 int fileSize = 1024;
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700100 byte[] blobData = generateData(fileSize, DataType.BINARY);
101
Vasu Nori82e891b2010-12-15 14:42:30 -0800102 long dlRequest = doBasicDownload(blobData, DOWNLOAD_TO_SYSTEM_CACHE);
103 verifyDownload(dlRequest, blobData);
104 mDownloadManager.remove(dlRequest);
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700105 }
106
107 /**
108 * Tests the basic downloading of a text file 300000 bytes in size.
109 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800110 @LargeTest
Vasu Nori82e891b2010-12-15 14:42:30 -0800111 public void testTextDownloadToSystemCache() throws Exception {
112 int fileSize = 1024;
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700113 byte[] blobData = generateData(fileSize, DataType.TEXT);
114
Vasu Nori82e891b2010-12-15 14:42:30 -0800115 long dlRequest = doBasicDownload(blobData, DOWNLOAD_TO_SYSTEM_CACHE);
116 verifyDownload(dlRequest, blobData);
117 mDownloadManager.remove(dlRequest);
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700118 }
Md Haquec6272b92016-03-08 14:51:33 -0800119
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700120 /**
Vasu Nori82e891b2010-12-15 14:42:30 -0800121 * Helper to verify a standard single-file download from the mock server, and clean up after
122 * verification
123 *
124 * Note that this also calls the Download manager's remove, which cleans up the file from cache.
125 *
126 * @param requestId The id of the download to remove
127 * @param fileData The data to verify the file contains
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700128 */
Vasu Nori82e891b2010-12-15 14:42:30 -0800129 private void verifyDownload(long requestId, byte[] fileData)
130 throws Exception {
131 int fileSize = fileData.length;
132 ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(requestId);
133 Cursor cursor = mDownloadManager.query(new Query().setFilterById(requestId));
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700134 try {
Vasu Nori82e891b2010-12-15 14:42:30 -0800135 assertEquals(1, cursor.getCount());
136 assertTrue(cursor.moveToFirst());
137
Vasu Nori82e891b2010-12-15 14:42:30 -0800138 verifyFileSize(pfd, fileSize);
139 verifyFileContents(pfd, fileData);
Md Haquec6272b92016-03-08 14:51:33 -0800140 assertTrue(new File(CACHE_DIR + "/" + DEFAULT_FILENAME).exists());
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700141 } finally {
Vasu Nori82e891b2010-12-15 14:42:30 -0800142 pfd.close();
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700143 cursor.close();
144 }
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700145 }
146
147 /**
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700148 * Tests trying to download to SD card when the file with same name already exists.
149 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800150 @LargeTest
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700151 public void testDownloadToExternal_fileExists() throws Exception {
152 File existentFile = createFileOnSD(null, 1, DataType.TEXT, null);
153 byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
154
155 // Prepare the mock server with a standard response
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700156 enqueueResponse(buildResponse(HTTP_OK, blobData));
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700157
158 try {
159 Uri uri = getServerUri(DEFAULT_FILENAME);
160 Request request = new Request(uri);
161
162 Uri localUri = Uri.fromFile(existentFile);
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700163 request.setDestinationUri(localUri);
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700164 long dlRequest = mDownloadManager.enqueue(request);
165
166 // wait for the download to complete
167 waitForDownloadOrTimeout(dlRequest);
168 Cursor cursor = getCursor(dlRequest);
169
170 try {
Vasu Nori82e891b2010-12-15 14:42:30 -0800171 verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_SUCCESSFUL);
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700172 } finally {
173 cursor.close();
174 }
175 } finally {
176 existentFile.delete();
177 }
178 }
179
180 /**
181 * Tests trying to download a file to SD card.
182 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800183 @LargeTest
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700184 public void testDownloadToExternal() throws Exception {
185 String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
186 File downloadedFile = new File(localDownloadDirectory, DEFAULT_FILENAME);
187 // make sure the file doesn't already exist in the directory
188 downloadedFile.delete();
189
190 try {
191 byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
192
193 // Prepare the mock server with a standard response
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700194 enqueueResponse(buildResponse(HTTP_OK, blobData));
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700195
196 Uri uri = getServerUri(DEFAULT_FILENAME);
197 Request request = new Request(uri);
198
199 Uri localUri = Uri.fromFile(downloadedFile);
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700200 request.setDestinationUri(localUri);
201
202 long dlRequest = mDownloadManager.enqueue(request);
203
204 // wait for the download to complete
205 waitForDownloadOrTimeout(dlRequest);
206
207 verifyAndCleanupSingleFileDownload(dlRequest, blobData);
208
209 assertEquals(1, mReceiver.numDownloadsCompleted());
210 } finally {
211 downloadedFile.delete();
212 }
213 }
214
215 /**
216 * Tests trying to download a file to the system partition.
217 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800218 @LargeTest
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700219 public void testDownloadToProhibitedDirectory() throws Exception {
220 File downloadedFile = new File(PROHIBITED_DIRECTORY, DEFAULT_FILENAME);
221 try {
222 byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
223
224 // Prepare the mock server with a standard response
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700225 enqueueResponse(buildResponse(HTTP_OK, blobData));
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700226
227 Uri uri = getServerUri(DEFAULT_FILENAME);
228 Request request = new Request(uri);
229
230 Uri localUri = Uri.fromFile(downloadedFile);
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700231 request.setDestinationUri(localUri);
232
233 try {
234 mDownloadManager.enqueue(request);
235 fail("Failed to throw SecurityException when trying to write to /system.");
236 } catch (SecurityException s) {
237 assertFalse(downloadedFile.exists());
238 }
239 } finally {
240 // Just in case file somehow got created, make sure to delete it
241 downloadedFile.delete();
242 }
243 }
244
245 /**
Neal Nguyendf7a8652010-09-09 14:54:26 -0700246 * Tests that we get the correct download ID from the download notification.
247 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800248 @LargeTest
Neal Nguyendf7a8652010-09-09 14:54:26 -0700249 public void testGetDownloadIdOnNotification() throws Exception {
250 byte[] blobData = generateData(3000, DataType.TEXT); // file size = 3000 bytes
251
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700252 enqueueResponse(buildResponse(HTTP_OK, blobData));
Neal Nguyendf7a8652010-09-09 14:54:26 -0700253 long dlRequest = doCommonStandardEnqueue();
254 waitForDownloadOrTimeout(dlRequest);
255
256 Set<Long> ids = mReceiver.getDownloadIds();
257 assertEquals(1, ids.size());
258 Iterator<Long> it = ids.iterator();
259 assertEquals("Download ID received from notification does not match initial id!",
260 dlRequest, it.next().longValue());
261 }
262
263 /**
264 * Tests the download failure error after too many redirects (>5).
265 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800266 @LargeTest
Neal Nguyendf7a8652010-09-09 14:54:26 -0700267 public void testErrorTooManyRedirects() throws Exception {
268 Uri uri = getServerUri(DEFAULT_FILENAME);
269
270 // force 6 redirects
271 for (int i = 0; i < 6; ++i) {
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700272 final MockResponse resp = buildResponse(HTTP_REDIRECT);
273 resp.setHeader("Location", uri.toString());
274 enqueueResponse(resp);
Neal Nguyendf7a8652010-09-09 14:54:26 -0700275 }
276 doErrorTest(uri, DownloadManager.ERROR_TOO_MANY_REDIRECTS);
277 }
278
279 /**
280 * Tests the download failure error from an unhandled HTTP status code
281 */
282 @LargeTest
283 public void testErrorUnhandledHttpCode() throws Exception {
284 Uri uri = getServerUri(DEFAULT_FILENAME);
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700285 enqueueResponse(buildResponse(HTTP_PARTIAL_CONTENT));
Neal Nguyendf7a8652010-09-09 14:54:26 -0700286
287 doErrorTest(uri, DownloadManager.ERROR_UNHANDLED_HTTP_CODE);
288 }
289
290 /**
291 * Tests the download failure error from an unhandled HTTP status code
292 */
293 @LargeTest
294 public void testErrorHttpDataError_invalidRedirect() throws Exception {
295 Uri uri = getServerUri(DEFAULT_FILENAME);
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700296 final MockResponse resp = buildResponse(HTTP_REDIRECT);
297 resp.setHeader("Location", "://blah.blah.blah.com");
298 enqueueResponse(resp);
Neal Nguyendf7a8652010-09-09 14:54:26 -0700299
300 doErrorTest(uri, DownloadManager.ERROR_HTTP_DATA_ERROR);
301 }
302
303 /**
304 * Tests that we can remove a download from the download manager.
305 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800306 @LargeTest
Neal Nguyendf7a8652010-09-09 14:54:26 -0700307 public void testRemoveDownload() throws Exception {
Vasu Nori82e891b2010-12-15 14:42:30 -0800308 int fileSize = 1024;
Neal Nguyendf7a8652010-09-09 14:54:26 -0700309 byte[] blobData = generateData(fileSize, DataType.BINARY);
310
Vasu Nori82e891b2010-12-15 14:42:30 -0800311 long dlRequest = doBasicDownload(blobData, DOWNLOAD_TO_DOWNLOAD_CACHE_DIR);
Neal Nguyendf7a8652010-09-09 14:54:26 -0700312 Cursor cursor = mDownloadManager.query(new Query().setFilterById(dlRequest));
313 try {
314 assertEquals("The count of downloads with this ID is not 1!", 1, cursor.getCount());
315 mDownloadManager.remove(dlRequest);
316 cursor.requery();
317 assertEquals("The count of downloads with this ID is not 0!", 0, cursor.getCount());
318 } finally {
319 cursor.close();
320 }
321 }
322
323 /**
324 * Tests that we can set the title of a download.
325 */
Md Haque0ef9faf2016-03-10 10:48:49 -0800326 @LargeTest
Neal Nguyendf7a8652010-09-09 14:54:26 -0700327 public void testSetTitle() throws Exception {
Vasu Nori82e891b2010-12-15 14:42:30 -0800328 int fileSize = 1024;
Neal Nguyendf7a8652010-09-09 14:54:26 -0700329 byte[] blobData = generateData(fileSize, DataType.BINARY);
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700330 enqueueResponse(buildResponse(HTTP_OK, blobData));
Neal Nguyendf7a8652010-09-09 14:54:26 -0700331
332 // An arbitrary unicode string title
333 final String title = "\u00a5123;\"\u0152\u017d \u054b \u0a07 \ucce0 \u6820\u03a8\u5c34" +
334 "\uf4ad\u0da9\uc0c5\uc1a8 \uf4c5 \uf4aa\u0023\'";
335
336 Uri uri = getServerUri(DEFAULT_FILENAME);
337 Request request = new Request(uri);
338 request.setTitle(title);
339
340 long dlRequest = mDownloadManager.enqueue(request);
341 waitForDownloadOrTimeout(dlRequest);
342
343 Cursor cursor = getCursor(dlRequest);
344 try {
345 verifyString(cursor, DownloadManager.COLUMN_TITLE, title);
346 } finally {
347 cursor.close();
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700348 }
349 }
Vasu Nori82e891b2010-12-15 14:42:30 -0800350
351 /**
352 * Tests that a download set for Wifi does not progress while Wifi is disabled, but resumes
353 * once Wifi is re-enabled.
354 */
355 @LargeTest
356 public void testDownloadNoWifi() throws Exception {
357 long timeout = 60 * 1000; // wait only 60 seconds before giving up
358 int fileSize = 1024; // 140k
359 byte[] blobData = generateData(fileSize, DataType.TEXT);
360
361 setWiFiStateOn(false);
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700362 enqueueResponse(buildResponse(HTTP_OK, blobData));
Vasu Nori82e891b2010-12-15 14:42:30 -0800363
364 try {
365 Uri uri = getServerUri(DEFAULT_FILENAME);
366 Request request = new Request(uri);
367 request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
368
369 long dlRequest = mDownloadManager.enqueue(request);
370
371 // wait for the download to complete
372 boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest,
373 WAIT_FOR_DOWNLOAD_POLL_TIME, timeout);
374 assertFalse("Download proceeded without Wifi connection!", success);
375
376 setWiFiStateOn(true);
377 waitForDownloadOrTimeout(dlRequest);
378
379 assertEquals(1, mReceiver.numDownloadsCompleted());
380 } finally {
381 setWiFiStateOn(true);
382 }
383 }
384
385 /**
Vasu Nori82e891b2010-12-15 14:42:30 -0800386 * Tests that we get an error code when the server drops the connection during a download.
387 */
388 @LargeTest
389 public void testServerDropConnection_body() throws Exception {
390 byte[] blobData = generateData(25000, DataType.TEXT); // file size = 25000 bytes
391
Jeff Sharkeyb14ad8c2012-03-28 18:59:21 -0700392 final MockResponse resp = buildResponse(HTTP_OK, blobData);
393 resp.setHeader("Content-Length", "50000");
394 enqueueResponse(resp);
395
Vasu Nori82e891b2010-12-15 14:42:30 -0800396 long dlRequest = doCommonStandardEnqueue();
397 waitForDownloadOrTimeout(dlRequest);
398
399 Cursor cursor = getCursor(dlRequest);
400 try {
401 verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
402 verifyInt(cursor, DownloadManager.COLUMN_REASON,
403 DownloadManager.ERROR_CANNOT_RESUME);
404 } finally {
405 cursor.close();
406 }
407 // Even tho the server drops the connection, we should still get a completed notification
408 assertEquals(1, mReceiver.numDownloadsCompleted());
409 }
Neal Nguyen40ef0f42010-08-09 14:08:26 -0700410}