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 #include "chrome/browser/ntp_snippets/download_suggestions_provider.h" | 5 #include "chrome/browser/ntp_snippets/download_suggestions_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 30 matching lines...) Expand all Loading... | |
41 using offline_pages::OfflinePageModelQueryBuilder; | 41 using offline_pages::OfflinePageModelQueryBuilder; |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 const int kDefaultMaxSuggestionsCount = 5; | 45 const int kDefaultMaxSuggestionsCount = 5; |
46 const char kAssetDownloadsPrefix = 'D'; | 46 const char kAssetDownloadsPrefix = 'D'; |
47 const char kOfflinePageDownloadsPrefix = 'O'; | 47 const char kOfflinePageDownloadsPrefix = 'O'; |
48 | 48 |
49 const char* kMaxSuggestionsCountParamName = "downloads_max_count"; | 49 const char* kMaxSuggestionsCountParamName = "downloads_max_count"; |
50 | 50 |
51 bool CompareOfflinePagesMostRecentlyCreatedFirst(const OfflinePageItem& left, | |
52 const OfflinePageItem& right) { | |
53 return left.creation_time > right.creation_time; | |
54 } | |
55 | |
51 int GetMaxSuggestionsCount() { | 56 int GetMaxSuggestionsCount() { |
52 bool assets_enabled = | 57 bool assets_enabled = |
53 base::FeatureList::IsEnabled(features::kAssetDownloadSuggestionsFeature); | 58 base::FeatureList::IsEnabled(features::kAssetDownloadSuggestionsFeature); |
54 return ntp_snippets::GetParamAsInt( | 59 return ntp_snippets::GetParamAsInt( |
55 assets_enabled ? features::kAssetDownloadSuggestionsFeature | 60 assets_enabled ? features::kAssetDownloadSuggestionsFeature |
56 : features::kOfflinePageDownloadSuggestionsFeature, | 61 : features::kOfflinePageDownloadSuggestionsFeature, |
57 kMaxSuggestionsCountParamName, kDefaultMaxSuggestionsCount); | 62 kMaxSuggestionsCountParamName, kDefaultMaxSuggestionsCount); |
58 } | 63 } |
59 | 64 |
60 std::string GetOfflinePagePerCategoryID(int64_t raw_offline_page_id) { | 65 std::string GetOfflinePagePerCategoryID(int64_t raw_offline_page_id) { |
(...skipping 26 matching lines...) Expand all Loading... | |
87 | 92 |
88 bool IsDownloadCompleted(const DownloadItem& item) { | 93 bool IsDownloadCompleted(const DownloadItem& item) { |
89 return item.GetState() == DownloadItem::DownloadState::COMPLETE && | 94 return item.GetState() == DownloadItem::DownloadState::COMPLETE && |
90 !item.GetFileExternallyRemoved(); | 95 !item.GetFileExternallyRemoved(); |
91 } | 96 } |
92 | 97 |
93 base::Time GetAssetDownloadPublishedTime(const DownloadItem& item) { | 98 base::Time GetAssetDownloadPublishedTime(const DownloadItem& item) { |
94 return item.GetStartTime(); | 99 return item.GetStartTime(); |
95 } | 100 } |
96 | 101 |
97 struct OrderDownloadsMostRecentlyDownloadedFirst { | 102 bool CompareDownloadsMostRecentlyDownloadedFirst(const DownloadItem* left, |
98 bool operator()(const DownloadItem* left, const DownloadItem* right) const { | 103 const DownloadItem* right) { |
99 return GetAssetDownloadPublishedTime(*left) > | 104 return GetAssetDownloadPublishedTime(*left) > |
100 GetAssetDownloadPublishedTime(*right); | 105 GetAssetDownloadPublishedTime(*right); |
101 } | 106 } |
102 }; | |
103 | 107 |
104 bool IsClientIdForOfflinePageDownload( | 108 bool IsClientIdForOfflinePageDownload( |
105 offline_pages::ClientPolicyController* policy_controller, | 109 offline_pages::ClientPolicyController* policy_controller, |
106 const offline_pages::ClientId& client_id) { | 110 const offline_pages::ClientId& client_id) { |
107 return policy_controller->IsSupportedByDownload(client_id.name_space); | 111 return policy_controller->IsSupportedByDownload(client_id.name_space); |
108 } | 112 } |
109 | 113 |
110 std::unique_ptr<OfflinePageModelQuery> BuildOfflinePageDownloadsQuery( | 114 std::unique_ptr<OfflinePageModelQuery> BuildOfflinePageDownloadsQuery( |
111 offline_pages::OfflinePageModel* model) { | 115 offline_pages::OfflinePageModel* model) { |
112 OfflinePageModelQueryBuilder builder; | 116 OfflinePageModelQueryBuilder builder; |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 | 306 |
303 void DownloadSuggestionsProvider::OfflinePageModelLoaded( | 307 void DownloadSuggestionsProvider::OfflinePageModelLoaded( |
304 offline_pages::OfflinePageModel* model) { | 308 offline_pages::OfflinePageModel* model) { |
305 DCHECK_EQ(offline_page_model_, model); | 309 DCHECK_EQ(offline_page_model_, model); |
306 AsynchronouslyFetchOfflinePagesDownloads(/*notify=*/true); | 310 AsynchronouslyFetchOfflinePagesDownloads(/*notify=*/true); |
307 } | 311 } |
308 | 312 |
309 void DownloadSuggestionsProvider::OfflinePageAdded( | 313 void DownloadSuggestionsProvider::OfflinePageAdded( |
310 offline_pages::OfflinePageModel* model, | 314 offline_pages::OfflinePageModel* model, |
311 const offline_pages::OfflinePageItem& added_page) { | 315 const offline_pages::OfflinePageItem& added_page) { |
312 // TODO(dewittj, vitaliii): Don't refetch everything when this is called. | |
313 DCHECK_EQ(offline_page_model_, model); | 316 DCHECK_EQ(offline_page_model_, model); |
314 AsynchronouslyFetchOfflinePagesDownloads(/*notify=*/true); | 317 if (!IsClientIdForOfflinePageDownload(model->GetPolicyController(), |
318 added_page.client_id)) { | |
319 return; | |
320 } | |
321 | |
322 // This is all in one statement so that it is completely compiled out in | |
323 // release builds. | |
324 DCHECK_EQ(ReadOfflinePageDismissedIDsFromPrefs().count( | |
vitaliii
2016/12/09 10:02:37
nit: Why not "DCHECK(!..."?
dewittj
2016/12/09 18:43:57
Feels more correct to compare to an integer rather
| |
325 GetOfflinePagePerCategoryID(added_page.offline_id)), | |
326 0U); | |
327 | |
328 if (static_cast<int>(cached_offline_page_downloads_.size()) < | |
329 GetMaxSuggestionsCount()) { | |
330 cached_offline_page_downloads_.push_back(added_page); | |
331 } else { | |
332 auto oldest_page_iterator = | |
333 std::max_element(cached_offline_page_downloads_.begin(), | |
334 cached_offline_page_downloads_.end(), | |
335 &CompareOfflinePagesMostRecentlyCreatedFirst); | |
336 *oldest_page_iterator = added_page; | |
Marc Treib
2016/12/09 15:34:34
This could crash if GetMaxSuggestionsCount ever re
dewittj
2016/12/09 18:43:57
Done.
| |
337 } | |
338 | |
339 SubmitContentSuggestions(); | |
315 } | 340 } |
316 | 341 |
317 void DownloadSuggestionsProvider::OfflinePageDeleted( | 342 void DownloadSuggestionsProvider::OfflinePageDeleted( |
318 int64_t offline_id, | 343 int64_t offline_id, |
319 const offline_pages::ClientId& client_id) { | 344 const offline_pages::ClientId& client_id) { |
320 DCHECK(offline_page_model_); | 345 DCHECK(offline_page_model_); |
321 if (IsClientIdForOfflinePageDownload( | 346 if (IsClientIdForOfflinePageDownload( |
322 offline_page_model_->GetPolicyController(), client_id)) { | 347 offline_page_model_->GetPolicyController(), client_id)) { |
323 InvalidateSuggestion(GetOfflinePagePerCategoryID(offline_id)); | 348 InvalidateSuggestion(GetOfflinePagePerCategoryID(offline_id)); |
324 } | 349 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
446 if (static_cast<int>(cached_asset_downloads_.size()) > | 471 if (static_cast<int>(cached_asset_downloads_.size()) > |
447 max_suggestions_count) { | 472 max_suggestions_count) { |
448 // Partially sorts |downloads| such that: | 473 // Partially sorts |downloads| such that: |
449 // 1) The element at the index |max_suggestions_count| is changed to the | 474 // 1) The element at the index |max_suggestions_count| is changed to the |
450 // element which would occur on this position if |downloads| was sorted; | 475 // element which would occur on this position if |downloads| was sorted; |
451 // 2) All of the elements before index |max_suggestions_count| are less than | 476 // 2) All of the elements before index |max_suggestions_count| are less than |
452 // or equal to the elements after it. | 477 // or equal to the elements after it. |
453 std::nth_element(cached_asset_downloads_.begin(), | 478 std::nth_element(cached_asset_downloads_.begin(), |
454 cached_asset_downloads_.begin() + max_suggestions_count, | 479 cached_asset_downloads_.begin() + max_suggestions_count, |
455 cached_asset_downloads_.end(), | 480 cached_asset_downloads_.end(), |
456 OrderDownloadsMostRecentlyDownloadedFirst()); | 481 &CompareDownloadsMostRecentlyDownloadedFirst); |
457 cached_asset_downloads_.resize(max_suggestions_count); | 482 cached_asset_downloads_.resize(max_suggestions_count); |
458 } | 483 } |
459 } | 484 } |
460 | 485 |
461 void DownloadSuggestionsProvider:: | 486 void DownloadSuggestionsProvider:: |
462 AsynchronouslyFetchAllDownloadsAndSubmitSuggestions() { | 487 AsynchronouslyFetchAllDownloadsAndSubmitSuggestions() { |
463 FetchAssetsDownloads(); | 488 FetchAssetsDownloads(); |
464 AsynchronouslyFetchOfflinePagesDownloads(/*notify=*/true); | 489 AsynchronouslyFetchOfflinePagesDownloads(/*notify=*/true); |
465 } | 490 } |
466 | 491 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 | 570 |
546 std::set<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs(); | 571 std::set<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs(); |
547 if (dismissed_ids.count(GetAssetDownloadPerCategoryID(item->GetId()))) { | 572 if (dismissed_ids.count(GetAssetDownloadPerCategoryID(item->GetId()))) { |
548 return false; | 573 return false; |
549 } | 574 } |
550 | 575 |
551 DCHECK_LE(static_cast<int>(cached_asset_downloads_.size()), | 576 DCHECK_LE(static_cast<int>(cached_asset_downloads_.size()), |
552 GetMaxSuggestionsCount()); | 577 GetMaxSuggestionsCount()); |
553 if (static_cast<int>(cached_asset_downloads_.size()) == | 578 if (static_cast<int>(cached_asset_downloads_.size()) == |
554 GetMaxSuggestionsCount()) { | 579 GetMaxSuggestionsCount()) { |
555 auto oldest = std::max_element(cached_asset_downloads_.begin(), | 580 auto oldest = std::max_element( |
556 cached_asset_downloads_.end(), | 581 cached_asset_downloads_.begin(), cached_asset_downloads_.end(), |
557 OrderDownloadsMostRecentlyDownloadedFirst()); | 582 &CompareDownloadsMostRecentlyDownloadedFirst); |
558 if (GetAssetDownloadPublishedTime(*item) <= | 583 if (GetAssetDownloadPublishedTime(*item) <= |
559 GetAssetDownloadPublishedTime(**oldest)) { | 584 GetAssetDownloadPublishedTime(**oldest)) { |
560 return false; | 585 return false; |
561 } | 586 } |
562 | 587 |
563 *oldest = item; | 588 *oldest = item; |
564 } else { | 589 } else { |
565 cached_asset_downloads_.push_back(item); | 590 cached_asset_downloads_.push_back(item); |
566 } | 591 } |
567 | 592 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
651 const int max_suggestions_count = GetMaxSuggestionsCount(); | 676 const int max_suggestions_count = GetMaxSuggestionsCount(); |
652 if (static_cast<int>(items.size()) > max_suggestions_count) { | 677 if (static_cast<int>(items.size()) > max_suggestions_count) { |
653 // Partially sorts |items| such that: | 678 // Partially sorts |items| such that: |
654 // 1) The element at the index |max_suggestions_count| is changed to the | 679 // 1) The element at the index |max_suggestions_count| is changed to the |
655 // element which would occur on this position if |items| was sorted; | 680 // element which would occur on this position if |items| was sorted; |
656 // 2) All of the elements before index |max_suggestions_count| are less than | 681 // 2) All of the elements before index |max_suggestions_count| are less than |
657 // or equal to the elements after it. | 682 // or equal to the elements after it. |
658 std::nth_element( | 683 std::nth_element( |
659 items.begin(), items.begin() + max_suggestions_count, items.end(), | 684 items.begin(), items.begin() + max_suggestions_count, items.end(), |
660 [](const OfflinePageItem* left, const OfflinePageItem* right) { | 685 [](const OfflinePageItem* left, const OfflinePageItem* right) { |
661 return left->creation_time > right->creation_time; | 686 return CompareOfflinePagesMostRecentlyCreatedFirst(*left, *right); |
662 }); | 687 }); |
663 items.resize(max_suggestions_count); | 688 items.resize(max_suggestions_count); |
664 } | 689 } |
665 | 690 |
666 cached_offline_page_downloads_.clear(); | 691 cached_offline_page_downloads_.clear(); |
667 for (const OfflinePageItem* item : items) { | 692 for (const OfflinePageItem* item : items) { |
668 cached_offline_page_downloads_.push_back(*item); | 693 cached_offline_page_downloads_.push_back(*item); |
669 } | 694 } |
670 | 695 |
671 if (old_dismissed_ids.size() != retained_dismissed_ids.size()) { | 696 if (old_dismissed_ids.size() != retained_dismissed_ids.size()) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
747 void DownloadSuggestionsProvider::UnregisterDownloadItemObservers() { | 772 void DownloadSuggestionsProvider::UnregisterDownloadItemObservers() { |
748 DCHECK_NE(download_manager_, nullptr); | 773 DCHECK_NE(download_manager_, nullptr); |
749 | 774 |
750 std::vector<DownloadItem*> all_downloads; | 775 std::vector<DownloadItem*> all_downloads; |
751 download_manager_->GetAllDownloads(&all_downloads); | 776 download_manager_->GetAllDownloads(&all_downloads); |
752 | 777 |
753 for (DownloadItem* item : all_downloads) { | 778 for (DownloadItem* item : all_downloads) { |
754 item->RemoveObserver(this); | 779 item->RemoveObserver(this); |
755 } | 780 } |
756 } | 781 } |
OLD | NEW |