OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.download.ui; | 5 package org.chromium.chrome.browser.download.ui; |
6 | 6 |
7 import android.content.ComponentName; | 7 import android.content.ComponentName; |
8 import android.support.v7.widget.RecyclerView.ViewHolder; | 8 import android.support.v7.widget.RecyclerView.ViewHolder; |
9 import android.text.TextUtils; | 9 import android.text.TextUtils; |
10 import android.view.LayoutInflater; | 10 import android.view.LayoutInflater; |
(...skipping 10 matching lines...) Expand all Loading... | |
21 import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.Downlo adItemWrapper; | 21 import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.Downlo adItemWrapper; |
22 import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.Offlin ePageItemWrapper; | 22 import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper.Offlin ePageItemWrapper; |
23 import org.chromium.chrome.browser.download.ui.DownloadManagerUi.DownloadUiObser ver; | 23 import org.chromium.chrome.browser.download.ui.DownloadManagerUi.DownloadUiObser ver; |
24 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri dge; | 24 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBri dge; |
25 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadIte m; | 25 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadIte m; |
26 import org.chromium.chrome.browser.widget.DateDividedAdapter; | 26 import org.chromium.chrome.browser.widget.DateDividedAdapter; |
27 import org.chromium.chrome.browser.widget.selection.SelectionDelegate; | 27 import org.chromium.chrome.browser.widget.selection.SelectionDelegate; |
28 import org.chromium.content_public.browser.DownloadState; | 28 import org.chromium.content_public.browser.DownloadState; |
29 | 29 |
30 import java.util.ArrayList; | 30 import java.util.ArrayList; |
31 import java.util.Calendar; | |
32 import java.util.Date; | |
33 import java.util.HashMap; | |
31 import java.util.List; | 34 import java.util.List; |
35 import java.util.Map; | |
32 import java.util.Set; | 36 import java.util.Set; |
33 | 37 |
34 /** Bridges the user's download history and the UI used to display it. */ | 38 /** Bridges the user's download history and the UI used to display it. */ |
35 public class DownloadHistoryAdapter extends DateDividedAdapter | 39 public class DownloadHistoryAdapter extends DateDividedAdapter |
36 implements DownloadUiObserver, DownloadSharedPreferenceHelper.Observer { | 40 implements DownloadUiObserver, DownloadSharedPreferenceHelper.Observer { |
37 | 41 |
38 /** Alerted about changes to internal state. */ | 42 /** Alerted about changes to internal state. */ |
39 static interface TestObserver { | 43 static interface TestObserver { |
40 abstract void onDownloadItemCreated(DownloadItem item); | 44 abstract void onDownloadItemCreated(DownloadItem item); |
41 abstract void onDownloadItemUpdated(DownloadItem item); | 45 abstract void onDownloadItemUpdated(DownloadItem item); |
42 } | 46 } |
43 | 47 |
44 private class BackendItemsImpl extends BackendItems { | 48 private class BackendItemsImpl extends BackendItems { |
45 @Override | 49 @Override |
46 public DownloadHistoryItemWrapper removeItem(String guid) { | 50 public DownloadHistoryItemWrapper removeItem(String guid) { |
47 DownloadHistoryItemWrapper wrapper = super.removeItem(guid); | 51 DownloadHistoryItemWrapper wrapper = super.removeItem(guid); |
48 | 52 |
49 if (wrapper != null) { | 53 if (wrapper != null) { |
50 mFilePathsToItemsMap.removeItem(wrapper); | 54 mFilePathsToItemsMap.removeItem(wrapper); |
51 if (getSelectionDelegate().isItemSelected(wrapper)) { | 55 if (getSelectionDelegate().isItemSelected(wrapper)) { |
52 getSelectionDelegate().toggleSelectionForItem(wrapper); | 56 getSelectionDelegate().toggleSelectionForItem(wrapper); |
53 } | 57 } |
54 } | 58 } |
55 | 59 |
56 return wrapper; | 60 return wrapper; |
57 } | 61 } |
58 } | 62 } |
59 | 63 |
64 /** Represents the subsection header of the suggested pages for a given date */ | |
gone
2017/02/15 23:58:09
end with a period
shaktisahu
2017/02/16 06:07:06
Done.
| |
65 public class SubsectionHeader extends TimedItem { | |
66 private Long mStableId; | |
67 private Date mDate; | |
68 private int mItemCount; | |
69 private long mTotalFileSize; | |
gone
2017/02/15 23:58:09
Everything here should be final. Stable ID can be
shaktisahu
2017/02/16 06:07:06
Done.
| |
70 | |
71 public SubsectionHeader(Date date, int itemCount, long totalFileSize) { | |
72 mDate = date; | |
73 mItemCount = itemCount; | |
74 mTotalFileSize = totalFileSize; | |
75 } | |
76 | |
77 @Override | |
78 public long getTimestamp() { | |
79 return mDate.getTime(); | |
80 } | |
81 | |
82 public int getItemCount() { | |
83 return mItemCount; | |
84 } | |
85 | |
86 public long getTotalFileSize() { | |
87 return mTotalFileSize; | |
88 } | |
89 | |
90 @Override | |
91 public long getStableId() { | |
92 if (mStableId == null) { | |
93 // Generate a stable ID based on timestamp. | |
94 mStableId = 0xFFFFFFFF00000000L + (getTimestamp() & 0x0FFFFFFFF) ; | |
95 } | |
96 return mStableId; | |
97 } | |
98 } | |
99 | |
60 /** | 100 /** |
61 * Tracks externally deleted items that have been removed from downloads his tory. | 101 * Tracks externally deleted items that have been removed from downloads his tory. |
62 * Shared across instances. | 102 * Shared across instances. |
63 */ | 103 */ |
64 private static final DeletedFileTracker sDeletedFileTracker = new DeletedFil eTracker(); | 104 private static final DeletedFileTracker sDeletedFileTracker = new DeletedFil eTracker(); |
65 | 105 |
66 private static final String EMPTY_QUERY = null; | 106 private static final String EMPTY_QUERY = null; |
67 | 107 |
68 private final BackendItems mRegularDownloadItems = new BackendItemsImpl(); | 108 private final BackendItems mRegularDownloadItems = new BackendItemsImpl(); |
69 private final BackendItems mIncognitoDownloadItems = new BackendItemsImpl(); | 109 private final BackendItems mIncognitoDownloadItems = new BackendItemsImpl(); |
70 private final BackendItems mOfflinePageItems = new BackendItemsImpl(); | 110 private final BackendItems mOfflinePageItems = new BackendItemsImpl(); |
71 | 111 |
112 private final Map<Date, Boolean> mSuggestedSectionExpanded = new HashMap<>() ; | |
gone
2017/02/15 23:58:09
Don't arbitrarily separate the BackendItemsImpls()
shaktisahu
2017/02/16 06:07:06
Done.
| |
113 | |
72 private final BackendItems mFilteredItems = new BackendItemsImpl(); | 114 private final BackendItems mFilteredItems = new BackendItemsImpl(); |
73 private final FilePathsToDownloadItemsMap mFilePathsToItemsMap = | 115 private final FilePathsToDownloadItemsMap mFilePathsToItemsMap = |
74 new FilePathsToDownloadItemsMap(); | 116 new FilePathsToDownloadItemsMap(); |
75 | 117 |
76 private final ComponentName mParentComponent; | 118 private final ComponentName mParentComponent; |
77 private final boolean mShowOffTheRecord; | 119 private final boolean mShowOffTheRecord; |
78 private final LoadingStateDelegate mLoadingDelegate; | 120 private final LoadingStateDelegate mLoadingDelegate; |
79 private final ObserverList<TestObserver> mObservers = new ObserverList<>(); | 121 private final ObserverList<TestObserver> mObservers = new ObserverList<>(); |
80 private final List<DownloadItemView> mViews = new ArrayList<>(); | 122 private final List<DownloadItemView> mViews = new ArrayList<>(); |
81 | 123 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 totalSize += mOfflinePageItems.getTotalBytes(); | 243 totalSize += mOfflinePageItems.getTotalBytes(); |
202 return totalSize; | 244 return totalSize; |
203 } | 245 } |
204 | 246 |
205 @Override | 247 @Override |
206 protected int getTimedItemViewResId() { | 248 protected int getTimedItemViewResId() { |
207 return R.layout.date_view; | 249 return R.layout.date_view; |
208 } | 250 } |
209 | 251 |
210 @Override | 252 @Override |
253 protected SubsectionHeaderViewHolder createSubsectionHeader(ViewGroup parent ) { | |
254 OfflineGroupHeaderView offlineHeader = | |
255 (OfflineGroupHeaderView) LayoutInflater.from(parent.getContext() ) | |
256 .inflate(R.layout.offline_download_header, parent, false ); | |
gone
2017/02/15 23:58:09
Can you clarify what you're expecting here? infla
shaktisahu
2017/02/16 06:07:06
The third param attachToRoot is false here. The re
gone
2017/02/17 19:21:16
Acknowledged. Misread the params list :/
| |
257 offlineHeader.setAdapter(this); | |
258 return new SubsectionHeaderViewHolder(offlineHeader); | |
259 } | |
260 | |
261 @Override | |
262 protected void bindViewHolderForSubsectionHeader( | |
263 SubsectionHeaderViewHolder holder, TimedItem timedItem) { | |
264 SubsectionHeader headerItem = (SubsectionHeader) timedItem; | |
265 Date date = new Date(headerItem.getTimestamp()); | |
266 OfflineGroupHeaderView headerView = (OfflineGroupHeaderView) holder.getV iew(); | |
267 headerView.updateView(date, isSubsectionExpanded(date), headerItem.getIt emCount(), | |
268 headerItem.getTotalFileSize()); | |
269 } | |
270 | |
271 @Override | |
211 public ViewHolder createViewHolder(ViewGroup parent) { | 272 public ViewHolder createViewHolder(ViewGroup parent) { |
212 DownloadItemView v = (DownloadItemView) LayoutInflater.from(parent.getCo ntext()).inflate( | 273 DownloadItemView v = (DownloadItemView) LayoutInflater.from(parent.getCo ntext()).inflate( |
213 R.layout.download_item_view, parent, false); | 274 R.layout.download_item_view, parent, false); |
214 v.setSelectionDelegate(getSelectionDelegate()); | 275 v.setSelectionDelegate(getSelectionDelegate()); |
215 mViews.add(v); | 276 mViews.add(v); |
216 return new DownloadHistoryItemViewHolder(v); | 277 return new DownloadHistoryItemViewHolder(v); |
217 } | 278 } |
218 | 279 |
219 @Override | 280 @Override |
220 public void bindViewHolderForTimedItem(ViewHolder current, TimedItem timedIt em) { | 281 public void bindViewHolderForTimedItem(ViewHolder current, TimedItem timedIt em) { |
221 final DownloadHistoryItemWrapper item = (DownloadHistoryItemWrapper) tim edItem; | 282 final DownloadHistoryItemWrapper item = (DownloadHistoryItemWrapper) tim edItem; |
222 | 283 |
223 DownloadHistoryItemViewHolder holder = (DownloadHistoryItemViewHolder) c urrent; | 284 DownloadHistoryItemViewHolder holder = (DownloadHistoryItemViewHolder) c urrent; |
224 holder.getItemView().displayItem(mBackendProvider, item); | 285 holder.getItemView().displayItem(mBackendProvider, item); |
225 } | 286 } |
226 | 287 |
288 @Override | |
289 protected ItemGroup createGroup(long timeStamp) { | |
290 return new DownloadItemGroup(timeStamp); | |
291 } | |
292 | |
227 /** Called when a new DownloadItem has been created by the native DownloadMa nager. */ | 293 /** Called when a new DownloadItem has been created by the native DownloadMa nager. */ |
228 public void onDownloadItemCreated(DownloadItem item) { | 294 public void onDownloadItemCreated(DownloadItem item) { |
229 boolean isOffTheRecord = item.getDownloadInfo().isOffTheRecord(); | 295 boolean isOffTheRecord = item.getDownloadInfo().isOffTheRecord(); |
230 if (isOffTheRecord && !mShowOffTheRecord) return; | 296 if (isOffTheRecord && !mShowOffTheRecord) return; |
231 | 297 |
232 BackendItems list = getDownloadItemList(isOffTheRecord); | 298 BackendItems list = getDownloadItemList(isOffTheRecord); |
233 assert list.findItemIndex(item.getId()) == BackendItems.INVALID_INDEX; | 299 assert list.findItemIndex(item.getId()) == BackendItems.INVALID_INDEX; |
234 | 300 |
235 DownloadItemWrapper wrapper = createDownloadItemWrapper(item); | 301 DownloadItemWrapper wrapper = createDownloadItemWrapper(item); |
236 boolean wasAdded = addDownloadHistoryItemWrapper(wrapper); | 302 boolean wasAdded = addDownloadHistoryItemWrapper(wrapper); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 private SelectionDelegate<DownloadHistoryItemWrapper> getSelectionDelegate() { | 454 private SelectionDelegate<DownloadHistoryItemWrapper> getSelectionDelegate() { |
389 return mBackendProvider.getSelectionDelegate(); | 455 return mBackendProvider.getSelectionDelegate(); |
390 } | 456 } |
391 | 457 |
392 /** Filters the list of downloads to show only files of a specific type. */ | 458 /** Filters the list of downloads to show only files of a specific type. */ |
393 private void filter(int filterType) { | 459 private void filter(int filterType) { |
394 mFilter = filterType; | 460 mFilter = filterType; |
395 mFilteredItems.clear(); | 461 mFilteredItems.clear(); |
396 mRegularDownloadItems.filter(mFilter, mSearchQuery, mFilteredItems); | 462 mRegularDownloadItems.filter(mFilter, mSearchQuery, mFilteredItems); |
397 mIncognitoDownloadItems.filter(mFilter, mSearchQuery, mFilteredItems); | 463 mIncognitoDownloadItems.filter(mFilter, mSearchQuery, mFilteredItems); |
398 mOfflinePageItems.filter(mFilter, mSearchQuery, mFilteredItems); | 464 |
465 Map<Date, Integer> suggestedPageCount = new HashMap<>(); | |
gone
2017/02/15 23:58:09
1) Pull this whole new block out to some private f
shaktisahu
2017/02/16 06:07:06
Done.
| |
466 Map<Date, Long> suggestedPageTotalSize = new HashMap<>(); | |
467 | |
468 BackendItems offlinePageItems = new BackendItemsImpl(); | |
gone
2017/02/15 23:58:09
filteredOfflinePageItems
shaktisahu
2017/02/16 06:07:06
Done.
| |
469 mOfflinePageItems.filter(mFilter, mSearchQuery, offlinePageItems); | |
470 | |
471 // Add the suggested pages to the adapter only if the section is expande d for that date. | |
gone
2017/02/15 23:58:09
This comment only applies to the inner if statemen
shaktisahu
2017/02/16 06:07:06
Done.
| |
472 for (DownloadHistoryItemWrapper item : offlinePageItems) { | |
473 OfflinePageItemWrapper offlineItem = (OfflinePageItemWrapper) item; | |
474 if (offlineItem.isSuggested()) { | |
475 incrementSuggestedPageCount( | |
476 offlineItem, suggestedPageCount, suggestedPageTotalSize) ; | |
477 if (!isSubsectionExpanded(getDateWithoutTime(offlineItem.getTime stamp()))) continue; | |
478 } | |
479 mFilteredItems.add(offlineItem); | |
480 } | |
481 | |
482 List<TimedItem> itemsToLoad = new ArrayList<>(); | |
483 itemsToLoad.addAll(mFilteredItems); | |
484 | |
485 // Add a header suggested pages for each date | |
gone
2017/02/15 23:58:09
// Add a TimedItem for each subsection.
shaktisahu
2017/02/16 06:07:06
Done.
| |
486 for (Date date : suggestedPageCount.keySet()) { | |
487 itemsToLoad.add(new SubsectionHeader( | |
488 date, suggestedPageCount.get(date), suggestedPageTotalSize.g et(date))); | |
489 } | |
490 | |
399 clear(false); | 491 clear(false); |
400 loadItems(mFilteredItems); | 492 loadItems(itemsToLoad); |
493 } | |
494 | |
495 // Updates the total number of suggested pages and file size grouped by date . | |
496 private void incrementSuggestedPageCount(OfflinePageItemWrapper offlineItem, | |
497 Map<Date, Integer> suggestedPageCount, Map<Date, Long> suggestedPage TotalSize) { | |
498 Date date = getDateWithoutTime(offlineItem.getTimestamp()); | |
499 | |
500 Integer count = suggestedPageCount.get(date); | |
501 if (count == null) count = 0; | |
gone
2017/02/15 23:58:09
Avoid Integers if you don't need to use them. The
shaktisahu
2017/02/16 06:07:06
Done.
| |
502 count++; | |
503 suggestedPageCount.put(date, count); | |
gone
2017/02/15 23:58:09
suggestedPageCount.put(date, count + 1);
shaktisahu
2017/02/16 06:07:06
Done.
| |
504 | |
505 Long fileSize = suggestedPageTotalSize.get(date); | |
506 if (fileSize == null) fileSize = 0L; | |
507 fileSize += offlineItem.getFileSize(); | |
508 suggestedPageTotalSize.put(date, fileSize); | |
gone
2017/02/15 23:58:09
Same comments as above.
shaktisahu
2017/02/16 06:07:06
Done.
| |
509 } | |
510 | |
511 /** | |
512 * Whether the suggested pages section is expanded for a given date. | |
513 * @param date The download date. | |
514 * @return Whether the suggested pages section is expanded. | |
515 */ | |
516 public boolean isSubsectionExpanded(Date date) { | |
517 // Default state is collpased. | |
518 if (mSuggestedSectionExpanded.get(date) == null) return false; | |
519 | |
520 return mSuggestedSectionExpanded.get(date); | |
521 } | |
522 | |
523 public void setSubsectionExpanded(Date date, boolean expanded) { | |
gone
2017/02/15 23:58:09
Javadoc.
shaktisahu
2017/02/16 06:07:06
Done.
| |
524 mSuggestedSectionExpanded.put(date, expanded); | |
gone
2017/02/15 23:58:09
Be consistent about what you're calling this thing
shaktisahu
2017/02/16 06:07:06
Done.
| |
525 clear(false); | |
526 filter(mFilter); | |
527 } | |
528 | |
529 @Override | |
530 protected boolean isSubsectionHeader(TimedItem timedItem) { | |
531 return timedItem instanceof SubsectionHeader; | |
401 } | 532 } |
402 | 533 |
403 private void initializeOfflinePageBridge() { | 534 private void initializeOfflinePageBridge() { |
404 mOfflinePageObserver = new OfflinePageDownloadBridge.Observer() { | 535 mOfflinePageObserver = new OfflinePageDownloadBridge.Observer() { |
405 @Override | 536 @Override |
406 public void onItemsLoaded() { | 537 public void onItemsLoaded() { |
407 onAllOfflinePagesRetrieved(getOfflinePageBridge().getAllItems()) ; | 538 onAllOfflinePagesRetrieved(getOfflinePageBridge().getAllItems()) ; |
408 } | 539 } |
409 | 540 |
410 @Override | 541 @Override |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 RecordHistogram.recordCountHistogram("Android.DownloadManager.InitialCou nt.Video", | 601 RecordHistogram.recordCountHistogram("Android.DownloadManager.InitialCou nt.Video", |
471 itemCounts[DownloadFilter.FILTER_VIDEO]); | 602 itemCounts[DownloadFilter.FILTER_VIDEO]); |
472 } | 603 } |
473 | 604 |
474 private void recordTotalDownloadCountHistogram() { | 605 private void recordTotalDownloadCountHistogram() { |
475 // The total count intentionally leaves out incognito downloads. This sh ould be revisited | 606 // The total count intentionally leaves out incognito downloads. This sh ould be revisited |
476 // if/when incognito downloads are persistently available in downloads h ome. | 607 // if/when incognito downloads are persistently available in downloads h ome. |
477 RecordHistogram.recordCountHistogram("Android.DownloadManager.InitialCou nt.Total", | 608 RecordHistogram.recordCountHistogram("Android.DownloadManager.InitialCou nt.Total", |
478 mRegularDownloadItems.size() + mOfflinePageItems.size()); | 609 mRegularDownloadItems.size() + mOfflinePageItems.size()); |
479 } | 610 } |
611 | |
612 private Date getDateWithoutTime(long timestamp) { | |
gone
2017/02/15 23:58:09
/** Calculates the {@link Date} for midnight of th
shaktisahu
2017/02/16 06:07:06
Done.
| |
613 Calendar cal = Calendar.getInstance(); | |
614 cal.setTimeInMillis(timestamp); | |
615 cal.set(Calendar.HOUR_OF_DAY, 0); | |
616 cal.set(Calendar.MINUTE, 0); | |
617 cal.set(Calendar.SECOND, 0); | |
618 cal.set(Calendar.MILLISECOND, 0); | |
619 return cal.getTime(); | |
620 } | |
480 } | 621 } |
OLD | NEW |