| Index: chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
|
| index 4305ae1cf224ab59242c50720dbd895b990b416e..9a38bef50e8160259278929a0ff2a318a9da9df5 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
|
| @@ -36,7 +36,6 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| private static final int DOWNLOAD_NOTIFICATION_TYPE_PAUSE = 5;
|
| private static final int DOWNLOAD_NOTIFICATION_TYPE_INTERRUPT = 6;
|
| private final Context mApplicationContext;
|
| - private final Object mLock = new Object();
|
| @Nullable private DownloadNotificationService mBoundService;
|
| private boolean mServiceStarted;
|
| private Set<String> mActiveDownloads = new HashSet<String>();
|
| @@ -77,26 +76,22 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| private final ServiceConnection mConnection = new ServiceConnection() {
|
| @Override
|
| public void onServiceConnected(ComponentName className, IBinder service) {
|
| - synchronized (mLock) {
|
| - if (!(service instanceof DownloadNotificationService.LocalBinder)) {
|
| - Log.w(TAG, "Not from DownloadNotificationService, do not connect."
|
| - + " Component name: " + className);
|
| - assert false;
|
| - return;
|
| - }
|
| - mBoundService = ((DownloadNotificationService.LocalBinder) service).getService();
|
| - // updateDownloadNotification() may leave some outstanding notifications
|
| - // before the service is connected, handle them now.
|
| - handlePendingNotifications();
|
| + if (!(service instanceof DownloadNotificationService.LocalBinder)) {
|
| + Log.w(TAG, "Not from DownloadNotificationService, do not connect."
|
| + + " Component name: " + className);
|
| + assert false;
|
| + return;
|
| }
|
| + mBoundService = ((DownloadNotificationService.LocalBinder) service).getService();
|
| + // updateDownloadNotification() may leave some outstanding notifications
|
| + // before the service is connected, handle them now.
|
| + handlePendingNotifications();
|
| }
|
|
|
| @Override
|
| public void onServiceDisconnected(ComponentName className) {
|
| - synchronized (mLock) {
|
| - mBoundService = null;
|
| - mServiceStarted = false;
|
| - }
|
| + mBoundService = null;
|
| + mServiceStarted = false;
|
| }
|
| };
|
|
|
| @@ -106,9 +101,7 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| */
|
| @VisibleForTesting
|
| void setDownloadNotificationService(DownloadNotificationService service) {
|
| - synchronized (mLock) {
|
| - mBoundService = service;
|
| - }
|
| + mBoundService = service;
|
| }
|
|
|
| /**
|
| @@ -116,20 +109,17 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| */
|
| @VisibleForTesting
|
| void handlePendingNotifications() {
|
| - synchronized (mLock) {
|
| - if (mPendingNotifications.isEmpty()) return;
|
| - for (PendingNotificationInfo info : mPendingNotifications) {
|
| - updateDownloadNotification(info);
|
| - }
|
| - mPendingNotifications.clear();
|
| + if (mPendingNotifications.isEmpty()) return;
|
| + for (PendingNotificationInfo info : mPendingNotifications) {
|
| + updateDownloadNotificationOnUiThread(info);
|
| }
|
| + mPendingNotifications.clear();
|
| }
|
|
|
| /**
|
| * Starts and binds to the download notification service if needed.
|
| */
|
| private void startAndBindToServiceIfNeeded() {
|
| - assert Thread.holdsLock(mLock);
|
| if (mServiceStarted) return;
|
| startService();
|
| mServiceStarted = true;
|
| @@ -139,7 +129,6 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| * Stops the download notification service if there are no download in progress.
|
| */
|
| private void stopServiceIfNeeded() {
|
| - assert Thread.holdsLock(mLock);
|
| if (mActiveDownloads.isEmpty() && mServiceStarted) {
|
| stopService();
|
| mServiceStarted = false;
|
| @@ -151,7 +140,6 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| */
|
| @VisibleForTesting
|
| void startService() {
|
| - assert Thread.holdsLock(mLock);
|
| mApplicationContext.startService(
|
| new Intent(mApplicationContext, DownloadNotificationService.class));
|
| mApplicationContext.bindService(new Intent(mApplicationContext,
|
| @@ -163,7 +151,6 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| */
|
| @VisibleForTesting
|
| void stopService() {
|
| - assert Thread.holdsLock(mLock);
|
| mApplicationContext.stopService(
|
| new Intent(mApplicationContext, DownloadNotificationService.class));
|
| }
|
| @@ -233,77 +220,86 @@ public class SystemDownloadNotifier implements DownloadNotifier {
|
| @VisibleForTesting
|
| void onSuccessNotificationShown(
|
| final PendingNotificationInfo notificationInfo, final int notificationId) {
|
| + DownloadManagerService.getDownloadManagerService(
|
| + mApplicationContext).onSuccessNotificationShown(
|
| + notificationInfo.downloadInfo, notificationInfo.canResolve,
|
| + notificationId, notificationInfo.systemDownloadId);
|
| + }
|
| +
|
| + /**
|
| + * Helper method to schedule download notification updates, can be called on any thread.
|
| + * @param info Pending notification information to be handled.
|
| + */
|
| + private void updateDownloadNotification(final PendingNotificationInfo notificationInfo) {
|
| ThreadUtils.postOnUiThread(new Runnable() {
|
| @Override
|
| public void run() {
|
| - DownloadManagerService.getDownloadManagerService(
|
| - mApplicationContext).onSuccessNotificationShown(
|
| - notificationInfo.downloadInfo, notificationInfo.canResolve,
|
| - notificationId, notificationInfo.systemDownloadId);
|
| + updateDownloadNotificationOnUiThread(notificationInfo);
|
| }
|
| });
|
| }
|
|
|
| /**
|
| - * Updates the download notification if the notification service is started. Otherwise,
|
| - * wait for the notification service to become ready.
|
| + * Updates the download notification on UI thread if the notification service is started.
|
| + * Otherwise, wait for the notification service to become ready.
|
| * @param info Pending notification information to be handled.
|
| */
|
| - private void updateDownloadNotification(final PendingNotificationInfo notificationInfo) {
|
| - synchronized (mLock) {
|
| - startAndBindToServiceIfNeeded();
|
| - final DownloadInfo info = notificationInfo.downloadInfo;
|
| - if (notificationInfo.type == DOWNLOAD_NOTIFICATION_TYPE_PROGRESS) {
|
| - mActiveDownloads.add(info.getDownloadGuid());
|
| - } else if (notificationInfo.type != DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL) {
|
| - mActiveDownloads.remove(info.getDownloadGuid());
|
| - }
|
| - if (mBoundService == null) {
|
| - // We need to wait for the service to connect before we can handle
|
| - // the notification. Put the notification in the pending notifications
|
| - // list.
|
| - mPendingNotifications.add(notificationInfo);
|
| - } else {
|
| - switch (notificationInfo.type) {
|
| - case DOWNLOAD_NOTIFICATION_TYPE_PROGRESS:
|
| - mBoundService.notifyDownloadProgress(info.getDownloadGuid(),
|
| - info.getFileName(), info.getPercentCompleted(),
|
| - info.getTimeRemainingInMillis(), notificationInfo.startTime,
|
| - info.isOffTheRecord(), notificationInfo.canDownloadWhileMetered,
|
| - info.isOfflinePage());
|
| - break;
|
| - case DOWNLOAD_NOTIFICATION_TYPE_PAUSE:
|
| - mBoundService.notifyDownloadPaused(info.getDownloadGuid(), true, false);
|
| - break;
|
| - case DOWNLOAD_NOTIFICATION_TYPE_INTERRUPT:
|
| - mBoundService.notifyDownloadPaused(
|
| - info.getDownloadGuid(), info.isResumable(),
|
| - notificationInfo.isAutoResumable);
|
| - break;
|
| - case DOWNLOAD_NOTIFICATION_TYPE_SUCCESS:
|
| - final int notificationId = mBoundService.notifyDownloadSuccessful(
|
| - info.getDownloadGuid(), info.getFilePath(), info.getFileName(),
|
| - notificationInfo.systemDownloadId, info.isOfflinePage(),
|
| - notificationInfo.isSupportedMimeType);
|
| - onSuccessNotificationShown(notificationInfo, notificationId);
|
| - stopServiceIfNeeded();
|
| - break;
|
| - case DOWNLOAD_NOTIFICATION_TYPE_FAILURE:
|
| - mBoundService.notifyDownloadFailed(
|
| - info.getDownloadGuid(), info.getFileName());
|
| - stopServiceIfNeeded();
|
| - break;
|
| - case DOWNLOAD_NOTIFICATION_TYPE_CANCEL:
|
| - mBoundService.notifyDownloadCanceled(info.getDownloadGuid());
|
| - stopServiceIfNeeded();
|
| - break;
|
| - case DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL:
|
| - mBoundService.resumeAllPendingDownloads();
|
| - stopServiceIfNeeded();
|
| - break;
|
| - default:
|
| - assert false;
|
| - }
|
| + private void updateDownloadNotificationOnUiThread(
|
| + final PendingNotificationInfo notificationInfo) {
|
| + startAndBindToServiceIfNeeded();
|
| + final DownloadInfo info = notificationInfo.downloadInfo;
|
| + if (notificationInfo.type == DOWNLOAD_NOTIFICATION_TYPE_PROGRESS) {
|
| + mActiveDownloads.add(info.getDownloadGuid());
|
| + } else if (notificationInfo.type != DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL) {
|
| + mActiveDownloads.remove(info.getDownloadGuid());
|
| + }
|
| + if (mBoundService == null) {
|
| + // We need to wait for the service to connect before we can handle
|
| + // the notification. Put the notification in the pending notifications
|
| + // list.
|
| + mPendingNotifications.add(notificationInfo);
|
| + } else {
|
| + switch (notificationInfo.type) {
|
| + case DOWNLOAD_NOTIFICATION_TYPE_PROGRESS:
|
| + mBoundService.notifyDownloadProgress(info.getDownloadGuid(),
|
| + info.getFileName(), info.getPercentCompleted(),
|
| + info.getTimeRemainingInMillis(), notificationInfo.startTime,
|
| + info.isOffTheRecord(),
|
| + notificationInfo.canDownloadWhileMetered,
|
| + info.isOfflinePage());
|
| + break;
|
| + case DOWNLOAD_NOTIFICATION_TYPE_PAUSE:
|
| + mBoundService.notifyDownloadPaused(info.getDownloadGuid(), true,
|
| + false);
|
| + break;
|
| + case DOWNLOAD_NOTIFICATION_TYPE_INTERRUPT:
|
| + mBoundService.notifyDownloadPaused(
|
| + info.getDownloadGuid(), info.isResumable(),
|
| + notificationInfo.isAutoResumable);
|
| + break;
|
| + case DOWNLOAD_NOTIFICATION_TYPE_SUCCESS:
|
| + final int notificationId = mBoundService.notifyDownloadSuccessful(
|
| + info.getDownloadGuid(), info.getFilePath(),
|
| + info.getFileName(), notificationInfo.systemDownloadId,
|
| + info.isOfflinePage(), notificationInfo.isSupportedMimeType);
|
| + onSuccessNotificationShown(notificationInfo, notificationId);
|
| + stopServiceIfNeeded();
|
| + break;
|
| + case DOWNLOAD_NOTIFICATION_TYPE_FAILURE:
|
| + mBoundService.notifyDownloadFailed(
|
| + info.getDownloadGuid(), info.getFileName());
|
| + stopServiceIfNeeded();
|
| + break;
|
| + case DOWNLOAD_NOTIFICATION_TYPE_CANCEL:
|
| + mBoundService.notifyDownloadCanceled(info.getDownloadGuid());
|
| + stopServiceIfNeeded();
|
| + break;
|
| + case DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL:
|
| + mBoundService.resumeAllPendingDownloads();
|
| + stopServiceIfNeeded();
|
| + break;
|
| + default:
|
| + assert false;
|
| }
|
| }
|
| }
|
|
|