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/content_suggestions_service.h" | 5 #include "components/ntp_snippets/content_suggestions_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
(...skipping 13 matching lines...) Expand all Loading... |
24 ContentSuggestionsService::ContentSuggestionsService( | 24 ContentSuggestionsService::ContentSuggestionsService( |
25 State state, | 25 State state, |
26 history::HistoryService* history_service, | 26 history::HistoryService* history_service, |
27 PrefService* pref_service) | 27 PrefService* pref_service) |
28 : state_(state), | 28 : state_(state), |
29 history_service_observer_(this), | 29 history_service_observer_(this), |
30 ntp_snippets_service_(nullptr), | 30 ntp_snippets_service_(nullptr), |
31 pref_service_(pref_service), | 31 pref_service_(pref_service), |
32 user_classifier_(pref_service) { | 32 user_classifier_(pref_service) { |
33 // Can be null in tests. | 33 // Can be null in tests. |
34 if (history_service) | 34 if (history_service) { |
35 history_service_observer_.Add(history_service); | 35 history_service_observer_.Add(history_service); |
| 36 } |
36 | 37 |
37 RestoreDismissedCategoriesFromPrefs(); | 38 RestoreDismissedCategoriesFromPrefs(); |
38 } | 39 } |
39 | 40 |
40 ContentSuggestionsService::~ContentSuggestionsService() = default; | 41 ContentSuggestionsService::~ContentSuggestionsService() = default; |
41 | 42 |
42 void ContentSuggestionsService::Shutdown() { | 43 void ContentSuggestionsService::Shutdown() { |
43 ntp_snippets_service_ = nullptr; | 44 ntp_snippets_service_ = nullptr; |
44 suggestions_by_category_.clear(); | 45 suggestions_by_category_.clear(); |
45 providers_by_category_.clear(); | 46 providers_by_category_.clear(); |
46 categories_.clear(); | 47 categories_.clear(); |
47 providers_.clear(); | 48 providers_.clear(); |
48 state_ = State::DISABLED; | 49 state_ = State::DISABLED; |
49 for (Observer& observer : observers_) | 50 for (Observer& observer : observers_) { |
50 observer.ContentSuggestionsServiceShutdown(); | 51 observer.ContentSuggestionsServiceShutdown(); |
| 52 } |
51 } | 53 } |
52 | 54 |
53 // static | 55 // static |
54 void ContentSuggestionsService::RegisterProfilePrefs( | 56 void ContentSuggestionsService::RegisterProfilePrefs( |
55 PrefRegistrySimple* registry) { | 57 PrefRegistrySimple* registry) { |
56 registry->RegisterListPref(prefs::kDismissedCategories); | 58 registry->RegisterListPref(prefs::kDismissedCategories); |
57 } | 59 } |
58 | 60 |
59 CategoryStatus ContentSuggestionsService::GetCategoryStatus( | 61 CategoryStatus ContentSuggestionsService::GetCategoryStatus( |
60 Category category) const { | 62 Category category) const { |
61 if (state_ == State::DISABLED) { | 63 if (state_ == State::DISABLED) { |
62 return CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED; | 64 return CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED; |
63 } | 65 } |
64 | 66 |
65 auto iterator = providers_by_category_.find(category); | 67 auto iterator = providers_by_category_.find(category); |
66 if (iterator == providers_by_category_.end()) | 68 if (iterator == providers_by_category_.end()) { |
67 return CategoryStatus::NOT_PROVIDED; | 69 return CategoryStatus::NOT_PROVIDED; |
| 70 } |
68 | 71 |
69 return iterator->second->GetCategoryStatus(category); | 72 return iterator->second->GetCategoryStatus(category); |
70 } | 73 } |
71 | 74 |
72 base::Optional<CategoryInfo> ContentSuggestionsService::GetCategoryInfo( | 75 base::Optional<CategoryInfo> ContentSuggestionsService::GetCategoryInfo( |
73 Category category) const { | 76 Category category) const { |
74 auto iterator = providers_by_category_.find(category); | 77 auto iterator = providers_by_category_.find(category); |
75 if (iterator == providers_by_category_.end()) | 78 if (iterator == providers_by_category_.end()) { |
76 return base::Optional<CategoryInfo>(); | 79 return base::Optional<CategoryInfo>(); |
| 80 } |
77 return iterator->second->GetCategoryInfo(category); | 81 return iterator->second->GetCategoryInfo(category); |
78 } | 82 } |
79 | 83 |
80 const std::vector<ContentSuggestion>& | 84 const std::vector<ContentSuggestion>& |
81 ContentSuggestionsService::GetSuggestionsForCategory(Category category) const { | 85 ContentSuggestionsService::GetSuggestionsForCategory(Category category) const { |
82 auto iterator = suggestions_by_category_.find(category); | 86 auto iterator = suggestions_by_category_.find(category); |
83 if (iterator == suggestions_by_category_.end()) | 87 if (iterator == suggestions_by_category_.end()) { |
84 return no_suggestions_; | 88 return no_suggestions_; |
| 89 } |
85 return iterator->second; | 90 return iterator->second; |
86 } | 91 } |
87 | 92 |
88 void ContentSuggestionsService::FetchSuggestionImage( | 93 void ContentSuggestionsService::FetchSuggestionImage( |
89 const ContentSuggestion::ID& suggestion_id, | 94 const ContentSuggestion::ID& suggestion_id, |
90 const ImageFetchedCallback& callback) { | 95 const ImageFetchedCallback& callback) { |
91 if (!providers_by_category_.count(suggestion_id.category())) { | 96 if (!providers_by_category_.count(suggestion_id.category())) { |
92 LOG(WARNING) << "Requested image for suggestion " << suggestion_id | 97 LOG(WARNING) << "Requested image for suggestion " << suggestion_id |
93 << " for unavailable category " << suggestion_id.category(); | 98 << " for unavailable category " << suggestion_id.category(); |
94 base::ThreadTaskRunnerHandle::Get()->PostTask( | 99 base::ThreadTaskRunnerHandle::Get()->PostTask( |
(...skipping 11 matching lines...) Expand all Loading... |
106 for (const auto& provider : providers_) { | 111 for (const auto& provider : providers_) { |
107 provider->ClearHistory(begin, end, filter); | 112 provider->ClearHistory(begin, end, filter); |
108 } | 113 } |
109 } | 114 } |
110 | 115 |
111 void ContentSuggestionsService::ClearAllCachedSuggestions() { | 116 void ContentSuggestionsService::ClearAllCachedSuggestions() { |
112 suggestions_by_category_.clear(); | 117 suggestions_by_category_.clear(); |
113 for (const auto& category_provider_pair : providers_by_category_) { | 118 for (const auto& category_provider_pair : providers_by_category_) { |
114 category_provider_pair.second->ClearCachedSuggestions( | 119 category_provider_pair.second->ClearCachedSuggestions( |
115 category_provider_pair.first); | 120 category_provider_pair.first); |
116 for (Observer& observer : observers_) | 121 for (Observer& observer : observers_) { |
117 observer.OnNewSuggestions(category_provider_pair.first); | 122 observer.OnNewSuggestions(category_provider_pair.first); |
| 123 } |
118 } | 124 } |
119 } | 125 } |
120 | 126 |
121 void ContentSuggestionsService::ClearCachedSuggestions(Category category) { | 127 void ContentSuggestionsService::ClearCachedSuggestions(Category category) { |
122 suggestions_by_category_[category].clear(); | 128 suggestions_by_category_[category].clear(); |
123 auto iterator = providers_by_category_.find(category); | 129 auto iterator = providers_by_category_.find(category); |
124 if (iterator != providers_by_category_.end()) | 130 if (iterator != providers_by_category_.end()) { |
125 iterator->second->ClearCachedSuggestions(category); | 131 iterator->second->ClearCachedSuggestions(category); |
| 132 } |
126 } | 133 } |
127 | 134 |
128 void ContentSuggestionsService::GetDismissedSuggestionsForDebugging( | 135 void ContentSuggestionsService::GetDismissedSuggestionsForDebugging( |
129 Category category, | 136 Category category, |
130 const DismissedSuggestionsCallback& callback) { | 137 const DismissedSuggestionsCallback& callback) { |
131 auto iterator = providers_by_category_.find(category); | 138 auto iterator = providers_by_category_.find(category); |
132 if (iterator != providers_by_category_.end()) | 139 if (iterator != providers_by_category_.end()) { |
133 iterator->second->GetDismissedSuggestionsForDebugging(category, callback); | 140 iterator->second->GetDismissedSuggestionsForDebugging(category, callback); |
134 else | 141 } else { |
135 callback.Run(std::vector<ContentSuggestion>()); | 142 callback.Run(std::vector<ContentSuggestion>()); |
| 143 } |
136 } | 144 } |
137 | 145 |
138 void ContentSuggestionsService::ClearDismissedSuggestionsForDebugging( | 146 void ContentSuggestionsService::ClearDismissedSuggestionsForDebugging( |
139 Category category) { | 147 Category category) { |
140 auto iterator = providers_by_category_.find(category); | 148 auto iterator = providers_by_category_.find(category); |
141 if (iterator != providers_by_category_.end()) | 149 if (iterator != providers_by_category_.end()) { |
142 iterator->second->ClearDismissedSuggestionsForDebugging(category); | 150 iterator->second->ClearDismissedSuggestionsForDebugging(category); |
| 151 } |
143 } | 152 } |
144 | 153 |
145 void ContentSuggestionsService::DismissSuggestion( | 154 void ContentSuggestionsService::DismissSuggestion( |
146 const ContentSuggestion::ID& suggestion_id) { | 155 const ContentSuggestion::ID& suggestion_id) { |
147 if (!providers_by_category_.count(suggestion_id.category())) { | 156 if (!providers_by_category_.count(suggestion_id.category())) { |
148 LOG(WARNING) << "Dismissed suggestion " << suggestion_id | 157 LOG(WARNING) << "Dismissed suggestion " << suggestion_id |
149 << " for unavailable category " << suggestion_id.category(); | 158 << " for unavailable category " << suggestion_id.category(); |
150 return; | 159 return; |
151 } | 160 } |
152 providers_by_category_[suggestion_id.category()]->DismissSuggestion( | 161 providers_by_category_[suggestion_id.category()]->DismissSuggestion( |
153 suggestion_id); | 162 suggestion_id); |
154 | 163 |
155 // Remove the suggestion locally. | 164 // Remove the suggestion locally. |
156 bool removed = RemoveSuggestionByID(suggestion_id); | 165 bool removed = RemoveSuggestionByID(suggestion_id); |
157 DCHECK(removed) << "The dismissed suggestion " << suggestion_id | 166 DCHECK(removed) << "The dismissed suggestion " << suggestion_id |
158 << " has already been removed. Providers must not call" | 167 << " has already been removed. Providers must not call" |
159 << " OnNewSuggestions in response to DismissSuggestion."; | 168 << " OnNewSuggestions in response to DismissSuggestion."; |
160 } | 169 } |
161 | 170 |
162 void ContentSuggestionsService::DismissCategory(Category category) { | 171 void ContentSuggestionsService::DismissCategory(Category category) { |
163 auto providers_it = providers_by_category_.find(category); | 172 auto providers_it = providers_by_category_.find(category); |
164 if (providers_it == providers_by_category_.end()) | 173 if (providers_it == providers_by_category_.end()) { |
165 return; | 174 return; |
| 175 } |
166 | 176 |
167 ContentSuggestionsProvider* provider = providers_it->second; | 177 ContentSuggestionsProvider* provider = providers_it->second; |
168 UnregisterCategory(category, provider); | 178 UnregisterCategory(category, provider); |
169 | 179 |
170 dismissed_providers_by_category_[category] = provider; | 180 dismissed_providers_by_category_[category] = provider; |
171 StoreDismissedCategoriesToPrefs(); | 181 StoreDismissedCategoriesToPrefs(); |
172 } | 182 } |
173 | 183 |
174 void ContentSuggestionsService::RestoreDismissedCategories() { | 184 void ContentSuggestionsService::RestoreDismissedCategories() { |
175 // Make a copy as the original will be modified during iteration. | 185 // Make a copy as the original will be modified during iteration. |
(...skipping 18 matching lines...) Expand all Loading... |
194 std::unique_ptr<ContentSuggestionsProvider> provider) { | 204 std::unique_ptr<ContentSuggestionsProvider> provider) { |
195 DCHECK(state_ == State::ENABLED); | 205 DCHECK(state_ == State::ENABLED); |
196 providers_.push_back(std::move(provider)); | 206 providers_.push_back(std::move(provider)); |
197 } | 207 } |
198 | 208 |
199 void ContentSuggestionsService::Fetch( | 209 void ContentSuggestionsService::Fetch( |
200 const Category& category, | 210 const Category& category, |
201 const std::set<std::string>& known_suggestion_ids, | 211 const std::set<std::string>& known_suggestion_ids, |
202 const FetchDoneCallback& callback) { | 212 const FetchDoneCallback& callback) { |
203 auto providers_it = providers_by_category_.find(category); | 213 auto providers_it = providers_by_category_.find(category); |
204 if (providers_it == providers_by_category_.end()) | 214 if (providers_it == providers_by_category_.end()) { |
205 return; | 215 return; |
| 216 } |
206 | 217 |
207 providers_it->second->Fetch(category, known_suggestion_ids, callback); | 218 providers_it->second->Fetch(category, known_suggestion_ids, callback); |
208 } | 219 } |
209 | 220 |
210 //////////////////////////////////////////////////////////////////////////////// | 221 //////////////////////////////////////////////////////////////////////////////// |
211 // Private methods | 222 // Private methods |
212 | 223 |
213 void ContentSuggestionsService::OnNewSuggestions( | 224 void ContentSuggestionsService::OnNewSuggestions( |
214 ContentSuggestionsProvider* provider, | 225 ContentSuggestionsProvider* provider, |
215 Category category, | 226 Category category, |
216 std::vector<ContentSuggestion> suggestions) { | 227 std::vector<ContentSuggestion> suggestions) { |
217 // Providers shouldn't call this when they're in a non-available state. | 228 // Providers shouldn't call this when they're in a non-available state. |
218 DCHECK( | 229 DCHECK( |
219 IsCategoryStatusInitOrAvailable(provider->GetCategoryStatus(category))); | 230 IsCategoryStatusInitOrAvailable(provider->GetCategoryStatus(category))); |
220 | 231 |
221 if (TryRegisterProviderForCategory(provider, category)) { | 232 if (TryRegisterProviderForCategory(provider, category)) { |
222 NotifyCategoryStatusChanged(category); | 233 NotifyCategoryStatusChanged(category); |
223 } else if (IsCategoryDismissed(category)) { | 234 } else if (IsCategoryDismissed(category)) { |
224 // The category has been registered as a dismissed one. We need to | 235 // The category has been registered as a dismissed one. We need to |
225 // check if the dismissal can be cleared now that we received new data. | 236 // check if the dismissal can be cleared now that we received new data. |
226 if (suggestions.empty()) | 237 if (suggestions.empty()) { |
227 return; | 238 return; |
| 239 } |
228 | 240 |
229 RestoreDismissedCategory(category); | 241 RestoreDismissedCategory(category); |
230 StoreDismissedCategoriesToPrefs(); | 242 StoreDismissedCategoriesToPrefs(); |
231 | 243 |
232 NotifyCategoryStatusChanged(category); | 244 NotifyCategoryStatusChanged(category); |
233 } | 245 } |
234 | 246 |
235 if (!IsCategoryStatusAvailable(provider->GetCategoryStatus(category))) { | 247 if (!IsCategoryStatusAvailable(provider->GetCategoryStatus(category))) { |
236 // A provider shouldn't send us suggestions while it's not available. | 248 // A provider shouldn't send us suggestions while it's not available. |
237 DCHECK(suggestions.empty()); | 249 DCHECK(suggestions.empty()); |
238 return; | 250 return; |
239 } | 251 } |
240 | 252 |
241 suggestions_by_category_[category] = std::move(suggestions); | 253 suggestions_by_category_[category] = std::move(suggestions); |
242 | 254 |
243 for (Observer& observer : observers_) | 255 for (Observer& observer : observers_) { |
244 observer.OnNewSuggestions(category); | 256 observer.OnNewSuggestions(category); |
| 257 } |
245 } | 258 } |
246 | 259 |
247 void ContentSuggestionsService::OnCategoryStatusChanged( | 260 void ContentSuggestionsService::OnCategoryStatusChanged( |
248 ContentSuggestionsProvider* provider, | 261 ContentSuggestionsProvider* provider, |
249 Category category, | 262 Category category, |
250 CategoryStatus new_status) { | 263 CategoryStatus new_status) { |
251 if (new_status == CategoryStatus::NOT_PROVIDED) { | 264 if (new_status == CategoryStatus::NOT_PROVIDED) { |
252 UnregisterCategory(category, provider); | 265 UnregisterCategory(category, provider); |
253 } else { | 266 } else { |
254 if (!IsCategoryStatusAvailable(new_status)) | 267 if (!IsCategoryStatusAvailable(new_status)) { |
255 suggestions_by_category_.erase(category); | 268 suggestions_by_category_.erase(category); |
| 269 } |
256 TryRegisterProviderForCategory(provider, category); | 270 TryRegisterProviderForCategory(provider, category); |
257 DCHECK_EQ(new_status, provider->GetCategoryStatus(category)); | 271 DCHECK_EQ(new_status, provider->GetCategoryStatus(category)); |
258 } | 272 } |
259 | 273 |
260 if (!IsCategoryDismissed(category)) | 274 if (!IsCategoryDismissed(category)) { |
261 NotifyCategoryStatusChanged(category); | 275 NotifyCategoryStatusChanged(category); |
| 276 } |
262 } | 277 } |
263 | 278 |
264 void ContentSuggestionsService::OnSuggestionInvalidated( | 279 void ContentSuggestionsService::OnSuggestionInvalidated( |
265 ContentSuggestionsProvider* provider, | 280 ContentSuggestionsProvider* provider, |
266 const ContentSuggestion::ID& suggestion_id) { | 281 const ContentSuggestion::ID& suggestion_id) { |
267 RemoveSuggestionByID(suggestion_id); | 282 RemoveSuggestionByID(suggestion_id); |
268 for (Observer& observer : observers_) | 283 for (Observer& observer : observers_) { |
269 observer.OnSuggestionInvalidated(suggestion_id); | 284 observer.OnSuggestionInvalidated(suggestion_id); |
| 285 } |
270 } | 286 } |
271 | 287 |
272 // history::HistoryServiceObserver implementation. | 288 // history::HistoryServiceObserver implementation. |
273 void ContentSuggestionsService::OnURLsDeleted( | 289 void ContentSuggestionsService::OnURLsDeleted( |
274 history::HistoryService* history_service, | 290 history::HistoryService* history_service, |
275 bool all_history, | 291 bool all_history, |
276 bool expired, | 292 bool expired, |
277 const history::URLRows& deleted_rows, | 293 const history::URLRows& deleted_rows, |
278 const std::set<GURL>& favicon_urls) { | 294 const std::set<GURL>& favicon_urls) { |
279 // We don't care about expired entries. | 295 // We don't care about expired entries. |
280 if (expired) | 296 if (expired) { |
281 return; | 297 return; |
| 298 } |
282 | 299 |
283 // Redirect to ClearHistory(). | 300 // Redirect to ClearHistory(). |
284 if (all_history) { | 301 if (all_history) { |
285 base::Time begin = base::Time(); | 302 base::Time begin = base::Time(); |
286 base::Time end = base::Time::Max(); | 303 base::Time end = base::Time::Max(); |
287 base::Callback<bool(const GURL& url)> filter = | 304 base::Callback<bool(const GURL& url)> filter = |
288 base::Bind([](const GURL& url) { return true; }); | 305 base::Bind([](const GURL& url) { return true; }); |
289 ClearHistory(begin, end, filter); | 306 ClearHistory(begin, end, filter); |
290 } else { | 307 } else { |
291 if (deleted_rows.empty()) | 308 if (deleted_rows.empty()) { |
292 return; | 309 return; |
| 310 } |
293 | 311 |
294 base::Time begin = deleted_rows[0].last_visit(); | 312 base::Time begin = deleted_rows[0].last_visit(); |
295 base::Time end = deleted_rows[0].last_visit(); | 313 base::Time end = deleted_rows[0].last_visit(); |
296 std::set<GURL> deleted_urls; | 314 std::set<GURL> deleted_urls; |
297 for (const history::URLRow& row : deleted_rows) { | 315 for (const history::URLRow& row : deleted_rows) { |
298 if (row.last_visit() < begin) | 316 if (row.last_visit() < begin) { |
299 begin = row.last_visit(); | 317 begin = row.last_visit(); |
300 if (row.last_visit() > end) | 318 } |
| 319 if (row.last_visit() > end) { |
301 end = row.last_visit(); | 320 end = row.last_visit(); |
| 321 } |
302 deleted_urls.insert(row.url()); | 322 deleted_urls.insert(row.url()); |
303 } | 323 } |
304 base::Callback<bool(const GURL& url)> filter = base::Bind( | 324 base::Callback<bool(const GURL& url)> filter = base::Bind( |
305 [](const std::set<GURL>& set, const GURL& url) { | 325 [](const std::set<GURL>& set, const GURL& url) { |
306 return set.count(url) != 0; | 326 return set.count(url) != 0; |
307 }, | 327 }, |
308 deleted_urls); | 328 deleted_urls); |
309 ClearHistory(begin, end, filter); | 329 ClearHistory(begin, end, filter); |
310 } | 330 } |
311 } | 331 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 | 394 |
375 bool ContentSuggestionsService::RemoveSuggestionByID( | 395 bool ContentSuggestionsService::RemoveSuggestionByID( |
376 const ContentSuggestion::ID& suggestion_id) { | 396 const ContentSuggestion::ID& suggestion_id) { |
377 std::vector<ContentSuggestion>* suggestions = | 397 std::vector<ContentSuggestion>* suggestions = |
378 &suggestions_by_category_[suggestion_id.category()]; | 398 &suggestions_by_category_[suggestion_id.category()]; |
379 auto position = | 399 auto position = |
380 std::find_if(suggestions->begin(), suggestions->end(), | 400 std::find_if(suggestions->begin(), suggestions->end(), |
381 [&suggestion_id](const ContentSuggestion& suggestion) { | 401 [&suggestion_id](const ContentSuggestion& suggestion) { |
382 return suggestion_id == suggestion.id(); | 402 return suggestion_id == suggestion.id(); |
383 }); | 403 }); |
384 if (position == suggestions->end()) | 404 if (position == suggestions->end()) { |
385 return false; | 405 return false; |
| 406 } |
386 suggestions->erase(position); | 407 suggestions->erase(position); |
387 | 408 |
388 return true; | 409 return true; |
389 } | 410 } |
390 | 411 |
391 void ContentSuggestionsService::NotifyCategoryStatusChanged(Category category) { | 412 void ContentSuggestionsService::NotifyCategoryStatusChanged(Category category) { |
392 for (Observer& observer : observers_) | 413 for (Observer& observer : observers_) { |
393 observer.OnCategoryStatusChanged(category, GetCategoryStatus(category)); | 414 observer.OnCategoryStatusChanged(category, GetCategoryStatus(category)); |
| 415 } |
394 } | 416 } |
395 | 417 |
396 void ContentSuggestionsService::SortCategories() { | 418 void ContentSuggestionsService::SortCategories() { |
397 std::sort(categories_.begin(), categories_.end(), | 419 std::sort(categories_.begin(), categories_.end(), |
398 [this](const Category& left, const Category& right) { | 420 [this](const Category& left, const Category& right) { |
399 return category_factory_.CompareCategories(left, right); | 421 return category_factory_.CompareCategories(left, right); |
400 }); | 422 }); |
401 } | 423 } |
402 | 424 |
403 bool ContentSuggestionsService::IsCategoryDismissed(Category category) const { | 425 bool ContentSuggestionsService::IsCategoryDismissed(Category category) const { |
404 return base::ContainsKey(dismissed_providers_by_category_, category); | 426 return base::ContainsKey(dismissed_providers_by_category_, category); |
405 } | 427 } |
406 | 428 |
407 void ContentSuggestionsService::RestoreDismissedCategory(Category category) { | 429 void ContentSuggestionsService::RestoreDismissedCategory(Category category) { |
408 auto dismissed_it = dismissed_providers_by_category_.find(category); | 430 auto dismissed_it = dismissed_providers_by_category_.find(category); |
409 DCHECK(base::ContainsKey(dismissed_providers_by_category_, category)); | 431 DCHECK(base::ContainsKey(dismissed_providers_by_category_, category)); |
410 | 432 |
411 // Keep the reference to the provider and remove it from the dismissed ones, | 433 // Keep the reference to the provider and remove it from the dismissed ones, |
412 // because the category registration enforces that it's not dismissed. | 434 // because the category registration enforces that it's not dismissed. |
413 ContentSuggestionsProvider* provider = dismissed_it->second; | 435 ContentSuggestionsProvider* provider = dismissed_it->second; |
414 dismissed_providers_by_category_.erase(dismissed_it); | 436 dismissed_providers_by_category_.erase(dismissed_it); |
415 | 437 |
416 if (provider) | 438 if (provider) { |
417 RegisterCategory(category, provider); | 439 RegisterCategory(category, provider); |
| 440 } |
418 } | 441 } |
419 | 442 |
420 void ContentSuggestionsService::RestoreDismissedCategoriesFromPrefs() { | 443 void ContentSuggestionsService::RestoreDismissedCategoriesFromPrefs() { |
421 // This must only be called at startup. | 444 // This must only be called at startup. |
422 DCHECK(dismissed_providers_by_category_.empty()); | 445 DCHECK(dismissed_providers_by_category_.empty()); |
423 DCHECK(providers_by_category_.empty()); | 446 DCHECK(providers_by_category_.empty()); |
424 | 447 |
425 const base::ListValue* list = | 448 const base::ListValue* list = |
426 pref_service_->GetList(prefs::kDismissedCategories); | 449 pref_service_->GetList(prefs::kDismissedCategories); |
427 for (const std::unique_ptr<base::Value>& entry : *list) { | 450 for (const std::unique_ptr<base::Value>& entry : *list) { |
(...skipping 12 matching lines...) Expand all Loading... |
440 void ContentSuggestionsService::StoreDismissedCategoriesToPrefs() { | 463 void ContentSuggestionsService::StoreDismissedCategoriesToPrefs() { |
441 base::ListValue list; | 464 base::ListValue list; |
442 for (const auto& category_provider_pair : dismissed_providers_by_category_) { | 465 for (const auto& category_provider_pair : dismissed_providers_by_category_) { |
443 list.AppendInteger(category_provider_pair.first.id()); | 466 list.AppendInteger(category_provider_pair.first.id()); |
444 } | 467 } |
445 | 468 |
446 pref_service_->Set(prefs::kDismissedCategories, list); | 469 pref_service_->Set(prefs::kDismissedCategories, list); |
447 } | 470 } |
448 | 471 |
449 } // namespace ntp_snippets | 472 } // namespace ntp_snippets |
OLD | NEW |