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/ntp_snippets_service.h" | 5 #include "components/ntp_snippets/ntp_snippets_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 std::set<std::string> NTPSnippetsService::GetSuggestionsHosts() const { | 303 std::set<std::string> NTPSnippetsService::GetSuggestionsHosts() const { |
304 // |suggestions_service_| can be null in tests. | 304 // |suggestions_service_| can be null in tests. |
305 if (!suggestions_service_) | 305 if (!suggestions_service_) |
306 return std::set<std::string>(); | 306 return std::set<std::string>(); |
307 | 307 |
308 // TODO(treib): This should just call GetSnippetHostsFromPrefs. | 308 // TODO(treib): This should just call GetSnippetHostsFromPrefs. |
309 return GetSuggestionsHostsImpl( | 309 return GetSuggestionsHostsImpl( |
310 suggestions_service_->GetSuggestionsDataFromCache()); | 310 suggestions_service_->GetSuggestionsDataFromCache()); |
311 } | 311 } |
312 | 312 |
313 void NTPSnippetsService::DiscardSuggestion(const std::string& suggestion_id) { | 313 void NTPSnippetsService::DismissSuggestion(const std::string& suggestion_id) { |
314 if (!ready()) | 314 if (!ready()) |
315 return; | 315 return; |
316 | 316 |
317 std::string snippet_id = GetWithinCategoryIDFromUniqueID(suggestion_id); | 317 std::string snippet_id = GetWithinCategoryIDFromUniqueID(suggestion_id); |
318 | 318 |
319 auto it = | 319 auto it = |
320 std::find_if(snippets_.begin(), snippets_.end(), | 320 std::find_if(snippets_.begin(), snippets_.end(), |
321 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { | 321 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { |
322 return snippet->id() == snippet_id; | 322 return snippet->id() == snippet_id; |
323 }); | 323 }); |
324 if (it == snippets_.end()) | 324 if (it == snippets_.end()) |
325 return; | 325 return; |
326 | 326 |
327 (*it)->set_discarded(true); | 327 (*it)->set_dismissed(true); |
328 | 328 |
329 database_->SaveSnippet(**it); | 329 database_->SaveSnippet(**it); |
330 database_->DeleteImage((*it)->id()); | 330 database_->DeleteImage((*it)->id()); |
331 | 331 |
332 discarded_snippets_.push_back(std::move(*it)); | 332 dismissed_snippets_.push_back(std::move(*it)); |
333 snippets_.erase(it); | 333 snippets_.erase(it); |
334 } | 334 } |
335 | 335 |
336 void NTPSnippetsService::ClearDiscardedSuggestionsForDebugging() { | 336 void NTPSnippetsService::ClearDismissedSuggestionsForDebugging() { |
337 if (!initialized()) | 337 if (!initialized()) |
338 return; | 338 return; |
339 | 339 |
340 if (discarded_snippets_.empty()) | 340 if (dismissed_snippets_.empty()) |
341 return; | 341 return; |
342 | 342 |
343 database_->DeleteSnippets(discarded_snippets_); | 343 database_->DeleteSnippets(dismissed_snippets_); |
344 discarded_snippets_.clear(); | 344 dismissed_snippets_.clear(); |
345 } | 345 } |
346 | 346 |
347 void NTPSnippetsService::SetObserver(Observer* observer) { | 347 void NTPSnippetsService::SetObserver(Observer* observer) { |
348 observer_ = observer; | 348 observer_ = observer; |
349 } | 349 } |
350 | 350 |
351 ContentSuggestionsCategoryStatus NTPSnippetsService::GetCategoryStatus( | 351 ContentSuggestionsCategoryStatus NTPSnippetsService::GetCategoryStatus( |
352 ContentSuggestionsCategory category) { | 352 ContentSuggestionsCategory category) { |
353 DCHECK_EQ(ContentSuggestionsCategory::ARTICLES, category); | 353 DCHECK_EQ(ContentSuggestionsCategory::ARTICLES, category); |
354 return category_status_; | 354 return category_status_; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 | 387 |
388 database_->SaveImage(snippet_id, image_data); | 388 database_->SaveImage(snippet_id, image_data); |
389 } | 389 } |
390 | 390 |
391 void NTPSnippetsService::OnDatabaseLoaded(NTPSnippet::PtrVector snippets) { | 391 void NTPSnippetsService::OnDatabaseLoaded(NTPSnippet::PtrVector snippets) { |
392 DCHECK(state_ == State::NOT_INITED || state_ == State::SHUT_DOWN); | 392 DCHECK(state_ == State::NOT_INITED || state_ == State::SHUT_DOWN); |
393 if (state_ == State::SHUT_DOWN) | 393 if (state_ == State::SHUT_DOWN) |
394 return; | 394 return; |
395 | 395 |
396 DCHECK(snippets_.empty()); | 396 DCHECK(snippets_.empty()); |
397 DCHECK(discarded_snippets_.empty()); | 397 DCHECK(dismissed_snippets_.empty()); |
398 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { | 398 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { |
399 if (snippet->is_discarded()) | 399 if (snippet->is_dismissed()) |
400 discarded_snippets_.emplace_back(std::move(snippet)); | 400 dismissed_snippets_.emplace_back(std::move(snippet)); |
401 else | 401 else |
402 snippets_.emplace_back(std::move(snippet)); | 402 snippets_.emplace_back(std::move(snippet)); |
403 } | 403 } |
404 std::sort(snippets_.begin(), snippets_.end(), | 404 std::sort(snippets_.begin(), snippets_.end(), |
405 [](const std::unique_ptr<NTPSnippet>& lhs, | 405 [](const std::unique_ptr<NTPSnippet>& lhs, |
406 const std::unique_ptr<NTPSnippet>& rhs) { | 406 const std::unique_ptr<NTPSnippet>& rhs) { |
407 return lhs->score() > rhs->score(); | 407 return lhs->score() > rhs->score(); |
408 }); | 408 }); |
409 | 409 |
410 ClearExpiredSnippets(); | 410 ClearExpiredSnippets(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 if (snippets_.size() > kMaxSnippetCount) { | 463 if (snippets_.size() > kMaxSnippetCount) { |
464 NTPSnippet::PtrVector to_delete( | 464 NTPSnippet::PtrVector to_delete( |
465 std::make_move_iterator(snippets_.begin() + kMaxSnippetCount), | 465 std::make_move_iterator(snippets_.begin() + kMaxSnippetCount), |
466 std::make_move_iterator(snippets_.end())); | 466 std::make_move_iterator(snippets_.end())); |
467 snippets_.resize(kMaxSnippetCount); | 467 snippets_.resize(kMaxSnippetCount); |
468 database_->DeleteSnippets(to_delete); | 468 database_->DeleteSnippets(to_delete); |
469 } | 469 } |
470 | 470 |
471 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", | 471 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", |
472 snippets_.size()); | 472 snippets_.size()); |
473 if (snippets_.empty() && !discarded_snippets_.empty()) { | 473 if (snippets_.empty() && !dismissed_snippets_.empty()) { |
474 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", | 474 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", |
475 discarded_snippets_.size()); | 475 dismissed_snippets_.size()); |
476 } | 476 } |
477 | 477 |
478 NotifyNewSuggestions(); | 478 NotifyNewSuggestions(); |
479 } | 479 } |
480 | 480 |
481 void NTPSnippetsService::MergeSnippets(NTPSnippet::PtrVector new_snippets) { | 481 void NTPSnippetsService::MergeSnippets(NTPSnippet::PtrVector new_snippets) { |
482 DCHECK(ready()); | 482 DCHECK(ready()); |
483 | 483 |
484 // Remove new snippets that we already have, or that have been discarded. | 484 // Remove new snippets that we already have, or that have been dismissed. |
485 std::set<std::string> old_snippet_ids; | 485 std::set<std::string> old_snippet_ids; |
486 InsertAllIDs(discarded_snippets_, &old_snippet_ids); | 486 InsertAllIDs(dismissed_snippets_, &old_snippet_ids); |
487 InsertAllIDs(snippets_, &old_snippet_ids); | 487 InsertAllIDs(snippets_, &old_snippet_ids); |
488 new_snippets.erase( | 488 new_snippets.erase( |
489 std::remove_if( | 489 std::remove_if( |
490 new_snippets.begin(), new_snippets.end(), | 490 new_snippets.begin(), new_snippets.end(), |
491 [&old_snippet_ids](const std::unique_ptr<NTPSnippet>& snippet) { | 491 [&old_snippet_ids](const std::unique_ptr<NTPSnippet>& snippet) { |
492 if (old_snippet_ids.count(snippet->id())) | 492 if (old_snippet_ids.count(snippet->id())) |
493 return true; | 493 return true; |
494 for (const SnippetSource& source : snippet->sources()) { | 494 for (const SnippetSource& source : snippet->sources()) { |
495 if (old_snippet_ids.count(source.url.spec())) | 495 if (old_snippet_ids.count(source.url.spec())) |
496 return true; | 496 return true; |
(...skipping 19 matching lines...) Expand all Loading... |
516 switches::kAddIncompleteSnippets)) { | 516 switches::kAddIncompleteSnippets)) { |
517 int num_new_snippets = new_snippets.size(); | 517 int num_new_snippets = new_snippets.size(); |
518 // Remove snippets that do not have all the info we need to display it to | 518 // Remove snippets that do not have all the info we need to display it to |
519 // the user. | 519 // the user. |
520 new_snippets.erase( | 520 new_snippets.erase( |
521 std::remove_if(new_snippets.begin(), new_snippets.end(), | 521 std::remove_if(new_snippets.begin(), new_snippets.end(), |
522 [](const std::unique_ptr<NTPSnippet>& snippet) { | 522 [](const std::unique_ptr<NTPSnippet>& snippet) { |
523 return !snippet->is_complete(); | 523 return !snippet->is_complete(); |
524 }), | 524 }), |
525 new_snippets.end()); | 525 new_snippets.end()); |
526 int num_snippets_discarded = num_new_snippets - new_snippets.size(); | 526 int num_snippets_dismissed = num_new_snippets - new_snippets.size(); |
527 UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch", | 527 UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch", |
528 num_snippets_discarded > 0); | 528 num_snippets_dismissed > 0); |
529 if (num_snippets_discarded > 0) { | 529 if (num_snippets_dismissed > 0) { |
530 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets", | 530 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets", |
531 num_snippets_discarded); | 531 num_snippets_dismissed); |
532 } | 532 } |
533 } | 533 } |
534 | 534 |
535 // Save the new snippets to the DB. | 535 // Save the new snippets to the DB. |
536 database_->SaveSnippets(new_snippets); | 536 database_->SaveSnippets(new_snippets); |
537 | 537 |
538 // Insert the new snippets at the front. | 538 // Insert the new snippets at the front. |
539 snippets_.insert(snippets_.begin(), | 539 snippets_.insert(snippets_.begin(), |
540 std::make_move_iterator(new_snippets.begin()), | 540 std::make_move_iterator(new_snippets.begin()), |
541 std::make_move_iterator(new_snippets.end())); | 541 std::make_move_iterator(new_snippets.end())); |
(...skipping 23 matching lines...) Expand all Loading... |
565 base::Time expiry = base::Time::Now(); | 565 base::Time expiry = base::Time::Now(); |
566 | 566 |
567 // Move expired snippets over into |to_delete|. | 567 // Move expired snippets over into |to_delete|. |
568 NTPSnippet::PtrVector to_delete; | 568 NTPSnippet::PtrVector to_delete; |
569 for (std::unique_ptr<NTPSnippet>& snippet : snippets_) { | 569 for (std::unique_ptr<NTPSnippet>& snippet : snippets_) { |
570 if (snippet->expiry_date() <= expiry) | 570 if (snippet->expiry_date() <= expiry) |
571 to_delete.emplace_back(std::move(snippet)); | 571 to_delete.emplace_back(std::move(snippet)); |
572 } | 572 } |
573 Compact(&snippets_); | 573 Compact(&snippets_); |
574 | 574 |
575 // Move expired discarded snippets over into |to_delete| as well. | 575 // Move expired dismissed snippets over into |to_delete| as well. |
576 for (std::unique_ptr<NTPSnippet>& snippet : discarded_snippets_) { | 576 for (std::unique_ptr<NTPSnippet>& snippet : dismissed_snippets_) { |
577 if (snippet->expiry_date() <= expiry) | 577 if (snippet->expiry_date() <= expiry) |
578 to_delete.emplace_back(std::move(snippet)); | 578 to_delete.emplace_back(std::move(snippet)); |
579 } | 579 } |
580 Compact(&discarded_snippets_); | 580 Compact(&dismissed_snippets_); |
581 | 581 |
582 // Finally, actually delete the removed snippets from the DB. | 582 // Finally, actually delete the removed snippets from the DB. |
583 database_->DeleteSnippets(to_delete); | 583 database_->DeleteSnippets(to_delete); |
584 | 584 |
585 // If there are any snippets left, schedule a timer for the next expiry. | 585 // If there are any snippets left, schedule a timer for the next expiry. |
586 if (snippets_.empty() && discarded_snippets_.empty()) | 586 if (snippets_.empty() && dismissed_snippets_.empty()) |
587 return; | 587 return; |
588 | 588 |
589 base::Time next_expiry = base::Time::Max(); | 589 base::Time next_expiry = base::Time::Max(); |
590 for (const auto& snippet : snippets_) { | 590 for (const auto& snippet : snippets_) { |
591 if (snippet->expiry_date() < next_expiry) | 591 if (snippet->expiry_date() < next_expiry) |
592 next_expiry = snippet->expiry_date(); | 592 next_expiry = snippet->expiry_date(); |
593 } | 593 } |
594 for (const auto& snippet : discarded_snippets_) { | 594 for (const auto& snippet : dismissed_snippets_) { |
595 if (snippet->expiry_date() < next_expiry) | 595 if (snippet->expiry_date() < next_expiry) |
596 next_expiry = snippet->expiry_date(); | 596 next_expiry = snippet->expiry_date(); |
597 } | 597 } |
598 DCHECK_GT(next_expiry, expiry); | 598 DCHECK_GT(next_expiry, expiry); |
599 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, | 599 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, |
600 base::Bind(&NTPSnippetsService::ClearExpiredSnippets, | 600 base::Bind(&NTPSnippetsService::ClearExpiredSnippets, |
601 base::Unretained(this))); | 601 base::Unretained(this))); |
602 } | 602 } |
603 | 603 |
604 void NTPSnippetsService::OnSnippetImageFetchedFromDatabase( | 604 void NTPSnippetsService::OnSnippetImageFetchedFromDatabase( |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 suggestions_service_subscription_ = | 663 suggestions_service_subscription_ = |
664 suggestions_service_->AddCallback(base::Bind( | 664 suggestions_service_->AddCallback(base::Bind( |
665 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this))); | 665 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this))); |
666 } | 666 } |
667 | 667 |
668 RescheduleFetching(); | 668 RescheduleFetching(); |
669 } | 669 } |
670 | 670 |
671 void NTPSnippetsService::EnterStateDisabled() { | 671 void NTPSnippetsService::EnterStateDisabled() { |
672 ClearCachedSuggestionsForDebugging(); | 672 ClearCachedSuggestionsForDebugging(); |
673 ClearDiscardedSuggestionsForDebugging(); | 673 ClearDismissedSuggestionsForDebugging(); |
674 | 674 |
675 expiry_timer_.Stop(); | 675 expiry_timer_.Stop(); |
676 suggestions_service_subscription_.reset(); | 676 suggestions_service_subscription_.reset(); |
677 RescheduleFetching(); | 677 RescheduleFetching(); |
678 } | 678 } |
679 | 679 |
680 void NTPSnippetsService::EnterStateShutdown() { | 680 void NTPSnippetsService::EnterStateShutdown() { |
681 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 681 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
682 NTPSnippetsServiceShutdown()); | 682 NTPSnippetsServiceShutdown()); |
683 | 683 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 } | 825 } |
826 | 826 |
827 void NTPSnippetsService::NotifyCategoryStatusChanged() { | 827 void NTPSnippetsService::NotifyCategoryStatusChanged() { |
828 if (observer_) { | 828 if (observer_) { |
829 observer_->OnCategoryStatusChanged(ContentSuggestionsCategory::ARTICLES, | 829 observer_->OnCategoryStatusChanged(ContentSuggestionsCategory::ARTICLES, |
830 category_status_); | 830 category_status_); |
831 } | 831 } |
832 } | 832 } |
833 | 833 |
834 } // namespace ntp_snippets | 834 } // namespace ntp_snippets |
OLD | NEW |