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

Side by Side Diff: components/ntp_snippets/content_suggestions_service.cc

Issue 2194203002: Make ContentSuggestionsService recognize new/removed categories (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@renaming
Patch Set: Put the status-change notification back in RegisterProvider() Created 4 years, 4 months 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 unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698