summaryrefslogtreecommitdiffstats
path: root/src/com/android/providers/downloads
diff options
context:
space:
mode:
authorZhao Wei Liew <zhaoweiliew@gmail.com>2016-10-01 19:36:07 +0800
committerMichael Bestas <mikeioannina@gmail.com>2016-12-30 22:22:07 +0200
commitb7d97dbaacfef3600db0c34a84570625979c4aa1 (patch)
tree42034a0eb32f58e0a0da843cf44428fd9d1fab80 /src/com/android/providers/downloads
parent963a851d0b9bb13714caf875279e7d5473725843 (diff)
downloadandroid_packages_providers_DownloadProvider-b7d97dbaacfef3600db0c34a84570625979c4aa1.tar.gz
android_packages_providers_DownloadProvider-b7d97dbaacfef3600db0c34a84570625979c4aa1.tar.bz2
android_packages_providers_DownloadProvider-b7d97dbaacfef3600db0c34a84570625979c4aa1.zip
DownloadProvider: Add support for manual pause/resume
Implement the following features: - Manually pause/resume individual downloads in DownloadManager - Manually pause/resume all downloads in notification Based on commit ecd609e7017b8a69688bbae25c17d878ea305f19. Change-Id: I433cdee2de8b3add0248bbb0a9d02f8da4e5bb38
Diffstat (limited to 'src/com/android/providers/downloads')
-rw-r--r--src/com/android/providers/downloads/Constants.java9
-rw-r--r--src/com/android/providers/downloads/DownloadNotifier.java72
-rw-r--r--src/com/android/providers/downloads/DownloadReceiver.java20
-rw-r--r--src/com/android/providers/downloads/DownloadStorageProvider.java17
-rw-r--r--src/com/android/providers/downloads/DownloadThread.java7
5 files changed, 116 insertions, 9 deletions
diff --git a/src/com/android/providers/downloads/Constants.java b/src/com/android/providers/downloads/Constants.java
index 79daeaed..6633057e 100644
--- a/src/com/android/providers/downloads/Constants.java
+++ b/src/com/android/providers/downloads/Constants.java
@@ -57,6 +57,15 @@ public class Constants {
/** the intent that gets sent when deleting the notification of a completed download */
public static final String ACTION_HIDE = "android.intent.action.DOWNLOAD_HIDE";
+ /** the intent that gets sent when manually resuming a manually paused download queue */
+ public static final String ACTION_RESUME_QUEUE = "android.intent.action.DOWNLOAD_RESUME_QUEUE";
+
+ /** the intent that gets sent when manually resuming a manually paused download */
+ public static final String ACTION_RESUME = "android.intent.action.DOWNLOAD_RESUME";
+
+ /** the intent that gets sent when manually pausing a running download */
+ public static final String ACTION_PAUSE = "android.intent.action.DOWNLOAD_PAUSE";
+
/** The default base name for downloaded files if we can't get one at the HTTP level */
public static final String DEFAULT_DL_FILENAME = "downloadfile";
diff --git a/src/com/android/providers/downloads/DownloadNotifier.java b/src/com/android/providers/downloads/DownloadNotifier.java
index b325117d..dce3c949 100644
--- a/src/com/android/providers/downloads/DownloadNotifier.java
+++ b/src/com/android/providers/downloads/DownloadNotifier.java
@@ -19,6 +19,7 @@ package com.android.providers.downloads;
import static android.app.DownloadManager.Request.VISIBILITY_VISIBLE;
import static android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED;
import static android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION;
+import static android.provider.Downloads.Impl.STATUS_PAUSED_MANUAL;
import static android.provider.Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
import static android.provider.Downloads.Impl.STATUS_RUNNING;
@@ -47,6 +48,7 @@ import android.util.LongSparseLongArray;
import com.android.internal.util.ArrayUtils;
+import java.lang.StringBuilder;
import java.text.NumberFormat;
import javax.annotation.concurrent.GuardedBy;
@@ -193,9 +195,30 @@ public class DownloadNotifier {
}
builder.setWhen(firstShown);
+ /**
+ * If *all* current downloads in the cluster are manually paused,
+ * display the appropriate notification icon and content.
+ *
+ * Also keep track of the number of paused downloads so as to
+ * display the current number of downloading files correctly.
+ */
+ int numPaused = 0;
+ for (int j = 0; j < cluster.size(); j++) {
+ cursor.moveToPosition(cluster.get(j));
+ int status = cursor.getInt(UpdateQuery.STATUS);
+ if (status == Downloads.Impl.STATUS_PAUSED_MANUAL) {
+ numPaused++;
+ }
+ }
+ boolean isClusterPaused = numPaused == cluster.size();
+
// Show relevant icon
if (type == TYPE_ACTIVE) {
- builder.setSmallIcon(android.R.drawable.stat_sys_download);
+ if (isClusterPaused) {
+ builder.setSmallIcon(R.drawable.download_pause);
+ } else {
+ builder.setSmallIcon(android.R.drawable.stat_sys_download);
+ }
} else if (type == TYPE_WAITING) {
builder.setSmallIcon(android.R.drawable.stat_sys_warning);
} else if (type == TYPE_COMPLETE) {
@@ -231,6 +254,32 @@ public class DownloadNotifier {
PendingIntent.getBroadcast(mContext,
0, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+ if (isClusterPaused) {
+ // Add a Resume action
+ final Intent resumeIntent = new Intent(Constants.ACTION_RESUME_QUEUE,
+ uri, mContext, DownloadReceiver.class);
+ resumeIntent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS,
+ downloadIds);
+
+ builder.addAction(
+ com.android.internal.R.drawable.ic_media_play,
+ res.getString(R.string.button_resume_download),
+ PendingIntent.getBroadcast(mContext,
+ 0, resumeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+ } else {
+ // Add a Pause action
+ final Intent pauseIntent = new Intent(Constants.ACTION_PAUSE,
+ uri, mContext, DownloadReceiver.class);
+ pauseIntent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS,
+ downloadIds);
+
+ builder.addAction(
+ com.android.internal.R.drawable.ic_media_pause,
+ res.getString(R.string.button_pause_download),
+ PendingIntent.getBroadcast(mContext,
+ 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+ }
+
} else if (type == TYPE_COMPLETE) {
cursor.moveToPosition(cluster.get(0));
final long id = cursor.getLong(UpdateQuery._ID);
@@ -329,7 +378,9 @@ public class DownloadNotifier {
builder.setContentTitle(getDownloadTitle(res, cursor));
if (type == TYPE_ACTIVE) {
- if (speedAsSizeText != null) {
+ if (isClusterPaused) {
+ builder.setContentText(res.getText(R.string.download_paused));
+ } else if (speedAsSizeText != null) {
builder.setContentText(res.getString(R.string.text_download_speed,
remainingText, speedAsSizeText));
} else {
@@ -367,8 +418,19 @@ public class DownloadNotifier {
}
if (type == TYPE_ACTIVE) {
- builder.setContentTitle(res.getQuantityString(
- R.plurals.notif_summary_active, cluster.size(), cluster.size()));
+ if (isClusterPaused) {
+ builder.setContentTitle(res.getString(R.string.download_paused));
+ } else if (numPaused > 0) {
+ StringBuilder sb = new StringBuilder(res.getQuantityString(
+ R.plurals.notif_summary_active,
+ cluster.size() - numPaused, cluster.size()));
+ sb.append(", ");
+ sb.append(res.getString(R.string.notif_summary_paused, numPaused));
+ builder.setContentTitle(sb.toString());
+ } else {
+ builder.setContentTitle(res.getQuantityString(
+ R.plurals.notif_summary_active, cluster.size(), cluster.size()));
+ }
builder.setContentText(remainingText);
builder.setContentInfo(percentText);
if (speedAsSizeText != null) {
@@ -471,7 +533,7 @@ public class DownloadNotifier {
}
private static boolean isActiveAndVisible(int status, int visibility) {
- return status == STATUS_RUNNING &&
+ return (status == STATUS_RUNNING || status == STATUS_PAUSED_MANUAL) &&
(visibility == VISIBILITY_VISIBLE
|| visibility == VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
diff --git a/src/com/android/providers/downloads/DownloadReceiver.java b/src/com/android/providers/downloads/DownloadReceiver.java
index a0dc6947..b61ae5ec 100644
--- a/src/com/android/providers/downloads/DownloadReceiver.java
+++ b/src/com/android/providers/downloads/DownloadReceiver.java
@@ -114,6 +114,26 @@ public class DownloadReceiver extends BroadcastReceiver {
NotificationManager notifManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
notifManager.cancel(notifTag, 0);
+ } else if (Constants.ACTION_PAUSE.equals(action)) {
+ long[] downloadIds = intent.getLongArrayExtra(
+ DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
+ DownloadManager manager = (DownloadManager) context.getSystemService(
+ Context.DOWNLOAD_SERVICE);
+ for (long id : downloadIds) {
+ manager.pauseDownload(id);
+ }
+ } else if (Constants.ACTION_RESUME_QUEUE.equals(action)) {
+ long[] downloadIds = intent.getLongArrayExtra(
+ DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
+ DownloadManager manager = (DownloadManager) context.getSystemService(
+ Context.DOWNLOAD_SERVICE);
+ for (long id : downloadIds) {
+ manager.resumeDownload(id);
+ Helpers.scheduleJob(context, DownloadInfo.queryDownloadInfo(context, id));
+ }
+ } else if (Constants.ACTION_RESUME.equals(action)) {
+ long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
+ Helpers.scheduleJob(context, DownloadInfo.queryDownloadInfo(context, id));
}
}
diff --git a/src/com/android/providers/downloads/DownloadStorageProvider.java b/src/com/android/providers/downloads/DownloadStorageProvider.java
index 4ec8e2d1..acf7c536 100644
--- a/src/com/android/providers/downloads/DownloadStorageProvider.java
+++ b/src/com/android/providers/downloads/DownloadStorageProvider.java
@@ -376,6 +376,10 @@ public class DownloadStorageProvider extends DocumentsProvider {
int extraFlags = Document.FLAG_PARTIAL;
final int status = cursor.getInt(
cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
+ final long progress = cursor.getLong(cursor.getColumnIndexOrThrow(
+ DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
+ final int reason = cursor.getInt(
+ cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON));
switch (status) {
case DownloadManager.STATUS_SUCCESSFUL:
// Verify that the document still exists in external storage. This is necessary
@@ -387,14 +391,21 @@ public class DownloadStorageProvider extends DocumentsProvider {
extraFlags = Document.FLAG_SUPPORTS_RENAME; // only successful is non-partial
break;
case DownloadManager.STATUS_PAUSED:
- summary = getContext().getString(R.string.download_queued);
+ if (reason == DownloadManager.PAUSED_MANUAL) {
+ if (size != null) {
+ long percent = progress * 100 / size;
+ summary = getContext().getString(R.string.download_paused_percent, percent);
+ } else {
+ summary = getContext().getString(R.string.download_paused);
+ }
+ } else {
+ summary = getContext().getString(R.string.download_queued);
+ }
break;
case DownloadManager.STATUS_PENDING:
summary = getContext().getString(R.string.download_queued);
break;
case DownloadManager.STATUS_RUNNING:
- final long progress = cursor.getLong(cursor.getColumnIndexOrThrow(
- DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
if (size != null) {
String percent =
NumberFormat.getPercentInstance().format((double) progress / size);
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java
index c6b4c71a..fac4e670 100644
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -26,6 +26,7 @@ import static android.provider.Downloads.Impl.STATUS_CANNOT_RESUME;
import static android.provider.Downloads.Impl.STATUS_FILE_ERROR;
import static android.provider.Downloads.Impl.STATUS_HTTP_DATA_ERROR;
import static android.provider.Downloads.Impl.STATUS_PAUSED_BY_APP;
+import static android.provider.Downloads.Impl.STATUS_PAUSED_MANUAL;
import static android.provider.Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
import static android.provider.Downloads.Impl.STATUS_RUNNING;
import static android.provider.Downloads.Impl.STATUS_SUCCESS;
@@ -154,9 +155,11 @@ public class DownloadThread extends Thread {
private static final String NOT_DELETED = COLUMN_DELETED + " == '0'";
private static final String NOT_PAUSED = "(" + COLUMN_CONTROL + " IS NULL OR "
+ COLUMN_CONTROL + " != '" + CONTROL_PAUSED + "')";
+ private static final String NOT_PAUSED_MANUAL = COLUMN_STATUS + " != '"
+ + STATUS_PAUSED_MANUAL + "'";
private static final String SELECTION_VALID = NOT_CANCELED + " AND " + NOT_DELETED + " AND "
- + NOT_PAUSED;
+ + NOT_PAUSED + " AND " + NOT_PAUSED_MANUAL;
public DownloadInfoDelta(DownloadInfo info) {
mUri = info.mUri;
@@ -206,6 +209,8 @@ public class DownloadThread extends Thread {
buildContentValues(), SELECTION_VALID, null) == 0) {
if (mInfo.queryDownloadControl() == CONTROL_PAUSED) {
throw new StopRequestException(STATUS_PAUSED_BY_APP, "Download paused!");
+ } else if (mInfo.queryDownloadStatus() == STATUS_PAUSED_MANUAL) {
+ throw new StopRequestException(STATUS_PAUSED_MANUAL, "Download paused manually!");
} else {
throw new StopRequestException(STATUS_CANCELED, "Download deleted or missing!");
}