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

Side by Side Diff: components/ntp_snippets/remote/remote_suggestions_provider.cc

Issue 2520853002: [NTP] Cleanup: add brackets in components/ntp_snippets. [2/2] (Closed)
Patch Set: "else if". Created 4 years 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 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 value_hours = kDefaultFetchingIntervalActiveSuggestionsConsumer[index]; 94 value_hours = kDefaultFetchingIntervalActiveSuggestionsConsumer[index];
95 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index]; 95 param_name = kFetchingIntervalParamNameActiveSuggestionsConsumer[index];
96 break; 96 break;
97 } 97 }
98 98
99 // The default value can be overridden by a variation parameter. 99 // The default value can be overridden by a variation parameter.
100 std::string param_value_str = variations::GetVariationParamValueByFeature( 100 std::string param_value_str = variations::GetVariationParamValueByFeature(
101 ntp_snippets::kArticleSuggestionsFeature, param_name); 101 ntp_snippets::kArticleSuggestionsFeature, param_name);
102 if (!param_value_str.empty()) { 102 if (!param_value_str.empty()) {
103 double param_value_hours = 0.0; 103 double param_value_hours = 0.0;
104 if (base::StringToDouble(param_value_str, &param_value_hours)) 104 if (base::StringToDouble(param_value_str, &param_value_hours)) {
105 value_hours = param_value_hours; 105 value_hours = param_value_hours;
106 else 106 } else {
107 LOG(WARNING) << "Invalid value for variation parameter " << param_name; 107 LOG(WARNING) << "Invalid value for variation parameter " << param_name;
108 }
108 } 109 }
109 110
110 return base::TimeDelta::FromSecondsD(value_hours * 3600.0); 111 return base::TimeDelta::FromSecondsD(value_hours * 3600.0);
111 } 112 }
112 113
113 std::unique_ptr<std::vector<std::string>> GetSnippetIDVector( 114 std::unique_ptr<std::vector<std::string>> GetSnippetIDVector(
114 const NTPSnippet::PtrVector& snippets) { 115 const NTPSnippet::PtrVector& snippets) {
115 auto result = base::MakeUnique<std::vector<std::string>>(); 116 auto result = base::MakeUnique<std::vector<std::string>>();
116 for (const auto& snippet : snippets) { 117 for (const auto& snippet : snippets) {
117 result->push_back(snippet->id()); 118 result->push_back(snippet->id());
118 } 119 }
119 return result; 120 return result;
120 } 121 }
121 122
122 bool HasIntersection(const std::vector<std::string>& a, 123 bool HasIntersection(const std::vector<std::string>& a,
123 const std::set<std::string>& b) { 124 const std::set<std::string>& b) {
124 for (const std::string& item : a) { 125 for (const std::string& item : a) {
125 if (base::ContainsValue(b, item)) 126 if (base::ContainsValue(b, item)) {
126 return true; 127 return true;
128 }
127 } 129 }
128 return false; 130 return false;
129 } 131 }
130 132
131 void EraseByPrimaryID(NTPSnippet::PtrVector* snippets, 133 void EraseByPrimaryID(NTPSnippet::PtrVector* snippets,
132 const std::vector<std::string>& ids) { 134 const std::vector<std::string>& ids) {
133 std::set<std::string> ids_lookup(ids.begin(), ids.end()); 135 std::set<std::string> ids_lookup(ids.begin(), ids.end());
134 snippets->erase( 136 snippets->erase(
135 std::remove_if(snippets->begin(), snippets->end(), 137 std::remove_if(snippets->begin(), snippets->end(),
136 [&ids_lookup](const std::unique_ptr<NTPSnippet>& snippet) { 138 [&ids_lookup](const std::unique_ptr<NTPSnippet>& snippet) {
(...skipping 21 matching lines...) Expand all
158 void RemoveNullPointers(NTPSnippet::PtrVector* snippets) { 160 void RemoveNullPointers(NTPSnippet::PtrVector* snippets) {
159 snippets->erase( 161 snippets->erase(
160 std::remove_if( 162 std::remove_if(
161 snippets->begin(), snippets->end(), 163 snippets->begin(), snippets->end(),
162 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }), 164 [](const std::unique_ptr<NTPSnippet>& snippet) { return !snippet; }),
163 snippets->end()); 165 snippets->end());
164 } 166 }
165 167
166 void AssignExpiryAndPublishDates(NTPSnippet::PtrVector* snippets) { 168 void AssignExpiryAndPublishDates(NTPSnippet::PtrVector* snippets) {
167 for (std::unique_ptr<NTPSnippet>& snippet : *snippets) { 169 for (std::unique_ptr<NTPSnippet>& snippet : *snippets) {
168 if (snippet->publish_date().is_null()) 170 if (snippet->publish_date().is_null()) {
169 snippet->set_publish_date(base::Time::Now()); 171 snippet->set_publish_date(base::Time::Now());
172 }
170 if (snippet->expiry_date().is_null()) { 173 if (snippet->expiry_date().is_null()) {
171 snippet->set_expiry_date( 174 snippet->set_expiry_date(
172 snippet->publish_date() + 175 snippet->publish_date() +
173 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins)); 176 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins));
174 } 177 }
175 } 178 }
176 } 179 }
177 180
178 void RemoveIncompleteSnippets(NTPSnippet::PtrVector* snippets) { 181 void RemoveIncompleteSnippets(NTPSnippet::PtrVector* snippets) {
179 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 182 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
(...skipping 20 matching lines...) Expand all
200 203
201 std::vector<ContentSuggestion> ConvertToContentSuggestions( 204 std::vector<ContentSuggestion> ConvertToContentSuggestions(
202 Category category, 205 Category category,
203 const NTPSnippet::PtrVector& snippets) { 206 const NTPSnippet::PtrVector& snippets) {
204 std::vector<ContentSuggestion> result; 207 std::vector<ContentSuggestion> result;
205 for (const std::unique_ptr<NTPSnippet>& snippet : snippets) { 208 for (const std::unique_ptr<NTPSnippet>& snippet : snippets) {
206 // TODO(sfiera): if a snippet is not going to be displayed, move it 209 // TODO(sfiera): if a snippet is not going to be displayed, move it
207 // directly to content.dismissed on fetch. Otherwise, we might prune 210 // directly to content.dismissed on fetch. Otherwise, we might prune
208 // other snippets to get down to kMaxSnippetCount, only to hide one of the 211 // other snippets to get down to kMaxSnippetCount, only to hide one of the
209 // incomplete ones we kept. 212 // incomplete ones we kept.
210 if (!snippet->is_complete()) 213 if (!snippet->is_complete()) {
211 continue; 214 continue;
215 }
212 ContentSuggestion suggestion(category, snippet->id(), 216 ContentSuggestion suggestion(category, snippet->id(),
213 snippet->best_source().url); 217 snippet->best_source().url);
214 suggestion.set_amp_url(snippet->best_source().amp_url); 218 suggestion.set_amp_url(snippet->best_source().amp_url);
215 suggestion.set_title(base::UTF8ToUTF16(snippet->title())); 219 suggestion.set_title(base::UTF8ToUTF16(snippet->title()));
216 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet())); 220 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet->snippet()));
217 suggestion.set_publish_date(snippet->publish_date()); 221 suggestion.set_publish_date(snippet->publish_date());
218 suggestion.set_publisher_name( 222 suggestion.set_publisher_name(
219 base::UTF8ToUTF16(snippet->best_source().publisher_name)); 223 base::UTF8ToUTF16(snippet->best_source().publisher_name));
220 suggestion.set_score(snippet->score()); 224 suggestion.set_score(snippet->score());
221 result.emplace_back(std::move(suggestion)); 225 result.emplace_back(std::move(suggestion));
222 } 226 }
223 return result; 227 return result;
224 } 228 }
225 229
226 void CallWithEmptyResults(FetchDoneCallback callback, Status status) { 230 void CallWithEmptyResults(FetchDoneCallback callback, Status status) {
227 if (callback.is_null()) 231 if (callback.is_null()) {
228 return; 232 return;
233 }
229 callback.Run(status, std::vector<ContentSuggestion>()); 234 callback.Run(status, std::vector<ContentSuggestion>());
230 } 235 }
231 236
232 } // namespace 237 } // namespace
233 238
234 RemoteSuggestionsProvider::RemoteSuggestionsProvider( 239 RemoteSuggestionsProvider::RemoteSuggestionsProvider(
235 Observer* observer, 240 Observer* observer,
236 CategoryFactory* category_factory, 241 CategoryFactory* category_factory,
237 PrefService* pref_service, 242 PrefService* pref_service,
238 const std::string& application_language_code, 243 const std::string& application_language_code,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 registry->RegisterListPref(kDeprecatedSnippetHostsPref); 304 registry->RegisterListPref(kDeprecatedSnippetHostsPref);
300 registry->RegisterListPref(prefs::kRemoteSuggestionCategories); 305 registry->RegisterListPref(prefs::kRemoteSuggestionCategories);
301 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0); 306 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalWifi, 0);
302 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback, 307 registry->RegisterInt64Pref(prefs::kSnippetBackgroundFetchingIntervalFallback,
303 0); 308 0);
304 309
305 NTPSnippetsStatusService::RegisterProfilePrefs(registry); 310 NTPSnippetsStatusService::RegisterProfilePrefs(registry);
306 } 311 }
307 312
308 void RemoteSuggestionsProvider::FetchSnippets(bool interactive_request) { 313 void RemoteSuggestionsProvider::FetchSnippets(bool interactive_request) {
309 if (ready()) 314 if (ready()) {
310 FetchSnippetsFromHosts(std::set<std::string>(), interactive_request); 315 FetchSnippetsFromHosts(std::set<std::string>(), interactive_request);
311 else 316 } else {
312 fetch_when_ready_ = true; 317 fetch_when_ready_ = true;
318 }
313 } 319 }
314 320
315 void RemoteSuggestionsProvider::FetchSnippetsFromHosts( 321 void RemoteSuggestionsProvider::FetchSnippetsFromHosts(
316 const std::set<std::string>& hosts, 322 const std::set<std::string>& hosts,
317 bool interactive_request) { 323 bool interactive_request) {
318 // TODO(tschumann): FetchSnippets() and FetchSnippetsFromHost() implement the 324 // TODO(tschumann): FetchSnippets() and FetchSnippetsFromHost() implement the
319 // fetch logic when called by the background fetcher or interactive "reload" 325 // fetch logic when called by the background fetcher or interactive "reload"
320 // requests. Fetch() is right now only called for the fetch-more use case. 326 // requests. Fetch() is right now only called for the fetch-more use case.
321 // The names are confusing and we need to clean them up. 327 // The names are confusing and we need to clean them up.
322 if (!ready()) 328 if (!ready()) {
323 return; 329 return;
330 }
324 MarkEmptyCategoriesAsLoading(); 331 MarkEmptyCategoriesAsLoading();
325 332
326 NTPSnippetsFetcher::Params params = 333 NTPSnippetsFetcher::Params params =
327 BuildFetchParams(/*exclude_archived_suggestions=*/true); 334 BuildFetchParams(/*exclude_archived_suggestions=*/true);
328 params.hosts = hosts; 335 params.hosts = hosts;
329 params.interactive_request = interactive_request; 336 params.interactive_request = interactive_request;
330 snippets_fetcher_->FetchSnippets( 337 snippets_fetcher_->FetchSnippets(
331 params, base::BindOnce(&RemoteSuggestionsProvider::OnFetchFinished, 338 params, base::BindOnce(&RemoteSuggestionsProvider::OnFetchFinished,
332 base::Unretained(this))); 339 base::Unretained(this)));
333 } 340 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 } 381 }
375 } 382 }
376 } 383 }
377 return result; 384 return result;
378 } 385 }
379 386
380 void RemoteSuggestionsProvider::MarkEmptyCategoriesAsLoading() { 387 void RemoteSuggestionsProvider::MarkEmptyCategoriesAsLoading() {
381 for (const auto& item : category_contents_) { 388 for (const auto& item : category_contents_) {
382 Category category = item.first; 389 Category category = item.first;
383 const CategoryContent& content = item.second; 390 const CategoryContent& content = item.second;
384 if (content.snippets.empty()) 391 if (content.snippets.empty()) {
385 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING); 392 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE_LOADING);
393 }
386 } 394 }
387 } 395 }
388 396
389 void RemoteSuggestionsProvider::RescheduleFetching(bool force) { 397 void RemoteSuggestionsProvider::RescheduleFetching(bool force) {
390 // The scheduler only exists on Android so far, it's null on other platforms. 398 // The scheduler only exists on Android so far, it's null on other platforms.
391 if (!scheduler_) 399 if (!scheduler_) {
392 return; 400 return;
401 }
393 402
394 if (ready()) { 403 if (ready()) {
395 base::TimeDelta old_interval_wifi = base::TimeDelta::FromInternalValue( 404 base::TimeDelta old_interval_wifi = base::TimeDelta::FromInternalValue(
396 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi)); 405 pref_service_->GetInt64(prefs::kSnippetBackgroundFetchingIntervalWifi));
397 base::TimeDelta old_interval_fallback = 406 base::TimeDelta old_interval_fallback =
398 base::TimeDelta::FromInternalValue(pref_service_->GetInt64( 407 base::TimeDelta::FromInternalValue(pref_service_->GetInt64(
399 prefs::kSnippetBackgroundFetchingIntervalFallback)); 408 prefs::kSnippetBackgroundFetchingIntervalFallback));
400 UserClassifier::UserClass user_class = user_classifier_->GetUserClass(); 409 UserClassifier::UserClass user_class = user_classifier_->GetUserClass();
401 base::TimeDelta interval_wifi = 410 base::TimeDelta interval_wifi =
402 GetFetchingInterval(/*is_wifi=*/true, user_class); 411 GetFetchingInterval(/*is_wifi=*/true, user_class);
(...skipping 28 matching lines...) Expand all
431 } 440 }
432 441
433 CategoryInfo RemoteSuggestionsProvider::GetCategoryInfo(Category category) { 442 CategoryInfo RemoteSuggestionsProvider::GetCategoryInfo(Category category) {
434 auto content_it = category_contents_.find(category); 443 auto content_it = category_contents_.find(category);
435 DCHECK(content_it != category_contents_.end()); 444 DCHECK(content_it != category_contents_.end());
436 return content_it->second.info; 445 return content_it->second.info;
437 } 446 }
438 447
439 void RemoteSuggestionsProvider::DismissSuggestion( 448 void RemoteSuggestionsProvider::DismissSuggestion(
440 const ContentSuggestion::ID& suggestion_id) { 449 const ContentSuggestion::ID& suggestion_id) {
441 if (!ready()) 450 if (!ready()) {
442 return; 451 return;
452 }
443 453
444 auto content_it = category_contents_.find(suggestion_id.category()); 454 auto content_it = category_contents_.find(suggestion_id.category());
445 DCHECK(content_it != category_contents_.end()); 455 DCHECK(content_it != category_contents_.end());
446 CategoryContent* content = &content_it->second; 456 CategoryContent* content = &content_it->second;
447 DismissSuggestionFromCategoryContent(content, 457 DismissSuggestionFromCategoryContent(content,
448 suggestion_id.id_within_category()); 458 suggestion_id.id_within_category());
449 } 459 }
450 460
451 void RemoteSuggestionsProvider::FetchSuggestionImage( 461 void RemoteSuggestionsProvider::FetchSuggestionImage(
452 const ContentSuggestion::ID& suggestion_id, 462 const ContentSuggestion::ID& suggestion_id,
453 const ImageFetchedCallback& callback) { 463 const ImageFetchedCallback& callback) {
454 database_->LoadImage( 464 database_->LoadImage(
455 suggestion_id.id_within_category(), 465 suggestion_id.id_within_category(),
456 base::Bind(&RemoteSuggestionsProvider::OnSnippetImageFetchedFromDatabase, 466 base::Bind(&RemoteSuggestionsProvider::OnSnippetImageFetchedFromDatabase,
457 base::Unretained(this), callback, suggestion_id)); 467 base::Unretained(this), callback, suggestion_id));
458 } 468 }
459 469
460 void RemoteSuggestionsProvider::ClearHistory( 470 void RemoteSuggestionsProvider::ClearHistory(
461 base::Time begin, 471 base::Time begin,
462 base::Time end, 472 base::Time end,
463 const base::Callback<bool(const GURL& url)>& filter) { 473 const base::Callback<bool(const GURL& url)>& filter) {
464 // Both time range and the filter are ignored and all suggestions are removed, 474 // Both time range and the filter are ignored and all suggestions are removed,
465 // because it is not known which history entries were used for the suggestions 475 // because it is not known which history entries were used for the suggestions
466 // personalization. 476 // personalization.
467 if (!ready()) 477 if (!ready()) {
468 nuke_when_initialized_ = true; 478 nuke_when_initialized_ = true;
469 else 479 } else {
470 NukeAllSnippets(); 480 NukeAllSnippets();
481 }
471 } 482 }
472 483
473 void RemoteSuggestionsProvider::ClearCachedSuggestions(Category category) { 484 void RemoteSuggestionsProvider::ClearCachedSuggestions(Category category) {
474 if (!initialized()) 485 if (!initialized()) {
475 return; 486 return;
487 }
476 488
477 auto content_it = category_contents_.find(category); 489 auto content_it = category_contents_.find(category);
478 if (content_it == category_contents_.end()) { 490 if (content_it == category_contents_.end()) {
479 return; 491 return;
480 } 492 }
481 CategoryContent* content = &content_it->second; 493 CategoryContent* content = &content_it->second;
482 if (content->snippets.empty()) 494 if (content->snippets.empty()) {
483 return; 495 return;
496 }
484 497
485 database_->DeleteSnippets(GetSnippetIDVector(content->snippets)); 498 database_->DeleteSnippets(GetSnippetIDVector(content->snippets));
486 database_->DeleteImages(GetSnippetIDVector(content->snippets)); 499 database_->DeleteImages(GetSnippetIDVector(content->snippets));
487 content->snippets.clear(); 500 content->snippets.clear();
488 501
489 if (IsCategoryStatusAvailable(content->status)) 502 if (IsCategoryStatusAvailable(content->status)) {
490 NotifyNewSuggestions(category, *content); 503 NotifyNewSuggestions(category, *content);
504 }
491 } 505 }
492 506
493 void RemoteSuggestionsProvider::GetDismissedSuggestionsForDebugging( 507 void RemoteSuggestionsProvider::GetDismissedSuggestionsForDebugging(
494 Category category, 508 Category category,
495 const DismissedSuggestionsCallback& callback) { 509 const DismissedSuggestionsCallback& callback) {
496 auto content_it = category_contents_.find(category); 510 auto content_it = category_contents_.find(category);
497 DCHECK(content_it != category_contents_.end()); 511 DCHECK(content_it != category_contents_.end());
498 callback.Run( 512 callback.Run(
499 ConvertToContentSuggestions(category, content_it->second.dismissed)); 513 ConvertToContentSuggestions(category, content_it->second.dismissed));
500 } 514 }
501 515
502 void RemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging( 516 void RemoteSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
503 Category category) { 517 Category category) {
504 auto content_it = category_contents_.find(category); 518 auto content_it = category_contents_.find(category);
505 DCHECK(content_it != category_contents_.end()); 519 DCHECK(content_it != category_contents_.end());
506 CategoryContent* content = &content_it->second; 520 CategoryContent* content = &content_it->second;
507 521
508 if (!initialized()) 522 if (!initialized()) {
509 return; 523 return;
524 }
510 525
511 if (content->dismissed.empty()) 526 if (content->dismissed.empty()) {
512 return; 527 return;
528 }
513 529
514 database_->DeleteSnippets(GetSnippetIDVector(content->dismissed)); 530 database_->DeleteSnippets(GetSnippetIDVector(content->dismissed));
515 // The image got already deleted when the suggestion was dismissed. 531 // The image got already deleted when the suggestion was dismissed.
516 532
517 content->dismissed.clear(); 533 content->dismissed.clear();
518 } 534 }
519 535
520 // static 536 // static
521 int RemoteSuggestionsProvider::GetMaxSnippetCountForTesting() { 537 int RemoteSuggestionsProvider::GetMaxSnippetCountForTesting() {
522 return kMaxSnippetCount; 538 return kMaxSnippetCount;
523 } 539 }
524 540
525 //////////////////////////////////////////////////////////////////////////////// 541 ////////////////////////////////////////////////////////////////////////////////
526 // Private methods 542 // Private methods
527 543
528 GURL RemoteSuggestionsProvider::FindSnippetImageUrl( 544 GURL RemoteSuggestionsProvider::FindSnippetImageUrl(
529 const ContentSuggestion::ID& suggestion_id) const { 545 const ContentSuggestion::ID& suggestion_id) const {
530 DCHECK(base::ContainsKey(category_contents_, suggestion_id.category())); 546 DCHECK(base::ContainsKey(category_contents_, suggestion_id.category()));
531 547
532 const CategoryContent& content = 548 const CategoryContent& content =
533 category_contents_.at(suggestion_id.category()); 549 category_contents_.at(suggestion_id.category());
534 const NTPSnippet* snippet = 550 const NTPSnippet* snippet =
535 content.FindSnippet(suggestion_id.id_within_category()); 551 content.FindSnippet(suggestion_id.id_within_category());
536 if (!snippet) 552 if (!snippet) {
537 return GURL(); 553 return GURL();
554 }
538 return snippet->salient_image_url(); 555 return snippet->salient_image_url();
539 } 556 }
540 557
541 // image_fetcher::ImageFetcherDelegate implementation. 558 // image_fetcher::ImageFetcherDelegate implementation.
542 void RemoteSuggestionsProvider::OnImageDataFetched( 559 void RemoteSuggestionsProvider::OnImageDataFetched(
543 const std::string& id_within_category, 560 const std::string& id_within_category,
544 const std::string& image_data) { 561 const std::string& image_data) {
545 if (image_data.empty()) 562 if (image_data.empty()) {
546 return; 563 return;
564 }
547 565
548 // Only save the image if the corresponding snippet still exists. 566 // Only save the image if the corresponding snippet still exists.
549 bool found = false; 567 bool found = false;
550 for (const auto& entry : category_contents_) { 568 for (const auto& entry : category_contents_) {
551 if (entry.second.FindSnippet(id_within_category)) { 569 if (entry.second.FindSnippet(id_within_category)) {
552 found = true; 570 found = true;
553 break; 571 break;
554 } 572 }
555 } 573 }
556 if (!found) 574 if (!found) {
557 return; 575 return;
576 }
558 577
559 // Only cache the data in the DB, the actual serving is done in the callback 578 // Only cache the data in the DB, the actual serving is done in the callback
560 // provided to |image_fetcher_| (OnSnippetImageDecodedFromNetwork()). 579 // provided to |image_fetcher_| (OnSnippetImageDecodedFromNetwork()).
561 database_->SaveImage(id_within_category, image_data); 580 database_->SaveImage(id_within_category, image_data);
562 } 581 }
563 582
564 void RemoteSuggestionsProvider::OnDatabaseLoaded( 583 void RemoteSuggestionsProvider::OnDatabaseLoaded(
565 NTPSnippet::PtrVector snippets) { 584 NTPSnippet::PtrVector snippets) {
566 if (state_ == State::ERROR_OCCURRED) 585 if (state_ == State::ERROR_OCCURRED) {
567 return; 586 return;
587 }
568 DCHECK(state_ == State::NOT_INITED); 588 DCHECK(state_ == State::NOT_INITED);
569 DCHECK(base::ContainsKey(category_contents_, articles_category_)); 589 DCHECK(base::ContainsKey(category_contents_, articles_category_));
570 590
571 base::TimeDelta database_load_time = 591 base::TimeDelta database_load_time =
572 base::TimeTicks::Now() - database_load_start_; 592 base::TimeTicks::Now() - database_load_start_;
573 UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Snippets.DatabaseLoadTime", 593 UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Snippets.DatabaseLoadTime",
574 database_load_time); 594 database_load_time);
575 595
576 NTPSnippet::PtrVector to_delete; 596 NTPSnippet::PtrVector to_delete;
577 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { 597 for (std::unique_ptr<NTPSnippet>& snippet : snippets) {
578 Category snippet_category = 598 Category snippet_category =
579 category_factory()->FromRemoteCategory(snippet->remote_category_id()); 599 category_factory()->FromRemoteCategory(snippet->remote_category_id());
580 auto content_it = category_contents_.find(snippet_category); 600 auto content_it = category_contents_.find(snippet_category);
581 // We should already know about the category. 601 // We should already know about the category.
582 if (content_it == category_contents_.end()) { 602 if (content_it == category_contents_.end()) {
583 DLOG(WARNING) << "Loaded a suggestion for unknown category " 603 DLOG(WARNING) << "Loaded a suggestion for unknown category "
584 << snippet_category << " from the DB; deleting"; 604 << snippet_category << " from the DB; deleting";
585 to_delete.emplace_back(std::move(snippet)); 605 to_delete.emplace_back(std::move(snippet));
586 continue; 606 continue;
587 } 607 }
588 CategoryContent* content = &content_it->second; 608 CategoryContent* content = &content_it->second;
589 if (snippet->is_dismissed()) 609 if (snippet->is_dismissed()) {
590 content->dismissed.emplace_back(std::move(snippet)); 610 content->dismissed.emplace_back(std::move(snippet));
591 else 611 } else {
592 content->snippets.emplace_back(std::move(snippet)); 612 content->snippets.emplace_back(std::move(snippet));
613 }
593 } 614 }
594 if (!to_delete.empty()) { 615 if (!to_delete.empty()) {
595 database_->DeleteSnippets(GetSnippetIDVector(to_delete)); 616 database_->DeleteSnippets(GetSnippetIDVector(to_delete));
596 database_->DeleteImages(GetSnippetIDVector(to_delete)); 617 database_->DeleteImages(GetSnippetIDVector(to_delete));
597 } 618 }
598 619
599 // Sort the suggestions in each category. 620 // Sort the suggestions in each category.
600 // TODO(treib): Persist the actual order in the DB somehow? crbug.com/654409 621 // TODO(treib): Persist the actual order in the DB somehow? crbug.com/654409
601 for (auto& entry : category_contents_) { 622 for (auto& entry : category_contents_) {
602 CategoryContent* content = &entry.second; 623 CategoryContent* content = &entry.second;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 content.snippets.size()); 767 content.snippets.size());
747 if (content.snippets.empty() && !content.dismissed.empty()) { 768 if (content.snippets.empty() && !content.dismissed.empty()) {
748 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", 769 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded",
749 content.dismissed.size()); 770 content.dismissed.size());
750 } 771 }
751 772
752 // Reschedule after a successful fetch. This resets all currently scheduled 773 // Reschedule after a successful fetch. This resets all currently scheduled
753 // fetches, to make sure the fallback interval triggers only if no wifi fetch 774 // fetches, to make sure the fallback interval triggers only if no wifi fetch
754 // succeeded, and also that we don't do a background fetch immediately after 775 // succeeded, and also that we don't do a background fetch immediately after
755 // a user-initiated one. 776 // a user-initiated one.
756 if (fetched_categories) 777 if (fetched_categories) {
757 RescheduleFetching(true); 778 RescheduleFetching(true);
779 }
758 } 780 }
759 781
760 void RemoteSuggestionsProvider::ArchiveSnippets( 782 void RemoteSuggestionsProvider::ArchiveSnippets(
761 CategoryContent* content, 783 CategoryContent* content,
762 NTPSnippet::PtrVector* to_archive) { 784 NTPSnippet::PtrVector* to_archive) {
763 // Archive previous snippets - move them at the beginning of the list. 785 // Archive previous snippets - move them at the beginning of the list.
764 content->archived.insert(content->archived.begin(), 786 content->archived.insert(content->archived.begin(),
765 std::make_move_iterator(to_archive->begin()), 787 std::make_move_iterator(to_archive->begin()),
766 std::make_move_iterator(to_archive->end())); 788 std::make_move_iterator(to_archive->end()));
767 to_archive->clear(); 789 to_archive->clear();
(...skipping 21 matching lines...) Expand all
789 811
790 void RemoteSuggestionsProvider::IntegrateSnippets( 812 void RemoteSuggestionsProvider::IntegrateSnippets(
791 CategoryContent* content, 813 CategoryContent* content,
792 NTPSnippet::PtrVector new_snippets) { 814 NTPSnippet::PtrVector new_snippets) {
793 DCHECK(ready()); 815 DCHECK(ready());
794 816
795 // Do not touch the current set of snippets if the newly fetched one is empty. 817 // Do not touch the current set of snippets if the newly fetched one is empty.
796 // TODO(tschumann): This should go. If we get empty results we should update 818 // TODO(tschumann): This should go. If we get empty results we should update
797 // accordingly and remove the old one (only of course if this was not received 819 // accordingly and remove the old one (only of course if this was not received
798 // through a fetch-more). 820 // through a fetch-more).
799 if (new_snippets.empty()) 821 if (new_snippets.empty()) {
800 return; 822 return;
823 }
801 824
802 // It's entirely possible that the newly fetched snippets contain articles 825 // It's entirely possible that the newly fetched snippets contain articles
803 // that have been present before. 826 // that have been present before.
804 // We need to make sure to only delete and archive snippets that don't 827 // We need to make sure to only delete and archive snippets that don't
805 // appear with the same ID in the new suggestions (it's fine for additional 828 // appear with the same ID in the new suggestions (it's fine for additional
806 // IDs though). 829 // IDs though).
807 EraseByPrimaryID(&content->snippets, *GetSnippetIDVector(new_snippets)); 830 EraseByPrimaryID(&content->snippets, *GetSnippetIDVector(new_snippets));
808 // Do not delete the thumbnail images as they are still handy on open NTPs. 831 // Do not delete the thumbnail images as they are still handy on open NTPs.
809 database_->DeleteSnippets(GetSnippetIDVector(content->snippets)); 832 database_->DeleteSnippets(GetSnippetIDVector(content->snippets));
810 // Note, that ArchiveSnippets will clear |content->snippets|. 833 // Note, that ArchiveSnippets will clear |content->snippets|.
811 ArchiveSnippets(content, &content->snippets); 834 ArchiveSnippets(content, &content->snippets);
812 835
813 database_->SaveSnippets(new_snippets); 836 database_->SaveSnippets(new_snippets);
814 837
815 content->snippets = std::move(new_snippets); 838 content->snippets = std::move(new_snippets);
816 } 839 }
817 840
818 void RemoteSuggestionsProvider::DismissSuggestionFromCategoryContent( 841 void RemoteSuggestionsProvider::DismissSuggestionFromCategoryContent(
819 CategoryContent* content, 842 CategoryContent* content,
820 const std::string& id_within_category) { 843 const std::string& id_within_category) {
821 auto it = std::find_if( 844 auto it = std::find_if(
822 content->snippets.begin(), content->snippets.end(), 845 content->snippets.begin(), content->snippets.end(),
823 [&id_within_category](const std::unique_ptr<NTPSnippet>& snippet) { 846 [&id_within_category](const std::unique_ptr<NTPSnippet>& snippet) {
824 return snippet->id() == id_within_category; 847 return snippet->id() == id_within_category;
825 }); 848 });
826 if (it == content->snippets.end()) 849 if (it == content->snippets.end()) {
827 return; 850 return;
851 }
828 852
829 (*it)->set_dismissed(true); 853 (*it)->set_dismissed(true);
830 854
831 database_->SaveSnippet(**it); 855 database_->SaveSnippet(**it);
832 856
833 content->dismissed.push_back(std::move(*it)); 857 content->dismissed.push_back(std::move(*it));
834 content->snippets.erase(it); 858 content->snippets.erase(it);
835 } 859 }
836 860
837 void RemoteSuggestionsProvider::ClearExpiredDismissedSnippets() { 861 void RemoteSuggestionsProvider::ClearExpiredDismissedSnippets() {
838 std::vector<Category> categories_to_erase; 862 std::vector<Category> categories_to_erase;
839 863
840 const base::Time now = base::Time::Now(); 864 const base::Time now = base::Time::Now();
841 865
842 for (auto& item : category_contents_) { 866 for (auto& item : category_contents_) {
843 Category category = item.first; 867 Category category = item.first;
844 CategoryContent* content = &item.second; 868 CategoryContent* content = &item.second;
845 869
846 NTPSnippet::PtrVector to_delete; 870 NTPSnippet::PtrVector to_delete;
847 // Move expired dismissed snippets over into |to_delete|. 871 // Move expired dismissed snippets over into |to_delete|.
848 for (std::unique_ptr<NTPSnippet>& snippet : content->dismissed) { 872 for (std::unique_ptr<NTPSnippet>& snippet : content->dismissed) {
849 if (snippet->expiry_date() <= now) 873 if (snippet->expiry_date() <= now) {
850 to_delete.emplace_back(std::move(snippet)); 874 to_delete.emplace_back(std::move(snippet));
875 }
851 } 876 }
852 RemoveNullPointers(&content->dismissed); 877 RemoveNullPointers(&content->dismissed);
853 878
854 // Delete the images. 879 // Delete the images.
855 database_->DeleteImages(GetSnippetIDVector(to_delete)); 880 database_->DeleteImages(GetSnippetIDVector(to_delete));
856 // Delete the removed article suggestions from the DB. 881 // Delete the removed article suggestions from the DB.
857 database_->DeleteSnippets(GetSnippetIDVector(to_delete)); 882 database_->DeleteSnippets(GetSnippetIDVector(to_delete));
858 883
859 if (content->snippets.empty() && content->dismissed.empty() && 884 if (content->snippets.empty() && content->dismissed.empty() &&
860 category != articles_category_ && 885 category != articles_category_ &&
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 // not be personalized. 917 // not be personalized.
893 for (const auto& item : category_contents_) { 918 for (const auto& item : category_contents_) {
894 Category category = item.first; 919 Category category = item.first;
895 920
896 ClearCachedSuggestions(category); 921 ClearCachedSuggestions(category);
897 ClearDismissedSuggestionsForDebugging(category); 922 ClearDismissedSuggestionsForDebugging(category);
898 923
899 UpdateCategoryStatus(category, CategoryStatus::NOT_PROVIDED); 924 UpdateCategoryStatus(category, CategoryStatus::NOT_PROVIDED);
900 925
901 // Remove the category entirely; it may or may not reappear. 926 // Remove the category entirely; it may or may not reappear.
902 if (category != articles_category_) 927 if (category != articles_category_) {
903 categories_to_erase.push_back(category); 928 categories_to_erase.push_back(category);
929 }
904 } 930 }
905 931
906 for (Category category : categories_to_erase) { 932 for (Category category : categories_to_erase) {
907 category_contents_.erase(category); 933 category_contents_.erase(category);
908 } 934 }
909 935
910 StoreCategoriesToPrefs(); 936 StoreCategoriesToPrefs();
911 } 937 }
912 938
913 void RemoteSuggestionsProvider::OnSnippetImageFetchedFromDatabase( 939 void RemoteSuggestionsProvider::OnSnippetImageFetchedFromDatabase(
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 // network request. 1020 // network request.
995 FetchSnippets(/*interactive_request=*/false); 1021 FetchSnippets(/*interactive_request=*/false);
996 fetch_when_ready_ = false; 1022 fetch_when_ready_ = false;
997 } 1023 }
998 1024
999 for (const auto& item : category_contents_) { 1025 for (const auto& item : category_contents_) {
1000 Category category = item.first; 1026 Category category = item.first;
1001 const CategoryContent& content = item.second; 1027 const CategoryContent& content = item.second;
1002 // FetchSnippets has set the status to |AVAILABLE_LOADING| if relevant, 1028 // FetchSnippets has set the status to |AVAILABLE_LOADING| if relevant,
1003 // otherwise we transition to |AVAILABLE| here. 1029 // otherwise we transition to |AVAILABLE| here.
1004 if (content.status != CategoryStatus::AVAILABLE_LOADING) 1030 if (content.status != CategoryStatus::AVAILABLE_LOADING) {
1005 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE); 1031 UpdateCategoryStatus(category, CategoryStatus::AVAILABLE);
1032 }
1006 } 1033 }
1007 } 1034 }
1008 1035
1009 void RemoteSuggestionsProvider::EnterStateDisabled() { 1036 void RemoteSuggestionsProvider::EnterStateDisabled() {
1010 NukeAllSnippets(); 1037 NukeAllSnippets();
1011 } 1038 }
1012 1039
1013 void RemoteSuggestionsProvider::EnterStateError() { 1040 void RemoteSuggestionsProvider::EnterStateError() {
1014 snippets_status_service_.reset(); 1041 snippets_status_service_.reset();
1015 } 1042 }
(...skipping 19 matching lines...) Expand all
1035 base::Bind(&RemoteSuggestionsProvider::OnSnippetsStatusChanged, 1062 base::Bind(&RemoteSuggestionsProvider::OnSnippetsStatusChanged,
1036 base::Unretained(this))); 1063 base::Unretained(this)));
1037 1064
1038 // Always notify here even if we got nothing from the database, because we 1065 // Always notify here even if we got nothing from the database, because we
1039 // don't know how long the fetch will take or if it will even complete. 1066 // don't know how long the fetch will take or if it will even complete.
1040 for (const auto& item : category_contents_) { 1067 for (const auto& item : category_contents_) {
1041 Category category = item.first; 1068 Category category = item.first;
1042 const CategoryContent& content = item.second; 1069 const CategoryContent& content = item.second;
1043 // Note: We might be in a non-available status here, e.g. DISABLED due to 1070 // Note: We might be in a non-available status here, e.g. DISABLED due to
1044 // enterprise policy. 1071 // enterprise policy.
1045 if (IsCategoryStatusAvailable(content.status)) 1072 if (IsCategoryStatusAvailable(content.status)) {
1046 NotifyNewSuggestions(category, content); 1073 NotifyNewSuggestions(category, content);
1074 }
1047 } 1075 }
1048 } 1076 }
1049 1077
1050 void RemoteSuggestionsProvider::OnSnippetsStatusChanged( 1078 void RemoteSuggestionsProvider::OnSnippetsStatusChanged(
1051 SnippetsStatus old_snippets_status, 1079 SnippetsStatus old_snippets_status,
1052 SnippetsStatus new_snippets_status) { 1080 SnippetsStatus new_snippets_status) {
1053 switch (new_snippets_status) { 1081 switch (new_snippets_status) {
1054 case SnippetsStatus::ENABLED_AND_SIGNED_IN: 1082 case SnippetsStatus::ENABLED_AND_SIGNED_IN:
1055 if (old_snippets_status == SnippetsStatus::ENABLED_AND_SIGNED_OUT) { 1083 if (old_snippets_status == SnippetsStatus::ENABLED_AND_SIGNED_OUT) {
1056 DCHECK(state_ == State::READY); 1084 DCHECK(state_ == State::READY);
(...skipping 26 matching lines...) Expand all
1083 break; 1111 break;
1084 1112
1085 case SnippetsStatus::SIGNED_OUT_AND_DISABLED: 1113 case SnippetsStatus::SIGNED_OUT_AND_DISABLED:
1086 EnterState(State::DISABLED); 1114 EnterState(State::DISABLED);
1087 UpdateAllCategoryStatus(CategoryStatus::SIGNED_OUT); 1115 UpdateAllCategoryStatus(CategoryStatus::SIGNED_OUT);
1088 break; 1116 break;
1089 } 1117 }
1090 } 1118 }
1091 1119
1092 void RemoteSuggestionsProvider::EnterState(State state) { 1120 void RemoteSuggestionsProvider::EnterState(State state) {
1093 if (state == state_) 1121 if (state == state_) {
1094 return; 1122 return;
1123 }
1095 1124
1096 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.EnteredState", 1125 UMA_HISTOGRAM_ENUMERATION("NewTabPage.Snippets.EnteredState",
1097 static_cast<int>(state), 1126 static_cast<int>(state),
1098 static_cast<int>(State::COUNT)); 1127 static_cast<int>(State::COUNT));
1099 1128
1100 switch (state) { 1129 switch (state) {
1101 case State::NOT_INITED: 1130 case State::NOT_INITED:
1102 // Initial state, it should not be possible to get back there. 1131 // Initial state, it should not be possible to get back there.
1103 NOTREACHED(); 1132 NOTREACHED();
1104 break; 1133 break;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 << " items in category " << category; 1175 << " items in category " << category;
1147 observer()->OnNewSuggestions(this, category, std::move(result)); 1176 observer()->OnNewSuggestions(this, category, std::move(result));
1148 } 1177 }
1149 1178
1150 void RemoteSuggestionsProvider::UpdateCategoryStatus(Category category, 1179 void RemoteSuggestionsProvider::UpdateCategoryStatus(Category category,
1151 CategoryStatus status) { 1180 CategoryStatus status) {
1152 auto content_it = category_contents_.find(category); 1181 auto content_it = category_contents_.find(category);
1153 DCHECK(content_it != category_contents_.end()); 1182 DCHECK(content_it != category_contents_.end());
1154 CategoryContent& content = content_it->second; 1183 CategoryContent& content = content_it->second;
1155 1184
1156 if (status == content.status) 1185 if (status == content.status) {
1157 return; 1186 return;
1187 }
1158 1188
1159 DVLOG(1) << "UpdateCategoryStatus(): " << category.id() << ": " 1189 DVLOG(1) << "UpdateCategoryStatus(): " << category.id() << ": "
1160 << static_cast<int>(content.status) << " -> " 1190 << static_cast<int>(content.status) << " -> "
1161 << static_cast<int>(status); 1191 << static_cast<int>(status);
1162 content.status = status; 1192 content.status = status;
1163 observer()->OnCategoryStatusChanged(this, category, content.status); 1193 observer()->OnCategoryStatusChanged(this, category, content.status);
1164 } 1194 }
1165 1195
1166 void RemoteSuggestionsProvider::UpdateAllCategoryStatus(CategoryStatus status) { 1196 void RemoteSuggestionsProvider::UpdateAllCategoryStatus(CategoryStatus status) {
1167 for (const auto& category : category_contents_) { 1197 for (const auto& category : category_contents_) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 : BuildRemoteCategoryInfo(title, allow_fetching_more_results); 1293 : BuildRemoteCategoryInfo(title, allow_fetching_more_results);
1264 CategoryContent* content = UpdateCategoryInfo(category, info); 1294 CategoryContent* content = UpdateCategoryInfo(category, info);
1265 content->included_in_last_server_response = 1295 content->included_in_last_server_response =
1266 included_in_last_server_response; 1296 included_in_last_server_response;
1267 } 1297 }
1268 } 1298 }
1269 1299
1270 void RemoteSuggestionsProvider::StoreCategoriesToPrefs() { 1300 void RemoteSuggestionsProvider::StoreCategoriesToPrefs() {
1271 // Collect all the CategoryContents. 1301 // Collect all the CategoryContents.
1272 std::vector<std::pair<Category, const CategoryContent*>> to_store; 1302 std::vector<std::pair<Category, const CategoryContent*>> to_store;
1273 for (const auto& entry : category_contents_) 1303 for (const auto& entry : category_contents_) {
1274 to_store.emplace_back(entry.first, &entry.second); 1304 to_store.emplace_back(entry.first, &entry.second);
1305 }
1275 // Sort them into the proper category order. 1306 // Sort them into the proper category order.
1276 std::sort(to_store.begin(), to_store.end(), 1307 std::sort(to_store.begin(), to_store.end(),
1277 [this](const std::pair<Category, const CategoryContent*>& left, 1308 [this](const std::pair<Category, const CategoryContent*>& left,
1278 const std::pair<Category, const CategoryContent*>& right) { 1309 const std::pair<Category, const CategoryContent*>& right) {
1279 return category_factory()->CompareCategories(left.first, 1310 return category_factory()->CompareCategories(left.first,
1280 right.first); 1311 right.first);
1281 }); 1312 });
1282 // Convert the relevant info into a base::ListValue for storage. 1313 // Convert the relevant info into a base::ListValue for storage.
1283 base::ListValue list; 1314 base::ListValue list;
1284 for (const auto& entry : to_store) { 1315 for (const auto& entry : to_store) {
(...skipping 20 matching lines...) Expand all
1305 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) = 1336 RemoteSuggestionsProvider::CategoryContent::CategoryContent(CategoryContent&&) =
1306 default; 1337 default;
1307 1338
1308 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default; 1339 RemoteSuggestionsProvider::CategoryContent::~CategoryContent() = default;
1309 1340
1310 RemoteSuggestionsProvider::CategoryContent& 1341 RemoteSuggestionsProvider::CategoryContent&
1311 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) = 1342 RemoteSuggestionsProvider::CategoryContent::operator=(CategoryContent&&) =
1312 default; 1343 default;
1313 1344
1314 } // namespace ntp_snippets 1345 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698