| 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 |