blob: 3a585b47c1640b19da48fac05f0c434db5163320 [file] [log] [blame]
/*
* 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.providers.downloads;
import static android.app.DownloadManager.STATUS_FAILED;
import static android.app.DownloadManager.STATUS_SUCCESSFUL;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
import android.app.DownloadManager;
import android.content.ContentResolver;
import android.content.ContextWrapper;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.util.Log;
import libcore.io.IoUtils;
import libcore.io.Streams;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;
/**
* Code common to tests that use the download manager public API.
*/
public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunctionalTest {
class Download {
final long mId;
private Download(long downloadId) {
this.mId = downloadId;
}
public int getStatus() {
return (int) getLongField(DownloadManager.COLUMN_STATUS);
}
public int getReason() {
return (int) getLongField(DownloadManager.COLUMN_REASON);
}
public int getStatusIfExists() {
Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
try {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
return (int) cursor.getLong(cursor.getColumnIndexOrThrow(
DownloadManager.COLUMN_STATUS));
} else {
// the row doesn't exist
return -1;
}
} finally {
cursor.close();
}
}
String getStringField(String field) {
Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
try {
assertEquals(1, cursor.getCount());
cursor.moveToFirst();
return cursor.getString(cursor.getColumnIndexOrThrow(field));
} finally {
cursor.close();
}
}
long getLongField(String field) {
Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
try {
assertEquals(1, cursor.getCount());
cursor.moveToFirst();
return cursor.getLong(cursor.getColumnIndexOrThrow(field));
} finally {
cursor.close();
}
}
byte[] getRawContents() throws Exception {
ParcelFileDescriptor downloadedFile = mManager.openDownloadedFile(mId);
assertTrue("Invalid file descriptor: " + downloadedFile,
downloadedFile.getFileDescriptor().valid());
final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
downloadedFile);
try {
return Streams.readFully(is);
} finally {
IoUtils.closeQuietly(is);
}
}
String getContents() throws Exception {
return new String(getRawContents());
}
void runUntilStatus(int status) throws TimeoutException {
final long startMillis = mSystemFacade.currentTimeMillis();
startDownload(mId);
waitForStatus(status, startMillis);
}
void runUntilStatus(int status, long timeout) throws TimeoutException {
final long startMillis = mSystemFacade.currentTimeMillis();
startDownload(mId);
waitForStatus(status, startMillis, timeout);
}
void waitForStatus(int expected, long afterMillis) throws TimeoutException {
waitForStatus(expected, afterMillis, 15 * SECOND_IN_MILLIS);
}
void waitForStatus(int expected, long afterMillis, long timeout) throws TimeoutException {
int actual = -1;
final long elapsedTimeout = SystemClock.elapsedRealtime() + timeout;
while (SystemClock.elapsedRealtime() < elapsedTimeout) {
if (getLongField(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP) >= afterMillis) {
actual = getStatus();
if (actual == STATUS_SUCCESSFUL || actual == STATUS_FAILED) {
assertEquals(expected, actual);
return;
} else if (actual == expected) {
return;
}
if (timeout > MINUTE_IN_MILLIS) {
final int percent = (int) (100
* getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
/ getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
Log.d(LOG_TAG, percent + "% complete");
}
}
if (timeout > MINUTE_IN_MILLIS) {
SystemClock.sleep(SECOND_IN_MILLIS * 3);
} else {
SystemClock.sleep(100);
}
}
throw new TimeoutException("Expected status " + expected + "; only reached " + actual);
}
// max time to wait before giving up on the current download operation.
private static final int MAX_TIME_TO_WAIT_FOR_OPERATION = 5;
// while waiting for the above time period, sleep this long to yield to the
// download thread
private static final int TIME_TO_SLEEP = 1000;
// waits until progress_so_far is >= (progress)%
boolean runUntilProgress(int progress) throws InterruptedException {
startDownload(mId);
int sleepCounter = MAX_TIME_TO_WAIT_FOR_OPERATION * 1000 / TIME_TO_SLEEP;
int numBytesReceivedSoFar = 0;
int totalBytes = 0;
for (int i = 0; i < sleepCounter; i++) {
Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
try {
assertEquals(1, cursor.getCount());
cursor.moveToFirst();
numBytesReceivedSoFar = cursor.getInt(
cursor.getColumnIndexOrThrow(
DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
totalBytes = cursor.getInt(
cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
} finally {
cursor.close();
}
Log.i(LOG_TAG, "in runUntilProgress, numBytesReceivedSoFar: " +
numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
if (totalBytes == 0) {
fail("total_bytes should not be zero");
return false;
} else {
if (numBytesReceivedSoFar * 100 / totalBytes >= progress) {
// progress_so_far is >= progress%. we are done
return true;
}
}
// download not done yet. sleep a while and try again
Thread.sleep(TIME_TO_SLEEP);
}
Log.i(LOG_TAG, "FAILED in runUntilProgress, numBytesReceivedSoFar: " +
numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
return false; // failed
}
}
protected static final String PACKAGE_NAME = "my.package.name";
protected static final String REQUEST_PATH = "/path";
protected DownloadManager mManager;
public AbstractPublicApiTest(FakeSystemFacade systemFacade) {
super(systemFacade);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mManager = new DownloadManager(new ContextWrapper(mContext) {
@Override
public ContentResolver getContentResolver() {
return mResolver;
}
@Override
public String getPackageName() {
return PACKAGE_NAME;
}
});
mManager.setAccessFilename(true);
}
protected DownloadManager.Request getRequest()
throws MalformedURLException, UnknownHostException {
return getRequest(getServerUri(REQUEST_PATH));
}
protected DownloadManager.Request getRequest(String path) {
return new DownloadManager.Request(Uri.parse(path));
}
protected Download enqueueRequest(DownloadManager.Request request) {
return new Download(mManager.enqueue(request));
}
}