Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: chrome/browser/ntp_snippets/download_suggestions_provider.cc

Issue 2562073002: [NTP::Downloads] Limit number of dismissed IDs instead of pruning. (Closed)
Patch Set: rebase & treib@ comments. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ntp_snippets/download_suggestions_provider.cc
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.cc b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
index b1e5fac85aeff9941e248a7713c9f2ebda436d4e..86155a2eb020577df5738f634934207df96749c9 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
@@ -17,6 +17,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "base/values.h"
#include "chrome/common/chrome_features.h"
#include "chrome/grit/generated_resources.h"
#include "components/ntp_snippets/features.h"
@@ -29,6 +30,7 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image.h"
+using base::ContainsValue;
using content::DownloadItem;
using content::DownloadManager;
using ntp_snippets::Category;
@@ -49,6 +51,9 @@ const char kOfflinePageDownloadsPrefix = 'O';
const char* kMaxSuggestionsCountParamName = "downloads_max_count";
+// Maximal number of dismissed asset download IDs stored at any time.
+const int kMaxDismissedIdCount = 100;
+
bool CompareOfflinePagesMostRecentlyCreatedFirst(const OfflinePageItem& left,
const OfflinePageItem& right) {
return left.creation_time > right.creation_time;
@@ -186,12 +191,8 @@ CategoryInfo DownloadSuggestionsProvider::GetCategoryInfo(Category category) {
void DownloadSuggestionsProvider::DismissSuggestion(
const ContentSuggestion::ID& suggestion_id) {
DCHECK_EQ(provided_category_, suggestion_id.category());
- std::set<std::string> dismissed_ids =
- ReadDismissedIDsFromPrefs(CorrespondsToOfflinePage(suggestion_id));
- dismissed_ids.insert(suggestion_id.id_within_category());
- StoreDismissedIDsToPrefs(CorrespondsToOfflinePage(suggestion_id),
- dismissed_ids);
+ AddToDismissedStorageIfNeeded(suggestion_id);
RemoveSuggestionFromCacheAndRetrieveMoreIfNeeded(suggestion_id);
}
@@ -262,7 +263,7 @@ void DownloadSuggestionsProvider::GetDismissedSuggestionsForDebugging(
void DownloadSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
Category category) {
DCHECK_EQ(provided_category_, category);
- StoreAssetDismissedIDsToPrefs(std::set<std::string>());
+ StoreAssetDismissedIDsToPrefs(std::vector<std::string>());
StoreOfflinePageDismissedIDsToPrefs(std::set<std::string>());
AsynchronouslyFetchAllDownloadsAndSubmitSuggestions();
}
@@ -274,6 +275,10 @@ void DownloadSuggestionsProvider::RegisterProfilePrefs(
registry->RegisterListPref(kDismissedOfflinePageDownloadSuggestions);
}
+int DownloadSuggestionsProvider::GetMaxDismissedCountForTesting() {
+ return kMaxDismissedIdCount;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Private methods
@@ -281,10 +286,12 @@ void DownloadSuggestionsProvider::
GetPagesMatchingQueryCallbackForGetDismissedSuggestions(
const ntp_snippets::DismissedSuggestionsCallback& callback,
const std::vector<OfflinePageItem>& offline_pages) const {
- std::set<std::string> dismissed_ids = ReadOfflinePageDismissedIDsFromPrefs();
+ std::set<std::string> dismissed_offline_ids =
+ ReadOfflinePageDismissedIDsFromPrefs();
std::vector<ContentSuggestion> suggestions;
for (const OfflinePageItem& item : offline_pages) {
- if (dismissed_ids.count(GetOfflinePagePerCategoryID(item.offline_id))) {
+ if (dismissed_offline_ids.count(
+ GetOfflinePagePerCategoryID(item.offline_id))) {
suggestions.push_back(ConvertOfflinePage(item));
}
}
@@ -293,10 +300,12 @@ void DownloadSuggestionsProvider::
std::vector<DownloadItem*> all_downloads;
download_manager_->GetAllDownloads(&all_downloads);
- dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+ std::vector<std::string> dismissed_asset_ids =
+ ReadAssetDismissedIDsFromPrefs();
for (const DownloadItem* item : all_downloads) {
- if (dismissed_ids.count(GetAssetDownloadPerCategoryID(item->GetId()))) {
+ if (ContainsValue(dismissed_asset_ids,
+ GetAssetDownloadPerCategoryID(item->GetId()))) {
suggestions.push_back(ConvertDownloadItem(*item));
}
}
@@ -369,7 +378,7 @@ void DownloadSuggestionsProvider::ManagerGoingDown(DownloadManager* manager) {
}
void DownloadSuggestionsProvider::OnDownloadUpdated(DownloadItem* item) {
- if (base::ContainsValue(cached_asset_downloads_, item)) {
+ if (ContainsValue(cached_asset_downloads_, item)) {
if (item->GetFileExternallyRemoved()) {
InvalidateSuggestion(GetAssetDownloadPerCategoryID(item->GetId()));
} else {
@@ -450,25 +459,23 @@ void DownloadSuggestionsProvider::FetchAssetsDownloads() {
std::vector<DownloadItem*> all_downloads;
download_manager_->GetAllDownloads(&all_downloads);
- std::set<std::string> old_dismissed_ids = ReadAssetDismissedIDsFromPrefs();
- std::set<std::string> retained_dismissed_ids;
+ std::vector<std::string> old_dismissed_ids = ReadAssetDismissedIDsFromPrefs();
cached_asset_downloads_.clear();
for (const DownloadItem* item : all_downloads) {
std::string within_category_id =
GetAssetDownloadPerCategoryID(item->GetId());
- if (!old_dismissed_ids.count(within_category_id)) {
+ if (!ContainsValue(old_dismissed_ids, within_category_id)) {
if (IsDownloadCompleted(*item)) {
cached_asset_downloads_.push_back(item);
}
- } else {
- retained_dismissed_ids.insert(within_category_id);
}
}
- if (old_dismissed_ids.size() != retained_dismissed_ids.size()) {
- StoreAssetDismissedIDsToPrefs(retained_dismissed_ids);
- }
-
+ // We do not prune dismissed IDs, because it is not possible to ensure that
+ // the list of downloads is complete (i.e. DownloadManager has finished
+ // reading them).
+ // TODO(vitaliii): Prune dismissed IDs once the |OnLoaded| notification is
+ // provided. See crbug.com/672758.
const int max_suggestions_count = GetMaxSuggestionsCount();
if (static_cast<int>(cached_asset_downloads_.size()) >
max_suggestions_count) {
@@ -566,12 +573,13 @@ bool DownloadSuggestionsProvider::CacheAssetDownloadIfNeeded(
return false;
}
- if (base::ContainsValue(cached_asset_downloads_, item)) {
+ if (ContainsValue(cached_asset_downloads_, item)) {
return false;
}
- std::set<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
- if (dismissed_ids.count(GetAssetDownloadPerCategoryID(item->GetId()))) {
+ std::vector<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+ if (ContainsValue(dismissed_ids,
+ GetAssetDownloadPerCategoryID(item->GetId()))) {
return false;
}
@@ -709,31 +717,38 @@ void DownloadSuggestionsProvider::InvalidateSuggestion(
ContentSuggestion::ID suggestion_id(provided_category_, id_within_category);
observer()->OnSuggestionInvalidated(this, suggestion_id);
- std::set<std::string> dismissed_ids =
- ReadDismissedIDsFromPrefs(CorrespondsToOfflinePage(suggestion_id));
- auto it = dismissed_ids.find(id_within_category);
- if (it != dismissed_ids.end()) {
- dismissed_ids.erase(it);
- StoreDismissedIDsToPrefs(CorrespondsToOfflinePage(suggestion_id),
- dismissed_ids);
- }
-
+ RemoveFromDismissedStorageIfNeeded(suggestion_id);
RemoveSuggestionFromCacheAndRetrieveMoreIfNeeded(suggestion_id);
}
-std::set<std::string>
+// TODO(vitaliii): Do not use std::vector, when we ensure that pruning happens
+// at the right time (crbug.com/672758).
+std::vector<std::string>
DownloadSuggestionsProvider::ReadAssetDismissedIDsFromPrefs() const {
- return ntp_snippets::prefs::ReadDismissedIDsFromPrefs(
- *pref_service_, kDismissedAssetDownloadSuggestions);
+ std::vector<std::string> dismissed_ids;
+ const base::ListValue* list =
+ pref_service_->GetList(kDismissedAssetDownloadSuggestions);
+ for (const std::unique_ptr<base::Value>& value : *list) {
+ std::string dismissed_id;
+ bool success = value->GetAsString(&dismissed_id);
+ DCHECK(success) << "Failed to parse dismissed id from prefs param "
+ << kDismissedAssetDownloadSuggestions << " into string.";
+ dismissed_ids.push_back(dismissed_id);
+ }
+ return dismissed_ids;
}
void DownloadSuggestionsProvider::StoreAssetDismissedIDsToPrefs(
- const std::set<std::string>& dismissed_ids) {
+ const std::vector<std::string>& dismissed_ids) {
DCHECK(std::all_of(
dismissed_ids.begin(), dismissed_ids.end(),
[](const std::string& id) { return id[0] == kAssetDownloadsPrefix; }));
- ntp_snippets::prefs::StoreDismissedIDsToPrefs(
- pref_service_, kDismissedAssetDownloadSuggestions, dismissed_ids);
+
+ base::ListValue list;
+ for (const std::string& dismissed_id : dismissed_ids) {
+ list.AppendString(dismissed_id);
+ }
+ pref_service_->Set(kDismissedAssetDownloadSuggestions, list);
}
std::set<std::string>
@@ -752,22 +767,45 @@ void DownloadSuggestionsProvider::StoreOfflinePageDismissedIDsToPrefs(
pref_service_, kDismissedOfflinePageDownloadSuggestions, dismissed_ids);
}
-std::set<std::string> DownloadSuggestionsProvider::ReadDismissedIDsFromPrefs(
- bool for_offline_page_downloads) const {
- if (for_offline_page_downloads) {
- return ReadOfflinePageDismissedIDsFromPrefs();
+void DownloadSuggestionsProvider::AddToDismissedStorageIfNeeded(
+ const ContentSuggestion::ID& suggestion_id) {
+ if (CorrespondsToOfflinePage(suggestion_id)) {
+ std::set<std::string> dismissed_ids =
+ ReadOfflinePageDismissedIDsFromPrefs();
+ dismissed_ids.insert(suggestion_id.id_within_category());
+ StoreOfflinePageDismissedIDsToPrefs(dismissed_ids);
+ } else {
+ std::vector<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+ // The suggestion may be double dismissed from previously opened NTPs.
+ if (!ContainsValue(dismissed_ids, suggestion_id.id_within_category())) {
+ dismissed_ids.push_back(suggestion_id.id_within_category());
+ // TODO(vitaliii): Remove this workaround once the dismissed ids are
+ // pruned. See crbug.com/672758.
+ while (dismissed_ids.size() > kMaxDismissedIdCount) {
+ dismissed_ids.erase(dismissed_ids.begin());
+ }
+ StoreAssetDismissedIDsToPrefs(dismissed_ids);
+ }
}
- return ReadAssetDismissedIDsFromPrefs();
}
-// TODO(vitaliii): Store one set instead of two. See crbug.com/656024.
-void DownloadSuggestionsProvider::StoreDismissedIDsToPrefs(
- bool for_offline_page_downloads,
- const std::set<std::string>& dismissed_ids) {
- if (for_offline_page_downloads) {
- StoreOfflinePageDismissedIDsToPrefs(dismissed_ids);
+void DownloadSuggestionsProvider::RemoveFromDismissedStorageIfNeeded(
+ const ContentSuggestion::ID& suggestion_id) {
+ if (CorrespondsToOfflinePage(suggestion_id)) {
+ std::set<std::string> dismissed_ids =
+ ReadOfflinePageDismissedIDsFromPrefs();
+ if (dismissed_ids.count(suggestion_id.id_within_category())) {
+ dismissed_ids.erase(suggestion_id.id_within_category());
+ StoreOfflinePageDismissedIDsToPrefs(dismissed_ids);
+ }
} else {
- StoreAssetDismissedIDsToPrefs(dismissed_ids);
+ std::vector<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+ auto it = std::find(dismissed_ids.begin(), dismissed_ids.end(),
+ suggestion_id.id_within_category());
+ if (it != dismissed_ids.end()) {
+ dismissed_ids.erase(it);
+ StoreAssetDismissedIDsToPrefs(dismissed_ids);
+ }
}
}

Powered by Google App Engine
This is Rietveld 408576698