Index: chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemGroup.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemGroup.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..acb79fc18e6265939a47e9fcc596f3b5282876da |
--- /dev/null |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemGroup.java |
@@ -0,0 +1,206 @@ |
+// 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.ui; |
+ |
+import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.OfflinePageItemWrapper; |
+import org.chromium.chrome.browser.widget.DateDividedAdapter; |
+import org.chromium.chrome.browser.widget.DateDividedAdapter.TimedItem; |
+ |
+/** |
+ * A bucket of downloaded items with the same date. It also holds the suggested offline items which |
+ * are shown at the end of the list for that date. |
+ */ |
+public class DownloadItemGroup extends DateDividedAdapter.ItemGroup { |
+ private int mNumSuggestedOfflinePages; |
+ private boolean mIsSuggestedOfflinePagesSectionExpanded; |
+ |
+ /** The header representing the offline pages that are automatically downloaded */ |
+ private TimedItem mSuggestedOfflinePagesHeader; |
+ |
+ public DownloadItemGroup(long timestamp) { |
+ super(timestamp); |
+ } |
+ |
+ /** @return Whether the suggested pages are expanded. */ |
+ public boolean isSuggestedOfflinePagesSectionExpanded() { |
+ return mIsSuggestedOfflinePagesSectionExpanded; |
+ } |
+ |
+ /** |
+ * Expands or collapses the suggested offline pages. |
+ * @param expanded Whether the suggested pages should be shown. |
+ */ |
+ public void setIsSuggestedOfflinePagesSectionExpanded(boolean expanded) { |
+ mIsSuggestedOfflinePagesSectionExpanded = expanded; |
+ } |
+ |
+ /** @return The total number of suggested pages for this date. */ |
+ public int getNumSuggestedOfflinePages() { |
+ return mNumSuggestedOfflinePages; |
+ } |
+ |
+ private TimedItem getSuggestedOfflinePagesHeader() { |
+ if (mSuggestedOfflinePagesHeader == null) { |
+ mSuggestedOfflinePagesHeader = new TimedItem() { |
+ private Long mStableId; |
+ |
+ @Override |
+ public long getTimestamp() { |
+ return mDate.getTime(); |
+ } |
+ |
+ @Override |
+ public long getStableId() { |
+ if (mStableId == null) { |
+ // Generate a stable ID based on timestamp. |
+ mStableId = 0xFFFFFFFF00000000L + (getTimestamp() & 0x0FFFFFFFF); |
+ } |
+ return mStableId; |
+ } |
+ }; |
+ } |
+ |
+ return mSuggestedOfflinePagesHeader; |
+ } |
+ |
+ @Override |
+ public void addItem(TimedItem item) { |
+ super.addItem(item); |
+ if (isSuggestedOfflinePage(item)) { |
+ mNumSuggestedOfflinePages++; |
+ } |
+ } |
+ |
+ @Override |
+ public void removeItem(TimedItem item) { |
+ super.removeItem(item); |
+ if (isSuggestedOfflinePage(item)) { |
+ mNumSuggestedOfflinePages--; |
Theresa
2017/02/13 19:15:00
This method should be responsible for removing the
|
+ } |
+ } |
+ |
+ /** |
+ * The visible items for the group are set to their respective positions in the list view. |
+ * Invisible (collpased) items are skipped. |
+ */ |
+ @Override |
+ protected void setPositionForItems(int startIndex) { |
+ int index = startIndex; |
+ boolean isFirstSuggestedItem = true; |
+ for (TimedItem item : mItems) { |
+ // Skip one position for the header at the beginning of the suggested items section. |
+ if (isFirstSuggestedItem && isSuggestedOfflinePage(item)) { |
+ index += 1; |
+ isFirstSuggestedItem = false; |
+ } |
+ item.setPosition(index); |
+ index += 1; |
+ } |
+ } |
+ |
+ @Override |
+ protected void markFirstAndLastItem() { |
+ TimedItem first = mItems.get(0); |
+ first.setIsFirstInGroup(true); |
+ |
+ TimedItem last = mItems.get(mItems.size() - 1); |
+ if (!isSuggestedOfflinePagesSectionExpanded() && mNumSuggestedOfflinePages > 0) { |
+ last = getSuggestedOfflinePagesHeader(); |
+ } |
+ |
+ last.setIsLastInGroup(true); |
+ } |
+ |
+ @Override |
+ public int size() { |
+ int size = super.size(); |
+ |
+ // The size should match the number of rows in the list view. So, adjust the size depending |
+ // on whether the suggested items section is expanded or collapsed. |
+ if (mNumSuggestedOfflinePages > 0) { |
+ // First item of the suggested pages section is the section header. |
+ size += 1; |
+ if (!isSuggestedOfflinePagesSectionExpanded()) { |
+ size -= mNumSuggestedOfflinePages; |
+ } |
+ } |
+ |
+ return size; |
+ } |
+ |
+ /** @return The total file size of the suggested pages for this date. */ |
+ public long getSuggestedOfflinePagesFileSize() { |
+ long size = 0; |
+ for (TimedItem item : mItems) { |
+ if (isSuggestedOfflinePage(item)) { |
+ size += ((DownloadHistoryItemWrapper) item).getFileSize(); |
+ } |
+ } |
+ return size; |
+ } |
+ |
+ private int getSuggestedOfflinePagesSectionHeaderPosition() { |
+ return mItems.size() - mNumSuggestedOfflinePages + 1; |
+ } |
+ |
+ private boolean isSuggestedOfflinePagesSectionHeader(int index) { |
+ return index == getSuggestedOfflinePagesSectionHeaderPosition() |
+ && mNumSuggestedOfflinePages > 0; |
+ } |
+ |
+ @Override |
+ protected TimedItem getItemAtInternal(int index) { |
+ // The suggested pages start at the end of the group. |
+ // So, the ordering of the items in this list is : |
+ // date header, regular items, suggested pages header, suggested pages (if expanded). |
+ int suggestedSectionHeaderIndex = getSuggestedOfflinePagesSectionHeaderPosition(); |
+ if (index < suggestedSectionHeaderIndex) { |
+ return mItems.get(index - 1); |
+ } else if (index == suggestedSectionHeaderIndex) { |
+ assert mNumSuggestedOfflinePages > 0; |
+ return getSuggestedOfflinePagesHeader(); |
+ } else { |
+ assert isSuggestedOfflinePagesSectionExpanded(); |
+ return mItems.get(index - 2); |
+ } |
+ } |
+ |
+ @Override |
+ public int getItemViewType(int position) { |
+ if (isSuggestedOfflinePagesSectionHeader(position)) { |
+ return DateDividedAdapter.TYPE_SUBSECTION_HEADER; |
+ } else { |
+ return super.getItemViewType(position); |
+ } |
+ } |
+ |
+ @Override |
+ public int compareItem(TimedItem lhs, TimedItem rhs) { |
+ if (isSuggestedOfflinePage(lhs) && !isSuggestedOfflinePage(rhs)) return 1; |
+ if (!isSuggestedOfflinePage(lhs) && isSuggestedOfflinePage(rhs)) return -1; |
+ |
+ return super.compareItem(lhs, rhs); |
+ } |
+ |
+ private boolean isSuggestedOfflinePage(TimedItem timedItem) { |
+ if (timedItem instanceof OfflinePageItemWrapper) { |
+ return ((OfflinePageItemWrapper) timedItem).isSuggested(); |
+ } |
+ |
+ return false; |
+ } |
+ |
+ @Override |
+ public int getNumberOfRowsToBeRemovedForItem(TimedItem item) { |
+ int numRowsToRemove = super.getNumberOfRowsToBeRemovedForItem(item); |
+ |
+ // Remove the suggested pages header too if this is the last item. |
+ if (mNumSuggestedOfflinePages == 1 && isSuggestedOfflinePage(item)) { |
+ numRowsToRemove++; |
+ } |
+ |
+ return numRowsToRemove; |
+ } |
+} |