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 "components/ntp_snippets/offline_pages/offline_page_suggestions_provide r.h" | 5 #include "components/ntp_snippets/offline_pages/offline_page_suggestions_provide r.h" |
6 | 6 |
7 #include <algorithm> | |
8 | |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/guid.h" | |
8 #include "base/location.h" | 11 #include "base/location.h" |
9 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
11 #include "base/threading/thread_task_runner_handle.h" | 14 #include "base/threading/thread_task_runner_handle.h" |
12 #include "base/values.h" | 15 #include "base/values.h" |
13 #include "components/ntp_snippets/pref_names.h" | 16 #include "components/ntp_snippets/pref_names.h" |
17 #include "components/offline_pages/client_namespace_constants.h" | |
14 #include "components/prefs/pref_registry_simple.h" | 18 #include "components/prefs/pref_registry_simple.h" |
15 #include "components/prefs/pref_service.h" | 19 #include "components/prefs/pref_service.h" |
20 #include "grit/components_strings.h" | |
21 #include "ui/base/l10n/l10n_util.h" | |
16 #include "ui/gfx/image/image.h" | 22 #include "ui/gfx/image/image.h" |
17 | 23 |
18 using offline_pages::MultipleOfflinePageItemResult; | 24 using offline_pages::MultipleOfflinePageItemResult; |
19 using offline_pages::OfflinePageModel; | 25 using offline_pages::OfflinePageModel; |
20 using offline_pages::OfflinePageItem; | 26 using offline_pages::OfflinePageItem; |
21 | 27 |
22 namespace ntp_snippets { | 28 namespace ntp_snippets { |
23 | 29 |
24 namespace { | 30 namespace { |
25 | 31 |
26 const int kMaxSuggestionsCount = 5; | 32 const int kMaxSuggestionsCount = 5; |
27 | 33 |
34 struct OrderByMostRecentlyVisited { | |
35 bool operator()(const OfflinePageItem* left, | |
36 const OfflinePageItem* right) const { | |
37 return left->last_access_time > right->last_access_time; | |
38 } | |
39 }; | |
40 | |
28 } // namespace | 41 } // namespace |
29 | 42 |
30 OfflinePageSuggestionsProvider::OfflinePageSuggestionsProvider( | 43 OfflinePageSuggestionsProvider::OfflinePageSuggestionsProvider( |
44 bool recent_tabs_enabled, | |
45 bool downloads_enabled, | |
46 bool download_manager_ui_enabled, | |
31 ContentSuggestionsProvider::Observer* observer, | 47 ContentSuggestionsProvider::Observer* observer, |
32 CategoryFactory* category_factory, | 48 CategoryFactory* category_factory, |
33 OfflinePageModel* offline_page_model, | 49 OfflinePageModel* offline_page_model, |
34 PrefService* pref_service) | 50 PrefService* pref_service) |
35 : ContentSuggestionsProvider(observer, category_factory), | 51 : ContentSuggestionsProvider(observer, category_factory), |
36 category_status_(CategoryStatus::AVAILABLE_LOADING), | 52 recent_tabs_status_(recent_tabs_enabled |
53 ? CategoryStatus::AVAILABLE_LOADING | |
54 : CategoryStatus::NOT_PROVIDED), | |
55 downloads_status_(downloads_enabled ? CategoryStatus::AVAILABLE_LOADING | |
56 : CategoryStatus::NOT_PROVIDED), | |
37 offline_page_model_(offline_page_model), | 57 offline_page_model_(offline_page_model), |
38 provided_category_( | 58 recent_tabs_category_( |
39 category_factory->FromKnownCategory(KnownCategories::OFFLINE_PAGES)), | 59 category_factory->FromKnownCategory(KnownCategories::RECENT_TABS)), |
40 pref_service_(pref_service) { | 60 downloads_category_( |
61 category_factory->FromKnownCategory(KnownCategories::DOWNLOADS)), | |
62 pref_service_(pref_service), | |
63 dismissed_recent_tab_ids_(ReadDismissedIDsFromPrefs( | |
64 prefs::kDismissedRecentOfflineTabSuggestions)), | |
65 dismissed_download_ids_( | |
66 ReadDismissedIDsFromPrefs(prefs::kDismissedDownloadSuggestions)), | |
67 download_manager_ui_enabled_(download_manager_ui_enabled) { | |
68 DCHECK(recent_tabs_enabled || downloads_enabled); | |
41 offline_page_model_->AddObserver(this); | 69 offline_page_model_->AddObserver(this); |
42 ReadDismissedIDsFromPrefs(); | |
43 FetchOfflinePages(); | 70 FetchOfflinePages(); |
44 } | 71 } |
45 | 72 |
46 OfflinePageSuggestionsProvider::~OfflinePageSuggestionsProvider() { | 73 OfflinePageSuggestionsProvider::~OfflinePageSuggestionsProvider() { |
47 offline_page_model_->RemoveObserver(this); | 74 offline_page_model_->RemoveObserver(this); |
48 } | 75 } |
49 | 76 |
50 // static | 77 // static |
51 void OfflinePageSuggestionsProvider::RegisterProfilePrefs( | 78 void OfflinePageSuggestionsProvider::RegisterProfilePrefs( |
52 PrefRegistrySimple* registry) { | 79 PrefRegistrySimple* registry) { |
53 registry->RegisterListPref(prefs::kDismissedOfflinePageSuggestions); | 80 registry->RegisterListPref(prefs::kDismissedRecentOfflineTabSuggestions); |
81 registry->RegisterListPref(prefs::kDismissedDownloadSuggestions); | |
54 } | 82 } |
55 | 83 |
56 //////////////////////////////////////////////////////////////////////////////// | 84 //////////////////////////////////////////////////////////////////////////////// |
57 // Private methods | 85 // Private methods |
58 | 86 |
59 std::vector<Category> OfflinePageSuggestionsProvider::GetProvidedCategories() { | 87 std::vector<Category> OfflinePageSuggestionsProvider::GetProvidedCategories() { |
60 return std::vector<Category>({provided_category_}); | 88 std::vector<Category> provided_categories; |
89 if (recent_tabs_status_ != CategoryStatus::NOT_PROVIDED) | |
90 provided_categories.push_back(recent_tabs_category_); | |
91 if (downloads_status_ != CategoryStatus::NOT_PROVIDED) | |
92 provided_categories.push_back(downloads_category_); | |
93 return provided_categories; | |
61 } | 94 } |
62 | 95 |
63 CategoryStatus OfflinePageSuggestionsProvider::GetCategoryStatus( | 96 CategoryStatus OfflinePageSuggestionsProvider::GetCategoryStatus( |
64 Category category) { | 97 Category category) { |
65 DCHECK_EQ(category, provided_category_); | 98 if (category == recent_tabs_category_) |
66 return category_status_; | 99 return recent_tabs_status_; |
100 if (category == downloads_category_) | |
101 return downloads_status_; | |
102 NOTREACHED() << "Unknown category " << category.id(); | |
103 return CategoryStatus::NOT_PROVIDED; | |
67 } | 104 } |
68 | 105 |
69 CategoryInfo OfflinePageSuggestionsProvider::GetCategoryInfo( | 106 CategoryInfo OfflinePageSuggestionsProvider::GetCategoryInfo( |
70 Category category) { | 107 Category category) { |
71 // TODO(pke): Use the proper string once it's agreed on. | 108 if (category == recent_tabs_category_) { |
72 return CategoryInfo(base::ASCIIToUTF16("Offline pages"), | 109 return CategoryInfo(l10n_util::GetStringUTF16( |
110 IDS_NTP_RECENT_TAB_SUGGESTIONS_SECTION_HEADER), | |
111 ContentSuggestionsCardLayout::MINIMAL_CARD, | |
112 /* has_more_button */ true); | |
Marc Treib
2016/08/12 13:05:43
Where would this "more" button lead - to the old "
Philipp Keck
2016/08/12 13:09:44
You're right, that's not the right thing. I remove
Marc Treib
2016/08/12 13:13:36
Yes, for the old bottom toolbar that we're replaci
| |
113 } | |
114 if (category == downloads_category_) { | |
115 return CategoryInfo( | |
116 l10n_util::GetStringUTF16(IDS_NTP_DOWNLOAD_SUGGESTIONS_SECTION_HEADER), | |
117 ContentSuggestionsCardLayout::MINIMAL_CARD, | |
118 /* has_more_button */ download_manager_ui_enabled_); | |
119 } | |
120 NOTREACHED() << "Unknown category " << category.id(); | |
121 return CategoryInfo(base::string16(), | |
73 ContentSuggestionsCardLayout::MINIMAL_CARD, | 122 ContentSuggestionsCardLayout::MINIMAL_CARD, |
74 /* has_more_button */ false); | 123 /* has_more_button */ false); |
75 } | 124 } |
76 | 125 |
77 void OfflinePageSuggestionsProvider::DismissSuggestion( | 126 void OfflinePageSuggestionsProvider::DismissSuggestion( |
78 const std::string& suggestion_id) { | 127 const std::string& suggestion_id) { |
128 Category category = GetCategoryFromUniqueID(suggestion_id); | |
79 std::string offline_page_id = GetWithinCategoryIDFromUniqueID(suggestion_id); | 129 std::string offline_page_id = GetWithinCategoryIDFromUniqueID(suggestion_id); |
80 dismissed_ids_.insert(offline_page_id); | 130 if (category == recent_tabs_category_) { |
81 StoreDismissedIDsToPrefs(); | 131 DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); |
132 dismissed_recent_tab_ids_.insert(offline_page_id); | |
133 StoreDismissedIDsToPrefs(prefs::kDismissedRecentOfflineTabSuggestions, | |
134 dismissed_recent_tab_ids_); | |
135 } else if (category == downloads_category_) { | |
136 DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); | |
137 dismissed_download_ids_.insert(offline_page_id); | |
138 StoreDismissedIDsToPrefs(prefs::kDismissedDownloadSuggestions, | |
139 dismissed_download_ids_); | |
140 } else { | |
141 NOTREACHED() << "Unknown category " << category.id(); | |
142 } | |
82 } | 143 } |
83 | 144 |
84 void OfflinePageSuggestionsProvider::FetchSuggestionImage( | 145 void OfflinePageSuggestionsProvider::FetchSuggestionImage( |
85 const std::string& suggestion_id, | 146 const std::string& suggestion_id, |
86 const ImageFetchedCallback& callback) { | 147 const ImageFetchedCallback& callback) { |
87 // TODO(pke): Fetch proper thumbnail from OfflinePageModel once it's available | 148 // TODO(pke): Fetch proper thumbnail from OfflinePageModel once it's available |
88 // there. | 149 // there. |
89 base::ThreadTaskRunnerHandle::Get()->PostTask( | 150 base::ThreadTaskRunnerHandle::Get()->PostTask( |
90 FROM_HERE, base::Bind(callback, suggestion_id, gfx::Image())); | 151 FROM_HERE, base::Bind(callback, suggestion_id, gfx::Image())); |
91 } | 152 } |
92 | 153 |
93 void OfflinePageSuggestionsProvider::ClearCachedSuggestionsForDebugging( | 154 void OfflinePageSuggestionsProvider::ClearCachedSuggestionsForDebugging( |
94 Category category) { | 155 Category category) { |
95 DCHECK_EQ(category, provided_category_); | |
96 // Ignored. | 156 // Ignored. |
97 } | 157 } |
98 | 158 |
99 std::vector<ContentSuggestion> | 159 std::vector<ContentSuggestion> |
100 OfflinePageSuggestionsProvider::GetDismissedSuggestionsForDebugging( | 160 OfflinePageSuggestionsProvider::GetDismissedSuggestionsForDebugging( |
101 Category category) { | 161 Category category) { |
102 // TODO(pke): Make GetDismissedSuggestionsForDebugging asynchronous so this | 162 // TODO(pke): Make GetDismissedSuggestionsForDebugging asynchronous so this |
103 // can return proper values. | 163 // can return proper values. |
104 DCHECK_EQ(category, provided_category_); | |
105 std::vector<ContentSuggestion> suggestions; | 164 std::vector<ContentSuggestion> suggestions; |
106 for (const std::string& dismissed_id : dismissed_ids_) { | 165 const std::set<std::string>* dismissed_ids = nullptr; |
166 if (category == recent_tabs_category_) { | |
167 DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); | |
168 dismissed_ids = &dismissed_recent_tab_ids_; | |
169 } else if (category == downloads_category_) { | |
170 DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); | |
171 dismissed_ids = &dismissed_download_ids_; | |
172 } else { | |
173 NOTREACHED() << "Unknown category " << category.id(); | |
174 return suggestions; | |
175 } | |
176 | |
177 for (const std::string& dismissed_id : *dismissed_ids) { | |
107 ContentSuggestion suggestion( | 178 ContentSuggestion suggestion( |
108 MakeUniqueID(provided_category_, dismissed_id), | 179 MakeUniqueID(category, dismissed_id), |
109 GURL("http://dismissed-offline-page-" + dismissed_id)); | 180 GURL("http://dismissed-offline-page-" + dismissed_id)); |
110 suggestion.set_title(base::UTF8ToUTF16("Title not available")); | 181 suggestion.set_title(base::UTF8ToUTF16("Title not available")); |
111 suggestions.push_back(std::move(suggestion)); | 182 suggestions.push_back(std::move(suggestion)); |
112 } | 183 } |
113 return suggestions; | 184 return suggestions; |
114 } | 185 } |
115 | 186 |
116 void OfflinePageSuggestionsProvider::ClearDismissedSuggestionsForDebugging( | 187 void OfflinePageSuggestionsProvider::ClearDismissedSuggestionsForDebugging( |
117 Category category) { | 188 Category category) { |
118 DCHECK_EQ(category, provided_category_); | 189 if (category == recent_tabs_category_) { |
119 dismissed_ids_.clear(); | 190 DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); |
120 StoreDismissedIDsToPrefs(); | 191 dismissed_recent_tab_ids_.clear(); |
192 StoreDismissedIDsToPrefs(prefs::kDismissedRecentOfflineTabSuggestions, | |
193 dismissed_recent_tab_ids_); | |
194 } else if (category == downloads_category_) { | |
195 DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); | |
196 dismissed_download_ids_.clear(); | |
197 StoreDismissedIDsToPrefs(prefs::kDismissedDownloadSuggestions, | |
198 dismissed_download_ids_); | |
199 } else { | |
200 NOTREACHED() << "Unknown category " << category.id(); | |
201 } | |
121 FetchOfflinePages(); | 202 FetchOfflinePages(); |
122 } | 203 } |
123 | 204 |
124 void OfflinePageSuggestionsProvider::OfflinePageModelLoaded( | 205 void OfflinePageSuggestionsProvider::OfflinePageModelLoaded( |
125 OfflinePageModel* model) { | 206 OfflinePageModel* model) { |
126 DCHECK_EQ(offline_page_model_, model); | 207 DCHECK_EQ(offline_page_model_, model); |
127 } | 208 } |
128 | 209 |
129 void OfflinePageSuggestionsProvider::OfflinePageModelChanged( | 210 void OfflinePageSuggestionsProvider::OfflinePageModelChanged( |
130 OfflinePageModel* model) { | 211 OfflinePageModel* model) { |
131 DCHECK_EQ(offline_page_model_, model); | 212 DCHECK_EQ(offline_page_model_, model); |
132 FetchOfflinePages(); | 213 FetchOfflinePages(); |
133 } | 214 } |
134 | 215 |
135 void OfflinePageSuggestionsProvider::OfflinePageDeleted( | 216 void OfflinePageSuggestionsProvider::OfflinePageDeleted( |
136 int64_t offline_id, | 217 int64_t offline_id, |
137 const offline_pages::ClientId& client_id) { | 218 const offline_pages::ClientId& client_id) { |
138 // TODO(pke): Implement, suggestion has to be removed from UI immediately. | 219 // TODO(pke): Implement, suggestion has to be removed from UI immediately. |
139 } | 220 } |
140 | 221 |
141 void OfflinePageSuggestionsProvider::FetchOfflinePages() { | 222 void OfflinePageSuggestionsProvider::FetchOfflinePages() { |
142 offline_page_model_->GetAllPages( | 223 offline_page_model_->GetAllPages( |
143 base::Bind(&OfflinePageSuggestionsProvider::OnOfflinePagesLoaded, | 224 base::Bind(&OfflinePageSuggestionsProvider::OnOfflinePagesLoaded, |
144 base::Unretained(this))); | 225 base::Unretained(this))); |
145 } | 226 } |
146 | 227 |
147 void OfflinePageSuggestionsProvider::OnOfflinePagesLoaded( | 228 void OfflinePageSuggestionsProvider::OnOfflinePagesLoaded( |
148 const MultipleOfflinePageItemResult& result) { | 229 const MultipleOfflinePageItemResult& result) { |
149 NotifyStatusChanged(CategoryStatus::AVAILABLE); | 230 bool need_recent_tabs = recent_tabs_status_ != CategoryStatus::NOT_PROVIDED; |
231 bool need_downloads = downloads_status_ != CategoryStatus::NOT_PROVIDED; | |
232 if (need_recent_tabs) | |
233 NotifyStatusChanged(recent_tabs_category_, CategoryStatus::AVAILABLE); | |
234 if (need_downloads) | |
235 NotifyStatusChanged(downloads_category_, CategoryStatus::AVAILABLE); | |
150 | 236 |
151 std::vector<ContentSuggestion> suggestions; | 237 std::vector<const OfflinePageItem*> recent_tab_items; |
238 std::vector<const OfflinePageItem*> download_items; | |
152 for (const OfflinePageItem& item : result) { | 239 for (const OfflinePageItem& item : result) { |
153 if (dismissed_ids_.count(base::IntToString(item.offline_id))) | 240 if (need_recent_tabs && |
154 continue; | 241 item.client_id.name_space == offline_pages::kLastNNamespace && |
155 suggestions.push_back(ConvertOfflinePage(item)); | 242 !dismissed_recent_tab_ids_.count(base::IntToString(item.offline_id))) { |
156 if (suggestions.size() == kMaxSuggestionsCount) | 243 recent_tab_items.push_back(&item); |
157 break; | 244 } |
245 | |
246 // TODO(pke): Use kDownloadNamespace once the OfflinePageModel uses that. | |
247 // The current logic is taken from DownloadUIAdapter::IsVisibleInUI. | |
248 if (need_downloads && | |
249 item.client_id.name_space == offline_pages::kAsyncNamespace && | |
250 base::IsValidGUID(item.client_id.id) && | |
251 !dismissed_download_ids_.count(base::IntToString(item.offline_id))) { | |
252 download_items.push_back(&item); | |
253 } | |
158 } | 254 } |
159 | 255 |
160 observer()->OnNewSuggestions(this, provided_category_, | 256 // TODO(pke): Once we have our OfflinePageModel getter and that doesn't do it |
161 std::move(suggestions)); | 257 // already, filter out duplicate URLs for recent tabs here. Duplicates for |
258 // downloads are fine. | |
259 | |
260 if (need_recent_tabs) { | |
261 observer()->OnNewSuggestions( | |
262 this, recent_tabs_category_, | |
263 GetMostRecentlyVisited(recent_tabs_category_, | |
264 std::move(recent_tab_items))); | |
265 } | |
266 if (need_downloads) { | |
267 observer()->OnNewSuggestions( | |
268 this, downloads_category_, | |
269 GetMostRecentlyVisited(downloads_category_, std::move(download_items))); | |
270 } | |
162 } | 271 } |
163 | 272 |
164 void OfflinePageSuggestionsProvider::NotifyStatusChanged( | 273 void OfflinePageSuggestionsProvider::NotifyStatusChanged( |
274 Category category, | |
165 CategoryStatus new_status) { | 275 CategoryStatus new_status) { |
166 if (category_status_ == new_status) | 276 if (category == recent_tabs_category_) { |
167 return; | 277 DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); |
168 category_status_ = new_status; | 278 if (recent_tabs_status_ == new_status) |
169 | 279 return; |
170 observer()->OnCategoryStatusChanged(this, provided_category_, new_status); | 280 recent_tabs_status_ = new_status; |
281 observer()->OnCategoryStatusChanged(this, category, new_status); | |
282 } else if (category == downloads_category_) { | |
283 DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); | |
284 if (downloads_status_ == new_status) | |
285 return; | |
286 downloads_status_ = new_status; | |
287 observer()->OnCategoryStatusChanged(this, category, new_status); | |
288 } else { | |
289 NOTREACHED() << "Unknown category " << category.id(); | |
290 } | |
171 } | 291 } |
172 | 292 |
173 ContentSuggestion OfflinePageSuggestionsProvider::ConvertOfflinePage( | 293 ContentSuggestion OfflinePageSuggestionsProvider::ConvertOfflinePage( |
294 Category category, | |
174 const OfflinePageItem& offline_page) const { | 295 const OfflinePageItem& offline_page) const { |
175 // TODO(pke): Make sure the URL is actually opened as an offline URL. | 296 // TODO(pke): Make sure the URL is actually opened as an offline URL. |
176 // Currently, the browser opens the offline URL and then immediately | 297 // Currently, the browser opens the offline URL and then immediately |
177 // redirects to the online URL if the device is online. | 298 // redirects to the online URL if the device is online. |
178 ContentSuggestion suggestion( | 299 ContentSuggestion suggestion( |
179 MakeUniqueID(provided_category_, | 300 MakeUniqueID(category, base::IntToString(offline_page.offline_id)), |
180 base::IntToString(offline_page.offline_id)), | |
181 offline_page.GetOfflineURL()); | 301 offline_page.GetOfflineURL()); |
182 | 302 |
183 // TODO(pke): Sort by most recently visited and only keep the top one of | 303 if (offline_page.title.empty()) { |
184 // multiple entries for the same URL. | 304 // TODO(pke): Remove this fallback once the OfflinePageModel provides titles |
185 // TODO(pke): Get more reasonable data from the OfflinePageModel here. | 305 // for all (relevant) OfflinePageItems. |
186 suggestion.set_title(base::UTF8ToUTF16(offline_page.url.spec())); | 306 suggestion.set_title(base::UTF8ToUTF16(offline_page.url.spec())); |
187 suggestion.set_snippet_text(base::string16()); | 307 } else { |
308 suggestion.set_title(offline_page.title); | |
309 } | |
188 suggestion.set_publish_date(offline_page.creation_time); | 310 suggestion.set_publish_date(offline_page.creation_time); |
189 suggestion.set_publisher_name(base::UTF8ToUTF16(offline_page.url.host())); | 311 suggestion.set_publisher_name(base::UTF8ToUTF16(offline_page.url.host())); |
190 return suggestion; | 312 return suggestion; |
191 } | 313 } |
192 | 314 |
193 void OfflinePageSuggestionsProvider::ReadDismissedIDsFromPrefs() { | 315 std::vector<ContentSuggestion> |
194 dismissed_ids_.clear(); | 316 OfflinePageSuggestionsProvider::GetMostRecentlyVisited( |
195 const base::ListValue* list = | 317 Category category, |
196 pref_service_->GetList(prefs::kDismissedOfflinePageSuggestions); | 318 std::vector<const OfflinePageItem*> offline_page_items) const { |
319 std::sort(offline_page_items.begin(), offline_page_items.end(), | |
320 OrderByMostRecentlyVisited()); | |
321 std::vector<ContentSuggestion> suggestions; | |
322 for (const OfflinePageItem* offline_page_item : offline_page_items) { | |
323 suggestions.push_back(ConvertOfflinePage(category, *offline_page_item)); | |
324 if (suggestions.size() == kMaxSuggestionsCount) | |
325 break; | |
326 } | |
327 return suggestions; | |
328 } | |
329 | |
330 std::set<std::string> OfflinePageSuggestionsProvider::ReadDismissedIDsFromPrefs( | |
331 const std::string& pref_name) const { | |
332 std::set<std::string> dismissed_ids; | |
333 const base::ListValue* list = pref_service_->GetList(pref_name); | |
197 for (const std::unique_ptr<base::Value>& value : *list) { | 334 for (const std::unique_ptr<base::Value>& value : *list) { |
198 std::string dismissed_id; | 335 std::string dismissed_id; |
199 bool success = value->GetAsString(&dismissed_id); | 336 bool success = value->GetAsString(&dismissed_id); |
200 DCHECK(success) << "Failed to parse dismissed offline page ID from prefs"; | 337 DCHECK(success) << "Failed to parse dismissed offline page ID from prefs"; |
201 dismissed_ids_.insert(std::move(dismissed_id)); | 338 dismissed_ids.insert(dismissed_id); |
202 } | 339 } |
340 return dismissed_ids; | |
203 } | 341 } |
204 | 342 |
205 void OfflinePageSuggestionsProvider::StoreDismissedIDsToPrefs() { | 343 void OfflinePageSuggestionsProvider::StoreDismissedIDsToPrefs( |
344 const std::string& pref_name, | |
345 const std::set<std::string>& dismissed_ids) { | |
206 base::ListValue list; | 346 base::ListValue list; |
207 for (const std::string& dismissed_id : dismissed_ids_) | 347 for (const std::string& dismissed_id : dismissed_ids) |
208 list.AppendString(dismissed_id); | 348 list.AppendString(dismissed_id); |
209 pref_service_->Set(prefs::kDismissedOfflinePageSuggestions, list); | 349 pref_service_->Set(pref_name, list); |
210 } | 350 } |
211 | 351 |
212 } // namespace ntp_snippets | 352 } // namespace ntp_snippets |
OLD | NEW |