OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/remote/remote_suggestions_provider.h" | 5 #include "components/ntp_snippets/remote/remote_suggestions_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "base/time/default_tick_clock.h" | 22 #include "base/time/default_tick_clock.h" |
23 #include "base/time/time.h" | 23 #include "base/time/time.h" |
24 #include "base/values.h" | 24 #include "base/values.h" |
25 #include "components/data_use_measurement/core/data_use_user_data.h" | 25 #include "components/data_use_measurement/core/data_use_user_data.h" |
26 #include "components/history/core/browser/history_service.h" | 26 #include "components/history/core/browser/history_service.h" |
27 #include "components/image_fetcher/image_decoder.h" | 27 #include "components/image_fetcher/image_decoder.h" |
28 #include "components/image_fetcher/image_fetcher.h" | 28 #include "components/image_fetcher/image_fetcher.h" |
29 #include "components/ntp_snippets/features.h" | 29 #include "components/ntp_snippets/features.h" |
30 #include "components/ntp_snippets/pref_names.h" | 30 #include "components/ntp_snippets/pref_names.h" |
31 #include "components/ntp_snippets/remote/remote_suggestions_database.h" | 31 #include "components/ntp_snippets/remote/remote_suggestions_database.h" |
32 #include "components/ntp_snippets/section_rankers/section_ranker.h" | |
32 #include "components/ntp_snippets/switches.h" | 33 #include "components/ntp_snippets/switches.h" |
33 #include "components/ntp_snippets/user_classifier.h" | 34 #include "components/ntp_snippets/user_classifier.h" |
34 #include "components/prefs/pref_registry_simple.h" | 35 #include "components/prefs/pref_registry_simple.h" |
35 #include "components/prefs/pref_service.h" | 36 #include "components/prefs/pref_service.h" |
36 #include "components/variations/variations_associated_data.h" | 37 #include "components/variations/variations_associated_data.h" |
37 #include "grit/components_strings.h" | 38 #include "grit/components_strings.h" |
38 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
39 #include "ui/gfx/image/image.h" | 40 #include "ui/gfx/image/image.h" |
40 | 41 |
41 namespace ntp_snippets { | 42 namespace ntp_snippets { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 if (callback.is_null()) { | 217 if (callback.is_null()) { |
217 return; | 218 return; |
218 } | 219 } |
219 callback.Run(status, std::vector<ContentSuggestion>()); | 220 callback.Run(status, std::vector<ContentSuggestion>()); |
220 } | 221 } |
221 | 222 |
222 } // namespace | 223 } // namespace |
223 | 224 |
224 RemoteSuggestionsProvider::RemoteSuggestionsProvider( | 225 RemoteSuggestionsProvider::RemoteSuggestionsProvider( |
225 Observer* observer, | 226 Observer* observer, |
226 CategoryFactory* category_factory, | |
227 PrefService* pref_service, | 227 PrefService* pref_service, |
228 const std::string& application_language_code, | 228 const std::string& application_language_code, |
229 SectionRanker* section_ranker, | |
229 const UserClassifier* user_classifier, | 230 const UserClassifier* user_classifier, |
230 NTPSnippetsScheduler* scheduler, | 231 NTPSnippetsScheduler* scheduler, |
231 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, | 232 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, |
232 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, | 233 std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, |
233 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder, | 234 std::unique_ptr<image_fetcher::ImageDecoder> image_decoder, |
234 std::unique_ptr<RemoteSuggestionsDatabase> database, | 235 std::unique_ptr<RemoteSuggestionsDatabase> database, |
235 std::unique_ptr<RemoteSuggestionsStatusService> status_service) | 236 std::unique_ptr<RemoteSuggestionsStatusService> status_service) |
236 : ContentSuggestionsProvider(observer, category_factory), | 237 : ContentSuggestionsProvider(observer), |
237 state_(State::NOT_INITED), | 238 state_(State::NOT_INITED), |
238 pref_service_(pref_service), | 239 pref_service_(pref_service), |
239 articles_category_( | 240 articles_category_( |
240 category_factory->FromKnownCategory(KnownCategories::ARTICLES)), | 241 Category::FromKnownCategory(KnownCategories::ARTICLES)), |
241 application_language_code_(application_language_code), | 242 application_language_code_(application_language_code), |
243 section_ranker_(section_ranker), | |
242 user_classifier_(user_classifier), | 244 user_classifier_(user_classifier), |
243 scheduler_(scheduler), | 245 scheduler_(scheduler), |
244 snippets_fetcher_(std::move(snippets_fetcher)), | 246 snippets_fetcher_(std::move(snippets_fetcher)), |
245 image_fetcher_(std::move(image_fetcher)), | 247 image_fetcher_(std::move(image_fetcher)), |
246 image_decoder_(std::move(image_decoder)), | 248 image_decoder_(std::move(image_decoder)), |
247 database_(std::move(database)), | 249 database_(std::move(database)), |
248 status_service_(std::move(status_service)), | 250 status_service_(std::move(status_service)), |
249 fetch_when_ready_(false), | 251 fetch_when_ready_(false), |
250 nuke_when_initialized_(false), | 252 nuke_when_initialized_(false), |
251 thumbnail_requests_throttler_( | 253 thumbnail_requests_throttler_( |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 DCHECK(base::ContainsKey(category_contents_, articles_category_)); | 592 DCHECK(base::ContainsKey(category_contents_, articles_category_)); |
591 | 593 |
592 base::TimeDelta database_load_time = | 594 base::TimeDelta database_load_time = |
593 base::TimeTicks::Now() - database_load_start_; | 595 base::TimeTicks::Now() - database_load_start_; |
594 UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Snippets.DatabaseLoadTime", | 596 UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Snippets.DatabaseLoadTime", |
595 database_load_time); | 597 database_load_time); |
596 | 598 |
597 NTPSnippet::PtrVector to_delete; | 599 NTPSnippet::PtrVector to_delete; |
598 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { | 600 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { |
599 Category snippet_category = | 601 Category snippet_category = |
600 category_factory()->FromRemoteCategory(snippet->remote_category_id()); | 602 Category::FromRemoteCategory(snippet->remote_category_id()); |
603 // The category is added to the ranker to enforce the order among remote | |
604 // categories. | |
605 section_ranker_->AppendCategoryIfNecessary(snippet_category); | |
Marc Treib
2016/12/13 12:22:42
Hm. This is one downside of the new design: Before
vitaliii
2016/12/14 08:59:38
Currently all non-registered categories are in the
Marc Treib
2016/12/14 10:24:30
Should it be some kind of error if someone tries t
tschumann
2016/12/15 13:05:20
We need to clearly handle the cases where a catego
vitaliii
2016/12/15 15:30:12
There are 2 places actually (the database does not
vitaliii
2016/12/15 15:30:12
Done.
I do not understand why you are concerned a
tschumann
2016/12/15 18:23:13
Well, but when we start-up and load the categories
vitaliii
2016/12/16 08:15:43
Of course. We do this already in RemoteSuggestions
| |
601 auto content_it = category_contents_.find(snippet_category); | 606 auto content_it = category_contents_.find(snippet_category); |
602 // We should already know about the category. | 607 // We should already know about the category. |
603 if (content_it == category_contents_.end()) { | 608 if (content_it == category_contents_.end()) { |
604 DLOG(WARNING) << "Loaded a suggestion for unknown category " | 609 DLOG(WARNING) << "Loaded a suggestion for unknown category " |
605 << snippet_category << " from the DB; deleting"; | 610 << snippet_category << " from the DB; deleting"; |
606 to_delete.emplace_back(std::move(snippet)); | 611 to_delete.emplace_back(std::move(snippet)); |
607 continue; | 612 continue; |
608 } | 613 } |
609 CategoryContent* content = &content_it->second; | 614 CategoryContent* content = &content_it->second; |
610 if (snippet->is_dismissed()) { | 615 if (snippet->is_dismissed()) { |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1284 &included_in_last_server_response)) { | 1289 &included_in_last_server_response)) { |
1285 DLOG(WARNING) << "Invalid category pref value, missing '" | 1290 DLOG(WARNING) << "Invalid category pref value, missing '" |
1286 << kCategoryContentProvidedByServer << "': " << *entry; | 1291 << kCategoryContentProvidedByServer << "': " << *entry; |
1287 continue; | 1292 continue; |
1288 } | 1293 } |
1289 bool allow_fetching_more_results = false; | 1294 bool allow_fetching_more_results = false; |
1290 // This wasn't always around, so it's okay if it's missing. | 1295 // This wasn't always around, so it's okay if it's missing. |
1291 dict->GetBoolean(kCategoryContentAllowFetchingMore, | 1296 dict->GetBoolean(kCategoryContentAllowFetchingMore, |
1292 &allow_fetching_more_results); | 1297 &allow_fetching_more_results); |
1293 | 1298 |
1294 Category category = category_factory()->FromIDValue(id); | 1299 Category category = Category::FromIDValue(id); |
1300 // The ranker may not persist the order of remote categories. | |
1301 section_ranker_->AppendCategoryIfNecessary(category); | |
1295 // TODO(tschumann): The following has a bad smell that category | 1302 // TODO(tschumann): The following has a bad smell that category |
1296 // serialization / deserialization should not be done inside this | 1303 // serialization / deserialization should not be done inside this |
1297 // class. We should move that into a central place that also knows how to | 1304 // class. We should move that into a central place that also knows how to |
1298 // parse data we received from remote backends. | 1305 // parse data we received from remote backends. |
1299 CategoryInfo info = | 1306 CategoryInfo info = |
1300 category == articles_category_ | 1307 category == articles_category_ |
1301 ? BuildArticleCategoryInfo(title) | 1308 ? BuildArticleCategoryInfo(title) |
1302 : BuildRemoteCategoryInfo(title, allow_fetching_more_results); | 1309 : BuildRemoteCategoryInfo(title, allow_fetching_more_results); |
1303 CategoryContent* content = UpdateCategoryInfo(category, info); | 1310 CategoryContent* content = UpdateCategoryInfo(category, info); |
1304 content->included_in_last_server_response = | 1311 content->included_in_last_server_response = |
1305 included_in_last_server_response; | 1312 included_in_last_server_response; |
1306 } | 1313 } |
1307 } | 1314 } |
1308 | 1315 |
1309 void RemoteSuggestionsProvider::StoreCategoriesToPrefs() { | 1316 void RemoteSuggestionsProvider::StoreCategoriesToPrefs() { |
1310 // Collect all the CategoryContents. | 1317 // Collect all the CategoryContents. |
1311 std::vector<std::pair<Category, const CategoryContent*>> to_store; | 1318 std::vector<std::pair<Category, const CategoryContent*>> to_store; |
1312 for (const auto& entry : category_contents_) { | 1319 for (const auto& entry : category_contents_) { |
1313 to_store.emplace_back(entry.first, &entry.second); | 1320 to_store.emplace_back(entry.first, &entry.second); |
1314 } | 1321 } |
1315 // Sort them into the proper category order. | 1322 // The ranker may not persist the order, thus, it is stored by the provider. |
Marc Treib
2016/12/13 12:22:42
Hm. Makes sense, but this is quite subtle. Do we h
vitaliii
2016/12/14 08:59:38
Done.
We did not have a test for this (actually,
Marc Treib
2016/12/14 10:24:30
What exactly do you think didn't work before?
vitaliii
2016/12/15 15:30:12
I thought that remote categories were not register
tschumann
2016/12/15 18:23:13
another reason to consolidate that logic in a more
vitaliii
2016/12/16 08:15:43
Acknowledged.
| |
1316 std::sort(to_store.begin(), to_store.end(), | 1323 std::sort(to_store.begin(), to_store.end(), |
1317 [this](const std::pair<Category, const CategoryContent*>& left, | 1324 [this](const std::pair<Category, const CategoryContent*>& left, |
1318 const std::pair<Category, const CategoryContent*>& right) { | 1325 const std::pair<Category, const CategoryContent*>& right) { |
1319 return category_factory()->CompareCategories(left.first, | 1326 return section_ranker_->Compare(left.first, right.first); |
1320 right.first); | |
1321 }); | 1327 }); |
1322 // Convert the relevant info into a base::ListValue for storage. | 1328 // Convert the relevant info into a base::ListValue for storage. |
1323 base::ListValue list; | 1329 base::ListValue list; |
1324 for (const auto& entry : to_store) { | 1330 for (const auto& entry : to_store) { |
1325 const Category& category = entry.first; | 1331 const Category& category = entry.first; |
1326 const CategoryContent& content = *entry.second; | 1332 const CategoryContent& content = *entry.second; |
1327 auto dict = base::MakeUnique<base::DictionaryValue>(); | 1333 auto dict = base::MakeUnique<base::DictionaryValue>(); |
1328 dict->SetInteger(kCategoryContentId, category.id()); | 1334 dict->SetInteger(kCategoryContentId, category.id()); |
1329 // TODO(tschumann): Persist other properties of the CategoryInfo. | 1335 // TODO(tschumann): Persist other properties of the CategoryInfo. |
1330 dict->SetString(kCategoryContentTitle, content.info.title()); | 1336 dict->SetString(kCategoryContentTitle, content.info.title()); |
(...skipping 14 matching lines...) Expand all Loading... | |
1345 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) = | 1351 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) = |
1346 default; | 1352 default; |
1347 | 1353 |
1348 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default; | 1354 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default; |
1349 | 1355 |
1350 RemoteSuggestionsProvider::CategoryContent& | 1356 RemoteSuggestionsProvider::CategoryContent& |
1351 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) = | 1357 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) = |
1352 default; | 1358 default; |
1353 | 1359 |
1354 } // namespace ntp_snippets | 1360 } // namespace ntp_snippets |
OLD | NEW |