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
// 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);
}
}
...@@ -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