Commit c5ee3983 authored by David Trainor's avatar David Trainor Committed by Commit Bot

Add size to the download notification text.

This CL makes the following modifications to the download notification
text:
- Moves time remaining (if known) to the subText/contentInfo.
- Changes the contentText to display percent downloaded, bytes
downloaded, or files downloaded.  The current primary usage will be of
bytes downloaded, which will have the format "XX KB / YY MB" or "XX KB /
?" if the total is unknown.

BUG=845324

Change-Id: Iaf331b6d31c21863ee0a653399d3226e1816dbbd
Reviewed-on: https://chromium-review.googlesource.com/1068127
Commit-Queue: David Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarJustin DeWitt <dewittj@chromium.org>
Reviewed-by: default avatarShakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561399}
parent ebac3c08
......@@ -541,14 +541,8 @@ public final class DownloadInfo {
String remappedMimeType = ChromeDownloadDelegate.remapGenericMimeType(
mimeType, url, fileName);
Progress progress = null;
if (percentCompleted == -1) {
// Indeterminate. Use byte counter.
progress = new Progress(bytesReceived, null, OfflineItemProgressUnit.BYTES);
} else {
// Determinate. Use percent.
progress = new Progress(percentCompleted, 100L, OfflineItemProgressUnit.PERCENTAGE);
}
Progress progress = new Progress(bytesReceived,
percentCompleted == -1 ? null : bytesTotalSize, OfflineItemProgressUnit.BYTES);
return new DownloadInfo.Builder()
.setBytesReceived(bytesReceived)
......
......@@ -74,20 +74,14 @@ public final class DownloadNotificationFactory {
Preconditions.checkNotNull(downloadUpdate.getContentId());
Preconditions.checkArgument(downloadUpdate.getNotificationId() != -1);
boolean indeterminate = downloadUpdate.getProgress().isIndeterminate()
|| downloadUpdate.getIsDownloadPending();
if (downloadUpdate.getIsDownloadPending()) {
contentText =
DownloadUtils.getPendingStatusString(downloadUpdate.getPendingState());
} else if (indeterminate || downloadUpdate.getTimeRemainingInMillis() < 0) {
// TODO(dimich): Enable the byte count back in M59. See bug 704049 for more info
// and details of what was temporarily reverted (for M58).
contentText = context.getResources().getString(R.string.download_started);
} else {
contentText = DownloadUtils.getTimeOrFilesLeftString(context,
downloadUpdate.getProgress(),
downloadUpdate.getTimeRemainingInMillis());
contentText = DownloadUtils.getProgressTextForNotification(
downloadUpdate.getProgress());
}
iconId = downloadUpdate.getIsDownloadPending()
? R.drawable.ic_download_pending
: android.R.drawable.stat_sys_download;
......@@ -128,19 +122,22 @@ public final class DownloadNotificationFactory {
context, cancelIntent, downloadUpdate.getNotificationId()));
if (!downloadUpdate.getIsDownloadPending()) {
boolean indeterminate = downloadUpdate.getProgress().isIndeterminate();
builder.setProgress(100,
indeterminate ? -1 : downloadUpdate.getProgress().getPercentage(),
indeterminate);
}
if (!indeterminate
if (!downloadUpdate.getProgress().isIndeterminate()
&& downloadUpdate.getTimeRemainingInMillis() >= 0
&& !LegacyHelpers.isLegacyOfflinePage(downloadUpdate.getContentId())) {
String percentText = DownloadUtils.getPercentageString(
downloadUpdate.getProgress().getPercentage());
String subText = DownloadUtils.formatRemainingTime(
context, downloadUpdate.getTimeRemainingInMillis());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.setSubText(percentText);
builder.setSubText(subText);
} else {
builder.setContentInfo(percentText);
builder.setContentInfo(subText);
}
}
......@@ -187,8 +184,16 @@ public final class DownloadNotificationFactory {
case COMPLETED:
Preconditions.checkArgument(downloadUpdate.getNotificationId() != -1);
contentText =
context.getResources().getString(R.string.download_notification_completed);
if (downloadUpdate.getTotalBytes() > 0) {
contentText = context.getResources().getString(
R.string.download_notification_completed_with_size,
DownloadUtils.getStringForBytes(
context, downloadUpdate.getTotalBytes()));
} else {
contentText = context.getResources().getString(
R.string.download_notification_completed);
}
iconId = R.drawable.offline_pin;
if (downloadUpdate.getIsOpenable()) {
......
......@@ -337,13 +337,14 @@ public class DownloadNotificationService2 {
* @param icon A {@link Bitmap} to be used as the large icon for display.
* @param originalUrl The original url of the downloaded file.
* @param referrer Referrer of the downloaded file.
* @param totalBytes The total number of bytes downloaded (size of file).
* @return ID of the successful download notification. Used for removing the
* notification when user click on the snackbar.
*/
@VisibleForTesting
public int notifyDownloadSuccessful(ContentId id, String filePath, String fileName,
long systemDownloadId, boolean isOffTheRecord, boolean isSupportedMimeType,
boolean isOpenable, Bitmap icon, String originalUrl, String referrer) {
boolean isOpenable, Bitmap icon, String originalUrl, String referrer, long totalBytes) {
Context context = ContextUtils.getApplicationContext();
int notificationId = getNotificationId(id);
if (icon == null && mDownloadSuccessLargeIcon == null) {
......@@ -365,6 +366,7 @@ public class DownloadNotificationService2 {
.setNotificationId(notificationId)
.setOriginalUrl(originalUrl)
.setReferrer(referrer)
.setTotalBytes(totalBytes)
.build();
Notification notification = DownloadNotificationFactory.buildNotification(
context, DownloadStatus.COMPLETED, downloadUpdate);
......
......@@ -32,6 +32,7 @@ public final class DownloadUpdate {
private final long mStartTime;
private final long mSystemDownloadId;
private final long mTimeRemainingInMillis;
private final long mTotalBytes;
private final @FailState int mFailState;
private final @PendingState int mPendingState;
......@@ -52,6 +53,7 @@ public final class DownloadUpdate {
this.mStartTime = builder.mStartTime;
this.mSystemDownloadId = builder.mSystemDownloadId;
this.mTimeRemainingInMillis = builder.mTimeRemainingInMillis;
this.mTotalBytes = builder.mTotalBytes;
this.mFailState = builder.mFailState;
this.mPendingState = builder.mPendingState;
}
......@@ -124,6 +126,10 @@ public final class DownloadUpdate {
return mTimeRemainingInMillis;
}
public long getTotalBytes() {
return mTotalBytes;
}
public @FailState int getFailState() {
return mFailState;
}
......@@ -152,6 +158,7 @@ public final class DownloadUpdate {
private long mStartTime;
private long mSystemDownloadId = -1;
private long mTimeRemainingInMillis;
private long mTotalBytes;
private @FailState int mFailState;
private @PendingState int mPendingState;
......@@ -235,6 +242,11 @@ public final class DownloadUpdate {
return this;
}
public Builder setTotalBytes(long totalBytes) {
this.mTotalBytes = totalBytes;
return this;
}
public Builder setFailState(@FailState int failState) {
this.mFailState = failState;
return this;
......
......@@ -99,6 +99,9 @@ public class DownloadUtils {
R.string.download_manager_ui_space_free_kb, R.string.download_manager_ui_space_free_mb,
R.string.download_manager_ui_space_free_gb};
private static final int[] BYTES_STRINGS = {
R.string.download_ui_kb, R.string.download_ui_mb, R.string.download_ui_gb};
private static final String TAG = "download";
private static final String DEFAULT_MIME_TYPE = "*/*";
......@@ -646,6 +649,51 @@ public class DownloadUtils {
return false;
}
/**
* Helper method to determine the progress text to use for an in progress download notification.
* @param progress The {@link Progress} struct that represents the current state of an in
* progress download.
* @return The {@link String} that represents the progress.
*/
public static String getProgressTextForNotification(Progress progress) {
Context context = ContextUtils.getApplicationContext();
if (progress.isIndeterminate() && progress.value == 0) {
return context.getResources().getString(R.string.download_started);
}
switch (progress.unit) {
case OfflineItemProgressUnit.PERCENTAGE:
if (progress.isIndeterminate()) {
return context.getResources().getString(R.string.download_started);
} else {
return getPercentageString(progress.getPercentage());
}
case OfflineItemProgressUnit.BYTES:
String bytes = getStringForBytes(context, progress.value);
if (progress.isIndeterminate()) {
return context.getResources().getString(
R.string.download_ui_indeterminate_bytes, bytes);
} else {
String total = getStringForBytes(context, progress.max);
return context.getResources().getString(
R.string.download_ui_determinate_bytes, bytes, total);
}
case OfflineItemProgressUnit.FILES:
if (progress.isIndeterminate()) {
int fileCount = (int) Math.min(Integer.MAX_VALUE, progress.value);
return context.getResources().getQuantityString(
R.plurals.download_ui_files_downloaded, fileCount, fileCount);
} else {
return formatRemainingFiles(context, progress);
}
default:
assert false;
}
return "";
}
/**
* Create a string that represents the percentage of the file that has downloaded.
* @param percentage Current percentage of the file.
......@@ -696,7 +744,6 @@ public class DownloadUtils {
* @param millis the remaining time in milli seconds.
* @return the formatted remaining time.
*/
@VisibleForTesting
public static String formatRemainingTime(Context context, long millis) {
long secondsLong = millis / 1000;
......@@ -914,7 +961,7 @@ public class DownloadUtils {
/**
* Format the number of available bytes into KB, MB, or GB and return the corresponding string
* resource. Uses deafult format "20 KB available."
* resource. Uses default format "20 KB available."
*
* @param context Context to use.
* @param bytes Number of bytes needed to display.
......@@ -924,6 +971,16 @@ public class DownloadUtils {
return getStringForBytes(context, BYTES_AVAILABLE_STRINGS, bytes);
}
/**
* Format the number of bytes into KB, MB, or GB and return the corresponding generated string.
* @param context Context to use.
* @param bytes Number of bytes needed to display.
* @return The formatted string to be displayed.
*/
public static String getStringForBytes(Context context, long bytes) {
return getStringForBytes(context, BYTES_STRINGS, bytes);
}
/**
* Format the number of bytes into KB, or MB, or GB and return the corresponding string
* resource.
......
......@@ -39,7 +39,7 @@ public class SystemDownloadNotifier2 implements DownloadNotifier {
final int notificationId = mDownloadNotificationService.notifyDownloadSuccessful(
info.getContentId(), info.getFilePath(), info.getFileName(), systemDownloadId,
info.isOffTheRecord(), isSupportedMimeType, info.getIsOpenable(), info.getIcon(),
info.getOriginalUrl(), info.getReferrer());
info.getOriginalUrl(), info.getReferrer(), info.getBytesTotalSize());
if (info.getIsOpenable()) {
DownloadManagerService.getDownloadManagerService().onSuccessNotificationShown(
......
......@@ -32,12 +32,14 @@ public class OfflinePageNotificationBridge {
/**
* Update download notification to success.
*
* @param guid GUID of a request to download a page related to the notification.
* @param url URL of the page to download.
* @param displayName Name to be displayed on notification.
* @param guid GUID of a request to download a page related to the notification.
* @param url URL of the page to download.
* @param displayName Name to be displayed on notification.
* @param networkBytesUsed The total number of bytes downloaded for this item.
*/
@CalledByNative
public static void notifyDownloadSuccessful(String guid, String url, String displayName) {
public static void notifyDownloadSuccessful(
String guid, String url, String displayName, long networkBytesUsed) {
DownloadNotifier notifier = getDownloadNotifier();
if (notifier == null) return;
......@@ -47,6 +49,7 @@ public class OfflinePageNotificationBridge {
.setFileName(displayName)
.setIsResumable(false)
.setIsOffTheRecord(false)
.setBytesTotalSize(networkBytesUsed)
.build();
notifier.notifyDownloadSuccessful(downloadInfo, -1, false, true);
......
......@@ -2069,6 +2069,9 @@ To obtain new licenses, connect to the internet and play your downloaded content
<message name="IDS_DOWNLOAD_NOTIFICATION_COMPLETED" desc="Download notification to be displayed when a download completes.">
Download complete
</message>
<message name="IDS_DOWNLOAD_NOTIFICATION_COMPLETED_WITH_SIZE" desc="Download notification to be displayed when a download completes, includes the size of the download as well after a separator character.">
Download complete <ph name="SEPARATOR"></ph> <ph name="BYTES_DOWNLOADED">%1$s<ex>4.3 MB</ex></ph>
</message>
<message name="IDS_DOWNLOAD_NOTIFICATION_FAILED" desc="Download notification to be displayed when a download fails.">
Download failed
</message>
......@@ -2117,6 +2120,21 @@ To obtain new licenses, connect to the internet and play your downloaded content
<message name="IDS_DOWNLOAD_STARTED" desc="Message to show when download has started [CHAR LIMIT=30]">
Downloading…
</message>
<message name="IDS_DOWNLOAD_UI_KB" desc="String indicating the size of a downloaded file (in progress or complete), in kilobytes.">
<ph name="kilobytes">%1$3.2f<ex>12.5</ex></ph> KB
</message>
<message name="IDS_DOWNLOAD_UI_MB" desc="String indicating the size of a downloaded file (in progress or complete), in megabytes.">
<ph name="megabytes">%1$3.2f<ex>12.5</ex></ph> MB
</message>
<message name="IDS_DOWNLOAD_UI_GB" desc="String indicating the size of a downloaded file (in progress or complete), in gigabytes.">
<ph name="gigabytes">%1$3.2f<ex>12.5</ex></ph> GB
</message>
<message name="IDS_DOWNLOAD_UI_INDETERMINATE_BYTES" desc="Appears in a notification when a user starts downloading a file. Indicates the number of bytes downloaded out of an unknown total file size. E.g. 3/? MB [downloaded]. As appropriate for your language, use '/' or 'of'; and change word order as needed.">
<ph name="BYTES_DOWNLOADED_WITH_UNITS">%1$s<ex>12.2 MB</ex></ph> / ?
</message>
<message name="IDS_DOWNLOAD_UI_DETERMINATE_BYTES" desc="Appears in a notification when a user starts downloading a file. Indicates the number of bytes downloaded out of the total file size. E.g. 3/7 MB [downloaded]. As appropriate for your language, use '/' or 'of'; and change word order as needed.">
<ph name="BYTES_DOWNLOADED_WITH_UNITS">%1$s<ex>12.2 MB</ex></ph> / <ph name="FILE_SIZE_WITH_UNITS">%2$s<ex>20.3 GB</ex></ph>
</message>
<message name="IDS_PREFETCH_BADGE_NEW" desc="Message on download home to show that there are new prefetched contents">
New
</message>
......@@ -2132,14 +2150,17 @@ To obtain new licenses, connect to the internet and play your downloaded content
<message name="IDS_FILE_SIZE_DOWNLOADED_MB" desc="Notification message showing how many MBs have been downloaded.">
Downloaded <ph name="MBS">%1$.1f<ex>10.1</ex></ph> MB
</message>
<message name="IDS_FILE_SIZE_DOWNLOADED_GB" desc="Notification message showing how many GBs have been downloaded.">
Downloaded <ph name="GBS">%1$.1f<ex>10.1</ex></ph> GB
</message>
<message name="IDS_ONE_FILE_LEFT" desc="Message showing 1 file left">
1 file left
</message>
<message name="IDS_FILES_LEFT" desc="Message showing how many files are left.">
<ph name="FILES">%1$d<ex>10</ex></ph> files left
</message>
<message name="IDS_FILE_SIZE_DOWNLOADED_GB" desc="Notification message showing how many GBs have been downloaded.">
Downloaded <ph name="GBS">%1$.1f<ex>10.1</ex></ph> GB
<message name="IDS_DOWNLOAD_UI_FILES_DOWNLOADED" desc="Number of files that have been downloaded. [ICU Syntax]">
{FILES, plural, =1 {%1$d file downloaded} other {%1$d files downloaded}}
</message>
<message name="IDS_REMAINING_DURATION_DAYS" desc="Message to show remaining duration in multiple days">
<ph name="DAYS">%1$d<ex>2</ex></ph> days left
......
......@@ -157,7 +157,7 @@ public class DownloadNotificationService2Test {
// Download is successful.
mDownloadNotificationService.notifyDownloadSuccessful(
ID1, "", "test", 1L, true, true, true, null, "", "");
ID1, "", "test", 1L, true, true, true, null, "", "", 0);
assertEquals(1, mDownloadNotificationService.getNotificationIds().size());
assertFalse(mDownloadForegroundServiceManager.mDownloadUpdateQueue.containsKey(
notificationId1));
......
......@@ -60,12 +60,13 @@ public class MockDownloadNotificationService2 extends DownloadNotificationServic
public int notifyDownloadSuccessful(final ContentId id, final String filePath,
final String fileName, final long systemDownloadId, final boolean isOffTheRecord,
final boolean isSupportedMimeType, final boolean isOpenable, final Bitmap icon,
final String originalUrl, final String referrer) {
final String originalUrl, final String referrer, final long totalBytes) {
return ThreadUtils.runOnUiThreadBlockingNoException(
()
-> MockDownloadNotificationService2.super.notifyDownloadSuccessful(id,
filePath, fileName, systemDownloadId, isOffTheRecord,
isSupportedMimeType, isOpenable, icon, originalUrl, referrer));
isSupportedMimeType, isOpenable, icon, originalUrl, referrer,
totalBytes));
}
@Override
......
......@@ -22,7 +22,7 @@ void OfflinePageNotificationBridge::NotifyDownloadSuccessful(
Java_OfflinePageNotificationBridge_notifyDownloadSuccessful(
env, ConvertUTF8ToJavaString(env, item.id.id),
ConvertUTF8ToJavaString(env, item.page_url.spec()),
ConvertUTF8ToJavaString(env, item.title));
ConvertUTF8ToJavaString(env, item.title), item.total_size_bytes);
}
void OfflinePageNotificationBridge::NotifyDownloadFailed(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment