Merge "fix downloadmanager tests. add few more. fix some. isolate flaky ones"
This commit is contained in:
@@ -36,6 +36,9 @@
|
||||
android:description="@string/permdesc_testDenied" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
|
||||
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED" />
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import coretestutils.http.MockResponse;
|
||||
import coretestutils.http.MockWebServer;
|
||||
|
||||
import android.app.DownloadManager.Query;
|
||||
import android.app.DownloadManager.Request;
|
||||
import android.app.DownloadManagerBaseTest.DataType;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -27,11 +31,10 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.SystemClock;
|
||||
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.util.Log;
|
||||
@@ -43,19 +46,12 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import coretestutils.http.MockResponse;
|
||||
import coretestutils.http.MockWebServer;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* Base class for Instrumented tests for the Download Manager.
|
||||
@@ -67,7 +63,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
|
||||
protected String mFileType = "text/plain";
|
||||
protected Context mContext = null;
|
||||
protected MultipleDownloadsCompletedReceiver mReceiver = null;
|
||||
protected static final int DEFAULT_FILE_SIZE = 130 * 1024; // 130kb
|
||||
protected static final int DEFAULT_FILE_SIZE = 10 * 1024; // 10kb
|
||||
protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024;
|
||||
|
||||
protected static final String LOG_TAG = "android.net.DownloadManagerBaseTest";
|
||||
@@ -85,6 +81,9 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
|
||||
protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
|
||||
protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes
|
||||
|
||||
protected static final int DOWNLOAD_TO_SYSTEM_CACHE = 1;
|
||||
protected static final int DOWNLOAD_TO_DOWNLOAD_CACHE_DIR = 2;
|
||||
|
||||
// Just a few popular file types used to return from a download
|
||||
protected enum DownloadFileType {
|
||||
PLAINTEXT,
|
||||
@@ -888,30 +887,46 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
|
||||
*/
|
||||
protected void removeAllCurrentDownloads() {
|
||||
Log.i(LOG_TAG, "Removing all current registered downloads...");
|
||||
ArrayList<Long> ids = new ArrayList<Long>();
|
||||
Cursor cursor = mDownloadManager.query(new Query());
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
int index = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
|
||||
long downloadId = cursor.getLong(index);
|
||||
|
||||
mDownloadManager.remove(downloadId);
|
||||
ids.add(downloadId);
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
// delete all ids
|
||||
for (long id : ids) {
|
||||
mDownloadManager.remove(id);
|
||||
}
|
||||
// make sure the database is empty
|
||||
cursor = mDownloadManager.query(new Query());
|
||||
try {
|
||||
assertEquals(0, cursor.getCount());
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to perform a standard enqueue of data to the mock server.
|
||||
* download is performed to the downloads cache dir (NOT systemcache dir)
|
||||
*
|
||||
* @param body The body to return in the response from the server
|
||||
*/
|
||||
protected long doStandardEnqueue(byte[] body) throws Exception {
|
||||
return enqueueDownloadRequest(body, DOWNLOAD_TO_DOWNLOAD_CACHE_DIR);
|
||||
}
|
||||
|
||||
protected long enqueueDownloadRequest(byte[] body, int location) throws Exception {
|
||||
// Prepare the mock server with a standard response
|
||||
enqueueResponse(HTTP_OK, body);
|
||||
return doCommonStandardEnqueue();
|
||||
return doEnqueue(location);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -920,9 +935,13 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
|
||||
* @param body The body to return in the response from the server, contained in the file
|
||||
*/
|
||||
protected long doStandardEnqueue(File body) throws Exception {
|
||||
return enqueueDownloadRequest(body, DOWNLOAD_TO_DOWNLOAD_CACHE_DIR);
|
||||
}
|
||||
|
||||
protected long enqueueDownloadRequest(File body, int location) throws Exception {
|
||||
// Prepare the mock server with a standard response
|
||||
enqueueResponse(HTTP_OK, body);
|
||||
return doCommonStandardEnqueue();
|
||||
return doEnqueue(location);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -930,13 +949,17 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
|
||||
* doing a standard enqueue request to the server.
|
||||
*/
|
||||
protected long doCommonStandardEnqueue() throws Exception {
|
||||
Uri uri = getServerUri(DEFAULT_FILENAME);
|
||||
Request request = new Request(uri);
|
||||
request.setTitle(DEFAULT_FILENAME);
|
||||
return doEnqueue(DOWNLOAD_TO_DOWNLOAD_CACHE_DIR);
|
||||
}
|
||||
|
||||
long dlRequest = mDownloadManager.enqueue(request);
|
||||
Log.i(LOG_TAG, "request ID: " + dlRequest);
|
||||
return dlRequest;
|
||||
private long doEnqueue(int location) throws Exception {
|
||||
Uri uri = getServerUri(DEFAULT_FILENAME);
|
||||
Request request = new Request(uri).setTitle(DEFAULT_FILENAME);
|
||||
if (location == DOWNLOAD_TO_SYSTEM_CACHE) {
|
||||
request.setDestinationToSystemCache();
|
||||
}
|
||||
|
||||
return mDownloadManager.enqueue(request);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -997,4 +1020,16 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that does the actual basic download verification.
|
||||
*/
|
||||
protected long doBasicDownload(byte[] blobData, int location) throws Exception {
|
||||
long dlRequest = enqueueDownloadRequest(blobData, location);
|
||||
|
||||
// wait for the download to complete
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
assertEquals(1, mReceiver.numDownloadsCompleted());
|
||||
return dlRequest;
|
||||
}
|
||||
}
|
||||
@@ -16,51 +16,35 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import coretestutils.http.MockResponse;
|
||||
|
||||
import android.app.DownloadManager.Query;
|
||||
import android.app.DownloadManager.Request;
|
||||
import android.app.DownloadManagerBaseTest.DataType;
|
||||
import android.app.DownloadManagerBaseTest.MultipleDownloadsCompletedReceiver;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Environment;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.StatFs;
|
||||
import android.os.SystemClock;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import coretestutils.http.MockResponse;
|
||||
import coretestutils.http.MockWebServer;
|
||||
|
||||
/**
|
||||
* Integration tests of the DownloadManager API.
|
||||
*/
|
||||
public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
|
||||
private final static String LOG_TAG = "android.net.DownloadManagerIntegrationTest";
|
||||
private final static String PROHIBITED_DIRECTORY =
|
||||
Environment.getRootDirectory().getAbsolutePath();
|
||||
public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
|
||||
private static final String TAG = "DownloadManagerFunctionalTest";
|
||||
private final static String CACHE_DIR =
|
||||
Environment.getDownloadCacheDirectory().getAbsolutePath();
|
||||
private final static String PROHIBITED_DIRECTORY =
|
||||
Environment.getRootDirectory().getAbsolutePath();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@@ -88,27 +72,13 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that does the actual basic download verification.
|
||||
*/
|
||||
protected long doBasicDownload(byte[] blobData) throws Exception {
|
||||
long dlRequest = doStandardEnqueue(blobData);
|
||||
|
||||
// wait for the download to complete
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
assertEquals(1, mReceiver.numDownloadsCompleted());
|
||||
return dlRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies a particular error code was received from a download
|
||||
*
|
||||
* @param uri The uri to enqueue to the DownloadManager
|
||||
* @param error The error code expected
|
||||
* @throws an Exception if the test fails
|
||||
* @throws Exception if the test fails
|
||||
*/
|
||||
@LargeTest
|
||||
public void doErrorTest(Uri uri, int error) throws Exception {
|
||||
Request request = new Request(uri);
|
||||
request.setTitle(DEFAULT_FILENAME);
|
||||
@@ -128,66 +98,57 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
* Test a basic download of a binary file 500k in size.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testBasicBinaryDownload() throws Exception {
|
||||
int fileSize = 500 * 1024; // 500k
|
||||
public void testBinaryDownloadToSystemCache() throws Exception {
|
||||
int fileSize = 1024;
|
||||
byte[] blobData = generateData(fileSize, DataType.BINARY);
|
||||
|
||||
long dlRequest = doBasicDownload(blobData);
|
||||
verifyAndCleanupSingleFileDownload(dlRequest, blobData);
|
||||
long dlRequest = doBasicDownload(blobData, DOWNLOAD_TO_SYSTEM_CACHE);
|
||||
verifyDownload(dlRequest, blobData);
|
||||
mDownloadManager.remove(dlRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the basic downloading of a text file 300000 bytes in size.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testBasicTextDownload() throws Exception {
|
||||
int fileSize = 300000;
|
||||
public void testTextDownloadToSystemCache() throws Exception {
|
||||
int fileSize = 1024;
|
||||
byte[] blobData = generateData(fileSize, DataType.TEXT);
|
||||
|
||||
long dlRequest = doBasicDownload(blobData);
|
||||
verifyAndCleanupSingleFileDownload(dlRequest, blobData);
|
||||
long dlRequest = doBasicDownload(blobData, DOWNLOAD_TO_SYSTEM_CACHE);
|
||||
verifyDownload(dlRequest, blobData);
|
||||
mDownloadManager.remove(dlRequest);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests when the server drops the connection after all headers (but before any data send).
|
||||
* Helper to verify a standard single-file download from the mock server, and clean up after
|
||||
* verification
|
||||
*
|
||||
* Note that this also calls the Download manager's remove, which cleans up the file from cache.
|
||||
*
|
||||
* @param requestId The id of the download to remove
|
||||
* @param fileData The data to verify the file contains
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDropConnection_headers() throws Exception {
|
||||
byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
|
||||
|
||||
MockResponse response = enqueueResponse(HTTP_OK, blobData);
|
||||
response.setCloseConnectionAfterHeader("content-length");
|
||||
long dlRequest = doCommonStandardEnqueue();
|
||||
|
||||
// Download will never complete when header is dropped
|
||||
boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest, DEFAULT_WAIT_POLL_TIME,
|
||||
DEFAULT_MAX_WAIT_TIME);
|
||||
|
||||
assertFalse(success);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we get an error code when the server drops the connection during a download.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testServerDropConnection_body() throws Exception {
|
||||
byte[] blobData = generateData(25000, DataType.TEXT); // file size = 25000 bytes
|
||||
|
||||
MockResponse response = enqueueResponse(HTTP_OK, blobData);
|
||||
response.setCloseConnectionAfterXBytes(15382);
|
||||
long dlRequest = doCommonStandardEnqueue();
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
Cursor cursor = getCursor(dlRequest);
|
||||
private void verifyDownload(long requestId, byte[] fileData)
|
||||
throws Exception {
|
||||
int fileSize = fileData.length;
|
||||
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(requestId);
|
||||
Cursor cursor = mDownloadManager.query(new Query().setFilterById(requestId));
|
||||
try {
|
||||
verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
|
||||
verifyInt(cursor, DownloadManager.COLUMN_REASON,
|
||||
DownloadManager.ERROR_CANNOT_RESUME);
|
||||
assertEquals(1, cursor.getCount());
|
||||
assertTrue(cursor.moveToFirst());
|
||||
|
||||
mServer.checkForExceptions();
|
||||
|
||||
verifyFileSize(pfd, fileSize);
|
||||
verifyFileContents(pfd, fileData);
|
||||
int colIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
|
||||
String fileName = cursor.getString(colIndex);
|
||||
assertTrue(fileName.startsWith(CACHE_DIR));
|
||||
} finally {
|
||||
pfd.close();
|
||||
cursor.close();
|
||||
}
|
||||
// Even tho the server drops the connection, we should still get a completed notification
|
||||
assertEquals(1, mReceiver.numDownloadsCompleted());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +159,7 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
// need to be sure all current downloads have stopped first
|
||||
removeAllCurrentDownloads();
|
||||
int NUM_FILES = 10;
|
||||
int MAX_FILE_SIZE = 500 * 1024; // 500 kb
|
||||
int MAX_FILE_SIZE = 10 * 1024; // 10 kb
|
||||
|
||||
Random r = new LoggingRng();
|
||||
for (int i=0; i<NUM_FILES; ++i) {
|
||||
@@ -213,7 +174,6 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
enqueueResponse(HTTP_OK, blobData);
|
||||
|
||||
long requestID = mDownloadManager.enqueue(request);
|
||||
Log.i(LOG_TAG, "request: " + i + " -- requestID: " + requestID);
|
||||
}
|
||||
|
||||
waitForDownloadsOrTimeout(WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
|
||||
@@ -236,8 +196,6 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
|
||||
assertEquals(NUM_FILES, mReceiver.numDownloadsCompleted());
|
||||
} finally {
|
||||
Log.i(LOG_TAG, "All download IDs: " + mReceiver.getDownloadIds().toString());
|
||||
Log.i(LOG_TAG, "Total downloads completed: " + mReceiver.getDownloadIds().size());
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
@@ -258,7 +216,6 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
Request request = new Request(uri);
|
||||
|
||||
Uri localUri = Uri.fromFile(existentFile);
|
||||
Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
|
||||
request.setDestinationUri(localUri);
|
||||
|
||||
long dlRequest = mDownloadManager.enqueue(request);
|
||||
@@ -268,9 +225,7 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
Cursor cursor = getCursor(dlRequest);
|
||||
|
||||
try {
|
||||
verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
|
||||
verifyInt(cursor, DownloadManager.COLUMN_REASON,
|
||||
DownloadManager.ERROR_FILE_ALREADY_EXISTS);
|
||||
verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_SUCCESSFUL);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
@@ -299,7 +254,6 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
Request request = new Request(uri);
|
||||
|
||||
Uri localUri = Uri.fromFile(downloadedFile);
|
||||
Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
|
||||
request.setDestinationUri(localUri);
|
||||
|
||||
long dlRequest = mDownloadManager.enqueue(request);
|
||||
@@ -331,7 +285,6 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
Request request = new Request(uri);
|
||||
|
||||
Uri localUri = Uri.fromFile(downloadedFile);
|
||||
Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
|
||||
request.setDestinationUri(localUri);
|
||||
|
||||
try {
|
||||
@@ -346,144 +299,6 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a download set for Wifi does not progress while Wifi is disabled, but resumes
|
||||
* once Wifi is re-enabled.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDownloadNoWifi() throws Exception {
|
||||
long timeout = 60 * 1000; // wait only 60 seconds before giving up
|
||||
int fileSize = 140 * 1024; // 140k
|
||||
byte[] blobData = generateData(fileSize, DataType.TEXT);
|
||||
|
||||
setWiFiStateOn(false);
|
||||
enqueueResponse(HTTP_OK, blobData);
|
||||
|
||||
try {
|
||||
Uri uri = getServerUri(DEFAULT_FILENAME);
|
||||
Request request = new Request(uri);
|
||||
request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
|
||||
|
||||
long dlRequest = mDownloadManager.enqueue(request);
|
||||
|
||||
// wait for the download to complete
|
||||
boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest,
|
||||
WAIT_FOR_DOWNLOAD_POLL_TIME, timeout);
|
||||
assertFalse("Download proceeded without Wifi connection!", success);
|
||||
|
||||
setWiFiStateOn(true);
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
assertEquals(1, mReceiver.numDownloadsCompleted());
|
||||
} finally {
|
||||
setWiFiStateOn(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests downloading a file to cache when there isn't enough space in the cache to hold the
|
||||
* entire file.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDownloadToCache_whenFull() throws Exception {
|
||||
int DOWNLOAD_FILE_SIZE = 500000;
|
||||
|
||||
StatFs fs = new StatFs(CACHE_DIR);
|
||||
Log.i(LOG_TAG, "getAvailableBlocks: " + fs.getAvailableBlocks());
|
||||
Log.i(LOG_TAG, "getBlockSize: " + fs.getBlockSize());
|
||||
|
||||
int blockSize = fs.getBlockSize();
|
||||
int availableBlocks = fs.getAvailableBlocks();
|
||||
int availableBytes = blockSize * availableBlocks;
|
||||
File outFile = null;
|
||||
|
||||
try {
|
||||
// fill cache to ensure we don't have enough space - take half the size of the
|
||||
// download size, and leave that much freespace left on the cache partition
|
||||
if (DOWNLOAD_FILE_SIZE <= availableBytes) {
|
||||
int writeSizeBytes = availableBytes - (DOWNLOAD_FILE_SIZE / 2);
|
||||
|
||||
int writeSizeBlocks = writeSizeBytes / blockSize;
|
||||
int remainderSizeBlocks = availableBlocks - writeSizeBlocks;
|
||||
|
||||
FileOutputStream fo = null;
|
||||
try {
|
||||
outFile = File.createTempFile("DM_TEST", null, new File(CACHE_DIR));
|
||||
Log.v(LOG_TAG, "writing " + writeSizeBlocks + " blocks to file "
|
||||
+ outFile.getAbsolutePath());
|
||||
|
||||
fo = new FileOutputStream(outFile);
|
||||
|
||||
byte[] buffer = new byte[blockSize];
|
||||
while (fs.getAvailableBlocks() >= remainderSizeBlocks) {
|
||||
fo.write(buffer);
|
||||
fs.restat(CACHE_DIR);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "error filling file: ", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (fo != null) {
|
||||
fo.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(LOG_TAG, "Done creating filler file.");
|
||||
assertTrue(DOWNLOAD_FILE_SIZE > (fs.getAvailableBlocks() * blockSize));
|
||||
byte[] blobData = generateData(DOWNLOAD_FILE_SIZE, DataType.TEXT);
|
||||
long dlRequest = doBasicDownload(blobData);
|
||||
verifyAndCleanupSingleFileDownload(dlRequest, blobData);
|
||||
|
||||
} finally {
|
||||
if (outFile != null) {
|
||||
outFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that files are not deleted when DOWNLOAD_CACHE_NON_PURGEABLE is set, even if we've
|
||||
* run out of space.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDownloadCacheNonPurgeable() throws Exception {
|
||||
int fileSize = 10000000;
|
||||
byte[] blobData = generateData(fileSize, DataType.BINARY);
|
||||
long dlRequest = -1;
|
||||
|
||||
// Fill up the cache partition until there's not enough room for another download.
|
||||
// Note that we need to initiate a download first, then check for the available space. This
|
||||
// is b/c there could be some files that are still left in the cache that can (and will be)
|
||||
// cleared out, but not until DM gets a request for a download and reclaims that
|
||||
// space first.
|
||||
boolean spaceAvailable = true;
|
||||
while (spaceAvailable) {
|
||||
dlRequest = doStandardEnqueue(blobData);
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
// Check if we've filled up the cache yet
|
||||
StatFs fs = new StatFs(CACHE_DIR);
|
||||
Log.i(LOG_TAG, "getAvailableBlocks: " + fs.getAvailableBlocks());
|
||||
Log.i(LOG_TAG, "getBlockSize: " + fs.getBlockSize());
|
||||
int availableBytes = fs.getBlockSize() * fs.getAvailableBlocks();
|
||||
spaceAvailable = (availableBytes > fileSize) ? true : false;
|
||||
}
|
||||
|
||||
// Now add one more download (should not fit in the space left over)
|
||||
dlRequest = doStandardEnqueue(blobData);
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
// For the last download we should have failed b/c there is not enough space left in cache
|
||||
Cursor cursor = getCursor(dlRequest);
|
||||
try {
|
||||
verifyInt(cursor, DownloadManager.COLUMN_REASON,
|
||||
DownloadManager.ERROR_INSUFFICIENT_SPACE);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we get the correct download ID from the download notification.
|
||||
*/
|
||||
@@ -545,10 +360,10 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
*/
|
||||
@LargeTest
|
||||
public void testRemoveDownload() throws Exception {
|
||||
int fileSize = 100 * 1024; // 100k
|
||||
int fileSize = 1024;
|
||||
byte[] blobData = generateData(fileSize, DataType.BINARY);
|
||||
|
||||
long dlRequest = doBasicDownload(blobData);
|
||||
long dlRequest = doBasicDownload(blobData, DOWNLOAD_TO_DOWNLOAD_CACHE_DIR);
|
||||
Cursor cursor = mDownloadManager.query(new Query().setFilterById(dlRequest));
|
||||
try {
|
||||
assertEquals("The count of downloads with this ID is not 1!", 1, cursor.getCount());
|
||||
@@ -565,7 +380,7 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
*/
|
||||
@LargeTest
|
||||
public void testSetTitle() throws Exception {
|
||||
int fileSize = 50 * 1024; // 50k
|
||||
int fileSize = 1024;
|
||||
byte[] blobData = generateData(fileSize, DataType.BINARY);
|
||||
MockResponse response = enqueueResponse(HTTP_OK, blobData);
|
||||
|
||||
@@ -587,4 +402,179 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a download set for Wifi does not progress while Wifi is disabled, but resumes
|
||||
* once Wifi is re-enabled.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDownloadNoWifi() throws Exception {
|
||||
long timeout = 60 * 1000; // wait only 60 seconds before giving up
|
||||
int fileSize = 1024; // 140k
|
||||
byte[] blobData = generateData(fileSize, DataType.TEXT);
|
||||
|
||||
setWiFiStateOn(false);
|
||||
enqueueResponse(HTTP_OK, blobData);
|
||||
|
||||
try {
|
||||
Uri uri = getServerUri(DEFAULT_FILENAME);
|
||||
Request request = new Request(uri);
|
||||
request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
|
||||
|
||||
long dlRequest = mDownloadManager.enqueue(request);
|
||||
|
||||
// wait for the download to complete
|
||||
boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest,
|
||||
WAIT_FOR_DOWNLOAD_POLL_TIME, timeout);
|
||||
assertFalse("Download proceeded without Wifi connection!", success);
|
||||
|
||||
setWiFiStateOn(true);
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
assertEquals(1, mReceiver.numDownloadsCompleted());
|
||||
} finally {
|
||||
setWiFiStateOn(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when the server drops the connection after all headers (but before any data send).
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDropConnection_headers() throws Exception {
|
||||
byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
|
||||
|
||||
MockResponse response = enqueueResponse(HTTP_OK, blobData);
|
||||
response.setCloseConnectionAfterHeader("content-length");
|
||||
long dlRequest = doCommonStandardEnqueue();
|
||||
|
||||
// Download will never complete when header is dropped
|
||||
boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest, DEFAULT_WAIT_POLL_TIME,
|
||||
DEFAULT_MAX_WAIT_TIME);
|
||||
|
||||
assertFalse(success);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we get an error code when the server drops the connection during a download.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testServerDropConnection_body() throws Exception {
|
||||
byte[] blobData = generateData(25000, DataType.TEXT); // file size = 25000 bytes
|
||||
|
||||
MockResponse response = enqueueResponse(HTTP_OK, blobData);
|
||||
response.setCloseConnectionAfterXBytes(15382);
|
||||
long dlRequest = doCommonStandardEnqueue();
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
Cursor cursor = getCursor(dlRequest);
|
||||
try {
|
||||
verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
|
||||
verifyInt(cursor, DownloadManager.COLUMN_REASON,
|
||||
DownloadManager.ERROR_CANNOT_RESUME);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
// Even tho the server drops the connection, we should still get a completed notification
|
||||
assertEquals(1, mReceiver.numDownloadsCompleted());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests downloading a file to system cache when there isn't enough space in the system cache
|
||||
* to hold the entire file. DownloadManager deletes enough files to make space for the
|
||||
* new download.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDownloadToCacheWithAlmostFullCache() throws Exception {
|
||||
int DOWNLOAD_FILE_SIZE = 1024 * 1024; // 1MB
|
||||
|
||||
StatFs fs = new StatFs(CACHE_DIR);
|
||||
int blockSize = fs.getBlockSize();
|
||||
int availableBlocks = fs.getAvailableBlocks();
|
||||
int availableBytes = blockSize * availableBlocks;
|
||||
Log.i(TAG, "INITIAL stage, available space in /cache: " + availableBytes);
|
||||
File outFile = File.createTempFile("DM_TEST", null, new File(CACHE_DIR));
|
||||
byte[] buffer = new byte[blockSize];
|
||||
|
||||
try {
|
||||
// fill cache to ensure we don't have enough space - take half the size of the
|
||||
// download size, and leave that much freespace left on the cache partition
|
||||
if (DOWNLOAD_FILE_SIZE <= availableBytes) {
|
||||
int writeSizeBytes = availableBytes - (DOWNLOAD_FILE_SIZE / 2);
|
||||
|
||||
int writeSizeBlocks = writeSizeBytes / blockSize;
|
||||
int remainderSizeBlocks = availableBlocks - writeSizeBlocks;
|
||||
|
||||
FileOutputStream fo = null;
|
||||
try {
|
||||
fo = new FileOutputStream(outFile);
|
||||
while (fs.getAvailableBlocks() >= remainderSizeBlocks) {
|
||||
fo.write(buffer);
|
||||
fs.restat(CACHE_DIR);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "error filling file: ", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (fo != null) {
|
||||
fo.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /cache should now be almost full.
|
||||
long spaceAvailable = fs.getAvailableBlocks() * blockSize;
|
||||
Log.i(TAG, "BEFORE download, available space in /cache: " + spaceAvailable);
|
||||
assertTrue(DOWNLOAD_FILE_SIZE > spaceAvailable);
|
||||
|
||||
// try to download 1MB file into /cache - and it should succeed
|
||||
byte[] blobData = generateData(DOWNLOAD_FILE_SIZE, DataType.TEXT);
|
||||
long dlRequest = doBasicDownload(blobData, DOWNLOAD_TO_SYSTEM_CACHE);
|
||||
verifyAndCleanupSingleFileDownload(dlRequest, blobData);
|
||||
} finally {
|
||||
if (outFile != null) {
|
||||
outFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that files are not deleted when DOWNLOAD_CACHE_NON_PURGEABLE is set, even if we've
|
||||
* run out of space.
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDownloadToCacheNonPurgeableWithFullCache() throws Exception {
|
||||
int fileSize = 1024 * 1024; // 1MB
|
||||
byte[] blobData = generateData(fileSize, DataType.BINARY);
|
||||
long dlRequest = -1;
|
||||
|
||||
// Fill up the cache partition with DOWNLOAD_CACHE_NON_PURGEABLE downloads
|
||||
// until 500KB is left.
|
||||
boolean spaceAvailable = true;
|
||||
while (spaceAvailable) {
|
||||
// since this tests package has android.permission.DOWNLOAD_CACHE_NON_PURGEABLE
|
||||
// permission, downloads are automatically set to be DOWNLOAD_CACHE_NON_PURGEABLE
|
||||
dlRequest = enqueueDownloadRequest(blobData, DOWNLOAD_TO_DOWNLOAD_CACHE_DIR);
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
// Check if we've filled up the cache yet
|
||||
StatFs fs = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
|
||||
int availableBytes = fs.getBlockSize() * fs.getAvailableBlocks();
|
||||
Log.i(TAG, "available space in /cache: " + availableBytes);
|
||||
spaceAvailable = (availableBytes > fileSize) ? true : false;
|
||||
}
|
||||
|
||||
// Now add one more 1MB download (should not fit in the space left over)
|
||||
dlRequest = enqueueDownloadRequest(blobData, DOWNLOAD_TO_DOWNLOAD_CACHE_DIR);
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
// For the last download we should have failed b/c there is not enough space left in cache
|
||||
Cursor cursor = getCursor(dlRequest);
|
||||
try {
|
||||
verifyInt(cursor, DownloadManager.COLUMN_REASON,
|
||||
DownloadManager.ERROR_INSUFFICIENT_SPACE);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,21 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Random;
|
||||
|
||||
import android.app.DownloadManager.Query;
|
||||
import android.app.DownloadManager.Request;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class DownloadManagerStressTest extends DownloadManagerBaseTest {
|
||||
private static String LOG_TAG = "android.net.DownloadManagerStressTest";
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@@ -42,8 +44,25 @@ public class DownloadManagerStressTest extends DownloadManagerBaseTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to downloading thousands of files simultaneously
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
setWiFiStateOn(true);
|
||||
removeAllCurrentDownloads();
|
||||
|
||||
if (mReceiver != null) {
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
mReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to downloading thousands of files simultaneously
|
||||
* don't run this test - downloadmanager needs to allow only a few simultaneous downloads.
|
||||
*/
|
||||
@Suppress
|
||||
public void testDownloadThousands() throws Exception {
|
||||
int NUM_FILES = 1500;
|
||||
int MAX_FILE_SIZE = 3000;
|
||||
@@ -106,6 +125,7 @@ public class DownloadManagerStressTest extends DownloadManagerBaseTest {
|
||||
/**
|
||||
* Tests trying to download a large file (50M bytes).
|
||||
*/
|
||||
@LargeTest
|
||||
public void testDownloadLargeFile() throws Exception {
|
||||
long fileSize = 50000000L; // note: kept relatively small to not exceed /cache dir size
|
||||
File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
|
||||
@@ -129,31 +149,4 @@ public class DownloadManagerStressTest extends DownloadManagerBaseTest {
|
||||
largeFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests trying to download a large file (~600M bytes) when there's not enough space in cache
|
||||
*/
|
||||
public void testInsufficientSpace() throws Exception {
|
||||
// @TODO: Rework this to fill up cache partition with a dynamically calculated size
|
||||
long fileSize = 600000000L;
|
||||
File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
|
||||
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
long dlRequest = doStandardEnqueue(largeFile);
|
||||
|
||||
// wait for the download to complete
|
||||
waitForDownloadOrTimeout(dlRequest);
|
||||
|
||||
cursor = getCursor(dlRequest);
|
||||
verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
|
||||
verifyInt(cursor, DownloadManager.COLUMN_REASON,
|
||||
DownloadManager.ERROR_INSUFFICIENT_SPACE);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
largeFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
|
||||
../../../coretests/src/android/app/DownloadManagerBaseTest.java
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := android-common frameworks-core-util-lib
|
||||
LOCAL_SDK_VERSION := current
|
||||
|
||||
@@ -0,0 +1,816 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.frameworks.downloadmanagertests;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.app.DownloadManager.Query;
|
||||
import android.app.DownloadManager.Request;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.Cursor;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.SystemClock;
|
||||
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
|
||||
import android.provider.Settings;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import coretestutils.http.MockResponse;
|
||||
import coretestutils.http.MockWebServer;
|
||||
|
||||
/**
|
||||
* Base class for Instrumented tests for the Download Manager.
|
||||
*/
|
||||
public class DownloadManagerBaseTest extends InstrumentationTestCase {
|
||||
|
||||
protected DownloadManager mDownloadManager = null;
|
||||
protected MockWebServer mServer = null;
|
||||
protected String mFileType = "text/plain";
|
||||
protected Context mContext = null;
|
||||
protected MultipleDownloadsCompletedReceiver mReceiver = null;
|
||||
protected static final int DEFAULT_FILE_SIZE = 10 * 1024; // 10kb
|
||||
protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024;
|
||||
|
||||
protected static final String LOG_TAG = "android.net.DownloadManagerBaseTest";
|
||||
protected static final int HTTP_OK = 200;
|
||||
protected static final int HTTP_REDIRECT = 307;
|
||||
protected static final int HTTP_PARTIAL_CONTENT = 206;
|
||||
protected static final int HTTP_NOT_FOUND = 404;
|
||||
protected static final int HTTP_SERVICE_UNAVAILABLE = 503;
|
||||
protected String DEFAULT_FILENAME = "somefile.txt";
|
||||
|
||||
protected static final int DEFAULT_MAX_WAIT_TIME = 2 * 60 * 1000; // 2 minutes
|
||||
protected static final int DEFAULT_WAIT_POLL_TIME = 5 * 1000; // 5 seconds
|
||||
|
||||
protected static final int WAIT_FOR_DOWNLOAD_POLL_TIME = 1 * 1000; // 1 second
|
||||
protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
|
||||
protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes
|
||||
|
||||
protected static final int DOWNLOAD_TO_SYSTEM_CACHE = 1;
|
||||
protected static final int DOWNLOAD_TO_DOWNLOAD_CACHE_DIR = 2;
|
||||
|
||||
// Just a few popular file types used to return from a download
|
||||
protected enum DownloadFileType {
|
||||
PLAINTEXT,
|
||||
APK,
|
||||
GIF,
|
||||
GARBAGE,
|
||||
UNRECOGNIZED,
|
||||
ZIP
|
||||
}
|
||||
|
||||
protected enum DataType {
|
||||
TEXT,
|
||||
BINARY
|
||||
}
|
||||
|
||||
public static class LoggingRng extends Random {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Creates RNG with self-generated seed value.
|
||||
*/
|
||||
public LoggingRng() {
|
||||
this(SystemClock.uptimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Creats RNG with given initial seed value
|
||||
|
||||
* @param seed The initial seed value
|
||||
*/
|
||||
public LoggingRng(long seed) {
|
||||
super(seed);
|
||||
Log.i(LOG_TAG, "Seeding RNG with value: " + seed);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
|
||||
private volatile int mNumDownloadsCompleted = 0;
|
||||
private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equalsIgnoreCase(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
|
||||
synchronized(this) {
|
||||
long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
|
||||
Log.i(LOG_TAG, "Received Notification for download: " + id);
|
||||
if (!downloadIds.contains(id)) {
|
||||
++mNumDownloadsCompleted;
|
||||
Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
|
||||
intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
|
||||
downloadIds.add(id);
|
||||
|
||||
DownloadManager dm = (DownloadManager)context.getSystemService(
|
||||
Context.DOWNLOAD_SERVICE);
|
||||
|
||||
Cursor cursor = dm.query(new Query().setFilterById(id));
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
int status = cursor.getInt(cursor.getColumnIndex(
|
||||
DownloadManager.COLUMN_STATUS));
|
||||
Log.i(LOG_TAG, "Download status is: " + status);
|
||||
} else {
|
||||
fail("No status found for completed download!");
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
} else {
|
||||
Log.i(LOG_TAG, "Notification for id: " + id + " has already been made.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of times the {@link #onReceive} callback has been called for the
|
||||
* {@link DownloadManager.ACTION_DOWNLOAD_COMPLETED} action, indicating the number of
|
||||
* downloads completed thus far.
|
||||
*
|
||||
* @return the number of downloads completed so far.
|
||||
*/
|
||||
public int numDownloadsCompleted() {
|
||||
return mNumDownloadsCompleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of download IDs.
|
||||
* @return A Set<Long> with the ids of the completed downloads.
|
||||
*/
|
||||
public Set<Long> getDownloadIds() {
|
||||
synchronized(this) {
|
||||
Set<Long> returnIds = new HashSet<Long>(downloadIds);
|
||||
return returnIds;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class WiFiChangedReceiver extends BroadcastReceiver {
|
||||
private Context mContext = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Sets the current state of WiFi.
|
||||
*
|
||||
* @param context The current app {@link Context}.
|
||||
*/
|
||||
public WiFiChangedReceiver(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION)) {
|
||||
Log.i(LOG_TAG, "ConnectivityManager state change: " + intent.getAction());
|
||||
synchronized (this) {
|
||||
this.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current state of WiFi.
|
||||
*
|
||||
* @return Returns true if WiFi is on, false otherwise.
|
||||
*/
|
||||
public boolean getWiFiIsOn() {
|
||||
ConnectivityManager connManager = (ConnectivityManager)mContext.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo info = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
Log.i(LOG_TAG, "WiFi Connection state is currently: " + info.isConnected());
|
||||
return info.isConnected();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
mContext = getInstrumentation().getContext();
|
||||
mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
mServer = new MockWebServer();
|
||||
mReceiver = registerNewMultipleDownloadsReceiver();
|
||||
// Note: callers overriding this should call mServer.play() with the desired port #
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to enqueue a response from the MockWebServer.
|
||||
*
|
||||
* @param status The HTTP status code to return for this response
|
||||
* @param body The body to return in this response
|
||||
* @return Returns the mock web server response that was queued (which can be modified)
|
||||
*/
|
||||
private MockResponse enqueueResponse(int status, byte[] body) {
|
||||
return doEnqueueResponse(status).setBody(body);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to enqueue a response from the MockWebServer.
|
||||
*
|
||||
* @param status The HTTP status code to return for this response
|
||||
* @param bodyFile The body to return in this response
|
||||
* @return Returns the mock web server response that was queued (which can be modified)
|
||||
*/
|
||||
private MockResponse enqueueResponse(int status, File bodyFile) {
|
||||
return doEnqueueResponse(status).setBody(bodyFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for enqueue'ing a response from the MockWebServer.
|
||||
*
|
||||
* @param status The HTTP status code to return for this response
|
||||
* @return Returns the mock web server response that was queued (which can be modified)
|
||||
*/
|
||||
private MockResponse doEnqueueResponse(int status) {
|
||||
MockResponse response = new MockResponse().setResponseCode(status);
|
||||
response.addHeader("Content-type", mFileType);
|
||||
mServer.enqueue(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to generate a random blob of bytes using a given RNG.
|
||||
*
|
||||
* @param size The size of the data to generate
|
||||
* @param type The type of data to generate: currently, one of {@link DataType.TEXT} or
|
||||
* {@link DataType.BINARY}.
|
||||
* @param rng (optional) The RNG to use; pass null to use
|
||||
* @return The random data that is generated.
|
||||
*/
|
||||
private byte[] generateData(int size, DataType type, Random rng) {
|
||||
int min = Byte.MIN_VALUE;
|
||||
int max = Byte.MAX_VALUE;
|
||||
|
||||
// Only use chars in the HTTP ASCII printable character range for Text
|
||||
if (type == DataType.TEXT) {
|
||||
min = 32;
|
||||
max = 126;
|
||||
}
|
||||
byte[] result = new byte[size];
|
||||
Log.i(LOG_TAG, "Generating data of size: " + size);
|
||||
|
||||
if (rng == null) {
|
||||
rng = new LoggingRng();
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result[i] = (byte) (min + rng.nextInt(max - min + 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to verify the size of a file.
|
||||
*
|
||||
* @param pfd The input file to compare the size of
|
||||
* @param size The expected size of the file
|
||||
*/
|
||||
protected void verifyFileSize(ParcelFileDescriptor pfd, long size) {
|
||||
assertEquals(pfd.getStatSize(), size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to verify the contents of a downloaded file versus a byte[].
|
||||
*
|
||||
* @param actual The file of whose contents to verify
|
||||
* @param expected The data we expect to find in the aforementioned file
|
||||
* @throws IOException if there was a problem reading from the file
|
||||
*/
|
||||
private void verifyFileContents(ParcelFileDescriptor actual, byte[] expected)
|
||||
throws IOException {
|
||||
AutoCloseInputStream input = new ParcelFileDescriptor.AutoCloseInputStream(actual);
|
||||
long fileSize = actual.getStatSize();
|
||||
|
||||
assertTrue(fileSize <= Integer.MAX_VALUE);
|
||||
assertEquals(expected.length, fileSize);
|
||||
|
||||
byte[] actualData = new byte[expected.length];
|
||||
assertEquals(input.read(actualData), fileSize);
|
||||
compareByteArrays(actualData, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to compare 2 byte arrays.
|
||||
*
|
||||
* @param actual The array whose data we want to verify
|
||||
* @param expected The array of data we expect to see
|
||||
*/
|
||||
private void compareByteArrays(byte[] actual, byte[] expected) {
|
||||
assertEquals(actual.length, expected.length);
|
||||
int length = actual.length;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
// assert has a bit of overhead, so only do the assert when the values are not the same
|
||||
if (actual[i] != expected[i]) {
|
||||
fail("Byte arrays are not equal.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MIME content string for a given type
|
||||
*
|
||||
* @param type The MIME type to return
|
||||
* @return the String representation of that MIME content type
|
||||
*/
|
||||
protected String getMimeMapping(DownloadFileType type) {
|
||||
switch (type) {
|
||||
case APK:
|
||||
return "application/vnd.android.package-archive";
|
||||
case GIF:
|
||||
return "image/gif";
|
||||
case ZIP:
|
||||
return "application/x-zip-compressed";
|
||||
case GARBAGE:
|
||||
return "zip\\pidy/doo/da";
|
||||
case UNRECOGNIZED:
|
||||
return "application/new.undefined.type.of.app";
|
||||
}
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Uri that should be used to access the mock server
|
||||
*
|
||||
* @param filename The name of the file to try to retrieve from the mock server
|
||||
* @return the Uri to use for access the file on the mock server
|
||||
*/
|
||||
private Uri getServerUri(String filename) throws Exception {
|
||||
URL url = mServer.getUrl("/" + filename);
|
||||
return Uri.parse(url.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create and register a new MultipleDownloadCompletedReciever
|
||||
*
|
||||
* This is used to track many simultaneous downloads by keeping count of all the downloads
|
||||
* that have completed.
|
||||
*
|
||||
* @return A new receiver that records and can be queried on how many downloads have completed.
|
||||
*/
|
||||
protected MultipleDownloadsCompletedReceiver registerNewMultipleDownloadsReceiver() {
|
||||
MultipleDownloadsCompletedReceiver receiver = new MultipleDownloadsCompletedReceiver();
|
||||
mContext.registerReceiver(receiver, new IntentFilter(
|
||||
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
|
||||
return receiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables WiFi.
|
||||
*
|
||||
* Note: Needs the following permissions:
|
||||
* android.permission.ACCESS_WIFI_STATE
|
||||
* android.permission.CHANGE_WIFI_STATE
|
||||
* @param enable true if it should be enabled, false if it should be disabled
|
||||
*/
|
||||
protected void setWiFiStateOn(boolean enable) throws Exception {
|
||||
Log.i(LOG_TAG, "Setting WiFi State to: " + enable);
|
||||
WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
|
||||
|
||||
manager.setWifiEnabled(enable);
|
||||
|
||||
String timeoutMessage = "Timed out waiting for Wifi to be "
|
||||
+ (enable ? "enabled!" : "disabled!");
|
||||
|
||||
WiFiChangedReceiver receiver = new WiFiChangedReceiver(mContext);
|
||||
mContext.registerReceiver(receiver, new IntentFilter(
|
||||
ConnectivityManager.CONNECTIVITY_ACTION));
|
||||
|
||||
synchronized (receiver) {
|
||||
long timeoutTime = SystemClock.elapsedRealtime() + DEFAULT_MAX_WAIT_TIME;
|
||||
boolean timedOut = false;
|
||||
|
||||
while (receiver.getWiFiIsOn() != enable && !timedOut) {
|
||||
try {
|
||||
receiver.wait(DEFAULT_WAIT_POLL_TIME);
|
||||
|
||||
if (SystemClock.elapsedRealtime() > timeoutTime) {
|
||||
timedOut = true;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// ignore InterruptedExceptions
|
||||
}
|
||||
}
|
||||
if (timedOut) {
|
||||
fail(timeoutMessage);
|
||||
}
|
||||
}
|
||||
assertEquals(enable, receiver.getWiFiIsOn());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to enables or disables airplane mode. If successful, it also broadcasts an intent
|
||||
* indicating that the mode has changed.
|
||||
*
|
||||
* Note: Needs the following permission:
|
||||
* android.permission.WRITE_SETTINGS
|
||||
* @param enable true if airplane mode should be ON, false if it should be OFF
|
||||
*/
|
||||
protected void setAirplaneModeOn(boolean enable) throws Exception {
|
||||
int state = enable ? 1 : 0;
|
||||
|
||||
// Change the system setting
|
||||
Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
|
||||
state);
|
||||
|
||||
String timeoutMessage = "Timed out waiting for airplane mode to be " +
|
||||
(enable ? "enabled!" : "disabled!");
|
||||
|
||||
// wait for airplane mode to change state
|
||||
int currentWaitTime = 0;
|
||||
while (Settings.System.getInt(mContext.getContentResolver(),
|
||||
Settings.System.AIRPLANE_MODE_ON, -1) != state) {
|
||||
timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, DEFAULT_MAX_WAIT_TIME,
|
||||
timeoutMessage);
|
||||
}
|
||||
|
||||
// Post the intent
|
||||
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
intent.putExtra("state", true);
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to wait for a particular download to finish, or else a timeout to occur
|
||||
*
|
||||
* Does not wait for a receiver notification of the download.
|
||||
*
|
||||
* @param id The download id to query on (wait for)
|
||||
*/
|
||||
private void waitForDownloadOrTimeout_skipNotification(long id) throws TimeoutException,
|
||||
InterruptedException {
|
||||
waitForDownloadOrTimeout(id, WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to wait for a particular download to finish, or else a timeout to occur
|
||||
*
|
||||
* Also guarantees a notification has been posted for the download.
|
||||
*
|
||||
* @param id The download id to query on (wait for)
|
||||
*/
|
||||
protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
|
||||
InterruptedException {
|
||||
waitForDownloadOrTimeout_skipNotification(id);
|
||||
waitForReceiverNotifications(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to wait for a particular download to finish, or else a timeout to occur
|
||||
*
|
||||
* Also guarantees a notification has been posted for the download.
|
||||
*
|
||||
* @param id The download id to query on (wait for)
|
||||
* @param poll The amount of time to wait
|
||||
* @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
|
||||
*/
|
||||
protected void waitForDownloadOrTimeout(long id, long poll, long timeoutMillis)
|
||||
throws TimeoutException, InterruptedException {
|
||||
doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
|
||||
waitForReceiverNotifications(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to wait for all downloads to finish, or else a specified timeout to occur
|
||||
*
|
||||
* Makes no guaranee that notifications have been posted for all downloads.
|
||||
*
|
||||
* @param poll The amount of time to wait
|
||||
* @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
|
||||
*/
|
||||
protected void waitForDownloadsOrTimeout(long poll, long timeoutMillis) throws TimeoutException,
|
||||
InterruptedException {
|
||||
doWaitForDownloadsOrTimeout(new Query(), poll, timeoutMillis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to wait for all downloads to finish, or else a timeout to occur, but does not throw
|
||||
*
|
||||
* Also guarantees a notification has been posted for the download.
|
||||
*
|
||||
* @param id The id of the download to query against
|
||||
* @param poll The amount of time to wait
|
||||
* @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
|
||||
* @return true if download completed successfully (didn't timeout), false otherwise
|
||||
*/
|
||||
private boolean waitForDownloadOrTimeoutNoThrow(long id, long poll, long timeoutMillis) {
|
||||
try {
|
||||
doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
|
||||
waitForReceiverNotifications(1);
|
||||
} catch (TimeoutException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to synchronously wait, or timeout if the maximum threshold has been exceeded.
|
||||
*
|
||||
* @param currentTotalWaitTime The total time waited so far
|
||||
* @param poll The amount of time to wait
|
||||
* @param maxTimeoutMillis The total wait time threshold; if we've waited more than this long,
|
||||
* we timeout and fail
|
||||
* @param timedOutMessage The message to display in the failure message if we timeout
|
||||
* @return The new total amount of time we've waited so far
|
||||
* @throws TimeoutException if timed out waiting for SD card to mount
|
||||
*/
|
||||
private int timeoutWait(int currentTotalWaitTime, long poll, long maxTimeoutMillis,
|
||||
String timedOutMessage) throws TimeoutException {
|
||||
long now = SystemClock.elapsedRealtime();
|
||||
long end = now + poll;
|
||||
|
||||
// if we get InterruptedException's, ignore them and just keep sleeping
|
||||
while (now < end) {
|
||||
try {
|
||||
Thread.sleep(end - now);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore interrupted exceptions
|
||||
}
|
||||
now = SystemClock.elapsedRealtime();
|
||||
}
|
||||
|
||||
currentTotalWaitTime += poll;
|
||||
if (currentTotalWaitTime > maxTimeoutMillis) {
|
||||
throw new TimeoutException(timedOutMessage);
|
||||
}
|
||||
return currentTotalWaitTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to wait for all downloads to finish, or else a timeout to occur
|
||||
*
|
||||
* @param query The query to pass to the download manager
|
||||
* @param poll The poll time to wait between checks
|
||||
* @param timeoutMillis The max amount of time (in ms) to wait for the download(s) to complete
|
||||
*/
|
||||
private void doWaitForDownloadsOrTimeout(Query query, long poll, long timeoutMillis)
|
||||
throws TimeoutException {
|
||||
int currentWaitTime = 0;
|
||||
while (true) {
|
||||
query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_PAUSED
|
||||
| DownloadManager.STATUS_RUNNING);
|
||||
Cursor cursor = mDownloadManager.query(query);
|
||||
|
||||
try {
|
||||
if (cursor.getCount() == 0) {
|
||||
Log.i(LOG_TAG, "All downloads should be done...");
|
||||
break;
|
||||
}
|
||||
currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
|
||||
"Timed out waiting for all downloads to finish");
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits for external store to be mounted (eg: SD Card).
|
||||
*
|
||||
* @throws InterruptedException if interrupted
|
||||
* @throws Exception if timed out waiting for SD card to mount
|
||||
*/
|
||||
protected void waitForExternalStoreMount() throws Exception {
|
||||
String extStorageState = Environment.getExternalStorageState();
|
||||
int currentWaitTime = 0;
|
||||
while (!extStorageState.equals(Environment.MEDIA_MOUNTED)) {
|
||||
Log.i(LOG_TAG, "Waiting for SD card...");
|
||||
currentWaitTime = timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME,
|
||||
DEFAULT_MAX_WAIT_TIME, "Timed out waiting for SD Card to be ready!");
|
||||
extStorageState = Environment.getExternalStorageState();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits for a download to start.
|
||||
*
|
||||
* @param dlRequest the download request id used by Download Manager to track the download.
|
||||
* @throws Exception if timed out while waiting for SD card to mount
|
||||
*/
|
||||
protected void waitForDownloadToStart(long dlRequest) throws Exception {
|
||||
Cursor cursor = getCursor(dlRequest);
|
||||
try {
|
||||
int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
|
||||
int value = cursor.getInt(columnIndex);
|
||||
int currentWaitTime = 0;
|
||||
|
||||
while (value != DownloadManager.STATUS_RUNNING &&
|
||||
(value != DownloadManager.STATUS_FAILED) &&
|
||||
(value != DownloadManager.STATUS_SUCCESSFUL)) {
|
||||
Log.i(LOG_TAG, "Waiting for download to start...");
|
||||
currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
|
||||
MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download to start!");
|
||||
cursor.requery();
|
||||
assertTrue(cursor.moveToFirst());
|
||||
columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
|
||||
value = cursor.getInt(columnIndex);
|
||||
}
|
||||
assertFalse("Download failed immediately after start",
|
||||
value == DownloadManager.STATUS_FAILED);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits for our receiver to receive notification for a given number of
|
||||
* downloads.
|
||||
*
|
||||
* @param targetNumber The number of notifications for unique downloads to wait for; pass in
|
||||
* -1 to not wait for notification.
|
||||
* @throws Exception if timed out while waiting
|
||||
*/
|
||||
private void waitForReceiverNotifications(int targetNumber) throws TimeoutException {
|
||||
int count = mReceiver.numDownloadsCompleted();
|
||||
int currentWaitTime = 0;
|
||||
|
||||
while (count < targetNumber) {
|
||||
Log.i(LOG_TAG, "Waiting for notification of downloads...");
|
||||
currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
|
||||
MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download notifications!"
|
||||
+ " Received " + count + "notifications.");
|
||||
count = mReceiver.numDownloadsCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits for a file to increase in size (such as to monitor that a download is
|
||||
* progressing).
|
||||
*
|
||||
* @param file The file whose size to track.
|
||||
* @throws Exception if timed out while waiting for the file to grow in size.
|
||||
*/
|
||||
protected void waitForFileToGrow(File file) throws Exception {
|
||||
int currentWaitTime = 0;
|
||||
|
||||
// File may not even exist yet, so wait until it does (or we timeout)
|
||||
while (!file.exists()) {
|
||||
Log.i(LOG_TAG, "Waiting for file to exist...");
|
||||
currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
|
||||
MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be created.");
|
||||
}
|
||||
|
||||
// Get original file size...
|
||||
long originalSize = file.length();
|
||||
|
||||
while (file.length() <= originalSize) {
|
||||
Log.i(LOG_TAG, "Waiting for file to be written to...");
|
||||
currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
|
||||
MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be written to.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to remove all downloads that are registered with the DL Manager.
|
||||
*
|
||||
* Note: This gives us a clean slate b/c it includes downloads that are pending, running,
|
||||
* paused, or have completed.
|
||||
*/
|
||||
protected void removeAllCurrentDownloads() {
|
||||
Log.i(LOG_TAG, "Removing all current registered downloads...");
|
||||
Cursor cursor = mDownloadManager.query(new Query());
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
int index = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
|
||||
long downloadId = cursor.getLong(index);
|
||||
|
||||
mDownloadManager.remove(downloadId);
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to perform a standard enqueue of data to the mock server.
|
||||
* download is performed to the downloads cache dir (NOT systemcache dir)
|
||||
*
|
||||
* @param body The body to return in the response from the server
|
||||
*/
|
||||
private long doStandardEnqueue(byte[] body) throws Exception {
|
||||
// Prepare the mock server with a standard response
|
||||
enqueueResponse(HTTP_OK, body);
|
||||
return doCommonStandardEnqueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to perform a standard enqueue of data to the mock server.
|
||||
*
|
||||
* @param body The body to return in the response from the server, contained in the file
|
||||
*/
|
||||
private long doStandardEnqueue(File body) throws Exception {
|
||||
// Prepare the mock server with a standard response
|
||||
enqueueResponse(HTTP_OK, body);
|
||||
return doCommonStandardEnqueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to do the additional steps (setting title and Uri of default filename) when
|
||||
* doing a standard enqueue request to the server.
|
||||
*/
|
||||
private long doCommonStandardEnqueue() throws Exception {
|
||||
Uri uri = getServerUri(DEFAULT_FILENAME);
|
||||
Request request = new Request(uri).setTitle(DEFAULT_FILENAME);
|
||||
return mDownloadManager.enqueue(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to verify an int value in a Cursor
|
||||
*
|
||||
* @param cursor The cursor containing the query results
|
||||
* @param columnName The name of the column to query
|
||||
* @param expected The expected int value
|
||||
*/
|
||||
private void verifyInt(Cursor cursor, String columnName, int expected) {
|
||||
int index = cursor.getColumnIndex(columnName);
|
||||
int actual = cursor.getInt(index);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a query based on ID and returns a Cursor for the query.
|
||||
*
|
||||
* @param id The id of the download in DL Manager; pass -1 to query all downloads
|
||||
* @return A cursor for the query results
|
||||
*/
|
||||
protected Cursor getCursor(long id) throws Exception {
|
||||
Query query = new Query();
|
||||
if (id != -1) {
|
||||
query.setFilterById(id);
|
||||
}
|
||||
|
||||
Cursor cursor = mDownloadManager.query(query);
|
||||
int currentWaitTime = 0;
|
||||
|
||||
try {
|
||||
while (!cursor.moveToFirst()) {
|
||||
Thread.sleep(DEFAULT_WAIT_POLL_TIME);
|
||||
currentWaitTime += DEFAULT_WAIT_POLL_TIME;
|
||||
if (currentWaitTime > DEFAULT_MAX_WAIT_TIME) {
|
||||
fail("timed out waiting for a non-null query result");
|
||||
}
|
||||
cursor.requery();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cursor.close();
|
||||
throw e;
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package com.android.frameworks.downloadmanagertests;
|
||||
import android.app.DownloadManager;
|
||||
import android.app.DownloadManager.Query;
|
||||
import android.app.DownloadManager.Request;
|
||||
import android.app.DownloadManagerBaseTest;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
|
||||
Reference in New Issue
Block a user