Commit b322c318 authored by qinmin's avatar qinmin Committed by Commit bot

Move DownloadSharedPreferenceEntry handling into another class

We might need to consolidate java/native download status later
Moving the java download status into a separate class so we can handle it without UI knowledge

Review-Url: https://codereview.chromium.org/2625493004
Cr-Commit-Position: refs/heads/master@{#442995}
parent 1de27c2c
...@@ -42,12 +42,10 @@ import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri ...@@ -42,12 +42,10 @@ import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri
import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.IntentUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Service responsible for creating and updating download notifications even after * Service responsible for creating and updating download notifications even after
* Chrome gets killed. * Chrome gets killed.
...@@ -74,7 +72,6 @@ public class DownloadNotificationService extends Service { ...@@ -74,7 +72,6 @@ public class DownloadNotificationService extends Service {
"org.chromium.chrome.browser.download.DOWNLOAD_OPEN"; "org.chromium.chrome.browser.download.DOWNLOAD_OPEN";
public static final int INVALID_DOWNLOAD_PERCENTAGE = -1; public static final int INVALID_DOWNLOAD_PERCENTAGE = -1;
@VisibleForTesting
static final String NOTIFICATION_NAMESPACE = "DownloadNotificationService"; static final String NOTIFICATION_NAMESPACE = "DownloadNotificationService";
private static final String TAG = "DownloadNotification"; private static final String TAG = "DownloadNotification";
...@@ -87,11 +84,8 @@ public class DownloadNotificationService extends Service { ...@@ -87,11 +84,8 @@ public class DownloadNotificationService extends Service {
private static final String KEY_AUTO_RESUMPTION_ATTEMPT_LEFT = "ResumptionAttemptLeft"; private static final String KEY_AUTO_RESUMPTION_ATTEMPT_LEFT = "ResumptionAttemptLeft";
private static final String KEY_NEXT_DOWNLOAD_NOTIFICATION_ID = "NextDownloadNotificationId"; private static final String KEY_NEXT_DOWNLOAD_NOTIFICATION_ID = "NextDownloadNotificationId";
static final String KEY_PENDING_DOWNLOAD_NOTIFICATIONS = "PendingDownloadNotifications";
private final IBinder mBinder = new LocalBinder(); private final IBinder mBinder = new LocalBinder();
private final List<DownloadSharedPreferenceEntry> mDownloadSharedPreferenceEntries =
new ArrayList<DownloadSharedPreferenceEntry>();
private final List<String> mDownloadsInProgress = new ArrayList<String>(); private final List<String> mDownloadsInProgress = new ArrayList<String>();
private NotificationManager mNotificationManager; private NotificationManager mNotificationManager;
...@@ -101,6 +95,7 @@ public class DownloadNotificationService extends Service { ...@@ -101,6 +95,7 @@ public class DownloadNotificationService extends Service {
private int mNumAutoResumptionAttemptLeft; private int mNumAutoResumptionAttemptLeft;
private boolean mStopPostingProgressNotifications; private boolean mStopPostingProgressNotifications;
private Bitmap mDownloadSuccessLargeIcon; private Bitmap mDownloadSuccessLargeIcon;
private DownloadSharedPreferenceHelper mDownloadSharedPreferenceHelper;
/** /**
* Class for clients to access. * Class for clients to access.
...@@ -135,7 +130,9 @@ public class DownloadNotificationService extends Service { ...@@ -135,7 +130,9 @@ public class DownloadNotificationService extends Service {
mNotificationManager = (NotificationManager) mContext.getSystemService( mNotificationManager = (NotificationManager) mContext.getSystemService(
Context.NOTIFICATION_SERVICE); Context.NOTIFICATION_SERVICE);
mSharedPrefs = ContextUtils.getAppSharedPreferences(); mSharedPrefs = ContextUtils.getAppSharedPreferences();
parseDownloadSharedPrefs(); mNumAutoResumptionAttemptLeft = mSharedPrefs.getInt(KEY_AUTO_RESUMPTION_ATTEMPT_LEFT,
MAX_RESUMPTION_ATTEMPT_LEFT);
mDownloadSharedPreferenceHelper = DownloadSharedPreferenceHelper.getInstance();
// Because this service is a started service and returns START_STICKY in // Because this service is a started service and returns START_STICKY in
// onStartCommand(), it will be restarted as soon as resources are available // onStartCommand(), it will be restarted as soon as resources are available
// after it is killed. As a result, onCreate() may be called after Chrome // after it is killed. As a result, onCreate() may be called after Chrome
...@@ -148,7 +145,6 @@ public class DownloadNotificationService extends Service { ...@@ -148,7 +145,6 @@ public class DownloadNotificationService extends Service {
} }
mNextNotificationId = mSharedPrefs.getInt( mNextNotificationId = mSharedPrefs.getInt(
KEY_NEXT_DOWNLOAD_NOTIFICATION_ID, STARTING_NOTIFICATION_ID); KEY_NEXT_DOWNLOAD_NOTIFICATION_ID, STARTING_NOTIFICATION_ID);
} }
/** /**
...@@ -158,14 +154,15 @@ public class DownloadNotificationService extends Service { ...@@ -158,14 +154,15 @@ public class DownloadNotificationService extends Service {
private void onBrowserKilled() { private void onBrowserKilled() {
cancelOffTheRecordNotifications(); cancelOffTheRecordNotifications();
pauseAllDownloads(); pauseAllDownloads();
if (!mDownloadSharedPreferenceEntries.isEmpty()) { List<DownloadSharedPreferenceEntry> entries = mDownloadSharedPreferenceHelper.getEntries();
if (!entries.isEmpty()) {
boolean scheduleAutoResumption = false; boolean scheduleAutoResumption = false;
boolean allowMeteredConnection = false; boolean allowMeteredConnection = false;
for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) { for (int i = 0; i < entries.size(); ++i) {
DownloadSharedPreferenceEntry entry = mDownloadSharedPreferenceEntries.get(i); DownloadSharedPreferenceEntry entry = entries.get(i);
if (entry.isAutoResumable) { if (entry.isAutoResumable) {
scheduleAutoResumption = true; scheduleAutoResumption = true;
if (mDownloadSharedPreferenceEntries.get(i).canDownloadWhileMetered) { if (entry.canDownloadWhileMetered) {
allowMeteredConnection = true; allowMeteredConnection = true;
break; break;
} }
...@@ -239,6 +236,7 @@ public class DownloadNotificationService extends Service { ...@@ -239,6 +236,7 @@ public class DownloadNotificationService extends Service {
* @param canDownloadWhileMetered Whether the download can happen in metered network. * @param canDownloadWhileMetered Whether the download can happen in metered network.
* @param isOfflinePage Whether the download is for offline page. * @param isOfflinePage Whether the download is for offline page.
*/ */
@VisibleForTesting
public void notifyDownloadProgress(String downloadGuid, String fileName, int percentage, public void notifyDownloadProgress(String downloadGuid, String fileName, int percentage,
long timeRemainingInMillis, long startTime, boolean isOffTheRecord, long timeRemainingInMillis, long startTime, boolean isOffTheRecord,
boolean canDownloadWhileMetered, boolean isOfflinePage) { boolean canDownloadWhileMetered, boolean isOfflinePage) {
...@@ -328,8 +326,9 @@ public class DownloadNotificationService extends Service { ...@@ -328,8 +326,9 @@ public class DownloadNotificationService extends Service {
int itemType = isOfflinePage ? DownloadSharedPreferenceEntry.ITEM_TYPE_OFFLINE_PAGE int itemType = isOfflinePage ? DownloadSharedPreferenceEntry.ITEM_TYPE_OFFLINE_PAGE
: DownloadSharedPreferenceEntry.ITEM_TYPE_DOWNLOAD; : DownloadSharedPreferenceEntry.ITEM_TYPE_DOWNLOAD;
addOrReplaceSharedPreferenceEntry(new DownloadSharedPreferenceEntry(notificationId, mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry(
isOffTheRecord, canDownloadWhileMetered, downloadGuid, fileName, itemType, true)); new DownloadSharedPreferenceEntry(notificationId, isOffTheRecord,
canDownloadWhileMetered, downloadGuid, fileName, itemType, true));
if (!mDownloadsInProgress.contains(downloadGuid)) { if (!mDownloadsInProgress.contains(downloadGuid)) {
mDownloadsInProgress.add(downloadGuid); mDownloadsInProgress.add(downloadGuid);
} }
...@@ -343,7 +342,7 @@ public class DownloadNotificationService extends Service { ...@@ -343,7 +342,7 @@ public class DownloadNotificationService extends Service {
@VisibleForTesting @VisibleForTesting
void cancelNotification(int notificationId, String downloadGuid) { void cancelNotification(int notificationId, String downloadGuid) {
mNotificationManager.cancel(NOTIFICATION_NAMESPACE, notificationId); mNotificationManager.cancel(NOTIFICATION_NAMESPACE, notificationId);
removeSharedPreferenceEntry(downloadGuid); mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid);
mDownloadsInProgress.remove(downloadGuid); mDownloadsInProgress.remove(downloadGuid);
} }
...@@ -351,8 +350,10 @@ public class DownloadNotificationService extends Service { ...@@ -351,8 +350,10 @@ public class DownloadNotificationService extends Service {
* Called when a download is canceled. * Called when a download is canceled.
* @param downloadGuid GUID of the download. * @param downloadGuid GUID of the download.
*/ */
@VisibleForTesting
public void notifyDownloadCanceled(String downloadGuid) { public void notifyDownloadCanceled(String downloadGuid) {
DownloadSharedPreferenceEntry entry = getDownloadSharedPreferenceEntry(downloadGuid); DownloadSharedPreferenceEntry entry =
mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(downloadGuid);
if (entry == null) return; if (entry == null) return;
cancelNotification(entry.notificationId, downloadGuid); cancelNotification(entry.notificationId, downloadGuid);
} }
...@@ -365,7 +366,8 @@ public class DownloadNotificationService extends Service { ...@@ -365,7 +366,8 @@ public class DownloadNotificationService extends Service {
*/ */
public void notifyDownloadPaused(String downloadGuid, boolean isResumable, public void notifyDownloadPaused(String downloadGuid, boolean isResumable,
boolean isAutoResumable) { boolean isAutoResumable) {
DownloadSharedPreferenceEntry entry = getDownloadSharedPreferenceEntry(downloadGuid); DownloadSharedPreferenceEntry entry =
mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(downloadGuid);
if (entry == null) return; if (entry == null) return;
if (!isResumable) { if (!isResumable) {
notifyDownloadFailed(downloadGuid, entry.fileName); notifyDownloadFailed(downloadGuid, entry.fileName);
...@@ -411,9 +413,11 @@ public class DownloadNotificationService extends Service { ...@@ -411,9 +413,11 @@ public class DownloadNotificationService extends Service {
updateNotification(entry.notificationId, builder.build()); updateNotification(entry.notificationId, builder.build());
// Update the SharedPreference entry with the new isAutoResumable value. // Update the SharedPreference entry with the new isAutoResumable value.
addOrReplaceSharedPreferenceEntry(new DownloadSharedPreferenceEntry(entry.notificationId, mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry(
entry.isOffTheRecord, entry.canDownloadWhileMetered, entry.downloadGuid, new DownloadSharedPreferenceEntry(
entry.fileName, entry.itemType, isAutoResumable)); entry.notificationId, entry.isOffTheRecord,
entry.canDownloadWhileMetered, entry.downloadGuid, entry.fileName,
entry.itemType, isAutoResumable));
mDownloadsInProgress.remove(downloadGuid); mDownloadsInProgress.remove(downloadGuid);
} }
...@@ -428,6 +432,7 @@ public class DownloadNotificationService extends Service { ...@@ -428,6 +432,7 @@ public class DownloadNotificationService extends Service {
* @return ID of the successful download notification. Used for removing the notification when * @return ID of the successful download notification. Used for removing the notification when
* user click on the snackbar. * user click on the snackbar.
*/ */
@VisibleForTesting
public int notifyDownloadSuccessful( public int notifyDownloadSuccessful(
String downloadGuid, String filePath, String fileName, long systemDownloadId, String downloadGuid, String filePath, String fileName, long systemDownloadId,
boolean isOfflinePage, boolean isSupportedMimeType) { boolean isOfflinePage, boolean isSupportedMimeType) {
...@@ -457,7 +462,7 @@ public class DownloadNotificationService extends Service { ...@@ -457,7 +462,7 @@ public class DownloadNotificationService extends Service {
} }
builder.setLargeIcon(mDownloadSuccessLargeIcon); builder.setLargeIcon(mDownloadSuccessLargeIcon);
updateNotification(notificationId, builder.build()); updateNotification(notificationId, builder.build());
removeSharedPreferenceEntry(downloadGuid); mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid);
mDownloadsInProgress.remove(downloadGuid); mDownloadsInProgress.remove(downloadGuid);
return notificationId; return notificationId;
} }
...@@ -467,11 +472,13 @@ public class DownloadNotificationService extends Service { ...@@ -467,11 +472,13 @@ public class DownloadNotificationService extends Service {
* @param downloadGuid GUID of the download. * @param downloadGuid GUID of the download.
* @param fileName GUID of the download. * @param fileName GUID of the download.
*/ */
@VisibleForTesting
public void notifyDownloadFailed(String downloadGuid, String fileName) { public void notifyDownloadFailed(String downloadGuid, String fileName) {
// If the download is not in history db, fileName could be empty. Get it from // If the download is not in history db, fileName could be empty. Get it from
// SharedPreferences. // SharedPreferences.
if (TextUtils.isEmpty(fileName)) { if (TextUtils.isEmpty(fileName)) {
DownloadSharedPreferenceEntry entry = getDownloadSharedPreferenceEntry(downloadGuid); DownloadSharedPreferenceEntry entry =
mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(downloadGuid);
if (entry == null) return; if (entry == null) return;
fileName = entry.fileName; fileName = entry.fileName;
} }
...@@ -481,7 +488,7 @@ public class DownloadNotificationService extends Service { ...@@ -481,7 +488,7 @@ public class DownloadNotificationService extends Service {
android.R.drawable.stat_sys_download_done, fileName, android.R.drawable.stat_sys_download_done, fileName,
mContext.getResources().getString(R.string.download_notification_failed)); mContext.getResources().getString(R.string.download_notification_failed));
updateNotification(notificationId, builder.build()); updateNotification(notificationId, builder.build());
removeSharedPreferenceEntry(downloadGuid); mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid);
mDownloadsInProgress.remove(downloadGuid); mDownloadsInProgress.remove(downloadGuid);
} }
...@@ -490,8 +497,9 @@ public class DownloadNotificationService extends Service { ...@@ -490,8 +497,9 @@ public class DownloadNotificationService extends Service {
*/ */
@VisibleForTesting @VisibleForTesting
void pauseAllDownloads() { void pauseAllDownloads() {
for (int i = mDownloadSharedPreferenceEntries.size() - 1; i >= 0; --i) { List<DownloadSharedPreferenceEntry> entries = mDownloadSharedPreferenceHelper.getEntries();
DownloadSharedPreferenceEntry entry = mDownloadSharedPreferenceEntries.get(i); for (int i = entries.size() - 1; i >= 0; --i) {
DownloadSharedPreferenceEntry entry = entries.get(i);
notifyDownloadPaused(entry.downloadGuid, !entry.isOffTheRecord, true); notifyDownloadPaused(entry.downloadGuid, !entry.isOffTheRecord, true);
} }
} }
...@@ -500,8 +508,9 @@ public class DownloadNotificationService extends Service { ...@@ -500,8 +508,9 @@ public class DownloadNotificationService extends Service {
* Cancels all off the record download notifications. * Cancels all off the record download notifications.
*/ */
void cancelOffTheRecordNotifications() { void cancelOffTheRecordNotifications() {
for (int i = mDownloadSharedPreferenceEntries.size() - 1; i >= 0; --i) { List<DownloadSharedPreferenceEntry> entries = mDownloadSharedPreferenceHelper.getEntries();
DownloadSharedPreferenceEntry entry = mDownloadSharedPreferenceEntries.get(i); for (int i = entries.size() - 1; i >= 0; --i) {
DownloadSharedPreferenceEntry entry = entries.get(i);
if (entry.isOffTheRecord) { if (entry.isOffTheRecord) {
notifyDownloadCanceled(entry.downloadGuid); notifyDownloadCanceled(entry.downloadGuid);
} }
...@@ -590,7 +599,7 @@ public class DownloadNotificationService extends Service { ...@@ -590,7 +599,7 @@ public class DownloadNotificationService extends Service {
private DownloadSharedPreferenceEntry getDownloadEntryFromIntent(Intent intent) { private DownloadSharedPreferenceEntry getDownloadEntryFromIntent(Intent intent) {
if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL) return null; if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL) return null;
String guid = IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_GUID); String guid = IntentUtils.safeGetStringExtra(intent, EXTRA_DOWNLOAD_GUID);
return getDownloadSharedPreferenceEntry(guid); return mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(guid);
} }
/** /**
...@@ -625,9 +634,9 @@ public class DownloadNotificationService extends Service { ...@@ -625,9 +634,9 @@ public class DownloadNotificationService extends Service {
} }
entry.isAutoResumable = true; entry.isAutoResumable = true;
// Update the SharedPreference entry. // Update the SharedPreference entry.
addOrReplaceSharedPreferenceEntry(entry); mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry(entry);
} else if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL } else if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL
&& (mDownloadSharedPreferenceEntries.isEmpty() && (mDownloadSharedPreferenceHelper.getEntries().isEmpty()
|| DownloadManagerService.hasDownloadManagerService())) { || DownloadManagerService.hasDownloadManagerService())) {
return; return;
} else if (intent.getAction() == ACTION_DOWNLOAD_OPEN) { } else if (intent.getAction() == ACTION_DOWNLOAD_OPEN) {
...@@ -777,55 +786,15 @@ public class DownloadNotificationService extends Service { ...@@ -777,55 +786,15 @@ public class DownloadNotificationService extends Service {
} }
/** /**
* Adds a DownloadSharedPreferenceEntry to SharedPrefs. If an entry with the GUID already exists * Resumes all pending downloads from SharedPreferences. If a download is
* in SharedPrefs, update it if it has changed.
* @param pendingEntry A DownloadSharedPreferenceEntry to be added.
*/
private void addOrReplaceSharedPreferenceEntry(DownloadSharedPreferenceEntry pendingEntry) {
Iterator<DownloadSharedPreferenceEntry> iterator =
mDownloadSharedPreferenceEntries.iterator();
while (iterator.hasNext()) {
DownloadSharedPreferenceEntry entry = iterator.next();
if (entry.downloadGuid.equals(pendingEntry.downloadGuid)) {
if (entry.equals(pendingEntry)) return;
iterator.remove();
break;
}
}
mDownloadSharedPreferenceEntries.add(pendingEntry);
storeDownloadSharedPreferenceEntries();
}
/**
* Removes a DownloadSharedPreferenceEntry from SharedPrefs given by the GUID.
* @param guid Download GUID to be removed.
*/
private void removeSharedPreferenceEntry(String guid) {
Iterator<DownloadSharedPreferenceEntry> iterator =
mDownloadSharedPreferenceEntries.iterator();
boolean found = false;
while (iterator.hasNext()) {
DownloadSharedPreferenceEntry entry = iterator.next();
if (entry.downloadGuid.equals(guid)) {
iterator.remove();
found = true;
break;
}
}
if (found) {
storeDownloadSharedPreferenceEntries();
}
}
/**
* Resumes all pending downloads from |mDownloadSharedPreferenceEntries|. If a download is
* already in progress, do nothing. * already in progress, do nothing.
*/ */
public void resumeAllPendingDownloads() { public void resumeAllPendingDownloads() {
boolean isNetworkMetered = DownloadManagerService.isActiveNetworkMetered(mContext); boolean isNetworkMetered = DownloadManagerService.isActiveNetworkMetered(mContext);
if (!DownloadManagerService.hasDownloadManagerService()) return; if (!DownloadManagerService.hasDownloadManagerService()) return;
for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) { List<DownloadSharedPreferenceEntry> entries = mDownloadSharedPreferenceHelper.getEntries();
DownloadSharedPreferenceEntry entry = mDownloadSharedPreferenceEntries.get(i); for (int i = 0; i < entries.size(); ++i) {
DownloadSharedPreferenceEntry entry = entries.get(i);
if (!entry.isAutoResumable) continue; if (!entry.isAutoResumable) continue;
if (mDownloadsInProgress.contains(entry.downloadGuid)) continue; if (mDownloadsInProgress.contains(entry.downloadGuid)) continue;
if (!entry.canDownloadWhileMetered && isNetworkMetered) continue; if (!entry.canDownloadWhileMetered && isNetworkMetered) continue;
...@@ -837,58 +806,13 @@ public class DownloadNotificationService extends Service { ...@@ -837,58 +806,13 @@ public class DownloadNotificationService extends Service {
} }
} }
/**
* Parse a list of the DownloadSharedPreferenceEntry and the number of auto resumption attempt
* left from the shared preference.
*/
void parseDownloadSharedPrefs() {
mNumAutoResumptionAttemptLeft = mSharedPrefs.getInt(KEY_AUTO_RESUMPTION_ATTEMPT_LEFT,
MAX_RESUMPTION_ATTEMPT_LEFT);
if (!mSharedPrefs.contains(KEY_PENDING_DOWNLOAD_NOTIFICATIONS)) return;
Set<String> entries = DownloadManagerService.getStoredDownloadInfo(
mSharedPrefs, KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
for (String entryString : entries) {
DownloadSharedPreferenceEntry entry =
DownloadSharedPreferenceEntry.parseFromString(entryString);
if (entry.notificationId > 0) {
mDownloadSharedPreferenceEntries.add(
DownloadSharedPreferenceEntry.parseFromString(entryString));
}
}
}
/**
* Gets a DownloadSharedPreferenceEntry that has the given GUID.
* @param guid GUID to query.
* @return a DownloadSharedPreferenceEntry that has the specified GUID.
*/
private DownloadSharedPreferenceEntry getDownloadSharedPreferenceEntry(String guid) {
for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) {
if (mDownloadSharedPreferenceEntries.get(i).downloadGuid.equals(guid)) {
return mDownloadSharedPreferenceEntries.get(i);
}
}
return null;
}
/**
* Helper method to store all the SharedPreferences entries.
*/
private void storeDownloadSharedPreferenceEntries() {
Set<String> entries = new HashSet<String>();
for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) {
entries.add(mDownloadSharedPreferenceEntries.get(i).getSharedPreferenceString());
}
DownloadManagerService.storeDownloadInfo(
mSharedPrefs, KEY_PENDING_DOWNLOAD_NOTIFICATIONS, entries);
}
/** /**
* Return the notification ID for the given download GUID. * Return the notification ID for the given download GUID.
* @return notification ID to be used. * @return notification ID to be used.
*/ */
private int getNotificationId(String downloadGuid) { private int getNotificationId(String downloadGuid) {
DownloadSharedPreferenceEntry entry = getDownloadSharedPreferenceEntry(downloadGuid); DownloadSharedPreferenceEntry entry =
mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(downloadGuid);
if (entry != null) return entry.notificationId; if (entry != null) return entry.notificationId;
int notificationId = mNextNotificationId; int notificationId = mNextNotificationId;
mNextNotificationId = mNextNotificationId == Integer.MAX_VALUE mNextNotificationId = mNextNotificationId == Integer.MAX_VALUE
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.download;
import android.content.SharedPreferences;
import org.chromium.base.ContextUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* Class for maintaining all entries of DownloadSharedPreferenceEntry.
*/
public class DownloadSharedPreferenceHelper {
@VisibleForTesting
static final String KEY_PENDING_DOWNLOAD_NOTIFICATIONS = "PendingDownloadNotifications";
private final List<DownloadSharedPreferenceEntry> mDownloadSharedPreferenceEntries =
new ArrayList<DownloadSharedPreferenceEntry>();
private SharedPreferences mSharedPrefs;
// "Initialization on demand holder idiom"
private static class LazyHolder {
private static final DownloadSharedPreferenceHelper INSTANCE =
new DownloadSharedPreferenceHelper();
}
/**
* Creates DownloadSharedPreferenceHelper.
*/
public static DownloadSharedPreferenceHelper getInstance() {
ThreadUtils.assertOnUiThread();
return LazyHolder.INSTANCE;
}
private DownloadSharedPreferenceHelper() {
mSharedPrefs = ContextUtils.getAppSharedPreferences();
parseDownloadSharedPrefs();
}
/**
* Adds a DownloadSharedPreferenceEntry to SharedPrefs. If an entry with the GUID already exists
* in SharedPrefs, update it if it has changed.
* @param pendingEntry A DownloadSharedPreferenceEntry to be added.
*/
public void addOrReplaceSharedPreferenceEntry(DownloadSharedPreferenceEntry pendingEntry) {
ThreadUtils.assertOnUiThread();
Iterator<DownloadSharedPreferenceEntry> iterator =
mDownloadSharedPreferenceEntries.iterator();
while (iterator.hasNext()) {
DownloadSharedPreferenceEntry entry = iterator.next();
if (entry.downloadGuid.equals(pendingEntry.downloadGuid)) {
if (entry.equals(pendingEntry)) return;
iterator.remove();
break;
}
}
mDownloadSharedPreferenceEntries.add(pendingEntry);
storeDownloadSharedPreferenceEntries();
}
/**
* Removes a DownloadSharedPreferenceEntry from SharedPrefs given by the GUID.
* @param guid Download GUID to be removed.
*/
public void removeSharedPreferenceEntry(String guid) {
ThreadUtils.assertOnUiThread();
Iterator<DownloadSharedPreferenceEntry> iterator =
mDownloadSharedPreferenceEntries.iterator();
boolean found = false;
while (iterator.hasNext()) {
DownloadSharedPreferenceEntry entry = iterator.next();
if (entry.downloadGuid.equals(guid)) {
iterator.remove();
found = true;
break;
}
}
if (found) {
storeDownloadSharedPreferenceEntries();
}
}
/**
* Gets a list of stored SharedPreference entries.
* @param a list of DownloadSharedPreferenceEntry stored in SharedPrefs.
*/
public List<DownloadSharedPreferenceEntry> getEntries() {
ThreadUtils.assertOnUiThread();
return mDownloadSharedPreferenceEntries;
}
/**
* Parse a list of the DownloadSharedPreferenceEntry from |mSharedPrefs|.
*/
private void parseDownloadSharedPrefs() {
if (!mSharedPrefs.contains(KEY_PENDING_DOWNLOAD_NOTIFICATIONS)) return;
Set<String> entries = DownloadManagerService.getStoredDownloadInfo(
mSharedPrefs, KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
for (String entryString : entries) {
DownloadSharedPreferenceEntry entry =
DownloadSharedPreferenceEntry.parseFromString(entryString);
if (entry.notificationId > 0) {
mDownloadSharedPreferenceEntries.add(
DownloadSharedPreferenceEntry.parseFromString(entryString));
}
}
}
/**
* Gets a DownloadSharedPreferenceEntry that has the given GUID.
* @param guid GUID to query.
* @return a DownloadSharedPreferenceEntry that has the specified GUID.
*/
public DownloadSharedPreferenceEntry getDownloadSharedPreferenceEntry(String guid) {
ThreadUtils.assertOnUiThread();
for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) {
if (mDownloadSharedPreferenceEntries.get(i).downloadGuid.equals(guid)) {
return mDownloadSharedPreferenceEntries.get(i);
}
}
return null;
}
/**
* Helper method to store all the SharedPreferences entries.
*/
private void storeDownloadSharedPreferenceEntries() {
Set<String> entries = new HashSet<String>();
for (int i = 0; i < mDownloadSharedPreferenceEntries.size(); ++i) {
entries.add(mDownloadSharedPreferenceEntries.get(i).getSharedPreferenceString());
}
DownloadManagerService.storeDownloadInfo(
mSharedPrefs, KEY_PENDING_DOWNLOAD_NOTIFICATIONS, entries);
}
}
...@@ -36,7 +36,6 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -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_PAUSE = 5;
private static final int DOWNLOAD_NOTIFICATION_TYPE_INTERRUPT = 6; private static final int DOWNLOAD_NOTIFICATION_TYPE_INTERRUPT = 6;
private final Context mApplicationContext; private final Context mApplicationContext;
private final Object mLock = new Object();
@Nullable private DownloadNotificationService mBoundService; @Nullable private DownloadNotificationService mBoundService;
private boolean mServiceStarted; private boolean mServiceStarted;
private Set<String> mActiveDownloads = new HashSet<String>(); private Set<String> mActiveDownloads = new HashSet<String>();
...@@ -77,26 +76,22 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -77,26 +76,22 @@ public class SystemDownloadNotifier implements DownloadNotifier {
private final ServiceConnection mConnection = new ServiceConnection() { private final ServiceConnection mConnection = new ServiceConnection() {
@Override @Override
public void onServiceConnected(ComponentName className, IBinder service) { public void onServiceConnected(ComponentName className, IBinder service) {
synchronized (mLock) { if (!(service instanceof DownloadNotificationService.LocalBinder)) {
if (!(service instanceof DownloadNotificationService.LocalBinder)) { Log.w(TAG, "Not from DownloadNotificationService, do not connect."
Log.w(TAG, "Not from DownloadNotificationService, do not connect." + " Component name: " + className);
+ " Component name: " + className); assert false;
assert false; return;
return;
}
mBoundService = ((DownloadNotificationService.LocalBinder) service).getService();
// updateDownloadNotification() may leave some outstanding notifications
// before the service is connected, handle them now.
handlePendingNotifications();
} }
mBoundService = ((DownloadNotificationService.LocalBinder) service).getService();
// updateDownloadNotification() may leave some outstanding notifications
// before the service is connected, handle them now.
handlePendingNotifications();
} }
@Override @Override
public void onServiceDisconnected(ComponentName className) { public void onServiceDisconnected(ComponentName className) {
synchronized (mLock) { mBoundService = null;
mBoundService = null; mServiceStarted = false;
mServiceStarted = false;
}
} }
}; };
...@@ -106,9 +101,7 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -106,9 +101,7 @@ public class SystemDownloadNotifier implements DownloadNotifier {
*/ */
@VisibleForTesting @VisibleForTesting
void setDownloadNotificationService(DownloadNotificationService service) { void setDownloadNotificationService(DownloadNotificationService service) {
synchronized (mLock) { mBoundService = service;
mBoundService = service;
}
} }
/** /**
...@@ -116,20 +109,17 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -116,20 +109,17 @@ public class SystemDownloadNotifier implements DownloadNotifier {
*/ */
@VisibleForTesting @VisibleForTesting
void handlePendingNotifications() { void handlePendingNotifications() {
synchronized (mLock) { if (mPendingNotifications.isEmpty()) return;
if (mPendingNotifications.isEmpty()) return; for (PendingNotificationInfo info : mPendingNotifications) {
for (PendingNotificationInfo info : mPendingNotifications) { updateDownloadNotificationOnUiThread(info);
updateDownloadNotification(info);
}
mPendingNotifications.clear();
} }
mPendingNotifications.clear();
} }
/** /**
* Starts and binds to the download notification service if needed. * Starts and binds to the download notification service if needed.
*/ */
private void startAndBindToServiceIfNeeded() { private void startAndBindToServiceIfNeeded() {
assert Thread.holdsLock(mLock);
if (mServiceStarted) return; if (mServiceStarted) return;
startService(); startService();
mServiceStarted = true; mServiceStarted = true;
...@@ -139,7 +129,6 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -139,7 +129,6 @@ public class SystemDownloadNotifier implements DownloadNotifier {
* Stops the download notification service if there are no download in progress. * Stops the download notification service if there are no download in progress.
*/ */
private void stopServiceIfNeeded() { private void stopServiceIfNeeded() {
assert Thread.holdsLock(mLock);
if (mActiveDownloads.isEmpty() && mServiceStarted) { if (mActiveDownloads.isEmpty() && mServiceStarted) {
stopService(); stopService();
mServiceStarted = false; mServiceStarted = false;
...@@ -151,7 +140,6 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -151,7 +140,6 @@ public class SystemDownloadNotifier implements DownloadNotifier {
*/ */
@VisibleForTesting @VisibleForTesting
void startService() { void startService() {
assert Thread.holdsLock(mLock);
mApplicationContext.startService( mApplicationContext.startService(
new Intent(mApplicationContext, DownloadNotificationService.class)); new Intent(mApplicationContext, DownloadNotificationService.class));
mApplicationContext.bindService(new Intent(mApplicationContext, mApplicationContext.bindService(new Intent(mApplicationContext,
...@@ -163,7 +151,6 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -163,7 +151,6 @@ public class SystemDownloadNotifier implements DownloadNotifier {
*/ */
@VisibleForTesting @VisibleForTesting
void stopService() { void stopService() {
assert Thread.holdsLock(mLock);
mApplicationContext.stopService( mApplicationContext.stopService(
new Intent(mApplicationContext, DownloadNotificationService.class)); new Intent(mApplicationContext, DownloadNotificationService.class));
} }
...@@ -233,77 +220,86 @@ public class SystemDownloadNotifier implements DownloadNotifier { ...@@ -233,77 +220,86 @@ public class SystemDownloadNotifier implements DownloadNotifier {
@VisibleForTesting @VisibleForTesting
void onSuccessNotificationShown( void onSuccessNotificationShown(
final PendingNotificationInfo notificationInfo, final int notificationId) { 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() { ThreadUtils.postOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
DownloadManagerService.getDownloadManagerService( updateDownloadNotificationOnUiThread(notificationInfo);
mApplicationContext).onSuccessNotificationShown(
notificationInfo.downloadInfo, notificationInfo.canResolve,
notificationId, notificationInfo.systemDownloadId);
} }
}); });
} }
/** /**
* Updates the download notification if the notification service is started. Otherwise, * Updates the download notification on UI thread if the notification service is started.
* wait for the notification service to become ready. * Otherwise, wait for the notification service to become ready.
* @param info Pending notification information to be handled. * @param info Pending notification information to be handled.
*/ */
private void updateDownloadNotification(final PendingNotificationInfo notificationInfo) { private void updateDownloadNotificationOnUiThread(
synchronized (mLock) { final PendingNotificationInfo notificationInfo) {
startAndBindToServiceIfNeeded(); startAndBindToServiceIfNeeded();
final DownloadInfo info = notificationInfo.downloadInfo; final DownloadInfo info = notificationInfo.downloadInfo;
if (notificationInfo.type == DOWNLOAD_NOTIFICATION_TYPE_PROGRESS) { if (notificationInfo.type == DOWNLOAD_NOTIFICATION_TYPE_PROGRESS) {
mActiveDownloads.add(info.getDownloadGuid()); mActiveDownloads.add(info.getDownloadGuid());
} else if (notificationInfo.type != DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL) { } else if (notificationInfo.type != DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL) {
mActiveDownloads.remove(info.getDownloadGuid()); mActiveDownloads.remove(info.getDownloadGuid());
} }
if (mBoundService == null) { if (mBoundService == null) {
// We need to wait for the service to connect before we can handle // We need to wait for the service to connect before we can handle
// the notification. Put the notification in the pending notifications // the notification. Put the notification in the pending notifications
// list. // list.
mPendingNotifications.add(notificationInfo); mPendingNotifications.add(notificationInfo);
} else { } else {
switch (notificationInfo.type) { switch (notificationInfo.type) {
case DOWNLOAD_NOTIFICATION_TYPE_PROGRESS: case DOWNLOAD_NOTIFICATION_TYPE_PROGRESS:
mBoundService.notifyDownloadProgress(info.getDownloadGuid(), mBoundService.notifyDownloadProgress(info.getDownloadGuid(),
info.getFileName(), info.getPercentCompleted(), info.getFileName(), info.getPercentCompleted(),
info.getTimeRemainingInMillis(), notificationInfo.startTime, info.getTimeRemainingInMillis(), notificationInfo.startTime,
info.isOffTheRecord(), notificationInfo.canDownloadWhileMetered, info.isOffTheRecord(),
info.isOfflinePage()); notificationInfo.canDownloadWhileMetered,
break; info.isOfflinePage());
case DOWNLOAD_NOTIFICATION_TYPE_PAUSE: break;
mBoundService.notifyDownloadPaused(info.getDownloadGuid(), true, false); case DOWNLOAD_NOTIFICATION_TYPE_PAUSE:
break; mBoundService.notifyDownloadPaused(info.getDownloadGuid(), true,
case DOWNLOAD_NOTIFICATION_TYPE_INTERRUPT: false);
mBoundService.notifyDownloadPaused( break;
info.getDownloadGuid(), info.isResumable(), case DOWNLOAD_NOTIFICATION_TYPE_INTERRUPT:
notificationInfo.isAutoResumable); mBoundService.notifyDownloadPaused(
break; info.getDownloadGuid(), info.isResumable(),
case DOWNLOAD_NOTIFICATION_TYPE_SUCCESS: notificationInfo.isAutoResumable);
final int notificationId = mBoundService.notifyDownloadSuccessful( break;
info.getDownloadGuid(), info.getFilePath(), info.getFileName(), case DOWNLOAD_NOTIFICATION_TYPE_SUCCESS:
notificationInfo.systemDownloadId, info.isOfflinePage(), final int notificationId = mBoundService.notifyDownloadSuccessful(
notificationInfo.isSupportedMimeType); info.getDownloadGuid(), info.getFilePath(),
onSuccessNotificationShown(notificationInfo, notificationId); info.getFileName(), notificationInfo.systemDownloadId,
stopServiceIfNeeded(); info.isOfflinePage(), notificationInfo.isSupportedMimeType);
break; onSuccessNotificationShown(notificationInfo, notificationId);
case DOWNLOAD_NOTIFICATION_TYPE_FAILURE: stopServiceIfNeeded();
mBoundService.notifyDownloadFailed( break;
info.getDownloadGuid(), info.getFileName()); case DOWNLOAD_NOTIFICATION_TYPE_FAILURE:
stopServiceIfNeeded(); mBoundService.notifyDownloadFailed(
break; info.getDownloadGuid(), info.getFileName());
case DOWNLOAD_NOTIFICATION_TYPE_CANCEL: stopServiceIfNeeded();
mBoundService.notifyDownloadCanceled(info.getDownloadGuid()); break;
stopServiceIfNeeded(); case DOWNLOAD_NOTIFICATION_TYPE_CANCEL:
break; mBoundService.notifyDownloadCanceled(info.getDownloadGuid());
case DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL: stopServiceIfNeeded();
mBoundService.resumeAllPendingDownloads(); break;
stopServiceIfNeeded(); case DOWNLOAD_NOTIFICATION_TYPE_RESUME_ALL:
break; mBoundService.resumeAllPendingDownloads();
default: stopServiceIfNeeded();
assert false; break;
} default:
assert false;
} }
} }
} }
......
...@@ -322,6 +322,7 @@ chrome_java_sources = [ ...@@ -322,6 +322,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/download/DownloadResumptionScheduler.java", "java/src/org/chromium/chrome/browser/download/DownloadResumptionScheduler.java",
"java/src/org/chromium/chrome/browser/download/DownloadServiceDelegate.java", "java/src/org/chromium/chrome/browser/download/DownloadServiceDelegate.java",
"java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceEntry.java", "java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceEntry.java",
"java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceHelper.java",
"java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java", "java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java",
"java/src/org/chromium/chrome/browser/download/DownloadUmaStatsEntry.java", "java/src/org/chromium/chrome/browser/download/DownloadUmaStatsEntry.java",
"java/src/org/chromium/chrome/browser/download/DownloadUtils.java", "java/src/org/chromium/chrome/browser/download/DownloadUtils.java",
......
...@@ -80,7 +80,7 @@ public class DownloadNotificationServiceTest extends ...@@ -80,7 +80,7 @@ public class DownloadNotificationServiceTest extends
super.setupService(); super.setupService();
SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit(); SharedPreferences.Editor editor = sharedPrefs.edit();
editor.remove(DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS); editor.remove(DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
editor.apply(); editor.apply();
super.tearDown(); super.tearDown();
} }
...@@ -148,7 +148,7 @@ public class DownloadNotificationServiceTest extends ...@@ -148,7 +148,7 @@ public class DownloadNotificationServiceTest extends
SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit(); SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putStringSet( editor.putStringSet(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications);
editor.apply(); editor.apply();
startNotificationService(); startNotificationService();
assertTrue(scheduler.mScheduled); assertTrue(scheduler.mScheduled);
...@@ -195,7 +195,7 @@ public class DownloadNotificationServiceTest extends ...@@ -195,7 +195,7 @@ public class DownloadNotificationServiceTest extends
SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit(); SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putStringSet( editor.putStringSet(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications);
editor.apply(); editor.apply();
startNotificationService(); startNotificationService();
assertFalse(scheduler.mScheduled); assertFalse(scheduler.mScheduled);
...@@ -223,7 +223,7 @@ public class DownloadNotificationServiceTest extends ...@@ -223,7 +223,7 @@ public class DownloadNotificationServiceTest extends
ContextUtils.getAppSharedPreferences(); ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit(); SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putStringSet( editor.putStringSet(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications);
editor.apply(); editor.apply();
startNotificationService(); startNotificationService();
assertTrue(getService().isPaused()); assertTrue(getService().isPaused());
...@@ -231,7 +231,7 @@ public class DownloadNotificationServiceTest extends ...@@ -231,7 +231,7 @@ public class DownloadNotificationServiceTest extends
assertTrue(getService().getNotificationIds().contains(1)); assertTrue(getService().getNotificationIds().contains(1));
assertTrue(getService().getNotificationIds().contains(2)); assertTrue(getService().getNotificationIds().contains(2));
assertTrue(sharedPrefs.contains( assertTrue(sharedPrefs.contains(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS)); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS));
} }
/** /**
...@@ -255,7 +255,7 @@ public class DownloadNotificationServiceTest extends ...@@ -255,7 +255,7 @@ public class DownloadNotificationServiceTest extends
SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit(); SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putStringSet( editor.putStringSet(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications);
editor.apply(); editor.apply();
startNotificationService(); startNotificationService();
assertEquals(2, getService().getNotificationIds().size()); assertEquals(2, getService().getNotificationIds().size());
...@@ -268,17 +268,17 @@ public class DownloadNotificationServiceTest extends ...@@ -268,17 +268,17 @@ public class DownloadNotificationServiceTest extends
assertEquals(3, getService().getNotificationIds().size()); assertEquals(3, getService().getNotificationIds().size());
int lastNotificationId = getService().getLastAddedNotificationId(); int lastNotificationId = getService().getLastAddedNotificationId();
Set<String> entries = DownloadManagerService.getStoredDownloadInfo( Set<String> entries = DownloadManagerService.getStoredDownloadInfo(
sharedPrefs, DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS); sharedPrefs, DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
assertEquals(3, entries.size()); assertEquals(3, entries.size());
service.notifyDownloadSuccessful(guid1, "/path/to/success", "success", 100L, false, false); service.notifyDownloadSuccessful(guid1, "/path/to/success", "success", 100L, false, false);
entries = DownloadManagerService.getStoredDownloadInfo( entries = DownloadManagerService.getStoredDownloadInfo(
sharedPrefs, DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS); sharedPrefs, DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
assertEquals(2, entries.size()); assertEquals(2, entries.size());
service.notifyDownloadFailed(guid2, "failed"); service.notifyDownloadFailed(guid2, "failed");
entries = DownloadManagerService.getStoredDownloadInfo( entries = DownloadManagerService.getStoredDownloadInfo(
sharedPrefs, DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS); sharedPrefs, DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
assertEquals(1, entries.size()); assertEquals(1, entries.size());
service.notifyDownloadCanceled(guid3); service.notifyDownloadCanceled(guid3);
...@@ -326,7 +326,7 @@ public class DownloadNotificationServiceTest extends ...@@ -326,7 +326,7 @@ public class DownloadNotificationServiceTest extends
SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences(); SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit(); SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putStringSet( editor.putStringSet(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications);
editor.apply(); editor.apply();
startNotificationService(); startNotificationService();
DownloadNotificationService service = bindNotificationService(); DownloadNotificationService service = bindNotificationService();
...@@ -370,12 +370,12 @@ public class DownloadNotificationServiceTest extends ...@@ -370,12 +370,12 @@ public class DownloadNotificationServiceTest extends
ContextUtils.getAppSharedPreferences(); ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit(); SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putStringSet( editor.putStringSet(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS, notifications);
editor.apply(); editor.apply();
startNotificationService(); startNotificationService();
assertTrue(getService().isPaused()); assertTrue(getService().isPaused());
assertFalse(sharedPrefs.contains( assertFalse(sharedPrefs.contains(
DownloadNotificationService.KEY_PENDING_DOWNLOAD_NOTIFICATIONS)); DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS));
} }
@SmallTest @SmallTest
......
...@@ -7,8 +7,11 @@ package org.chromium.chrome.browser.download; ...@@ -7,8 +7,11 @@ package org.chromium.chrome.browser.download;
import android.app.Notification; import android.app.Notification;
import android.content.Context; import android.content.Context;
import org.chromium.base.ThreadUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable;
/** /**
* Mock class to DownloadNotificationService for testing purpose. * Mock class to DownloadNotificationService for testing purpose.
...@@ -59,5 +62,56 @@ public class MockDownloadNotificationService extends DownloadNotificationService ...@@ -59,5 +62,56 @@ public class MockDownloadNotificationService extends DownloadNotificationService
public Context getApplicationContext() { public Context getApplicationContext() {
return mContext == null ? super.getApplicationContext() : mContext; return mContext == null ? super.getApplicationContext() : mContext;
} }
@Override
public int notifyDownloadSuccessful(
final String downloadGuid, final String filePath, final String fileName,
final long systemDownloadId, final boolean isOfflinePage,
final boolean isSupportedMimeType) {
return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return MockDownloadNotificationService.super.notifyDownloadSuccessful(
downloadGuid, filePath, fileName, systemDownloadId, isOfflinePage,
isSupportedMimeType);
}
});
}
@Override
public void notifyDownloadProgress(final String downloadGuid, final String fileName,
final int percentage, final long timeRemainingInMillis, final long startTime,
final boolean isOffTheRecord, final boolean canDownloadWhileMetered,
final boolean isOfflinePage) {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
MockDownloadNotificationService.super.notifyDownloadProgress(
downloadGuid, fileName, percentage, timeRemainingInMillis, startTime,
isOffTheRecord, canDownloadWhileMetered, isOfflinePage);
}
});
}
@Override
public void notifyDownloadFailed(final String downloadGuid, final String fileName) {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
MockDownloadNotificationService.super.notifyDownloadFailed(
downloadGuid, fileName);
}
});
}
@Override
public void notifyDownloadCanceled(final String downloadGuid) {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
MockDownloadNotificationService.super.notifyDownloadCanceled(downloadGuid);
}
});
}
} }
...@@ -12,6 +12,8 @@ import org.chromium.base.ThreadUtils; ...@@ -12,6 +12,8 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.AdvancedMockContext; import org.chromium.base.test.util.AdvancedMockContext;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import java.util.UUID; import java.util.UUID;
...@@ -79,7 +81,13 @@ public class SystemDownloadNotifierTest extends InstrumentationTestCase { ...@@ -79,7 +81,13 @@ public class SystemDownloadNotifierTest extends InstrumentationTestCase {
DownloadInfo info = new DownloadInfo.Builder() DownloadInfo info = new DownloadInfo.Builder()
.setDownloadGuid(UUID.randomUUID().toString()).build(); .setDownloadGuid(UUID.randomUUID().toString()).build();
mDownloadNotifier.notifyDownloadProgress(info, 1L, true); mDownloadNotifier.notifyDownloadProgress(info, 1L, true);
assertTrue(mDownloadNotifier.mStarted); assertFalse(mDownloadNotifier.mStarted);
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return mDownloadNotifier.mStarted;
}
});
onServiceConnected(); onServiceConnected();
assertEquals(1, mService.getNotificationIds().size()); assertEquals(1, mService.getNotificationIds().size());
...@@ -95,14 +103,24 @@ public class SystemDownloadNotifierTest extends InstrumentationTestCase { ...@@ -95,14 +103,24 @@ public class SystemDownloadNotifierTest extends InstrumentationTestCase {
DownloadInfo info = new DownloadInfo.Builder() DownloadInfo info = new DownloadInfo.Builder()
.setDownloadGuid(UUID.randomUUID().toString()).build(); .setDownloadGuid(UUID.randomUUID().toString()).build();
mDownloadNotifier.notifyDownloadProgress(info, 1L, true); mDownloadNotifier.notifyDownloadProgress(info, 1L, true);
assertTrue(mDownloadNotifier.mStarted); assertFalse(mDownloadNotifier.mStarted);
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return mDownloadNotifier.mStarted;
}
});
DownloadInfo info2 = new DownloadInfo.Builder() DownloadInfo info2 = new DownloadInfo.Builder()
.setDownloadGuid(UUID.randomUUID().toString()).build(); .setDownloadGuid(UUID.randomUUID().toString()).build();
mDownloadNotifier.notifyDownloadProgress(info2, 1L, true); mDownloadNotifier.notifyDownloadProgress(info2, 1L, true);
mDownloadNotifier.notifyDownloadFailed(info); mDownloadNotifier.notifyDownloadFailed(info);
assertTrue(mDownloadNotifier.mStarted);
mDownloadNotifier.notifyDownloadSuccessful(info2, 100L, true, false); mDownloadNotifier.notifyDownloadSuccessful(info2, 100L, true, false);
assertFalse(mDownloadNotifier.mStarted); CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return !mDownloadNotifier.mStarted;
}
});
} }
} }
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