| Index: chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
|
| index 546f050a05a5a990fbb9c573fd7e7b22f9322b49..e31c33784f846e8145689bc93a36e6df161de504 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
|
| @@ -548,37 +548,26 @@ public class DownloadManagerService extends BroadcastReceiver implements
|
| }
|
|
|
| /**
|
| - * Updates notifications for a given list of downloads. Should not be called from UI thread.
|
| + * Updates notifications for a given list of downloads.
|
| * @param progresses A list of notifications to update.
|
| - * @return A List of failed downloads.
|
| */
|
| - private List<DownloadItem> updateAllNotifications(List<DownloadProgress> progresses) {
|
| - assert !ThreadUtils.runningOnUiThread();
|
| - List<DownloadItem> downloadItems = new ArrayList<DownloadItem>();
|
| + private void updateAllNotifications(List<DownloadProgress> progresses) {
|
| + assert ThreadUtils.runningOnUiThread();
|
| for (int i = 0; i < progresses.size(); ++i) {
|
| DownloadProgress progress = progresses.get(i);
|
| DownloadItem item = progress.mDownloadItem;
|
| DownloadInfo info = item.getDownloadInfo();
|
| + boolean notificationUpdateScheduled = true;
|
| + boolean removeFromDownloadProgressMap = true;
|
| switch (progress.mDownloadStatus) {
|
| case DOWNLOAD_STATUS_COMPLETE:
|
| - boolean success = addCompletedDownload(item);
|
| - if (success) {
|
| - boolean canResolve = isOMADownloadDescription(info)
|
| - || canResolveDownloadItem(
|
| - mContext, item, progress.mIsSupportedMimeType);
|
| - long systemDownloadId = item.getSystemDownloadId();
|
| - mDownloadNotifier.notifyDownloadSuccessful(
|
| - info, systemDownloadId, canResolve, progress.mIsSupportedMimeType);
|
| - broadcastDownloadSuccessful(info);
|
| - } else {
|
| - downloadItems.add(item);
|
| - mDownloadNotifier.notifyDownloadFailed(info);
|
| - }
|
| + notificationUpdateScheduled = updateDownloadSuccessNotification(progress);
|
| + removeFromDownloadProgressMap = notificationUpdateScheduled;
|
| break;
|
| case DOWNLOAD_STATUS_FAILED:
|
| - downloadItems.add(item);
|
| mDownloadNotifier.notifyDownloadFailed(info);
|
| Log.w(TAG, "Download failed: " + info.getFilePath());
|
| + onDownloadFailed(info.getFileName(), DownloadManager.ERROR_UNKNOWN);
|
| break;
|
| case DOWNLOAD_STATUS_IN_PROGRESS:
|
| if (info.isPaused()) {
|
| @@ -587,6 +576,7 @@ public class DownloadManagerService extends BroadcastReceiver implements
|
| } else {
|
| mDownloadNotifier.notifyDownloadProgress(info,
|
| progress.mStartTimeInMillis, progress.mCanDownloadWhileMetered);
|
| + removeFromDownloadProgressMap = false;
|
| }
|
| break;
|
| case DOWNLOAD_STATUS_CANCELLED:
|
| @@ -594,13 +584,61 @@ public class DownloadManagerService extends BroadcastReceiver implements
|
| break;
|
| case DOWNLOAD_STATUS_INTERRUPTED:
|
| mDownloadNotifier.notifyDownloadInterrupted(info, progress.mIsAutoResumable);
|
| + removeFromDownloadProgressMap = !progress.mIsAutoResumable;
|
| break;
|
| default:
|
| assert false;
|
| break;
|
| }
|
| + if (notificationUpdateScheduled) {
|
| + progress.mIsUpdated = false;
|
| + }
|
| + if (removeFromDownloadProgressMap) {
|
| + mDownloadProgressMap.remove(item.getId());
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Helper method to schedule a task to update the download success notification.
|
| + * @param progresses Download progress to update.
|
| + * @return True if the task can be scheduled, or false otherwise.
|
| + */
|
| + private boolean updateDownloadSuccessNotification(DownloadProgress progress) {
|
| + final boolean isSupportedMimeType = progress.mIsSupportedMimeType;
|
| + final DownloadItem item = progress.mDownloadItem;
|
| + AsyncTask<Void, Void, Pair<Long, Boolean>> task =
|
| + new AsyncTask<Void, Void, Pair<Long, Boolean>>() {
|
| + @Override
|
| + public Pair<Long, Boolean> doInBackground(Void... params) {
|
| + boolean success = addCompletedDownload(item);
|
| + boolean canResolve = success ? (isOMADownloadDescription(item.getDownloadInfo())
|
| + || canResolveDownloadItem(mContext, item, isSupportedMimeType)) : false;
|
| + return Pair.create(item.getSystemDownloadId(), canResolve);
|
| + }
|
| +
|
| + @Override
|
| + protected void onPostExecute(Pair<Long, Boolean> result) {
|
| + DownloadInfo info = item.getDownloadInfo();
|
| + if (result.first != DownloadItem.INVALID_DOWNLOAD_ID) {
|
| + mDownloadNotifier.notifyDownloadSuccessful(
|
| + info, result.first, result.second, isSupportedMimeType);
|
| + broadcastDownloadSuccessful(info);
|
| + } else {
|
| + mDownloadNotifier.notifyDownloadFailed(info);
|
| + // TODO(qinmin): get the failure message from native.
|
| + onDownloadFailed(info.getFileName(), DownloadManager.ERROR_UNKNOWN);
|
| + }
|
| + }
|
| + };
|
| + try {
|
| + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
| + return true;
|
| + } catch (RejectedExecutionException e) {
|
| + // Reaching thread limit, update will be reschduled for the next run.
|
| + Log.e(TAG, "Thread limit reached, reschedule notification update later.");
|
| + return false;
|
| }
|
| - return downloadItems;
|
| }
|
|
|
| /**
|
| @@ -610,6 +648,7 @@ public class DownloadManagerService extends BroadcastReceiver implements
|
| * @return true if the download is added to the DownloadManager, or false otherwise.
|
| */
|
| protected boolean addCompletedDownload(DownloadItem downloadItem) {
|
| + assert !ThreadUtils.runningOnUiThread();
|
| DownloadInfo downloadInfo = downloadItem.getDownloadInfo();
|
| String description = downloadInfo.getDescription();
|
| if (TextUtils.isEmpty(description)) description = downloadInfo.getFileName();
|
| @@ -653,7 +692,8 @@ public class DownloadManagerService extends BroadcastReceiver implements
|
| /**
|
| * Schedule an update if there is no update scheduled.
|
| */
|
| - private void scheduleUpdateIfNeeded() {
|
| + @VisibleForTesting
|
| + protected void scheduleUpdateIfNeeded() {
|
| if (mIsUIUpdateScheduled) return;
|
|
|
| mIsUIUpdateScheduled = true;
|
| @@ -669,45 +709,7 @@ public class DownloadManagerService extends BroadcastReceiver implements
|
| mIsUIUpdateScheduled = false;
|
| return;
|
| }
|
| - // Make a copy of the |progressUpdated|, so that we can update the notification on another
|
| - // thread without worrying about concurrent modifications.
|
| - final List<DownloadProgress> progressToUpdate = new ArrayList<DownloadProgress>();
|
| - for (int i = 0; i < progressPendingUpdate.size(); ++i) {
|
| - progressToUpdate.add(new DownloadProgress(progressPendingUpdate.get(i)));
|
| - }
|
| - AsyncTask<Void, Void, List<DownloadItem>> task =
|
| - new AsyncTask<Void, Void, List<DownloadItem>>() {
|
| - @Override
|
| - public List<DownloadItem> doInBackground(Void... params) {
|
| - return updateAllNotifications(progressToUpdate);
|
| - }
|
| -
|
| - @Override
|
| - protected void onPostExecute(List<DownloadItem> result) {
|
| - for (int i = 0; i < result.size(); ++i) {
|
| - // TODO(qinmin): get the failure message from native.
|
| - onDownloadFailed(result.get(i).getDownloadInfo().getFileName(),
|
| - DownloadManager.ERROR_UNKNOWN);
|
| - }
|
| - }
|
| - };
|
| - try {
|
| - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
| - for (int i = 0; i < progressPendingUpdate.size(); ++i) {
|
| - DownloadProgress progress = progressPendingUpdate.get(i);
|
| - progress.mIsUpdated = false;
|
| - // Remove progress entry from mDownloadProgressMap if they are no longer needed.
|
| - if ((progress.mDownloadStatus != DOWNLOAD_STATUS_IN_PROGRESS
|
| - || progress.mDownloadItem.getDownloadInfo().isPaused())
|
| - && (progress.mDownloadStatus != DOWNLOAD_STATUS_INTERRUPTED
|
| - || !progress.mIsAutoResumable)) {
|
| - mDownloadProgressMap.remove(progress.mDownloadItem.getId());
|
| - }
|
| - }
|
| - } catch (RejectedExecutionException e) {
|
| - // Reaching thread limit, update will be reschduled for the next run.
|
| - Log.e(TAG, "reaching thread limit, reschedule notification update later.");
|
| - }
|
| + updateAllNotifications(progressPendingUpdate);
|
|
|
| Runnable scheduleNextUpdateTask = new Runnable(){
|
| @Override
|
|
|