Index: chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java |
index f3f9905fe82789bc1f0b637f02c36efe92864074..41fd5f5652e38e6a462eb28b87199676ac16edd0 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java |
@@ -16,10 +16,12 @@ import org.chromium.base.metrics.RecordUserAction; |
import org.chromium.chrome.R; |
import org.chromium.chrome.browser.download.DownloadItem; |
import org.chromium.chrome.browser.download.DownloadSharedPreferenceHelper; |
+import org.chromium.chrome.browser.download.DownloadUtils; |
import org.chromium.chrome.browser.download.ui.BackendProvider.DownloadDelegate; |
import org.chromium.chrome.browser.download.ui.BackendProvider.OfflinePageDelegate; |
import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.DownloadItemWrapper; |
import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.OfflinePageItemWrapper; |
+import org.chromium.chrome.browser.download.ui.DownloadManagerUi.DownloadBackendProvider; |
import org.chromium.chrome.browser.download.ui.DownloadManagerUi.DownloadUiObserver; |
import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge; |
import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadItem; |
@@ -28,9 +30,9 @@ import org.chromium.chrome.browser.widget.selection.SelectionDelegate; |
import org.chromium.content_public.browser.DownloadState; |
import java.util.ArrayList; |
-import java.util.Calendar; |
import java.util.Date; |
import java.util.HashMap; |
+import java.util.HashSet; |
import java.util.Iterator; |
import java.util.List; |
import java.util.Map; |
@@ -66,14 +68,13 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
/** Represents the subsection header of the suggested pages for a given date. */ |
public class SubsectionHeader extends TimedItem { |
private final long mTimestamp; |
- private final int mItemCount; |
- private final long mTotalFileSize; |
+ private int mItemCount; |
+ private long mTotalFileSize; |
private final Long mStableId; |
+ private boolean mIsExpanded; |
- public SubsectionHeader(Date date, int itemCount, long totalFileSize) { |
+ public SubsectionHeader(Date date) { |
mTimestamp = date.getTime(); |
- mItemCount = itemCount; |
- mTotalFileSize = totalFileSize; |
// Generate a stable ID based on timestamp. |
mStableId = 0xFFFFFFFF00000000L + (getTimestamp() & 0x0FFFFFFFF); |
@@ -96,6 +97,98 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
public long getStableId() { |
return mStableId; |
} |
+ |
+ /** @return Whether the subsection is currently expanded. */ |
+ public boolean isExpanded() { |
+ return mIsExpanded; |
+ } |
+ |
+ /** |
+ * @param isExpanded Whether the subsection is currently expanded. |
+ */ |
+ public void setIsExpanded(boolean isExpanded) { |
+ this.mIsExpanded = isExpanded; |
Theresa
2017/03/03 18:35:50
nit: "this." isn't necessary.
shaktisahu
2017/03/04 03:56:09
Done.
|
+ } |
+ |
+ /** |
+ * Helper method to set the properties of this class. |
+ */ |
+ public void update(int itemCount, long totalFileSize) { |
+ mItemCount = itemCount; |
+ mTotalFileSize = totalFileSize; |
+ } |
+ } |
+ |
+ /** |
+ * Separately maintains the selected state of the headers in addition to the other selected |
+ * items. |
+ */ |
+ public class DownloadItemSelectionDelegate |
+ extends SelectionDelegate<DownloadHistoryItemWrapper> { |
+ private Set<SubsectionHeader> mSelectedHeaders = new HashSet<>(); |
+ |
+ @Override |
+ public boolean isSelectionEnabled() { |
+ return !mSelectedHeaders.isEmpty() || super.isSelectionEnabled(); |
Theresa
2017/03/03 18:35:50
If any header is selected, doesn't that mean it's
shaktisahu
2017/03/04 03:56:09
Actually, this might be redundant in the current m
|
+ } |
+ |
+ /** |
+ * True if the header is currently selected. False otherwise. |
+ * @param header The given header. |
+ * @return Whether the header is selected. |
+ */ |
+ public boolean isHeaderSelected(SubsectionHeader header) { |
+ return mSelectedHeaders.contains(header); |
+ } |
+ |
+ @Override |
+ public void clearSelection() { |
+ mSelectedHeaders.clear(); |
+ super.clearSelection(); |
+ } |
+ |
+ /** |
+ * Toggles selection for a given header and sets the associated items to correct selection |
+ * state. |
+ * @param header The given header. |
+ * @return True if the header is selected after the toggle, false otherwise. |
+ */ |
+ public boolean toggleSelectionForHeader(SubsectionHeader header) { |
+ boolean newSelectedState = !isHeaderSelected(header); |
+ List<DownloadHistoryItemWrapper> items = header.isExpanded() |
+ ? getSuggestedItemsForDate(header.getTimestamp()) |
+ : mOfflinePageItems; |
+ |
+ for (DownloadHistoryItemWrapper item : items) { |
+ if (!DownloadUtils.isSameDay(header.getTimestamp(), item.getTimestamp())) { |
+ continue; |
+ } |
+ |
+ if (!((OfflinePageItemWrapper) item).isSuggested()) continue; |
+ |
+ if (newSelectedState != isItemSelected(item)) { |
+ toggleSelectionForItem(item); |
+ } |
+ } |
+ |
+ return setSelectionForHeader(header, newSelectedState); |
+ } |
+ |
+ /** |
+ * Sets the selection state for a given header. Doesn't affect the associated items. |
+ * @param header The given header. |
+ * @param selected The new selected state. |
+ * @return Whether the header was successfully selected. |
+ */ |
+ public boolean setSelectionForHeader(SubsectionHeader header, boolean selected) { |
+ if (selected) { |
+ mSelectedHeaders.add(header); |
+ } else { |
+ mSelectedHeaders.remove(header); |
+ } |
+ |
+ return isHeaderSelected(header); |
+ } |
} |
/** |
@@ -113,7 +206,7 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
private final FilePathsToDownloadItemsMap mFilePathsToItemsMap = |
new FilePathsToDownloadItemsMap(); |
- private final Map<Date, Boolean> mSubsectionExpanded = new HashMap<>(); |
+ private final Map<Date, SubsectionHeader> mSubsectionHeaders = new HashMap<>(); |
private final ComponentName mParentComponent; |
private final boolean mShowOffTheRecord; |
private final LoadingStateDelegate mLoadingDelegate; |
@@ -137,6 +230,10 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
public void initialize(BackendProvider provider) { |
mBackendProvider = provider; |
+ DownloadBackendProvider downloadBackendProvider = |
+ (DownloadBackendProvider) mBackendProvider; |
+ downloadBackendProvider.setSelectionDelegate(new DownloadItemSelectionDelegate()); |
+ |
// Get all regular and (if necessary) off the record downloads. |
DownloadDelegate downloadManager = getDownloadDelegate(); |
downloadManager.addDownloadHistoryAdapter(this); |
@@ -254,6 +351,7 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
(OfflineGroupHeaderView) LayoutInflater.from(parent.getContext()) |
.inflate(R.layout.offline_download_header, parent, false); |
offlineHeader.setAdapter(this); |
+ offlineHeader.setSelectionDelegate(getSelectionDelegate()); |
return new SubsectionHeaderViewHolder(offlineHeader); |
} |
@@ -261,10 +359,8 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
protected void bindViewHolderForSubsectionHeader( |
SubsectionHeaderViewHolder holder, TimedItem timedItem) { |
SubsectionHeader headerItem = (SubsectionHeader) timedItem; |
- Date date = new Date(headerItem.getTimestamp()); |
OfflineGroupHeaderView headerView = (OfflineGroupHeaderView) holder.getView(); |
- headerView.update(date, isSubsectionExpanded(date), headerItem.getItemCount(), |
- headerItem.getTotalFileSize()); |
+ headerView.displayHeader(headerItem); |
} |
@Override |
@@ -281,7 +377,8 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
final DownloadHistoryItemWrapper item = (DownloadHistoryItemWrapper) timedItem; |
DownloadHistoryItemViewHolder holder = (DownloadHistoryItemViewHolder) current; |
- holder.getItemView().displayItem(mBackendProvider, item); |
+ DownloadItemView itemView = holder.getItemView(); |
+ itemView.displayItem(mBackendProvider, item); |
} |
@Override |
@@ -450,8 +547,8 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
return mBackendProvider.getOfflinePageBridge(); |
} |
- private SelectionDelegate<DownloadHistoryItemWrapper> getSelectionDelegate() { |
- return mBackendProvider.getSelectionDelegate(); |
+ public DownloadItemSelectionDelegate getSelectionDelegate() { |
+ return (DownloadItemSelectionDelegate) mBackendProvider.getSelectionDelegate(); |
} |
/** Filters the list of downloads to show only files of a specific type. */ |
@@ -461,7 +558,12 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
List<TimedItem> filteredTimedItems = new ArrayList<>(); |
mRegularDownloadItems.filter(mFilter, mSearchQuery, filteredTimedItems); |
mIncognitoDownloadItems.filter(mFilter, mSearchQuery, filteredTimedItems); |
- filterOfflinePageItems(filteredTimedItems); |
+ |
+ if (TextUtils.isEmpty(mSearchQuery)) { |
+ filterOfflinePageItems(filteredTimedItems); |
+ } else { |
+ mOfflinePageItems.filter(mFilter, mSearchQuery, filteredTimedItems); |
+ } |
clear(false); |
loadItems(filteredTimedItems); |
@@ -490,7 +592,10 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
offlineItem, suggestedPageCountMap, suggestedPageTotalSizeMap); |
// TODO(shaktisahu): Check with UX if we need to skip this check and the subsection |
// headers when filtering for active search text. |
- if (!isSubsectionExpanded(getDateWithoutTime(offlineItem.getTimestamp()))) continue; |
+ if (!isSubsectionExpanded( |
+ DownloadUtils.getDateWithoutTime(offlineItem.getTimestamp()))) { |
+ continue; |
+ } |
} |
filteredTimedItems.add(offlineItem); |
} |
@@ -502,7 +607,7 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
// Updates the total number of suggested pages and file size grouped by date. |
private void incrementSuggestedPageCount(OfflinePageItemWrapper offlineItem, |
Map<Date, Integer> pageCountMap, Map<Date, Long> fileSizeMap) { |
- Date date = getDateWithoutTime(offlineItem.getTimestamp()); |
+ Date date = DownloadUtils.getDateWithoutTime(offlineItem.getTimestamp()); |
int count = pageCountMap.containsKey(date) ? pageCountMap.get(date) : 0; |
pageCountMap.put(date, count + 1); |
@@ -516,14 +621,18 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
Map<Date, Integer> pageCountMap, Map<Date, Long> fileSizeMap) { |
for (Map.Entry<Date, Integer> entry : pageCountMap.entrySet()) { |
Date date = entry.getKey(); |
- filteredTimedItems.add( |
- new SubsectionHeader(date, pageCountMap.get(date), fileSizeMap.get(date))); |
+ if (!mSubsectionHeaders.containsKey(date)) { |
+ mSubsectionHeaders.put(date, new SubsectionHeader(date)); |
+ } |
+ |
+ mSubsectionHeaders.get(date).update(pageCountMap.get(date), fileSizeMap.get(date)); |
+ filteredTimedItems.add(mSubsectionHeaders.get(date)); |
} |
// Remove entry from |mSubsectionExpanded| if there are no more suggested pages. |
- Iterator<Entry<Date, Boolean>> iter = mSubsectionExpanded.entrySet().iterator(); |
+ Iterator<Entry<Date, SubsectionHeader>> iter = mSubsectionHeaders.entrySet().iterator(); |
while (iter.hasNext()) { |
- Entry<Date, Boolean> entry = iter.next(); |
+ Entry<Date, SubsectionHeader> entry = iter.next(); |
if (!pageCountMap.containsKey(entry.getKey())) { |
iter.remove(); |
} |
@@ -537,11 +646,11 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
*/ |
public boolean isSubsectionExpanded(Date date) { |
// Default state is collpased. |
- if (mSubsectionExpanded.get(date) == null) { |
- mSubsectionExpanded.put(date, false); |
+ if (!mSubsectionHeaders.containsKey(date)) { |
+ return false; |
} |
- return mSubsectionExpanded.get(date); |
+ return mSubsectionHeaders.get(date).isExpanded(); |
} |
/** |
@@ -550,11 +659,34 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
* @param expanded Whether the suggested pages should be expanded. |
*/ |
public void setSubsectionExpanded(Date date, boolean expanded) { |
- mSubsectionExpanded.put(date, expanded); |
+ mSubsectionHeaders.get(date).setIsExpanded(expanded); |
clear(false); |
filter(mFilter); |
} |
+ /** |
+ * Returns a list of suggested pages for a given date. |
+ * @param timestamp The timestamp of the midnight. |
+ * @return A list containing all the suggested pages for that date. |
+ */ |
+ public List<DownloadHistoryItemWrapper> getSuggestedItemsForDate(long timestamp) { |
+ List<DownloadHistoryItemWrapper> suggestedItems = new ArrayList<>(); |
+ |
+ DownloadItemGroup group = (DownloadItemGroup) getGroupForDate(timestamp); |
+ for (int i = 0; i < group.size(); i++) { |
+ TimedItem item = group.getItemAt(i); |
+ if (item == null || !(item instanceof OfflinePageItemWrapper)) continue; |
+ |
+ OfflinePageItemWrapper offlineItem = (OfflinePageItemWrapper) item; |
+ if (!offlineItem.isSuggested()) continue; |
+ |
+ suggestedItems.add(offlineItem); |
+ } |
+ |
+ System.out.println(suggestedItems.size() + " suggestedItems for " + new Date(timestamp)); |
+ return suggestedItems; |
+ } |
+ |
@Override |
protected boolean isSubsectionHeader(TimedItem timedItem) { |
return timedItem instanceof SubsectionHeader; |
@@ -637,17 +769,4 @@ public class DownloadHistoryAdapter extends DateDividedAdapter |
RecordHistogram.recordCountHistogram("Android.DownloadManager.InitialCount.Total", |
mRegularDownloadItems.size() + mOfflinePageItems.size()); |
} |
- |
- /** |
- * Calculates the {@link Date} for midnight of the date represented by the timestamp. |
- */ |
- private Date getDateWithoutTime(long timestamp) { |
- Calendar cal = Calendar.getInstance(); |
- cal.setTimeInMillis(timestamp); |
- cal.set(Calendar.HOUR_OF_DAY, 0); |
- cal.set(Calendar.MINUTE, 0); |
- cal.set(Calendar.SECOND, 0); |
- cal.set(Calendar.MILLISECOND, 0); |
- return cal.getTime(); |
- } |
} |