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 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 } | 128 } |
129 Category category = id_category_map_.at(suggestion_id); | 129 Category category = id_category_map_.at(suggestion_id); |
130 if (!providers_by_category_.count(category)) { | 130 if (!providers_by_category_.count(category)) { |
131 LOG(WARNING) << "Dismissed suggestion " << suggestion_id | 131 LOG(WARNING) << "Dismissed suggestion " << suggestion_id |
132 << " for unavailable category " << category; | 132 << " for unavailable category " << category; |
133 return; | 133 return; |
134 } | 134 } |
135 providers_by_category_[category]->DismissSuggestion(suggestion_id); | 135 providers_by_category_[category]->DismissSuggestion(suggestion_id); |
136 | 136 |
137 // Remove the suggestion locally. | 137 // Remove the suggestion locally. |
138 id_category_map_.erase(suggestion_id); | 138 bool removed = RemoveSuggestionByID(category, suggestion_id); |
139 std::vector<ContentSuggestion>* suggestions = | 139 DCHECK(removed) << "The dismissed suggestion " << suggestion_id |
140 &suggestions_by_category_[category]; | 140 << " has already been removed. Providers must not call" |
141 auto position = | 141 << " OnNewSuggestions in response to DismissSuggestion."; |
142 std::find_if(suggestions->begin(), suggestions->end(), | |
143 [&suggestion_id](const ContentSuggestion& suggestion) { | |
144 return suggestion_id == suggestion.id(); | |
145 }); | |
146 DCHECK(position != suggestions->end()) | |
147 << "The dismissed suggestion " << suggestion_id | |
148 << " has already been removed. Providers must not call OnNewSuggestions" | |
149 " in response to DismissSuggestion."; | |
150 suggestions->erase(position); | |
151 } | 142 } |
152 | 143 |
153 void ContentSuggestionsService::AddObserver(Observer* observer) { | 144 void ContentSuggestionsService::AddObserver(Observer* observer) { |
154 observers_.AddObserver(observer); | 145 observers_.AddObserver(observer); |
155 } | 146 } |
156 | 147 |
157 void ContentSuggestionsService::RemoveObserver(Observer* observer) { | 148 void ContentSuggestionsService::RemoveObserver(Observer* observer) { |
158 observers_.RemoveObserver(observer); | 149 observers_.RemoveObserver(observer); |
159 } | 150 } |
160 | 151 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 providers_by_category_.erase(providers_it); | 205 providers_by_category_.erase(providers_it); |
215 categories_.erase( | 206 categories_.erase( |
216 std::find(categories_.begin(), categories_.end(), category)); | 207 std::find(categories_.begin(), categories_.end(), category)); |
217 } else { | 208 } else { |
218 RegisterCategoryIfRequired(provider, category); | 209 RegisterCategoryIfRequired(provider, category); |
219 DCHECK_EQ(new_status, provider->GetCategoryStatus(category)); | 210 DCHECK_EQ(new_status, provider->GetCategoryStatus(category)); |
220 } | 211 } |
221 NotifyCategoryStatusChanged(category); | 212 NotifyCategoryStatusChanged(category); |
222 } | 213 } |
223 | 214 |
| 215 void ContentSuggestionsService::OnSuggestionInvalidated( |
| 216 ContentSuggestionsProvider* provider, |
| 217 Category category, |
| 218 const std::string& suggestion_id) { |
| 219 RemoveSuggestionByID(category, suggestion_id); |
| 220 FOR_EACH_OBSERVER(Observer, observers_, |
| 221 OnSuggestionInvalidated(category, suggestion_id)); |
| 222 } |
| 223 |
224 bool ContentSuggestionsService::RegisterCategoryIfRequired( | 224 bool ContentSuggestionsService::RegisterCategoryIfRequired( |
225 ContentSuggestionsProvider* provider, | 225 ContentSuggestionsProvider* provider, |
226 Category category) { | 226 Category category) { |
227 auto it = providers_by_category_.find(category); | 227 auto it = providers_by_category_.find(category); |
228 if (it != providers_by_category_.end()) { | 228 if (it != providers_by_category_.end()) { |
229 DCHECK_EQ(it->second, provider); | 229 DCHECK_EQ(it->second, provider); |
230 return false; | 230 return false; |
231 } | 231 } |
232 | 232 |
233 providers_by_category_[category] = provider; | 233 providers_by_category_[category] = provider; |
234 categories_.push_back(category); | 234 categories_.push_back(category); |
235 std::sort(categories_.begin(), categories_.end(), | 235 std::sort(categories_.begin(), categories_.end(), |
236 [this](const Category& left, const Category& right) { | 236 [this](const Category& left, const Category& right) { |
237 return category_factory_.CompareCategories(left, right); | 237 return category_factory_.CompareCategories(left, right); |
238 }); | 238 }); |
239 if (IsCategoryStatusAvailable(provider->GetCategoryStatus(category))) { | 239 if (IsCategoryStatusAvailable(provider->GetCategoryStatus(category))) { |
240 suggestions_by_category_.insert( | 240 suggestions_by_category_.insert( |
241 std::make_pair(category, std::vector<ContentSuggestion>())); | 241 std::make_pair(category, std::vector<ContentSuggestion>())); |
242 } | 242 } |
243 return true; | 243 return true; |
244 } | 244 } |
245 | 245 |
| 246 bool ContentSuggestionsService::RemoveSuggestionByID( |
| 247 Category category, |
| 248 const std::string& suggestion_id) { |
| 249 id_category_map_.erase(suggestion_id); |
| 250 std::vector<ContentSuggestion>* suggestions = |
| 251 &suggestions_by_category_[category]; |
| 252 auto position = |
| 253 std::find_if(suggestions->begin(), suggestions->end(), |
| 254 [&suggestion_id](const ContentSuggestion& suggestion) { |
| 255 return suggestion_id == suggestion.id(); |
| 256 }); |
| 257 if (position == suggestions->end()) |
| 258 return false; |
| 259 suggestions->erase(position); |
| 260 return true; |
| 261 } |
| 262 |
246 void ContentSuggestionsService::NotifyCategoryStatusChanged(Category category) { | 263 void ContentSuggestionsService::NotifyCategoryStatusChanged(Category category) { |
247 FOR_EACH_OBSERVER( | 264 FOR_EACH_OBSERVER( |
248 Observer, observers_, | 265 Observer, observers_, |
249 OnCategoryStatusChanged(category, GetCategoryStatus(category))); | 266 OnCategoryStatusChanged(category, GetCategoryStatus(category))); |
250 } | 267 } |
251 | 268 |
252 } // namespace ntp_snippets | 269 } // namespace ntp_snippets |
OLD | NEW |