summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/drawable/download_pause.xml15
-rw-r--r--res/values/cm_strings.xml8
-rw-r--r--src/com/android/providers/downloads/Constants.java3
-rw-r--r--src/com/android/providers/downloads/DownloadNotifier.java41
-rw-r--r--src/com/android/providers/downloads/DownloadReceiver.java3
-rw-r--r--src/com/android/providers/downloads/DownloadStorageProvider.java17
-rw-r--r--src/com/android/providers/downloads/DownloadThread.java18
-rw-r--r--ui/src/com/android/providers/downloads/ui/TrampolineActivity.java15
8 files changed, 109 insertions, 11 deletions
diff --git a/res/drawable/download_pause.xml b/res/drawable/download_pause.xml
new file mode 100644
index 00000000..3a862d22
--- /dev/null
+++ b/res/drawable/download_pause.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <group>
+ <path
+ android:fillColor="#fafafa"
+ android:pathData="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+ </group>
+</vector>
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index fb6f06c3..b850b25e 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -16,4 +16,12 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="download_speed_text"><xliff:g id="text">%1$s</xliff:g>, <xliff:g id="size" example="230 kB">%2$s</xliff:g>/s</string>
+
+ <!-- Status indicating that the download has been paused to start in the future. Appears for an
+ individual item in the download list. [CHAR LIMIT=24] -->
+ <string name="download_paused">Paused</string>
+ <!-- Representation of download progress percentage when paused. [CHAR LIMIT=24] -->
+ <string name="download_paused_percent">Paused, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+ <!-- Representation of download progress percentage when queued. [CHAR LIMIT=24] -->
+ <string name="download_queued_percent">Queued, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
</resources>
diff --git a/src/com/android/providers/downloads/Constants.java b/src/com/android/providers/downloads/Constants.java
index 7b8fcd24..a10cb514 100644
--- a/src/com/android/providers/downloads/Constants.java
+++ b/src/com/android/providers/downloads/Constants.java
@@ -57,6 +57,9 @@ 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 choosing to resume the paused download */
+ public static final String ACTION_RESUME = "android.intent.action.DOWNLOAD_RESUME";
+
/** 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 3af97463..5e1b9de2 100644
--- a/src/com/android/providers/downloads/DownloadNotifier.java
+++ b/src/com/android/providers/downloads/DownloadNotifier.java
@@ -154,9 +154,25 @@ public class DownloadNotifier {
}
builder.setWhen(firstShown);
+ // Check paused status about these downloads. If exists, will
+ // update icon and content title/content text in notification.
+ boolean hasPausedStatus = false;
+ int pausedStatus = -1;
+ for (DownloadInfo info : cluster) {
+ if (isPausedStatus(info.mStatus)) {
+ hasPausedStatus = true;
+ pausedStatus = info.mStatus;
+ break;
+ }
+ }
+
// Show relevant icon
if (type == TYPE_ACTIVE) {
- builder.setSmallIcon(android.R.drawable.stat_sys_download);
+ if (hasPausedStatus) {
+ 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) {
@@ -264,7 +280,13 @@ public class DownloadNotifier {
builder.setContentTitle(getDownloadTitle(res, info));
if (type == TYPE_ACTIVE) {
- if (speedAsSizeText != null) {
+ if (hasPausedStatus) {
+ if (pausedStatus == Downloads.Impl.STATUS_PAUSED_BY_MANUAL) {
+ builder.setContentText(res.getText(R.string.download_paused));
+ } else {
+ builder.setContentText(res.getText(R.string.download_queued));
+ }
+ } else if (speedAsSizeText != null) {
builder.setContentText(res.getString(R.string.download_speed_text,
remainingText, speedAsSizeText));
}
@@ -293,8 +315,12 @@ public class DownloadNotifier {
}
if (type == TYPE_ACTIVE) {
- builder.setContentTitle(res.getQuantityString(
- R.plurals.notif_summary_active, cluster.size(), cluster.size()));
+ if (hasPausedStatus) {
+ builder.setContentTitle(res.getString(R.string.download_queued));
+ } else {
+ builder.setContentTitle(res.getQuantityString(
+ R.plurals.notif_summary_active, cluster.size(), cluster.size()));
+ }
builder.setContentText(remainingText);
builder.setContentInfo(res.getString(R.string.download_speed_text,
percentText, speedAsSizeText));
@@ -380,7 +406,7 @@ public class DownloadNotifier {
}
private static boolean isActiveAndVisible(DownloadInfo download) {
- return download.mStatus == STATUS_RUNNING &&
+ return Downloads.Impl.isStatusInformational(download.mStatus) &&
(download.mVisibility == VISIBILITY_VISIBLE
|| download.mVisibility == VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
@@ -390,4 +416,9 @@ public class DownloadNotifier {
(download.mVisibility == VISIBILITY_VISIBLE_NOTIFY_COMPLETED
|| download.mVisibility == VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION);
}
+
+ private static boolean isPausedStatus(int status) {
+ return status == Downloads.Impl.STATUS_WAITING_FOR_NETWORK ||
+ status == Downloads.Impl.STATUS_PAUSED_BY_MANUAL;
+ }
}
diff --git a/src/com/android/providers/downloads/DownloadReceiver.java b/src/com/android/providers/downloads/DownloadReceiver.java
index 28e2a673..d2872356 100644
--- a/src/com/android/providers/downloads/DownloadReceiver.java
+++ b/src/com/android/providers/downloads/DownloadReceiver.java
@@ -87,7 +87,8 @@ public class DownloadReceiver extends BroadcastReceiver {
}
});
- } else if (Constants.ACTION_RETRY.equals(action)) {
+ } else if (Constants.ACTION_RETRY.equals(action) ||
+ Constants.ACTION_RESUME.equals(action)) {
startService(context);
} else if (Constants.ACTION_OPEN.equals(action)
diff --git a/src/com/android/providers/downloads/DownloadStorageProvider.java b/src/com/android/providers/downloads/DownloadStorageProvider.java
index 1b5dc844..69efab31 100644
--- a/src/com/android/providers/downloads/DownloadStorageProvider.java
+++ b/src/com/android/providers/downloads/DownloadStorageProvider.java
@@ -303,20 +303,31 @@ public class DownloadStorageProvider extends DocumentsProvider {
size = null;
}
+ final long progress = cursor.getLong(cursor.getColumnIndexOrThrow(
+ DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
final int status = cursor.getInt(
cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
+ final int reason = cursor.getInt(
+ cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON));
switch (status) {
case DownloadManager.STATUS_SUCCESSFUL:
break;
case DownloadManager.STATUS_PAUSED:
- summary = getContext().getString(R.string.download_queued);
+ if (size != null) {
+ final long percent = progress * 100 / size;
+ summary = (reason == DownloadManager.PAUSED_BY_MANUAL) ?
+ getContext().getString(R.string.download_paused_percent, percent) :
+ getContext().getString(R.string.download_queued_percent, percent);
+ } else {
+ summary = (reason == DownloadManager.PAUSED_BY_MANUAL) ?
+ getContext().getString(R.string.download_paused) :
+ 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 325b4eee..c905e25a 100644
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -116,6 +116,11 @@ public class DownloadThread implements Runnable {
private volatile boolean mPolicyDirty;
+ // Add for carrier feature - download breakpoint continuing.
+ // Support continuing download after the download is broken
+ // although HTTP Server doesn't contain etag in its response.
+ private final static String QRD_ETAG = "qrd_magic_etag";
+
/**
* Local changes to {@link DownloadInfo}. These are kept local to avoid
* racing with the thread that updates based on change notifications.
@@ -686,6 +691,11 @@ public class DownloadThread implements Runnable {
if (mInfo.mStatus == Downloads.Impl.STATUS_CANCELED || mInfo.mDeleted) {
throw new StopRequestException(Downloads.Impl.STATUS_CANCELED, "download canceled");
}
+ if (mInfo.mStatus == Downloads.Impl.STATUS_PAUSED_BY_MANUAL) {
+ // user pauses the download by manual, here send exception and stop data transfer.
+ throw new StopRequestException(Downloads.Impl.STATUS_PAUSED_BY_MANUAL,
+ "download paused by manual");
+ }
}
// if policy has been changed, trigger connectivity check
@@ -767,6 +777,10 @@ public class DownloadThread implements Runnable {
mInfoDelta.mETag = conn.getHeaderField("ETag");
+ if (mInfoDelta.mETag == null) {
+ mInfoDelta.mETag = QRD_ETAG;
+ }
+
mInfoDelta.writeToDatabaseOrThrow();
// Check connectivity again now that we know the total size
@@ -812,7 +826,9 @@ public class DownloadThread implements Runnable {
if (resuming) {
if (mInfoDelta.mETag != null) {
- conn.addRequestProperty("If-Match", mInfoDelta.mETag);
+ if (!mInfoDelta.mETag.equals(QRD_ETAG)) {
+ conn.addRequestProperty("If-Match", mInfoDelta.mETag);
+ }
}
conn.addRequestProperty("Range", "bytes=" + mInfoDelta.mCurrentBytes + "-");
}
diff --git a/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java b/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java
index 6bcff73b..8ada01b0 100644
--- a/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java
+++ b/ui/src/com/android/providers/downloads/ui/TrampolineActivity.java
@@ -77,14 +77,27 @@ public class TrampolineActivity extends Activity {
Log.d(Constants.TAG, "Found " + id + " with status " + status + ", reason " + reason);
switch (status) {
case DownloadManager.STATUS_PENDING:
- case DownloadManager.STATUS_RUNNING:
sendRunningDownloadClickedBroadcast(id);
finish();
break;
+ case DownloadManager.STATUS_RUNNING:
+ // Add for carrier feature - pause and resume download by manual.
+ dm.pauseDownload(id);
+ finish();
+ break;
+
case DownloadManager.STATUS_PAUSED:
if (reason == DownloadManager.PAUSED_QUEUED_FOR_WIFI) {
PausedDialogFragment.show(getFragmentManager(), id);
+ } else if (reason == DownloadManager.PAUSED_BY_MANUAL) {
+ // Add for carrier feature - pause and resume download by manual.
+ dm.resumeDownload(id);
+ Intent intent = new Intent(Constants.ACTION_RESUME);
+ intent.setClassName("com.android.providers.downloads",
+ "com.android.providers.downloads.DownloadReceiver");
+ sendBroadcast(intent);
+ finish();
} else {
sendRunningDownloadClickedBroadcast(id);
finish();