Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1625)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java

Issue 2713433002: remove unnecessary thread hopping when updating Download notifications (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698