Chromium Code Reviews| 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 observers_.RemoveObserver(observer); | 125 observers_.RemoveObserver(observer); |
| 126 } | 126 } |
| 127 | 127 |
| 128 void ContentSuggestionsService::RegisterProvider( | 128 void ContentSuggestionsService::RegisterProvider( |
| 129 ContentSuggestionsProvider* provider) { | 129 ContentSuggestionsProvider* provider) { |
| 130 // TODO(pke): When NTPSnippetsService is purely a provider, think about | 130 // TODO(pke): When NTPSnippetsService is purely a provider, think about |
| 131 // removing this state check. | 131 // removing this state check. |
| 132 if (state_ == State::DISABLED) | 132 if (state_ == State::DISABLED) |
| 133 return; | 133 return; |
| 134 | 134 |
| 135 provider->SetObserver(this); | |
| 135 for (Category category : provider->GetProvidedCategories()) { | 136 for (Category category : provider->GetProvidedCategories()) { |
| 136 DCHECK_EQ(0ul, providers_.count(category)); | 137 DCHECK_NE(CategoryStatus::NOT_PROVIDED, |
| 137 providers_[category] = provider; | 138 provider->GetCategoryStatus(category)); |
| 138 categories_.push_back(category); | 139 EnsureCategoryRegistered(provider, category); |
| 139 if (IsCategoryStatusAvailable(provider->GetCategoryStatus(category))) { | |
| 140 suggestions_by_category_[category] = std::vector<ContentSuggestion>(); | |
| 141 } | |
| 142 NotifyCategoryStatusChanged(category); | 140 NotifyCategoryStatusChanged(category); |
| 143 } | 141 } |
| 144 std::sort(categories_.begin(), categories_.end(), | |
| 145 [this](const Category& left, const Category& right) { | |
| 146 return category_factory_.CompareCategories(left, right); | |
| 147 }); | |
| 148 provider->SetObserver(this); | |
| 149 } | 142 } |
| 150 | 143 |
| 151 //////////////////////////////////////////////////////////////////////////////// | 144 //////////////////////////////////////////////////////////////////////////////// |
| 152 // Private methods | 145 // Private methods |
| 153 | 146 |
| 154 void ContentSuggestionsService::OnNewSuggestions( | 147 void ContentSuggestionsService::OnNewSuggestions( |
| 155 Category changed_category, | 148 ContentSuggestionsProvider* provider, |
| 149 Category category, | |
| 156 std::vector<ContentSuggestion> new_suggestions) { | 150 std::vector<ContentSuggestion> new_suggestions) { |
| 157 DCHECK(IsCategoryRegistered(changed_category)); | 151 if (EnsureCategoryRegistered(provider, category)) { |
| 152 NotifyCategoryStatusChanged(category); | |
|
Marc Treib
2016/08/01 14:23:37
Hm, you call this before the new suggestions are a
Philipp Keck
2016/08/01 14:59:03
Related question:
If a category is registered whi
Marc Treib
2016/08/01 15:17:47
This way; the other way around is even weirder (th
Philipp Keck
2016/08/01 15:58:12
I'm not opposed to that, we could also get rid of
Marc Treib
2016/08/01 16:28:51
I thought it should only be in AVAILABLE_LOADING i
Philipp Keck
2016/08/01 17:04:58
Acknowledged.
| |
| 153 } | |
| 158 | 154 |
| 159 for (const ContentSuggestion& suggestion : | 155 for (const ContentSuggestion& suggestion : |
| 160 suggestions_by_category_[changed_category]) { | 156 suggestions_by_category_[category]) { |
| 161 id_category_map_.erase(suggestion.id()); | 157 id_category_map_.erase(suggestion.id()); |
| 162 } | 158 } |
| 163 | 159 |
| 164 for (const ContentSuggestion& suggestion : new_suggestions) { | 160 for (const ContentSuggestion& suggestion : new_suggestions) { |
| 165 id_category_map_.insert(std::make_pair(suggestion.id(), changed_category)); | 161 id_category_map_.insert(std::make_pair(suggestion.id(), category)); |
| 166 } | 162 } |
| 167 | 163 |
| 168 suggestions_by_category_[changed_category] = std::move(new_suggestions); | 164 suggestions_by_category_[category] = std::move(new_suggestions); |
| 169 | 165 |
| 170 FOR_EACH_OBSERVER(Observer, observers_, OnNewSuggestions()); | 166 FOR_EACH_OBSERVER(Observer, observers_, OnNewSuggestions()); |
| 171 } | 167 } |
| 172 | 168 |
| 173 void ContentSuggestionsService::OnCategoryStatusChanged( | 169 void ContentSuggestionsService::OnCategoryStatusChanged( |
| 174 Category changed_category, | 170 ContentSuggestionsProvider* provider, |
| 171 Category category, | |
| 175 CategoryStatus new_status) { | 172 CategoryStatus new_status) { |
| 176 if (!IsCategoryStatusAvailable(new_status)) { | 173 if (!IsCategoryStatusAvailable(new_status)) { |
| 177 for (const ContentSuggestion& suggestion : | 174 for (const ContentSuggestion& suggestion : |
| 178 suggestions_by_category_[changed_category]) { | 175 suggestions_by_category_[category]) { |
| 179 id_category_map_.erase(suggestion.id()); | 176 id_category_map_.erase(suggestion.id()); |
| 180 } | 177 } |
| 181 suggestions_by_category_.erase(changed_category); | 178 suggestions_by_category_.erase(category); |
| 182 } | 179 } |
| 183 NotifyCategoryStatusChanged(changed_category); | 180 if (new_status == CategoryStatus::NOT_PROVIDED) { |
| 181 auto providers_entry = providers_.find(category); | |
|
tschumann
2016/08/01 14:21:17
nit: the usual naming would be 'providers_it'.
Philipp Keck
2016/08/01 14:59:04
Done.
| |
| 182 DCHECK(providers_entry != providers_.end()); | |
| 183 DCHECK_EQ(provider, providers_entry->second); | |
| 184 providers_.erase(providers_entry); | |
|
Marc Treib
2016/08/01 14:23:37
Hm, maybe providers_ should be renamed to provider
Philipp Keck
2016/08/01 14:59:04
Done.
| |
| 185 categories_.erase( | |
| 186 std::find(categories_.begin(), categories_.end(), category)); | |
| 187 } else { | |
| 188 EnsureCategoryRegistered(provider, category); | |
| 189 DCHECK_EQ(new_status, provider->GetCategoryStatus(category)); | |
| 190 } | |
| 191 NotifyCategoryStatusChanged(category); | |
| 184 } | 192 } |
| 185 | 193 |
| 186 void ContentSuggestionsService::OnProviderShutdown( | 194 void ContentSuggestionsService::OnProviderShutdown( |
| 187 ContentSuggestionsProvider* provider) { | 195 ContentSuggestionsProvider* provider) { |
| 188 for (Category category : provider->GetProvidedCategories()) { | 196 for (Category category : provider->GetProvidedCategories()) { |
| 189 auto iterator = std::find(categories_.begin(), categories_.end(), category); | 197 auto iterator = std::find(categories_.begin(), categories_.end(), category); |
| 190 DCHECK(iterator != categories_.end()); | 198 DCHECK(iterator != categories_.end()); |
| 191 categories_.erase(iterator); | 199 categories_.erase(iterator); |
| 192 for (const ContentSuggestion& suggestion : | 200 for (const ContentSuggestion& suggestion : |
| 193 suggestions_by_category_[category]) { | 201 suggestions_by_category_[category]) { |
| 194 id_category_map_.erase(suggestion.id()); | 202 id_category_map_.erase(suggestion.id()); |
| 195 } | 203 } |
| 196 suggestions_by_category_.erase(category); | 204 suggestions_by_category_.erase(category); |
| 197 providers_.erase(category); | 205 providers_.erase(category); |
| 198 NotifyCategoryStatusChanged(category); | 206 NotifyCategoryStatusChanged(category); |
| 199 } | 207 } |
| 200 } | 208 } |
| 201 | 209 |
| 202 bool ContentSuggestionsService::IsCategoryRegistered(Category category) const { | 210 bool ContentSuggestionsService::EnsureCategoryRegistered( |
|
tschumann
2016/08/01 14:21:17
nit: it feels weird for EnsureCategoryRegistered t
Philipp Keck
2016/08/01 14:59:03
Marc suggested EnsureCategoryIsRegistered.
The lo
Marc Treib
2016/08/01 15:17:47
I'd prefer if it either always or never notified.
Philipp Keck
2016/08/01 15:58:12
How about "RegisterCategory[IfRequired/IfNecessary
Marc Treib
2016/08/01 16:28:51
Sure, that works too.
Philipp Keck
2016/08/01 17:04:58
Done.
| |
| 203 return std::find(categories_.begin(), categories_.end(), category) != | 211 ContentSuggestionsProvider* provider, |
| 204 categories_.end(); | 212 Category category) { |
| 213 auto entry = providers_.find(category); | |
| 214 if (entry != providers_.end()) { | |
| 215 DCHECK_EQ(entry->second, provider); | |
| 216 return false; | |
| 217 } | |
| 218 | |
| 219 providers_[category] = provider; | |
| 220 categories_.push_back(category); | |
| 221 std::sort(categories_.begin(), categories_.end(), | |
| 222 [this](const Category& left, const Category& right) { | |
| 223 return category_factory_.CompareCategories(left, right); | |
| 224 }); | |
| 225 if (IsCategoryStatusAvailable(provider->GetCategoryStatus(category))) { | |
| 226 suggestions_by_category_[category] = std::vector<ContentSuggestion>(); | |
| 227 } | |
| 228 return true; | |
| 205 } | 229 } |
| 206 | 230 |
| 207 void ContentSuggestionsService::NotifyCategoryStatusChanged(Category category) { | 231 void ContentSuggestionsService::NotifyCategoryStatusChanged(Category category) { |
| 208 FOR_EACH_OBSERVER( | 232 FOR_EACH_OBSERVER( |
| 209 Observer, observers_, | 233 Observer, observers_, |
| 210 OnCategoryStatusChanged(category, GetCategoryStatus(category))); | 234 OnCategoryStatusChanged(category, GetCategoryStatus(category))); |
| 211 } | 235 } |
| 212 | 236 |
| 213 } // namespace ntp_snippets | 237 } // namespace ntp_snippets |
| OLD | NEW |