summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteve Howard <showard@google.com>2010-06-22 18:20:55 -0700
committerSteve Howard <showard@google.com>2010-07-01 11:35:26 -0700
commit23357198c440e6872d3aef3e608295db7f8273bc (patch)
tree16391d655af983b751b41af5267e8053009a1f2c /src
parentb0aada69b9e6258bb9a1a7c1b783d0361ef3c6f2 (diff)
downloadandroid_packages_providers_DownloadProvider-23357198c440e6872d3aef3e608295db7f8273bc.tar.gz
android_packages_providers_DownloadProvider-23357198c440e6872d3aef3e608295db7f8273bc.tar.bz2
android_packages_providers_DownloadProvider-23357198c440e6872d3aef3e608295db7f8273bc.zip
Stub out the system clock in the download manager, add tests
Introduce SystemFacade, an interface that allows us to stub out the system clock for testing the download manager. This allows us to test retrying a failed download without having the test wait 60 seconds. This interface can include other dependencies in the future as well. I've also used this to add tests for 503 (retry-after) and 301 (redirect), and I've added a test for download to the cache partition. Other changes: * made MockWebServer capable of checking + rethrowing exceptions from child threads * refactoring + cleanup of DownloadManagerFunctionalTest
Diffstat (limited to 'src')
-rw-r--r--src/com/android/providers/downloads/DownloadService.java24
-rw-r--r--src/com/android/providers/downloads/DownloadThread.java16
-rw-r--r--src/com/android/providers/downloads/RealSystemFacade.java7
-rw-r--r--src/com/android/providers/downloads/SystemFacade.java6
4 files changed, 38 insertions, 15 deletions
diff --git a/src/com/android/providers/downloads/DownloadService.java b/src/com/android/providers/downloads/DownloadService.java
index 9e890ea0..f3bc9586 100644
--- a/src/com/android/providers/downloads/DownloadService.java
+++ b/src/com/android/providers/downloads/DownloadService.java
@@ -17,6 +17,7 @@
package com.android.providers.downloads;
import com.google.android.collect.Lists;
+import com.google.common.annotations.VisibleForTesting;
import android.app.AlarmManager;
import android.app.PendingIntent;
@@ -62,7 +63,7 @@ public class DownloadService extends Service {
/** Observer to get notified when the content observer's data changes */
private DownloadManagerContentObserver mObserver;
-
+
/** Class to handle Notification Manager updates */
private DownloadNotification mNotifier;
@@ -109,6 +110,9 @@ public class DownloadService extends Service {
*/
private CharArrayBuffer mNewChars;
+ @VisibleForTesting
+ SystemFacade mSystemFacade;
+
/* ------------ Inner Classes ------------ */
/**
@@ -200,6 +204,10 @@ public class DownloadService extends Service {
Log.v(Constants.TAG, "Service onCreate");
}
+ if (mSystemFacade == null) {
+ mSystemFacade = new RealSystemFacade();
+ }
+
mDownloads = Lists.newArrayList();
mObserver = new DownloadManagerContentObserver();
@@ -209,7 +217,7 @@ public class DownloadService extends Service {
mMediaScannerService = null;
mMediaScannerConnecting = false;
mMediaScannerConnection = new MediaScannerConnection();
-
+
mNotifier = new DownloadNotification(this);
mNotifier.mNotificationMgr.cancelAll();
mNotifier.updateNotification();
@@ -259,10 +267,10 @@ public class DownloadService extends Service {
public UpdateThread() {
super("Download Service");
}
-
+
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
+
boolean keepService = false;
// for each update from the database, remember which download is
// supposed to get restarted soonest in the future
@@ -292,7 +300,7 @@ public class DownloadService extends Service {
DownloadReceiver.class.getName());
alarms.set(
AlarmManager.RTC_WAKEUP,
- System.currentTimeMillis() + wakeUp,
+ mSystemFacade.currentTimeMillis() + wakeUp,
PendingIntent.getBroadcast(DownloadService.this, 0, intent,
PendingIntent.FLAG_ONE_SHOT));
}
@@ -305,7 +313,7 @@ public class DownloadService extends Service {
}
boolean networkAvailable = Helpers.isNetworkAvailable(DownloadService.this);
boolean networkRoaming = Helpers.isNetworkRoaming(DownloadService.this);
- long now = System.currentTimeMillis();
+ long now = mSystemFacade.currentTimeMillis();
Cursor cursor = getContentResolver().query(Downloads.Impl.CONTENT_URI,
null, null, null, Downloads.Impl._ID);
@@ -666,7 +674,7 @@ public class DownloadService extends Service {
ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, info.mId),
values, null, null);
}
- DownloadThread downloader = new DownloadThread(this, info);
+ DownloadThread downloader = new DownloadThread(this, mSystemFacade, info);
info.mHasActiveThread = true;
downloader.start();
}
@@ -757,7 +765,7 @@ public class DownloadService extends Service {
getContentResolver().update(
ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, info.mId),
values, null, null);
- DownloadThread downloader = new DownloadThread(this, info);
+ DownloadThread downloader = new DownloadThread(this, mSystemFacade, info);
info.mHasActiveThread = true;
downloader.start();
}
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java
index d2bd3220..f1296b8f 100644
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -56,9 +56,11 @@ public class DownloadThread extends Thread {
private Context mContext;
private DownloadInfo mInfo;
+ private SystemFacade mSystemFacade;
- public DownloadThread(Context context, DownloadInfo info) {
+ public DownloadThread(Context context, SystemFacade systemFacade, DownloadInfo info) {
mContext = context;
+ mSystemFacade = systemFacade;
mInfo = info;
}
@@ -131,7 +133,7 @@ public class DownloadThread extends Thread {
// Tough luck, that's not a resumable download
if (Config.LOGD) {
Log.d(Constants.TAG,
- "can't resume interrupted non-resumable download");
+ "can't resume interrupted non-resumable download");
}
f.delete();
finalStatus = Downloads.Impl.STATUS_PRECONDITION_FAILED;
@@ -363,7 +365,7 @@ http_request_loop:
if (mimeType == null) {
header = response.getFirstHeader("Content-Type");
if (header != null) {
- mimeType = sanitizeMimeType(header.getValue());
+ mimeType = sanitizeMimeType(header.getValue());
}
}
header = response.getFirstHeader("ETag");
@@ -593,7 +595,7 @@ http_request_loop:
}
}
bytesSoFar += bytesRead;
- long now = System.currentTimeMillis();
+ long now = mSystemFacade.currentTimeMillis();
if (bytesSoFar - bytesNotified > Constants.MIN_PROGRESS_STEP
&& now - timeLastNotification
> Constants.MIN_PROGRESS_TIME) {
@@ -678,7 +680,7 @@ http_request_loop:
} else if (Downloads.Impl.isStatusSuccess(finalStatus) &&
DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING
.equalsIgnoreCase(mimeType)) {
- // transfer the file to the DRM content provider
+ // transfer the file to the DRM content provider
File file = new File(filename);
Intent item = DrmStore.addDrmFile(mContext.getContentResolver(), file, null);
if (item == null) {
@@ -688,7 +690,7 @@ http_request_loop:
filename = item.getDataString();
mimeType = item.getType();
}
-
+
file.delete();
} else if (Downloads.Impl.isStatusSuccess(finalStatus)) {
// make sure the file is readable
@@ -748,7 +750,7 @@ http_request_loop:
values.put(Downloads.Impl.COLUMN_URI, uri);
}
values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimeType);
- values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, System.currentTimeMillis());
+ values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, mSystemFacade.currentTimeMillis());
values.put(Constants.RETRY_AFTER_X_REDIRECT_COUNT, retryAfter + (redirectCount << 28));
if (!countRetry) {
values.put(Constants.FAILED_CONNECTIONS, 0);
diff --git a/src/com/android/providers/downloads/RealSystemFacade.java b/src/com/android/providers/downloads/RealSystemFacade.java
new file mode 100644
index 00000000..88f10d8c
--- /dev/null
+++ b/src/com/android/providers/downloads/RealSystemFacade.java
@@ -0,0 +1,7 @@
+package com.android.providers.downloads;
+
+class RealSystemFacade implements SystemFacade {
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+}
diff --git a/src/com/android/providers/downloads/SystemFacade.java b/src/com/android/providers/downloads/SystemFacade.java
new file mode 100644
index 00000000..4498877d
--- /dev/null
+++ b/src/com/android/providers/downloads/SystemFacade.java
@@ -0,0 +1,6 @@
+
+package com.android.providers.downloads;
+
+interface SystemFacade {
+ public long currentTimeMillis();
+}