| 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 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
| 17 #include "base/path_service.h" | 17 #include "base/path_service.h" |
| 18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/task_runner_util.h" | 19 #include "base/task_runner_util.h" |
| 20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 21 #include "base/values.h" | 21 #include "base/values.h" |
| 22 #include "components/image_fetcher/image_decoder.h" |
| 22 #include "components/image_fetcher/image_fetcher.h" | 23 #include "components/image_fetcher/image_fetcher.h" |
| 23 #include "components/ntp_snippets/ntp_snippets_constants.h" | 24 #include "components/ntp_snippets/ntp_snippets_constants.h" |
| 24 #include "components/ntp_snippets/ntp_snippets_database.h" | 25 #include "components/ntp_snippets/ntp_snippets_database.h" |
| 25 #include "components/ntp_snippets/pref_names.h" | 26 #include "components/ntp_snippets/pref_names.h" |
| 26 #include "components/ntp_snippets/switches.h" | 27 #include "components/ntp_snippets/switches.h" |
| 27 #include "components/prefs/pref_registry_simple.h" | 28 #include "components/prefs/pref_registry_simple.h" |
| 28 #include "components/prefs/pref_service.h" | 29 #include "components/prefs/pref_service.h" |
| 29 #include "components/suggestions/proto/suggestions.pb.h" | 30 #include "components/suggestions/proto/suggestions.pb.h" |
| 30 #include "components/sync_driver/sync_service.h" | 31 #include "components/sync_driver/sync_service.h" |
| 31 #include "components/variations/variations_associated_data.h" | 32 #include "components/variations/variations_associated_data.h" |
| 32 #include "ui/gfx/image/image.h" | 33 #include "ui/gfx/image/image.h" |
| 33 | 34 |
| 35 using image_fetcher::ImageDecoder; |
| 34 using image_fetcher::ImageFetcher; | 36 using image_fetcher::ImageFetcher; |
| 35 using suggestions::ChromeSuggestion; | 37 using suggestions::ChromeSuggestion; |
| 36 using suggestions::SuggestionsProfile; | 38 using suggestions::SuggestionsProfile; |
| 37 using suggestions::SuggestionsService; | 39 using suggestions::SuggestionsService; |
| 38 | 40 |
| 39 namespace ntp_snippets { | 41 namespace ntp_snippets { |
| 40 | 42 |
| 41 namespace { | 43 namespace { |
| 42 | 44 |
| 43 // Number of snippets requested to the server. Consider replacing sparse UMA | 45 // Number of snippets requested to the server. Consider replacing sparse UMA |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 | 181 |
| 180 NTPSnippetsService::NTPSnippetsService( | 182 NTPSnippetsService::NTPSnippetsService( |
| 181 bool enabled, | 183 bool enabled, |
| 182 PrefService* pref_service, | 184 PrefService* pref_service, |
| 183 sync_driver::SyncService* sync_service, | 185 sync_driver::SyncService* sync_service, |
| 184 SuggestionsService* suggestions_service, | 186 SuggestionsService* suggestions_service, |
| 185 const std::string& application_language_code, | 187 const std::string& application_language_code, |
| 186 NTPSnippetsScheduler* scheduler, | 188 NTPSnippetsScheduler* scheduler, |
| 187 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, | 189 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher, |
| 188 std::unique_ptr<ImageFetcher> image_fetcher, | 190 std::unique_ptr<ImageFetcher> image_fetcher, |
| 191 std::unique_ptr<ImageDecoder> image_decoder, |
| 189 std::unique_ptr<NTPSnippetsDatabase> database) | 192 std::unique_ptr<NTPSnippetsDatabase> database) |
| 190 : state_(State::NOT_INITED), | 193 : state_(State::NOT_INITED), |
| 191 explicitly_disabled_(!enabled), | 194 explicitly_disabled_(!enabled), |
| 192 pref_service_(pref_service), | 195 pref_service_(pref_service), |
| 193 sync_service_(sync_service), | 196 sync_service_(sync_service), |
| 194 sync_service_observer_(this), | 197 sync_service_observer_(this), |
| 195 suggestions_service_(suggestions_service), | 198 suggestions_service_(suggestions_service), |
| 196 application_language_code_(application_language_code), | 199 application_language_code_(application_language_code), |
| 197 scheduler_(scheduler), | 200 scheduler_(scheduler), |
| 198 snippets_fetcher_(std::move(snippets_fetcher)), | 201 snippets_fetcher_(std::move(snippets_fetcher)), |
| 199 image_fetcher_(std::move(image_fetcher)), | 202 image_fetcher_(std::move(image_fetcher)), |
| 203 image_decoder_(std::move(image_decoder)), |
| 200 database_(std::move(database)), | 204 database_(std::move(database)), |
| 201 fetch_after_load_(false) { | 205 fetch_after_load_(false) { |
| 202 // TODO(dgn) should be removed after branch point (https:://crbug.com/617585). | 206 // TODO(dgn) should be removed after branch point (https:://crbug.com/617585). |
| 203 ClearDeprecatedPrefs(); | 207 ClearDeprecatedPrefs(); |
| 204 | 208 |
| 205 if (explicitly_disabled_) { | 209 if (explicitly_disabled_) { |
| 206 EnterState(State::DISABLED); | 210 EnterState(State::DISABLED); |
| 207 return; | 211 return; |
| 208 } | 212 } |
| 209 | 213 |
| 210 // We transition to other states while finalizing the initialization, when the | 214 // We transition to other states while finalizing the initialization, when the |
| 211 // database is done loading. | 215 // database is done loading. |
| 212 database_->Load(base::Bind(&NTPSnippetsService::OnDatabaseLoaded, | 216 database_->LoadSnippets(base::Bind(&NTPSnippetsService::OnDatabaseLoaded, |
| 213 base::Unretained(this))); | 217 base::Unretained(this))); |
| 214 } | 218 } |
| 215 | 219 |
| 216 NTPSnippetsService::~NTPSnippetsService() { | 220 NTPSnippetsService::~NTPSnippetsService() { |
| 217 DCHECK(state_ == State::SHUT_DOWN); | 221 DCHECK(state_ == State::SHUT_DOWN); |
| 218 } | 222 } |
| 219 | 223 |
| 220 // static | 224 // static |
| 221 void NTPSnippetsService::RegisterProfilePrefs(PrefRegistrySimple* registry) { | 225 void NTPSnippetsService::RegisterProfilePrefs(PrefRegistrySimple* registry) { |
| 222 registry->RegisterListPref(prefs::kDeprecatedSnippets); | 226 registry->RegisterListPref(prefs::kDeprecatedSnippets); |
| 223 registry->RegisterListPref(prefs::kDeprecatedDiscardedSnippets); | 227 registry->RegisterListPref(prefs::kDeprecatedDiscardedSnippets); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 GetFetchingIntervalWifiCharging(), GetFetchingIntervalWifi(now), | 259 GetFetchingIntervalWifiCharging(), GetFetchingIntervalWifi(now), |
| 256 GetFetchingIntervalFallback(), GetRescheduleTime(now)); | 260 GetFetchingIntervalFallback(), GetRescheduleTime(now)); |
| 257 } else { | 261 } else { |
| 258 scheduler_->Unschedule(); | 262 scheduler_->Unschedule(); |
| 259 } | 263 } |
| 260 } | 264 } |
| 261 | 265 |
| 262 void NTPSnippetsService::FetchSnippetImage( | 266 void NTPSnippetsService::FetchSnippetImage( |
| 263 const std::string& snippet_id, | 267 const std::string& snippet_id, |
| 264 const ImageFetchedCallback& callback) { | 268 const ImageFetchedCallback& callback) { |
| 265 auto it = | 269 database_->LoadImage( |
| 266 std::find_if(snippets_.begin(), snippets_.end(), | 270 snippet_id, |
| 267 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { | 271 base::Bind(&NTPSnippetsService::OnSnippetImageFetchedFromDatabase, |
| 268 return snippet->id() == snippet_id; | 272 base::Unretained(this), snippet_id, callback)); |
| 269 }); | |
| 270 if (it == snippets_.end()) { | |
| 271 gfx::Image empty_image; | |
| 272 callback.Run(snippet_id, empty_image); | |
| 273 return; | |
| 274 } | |
| 275 | |
| 276 const NTPSnippet& snippet = *it->get(); | |
| 277 image_fetcher_->StartOrQueueNetworkRequest( | |
| 278 snippet.id(), snippet.salient_image_url(), callback); | |
| 279 // TODO(treib): Cache/persist the snippet image. | |
| 280 } | 273 } |
| 281 | 274 |
| 282 void NTPSnippetsService::ClearSnippets() { | 275 void NTPSnippetsService::ClearSnippets() { |
| 283 if (!initialized()) | 276 if (!initialized()) |
| 284 return; | 277 return; |
| 285 | 278 |
| 286 if (snippets_.empty()) | 279 if (snippets_.empty()) |
| 287 return; | 280 return; |
| 288 | 281 |
| 289 database_->Delete(snippets_); | 282 database_->DeleteSnippets(snippets_); |
| 290 snippets_.clear(); | 283 snippets_.clear(); |
| 291 | 284 |
| 292 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 285 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 293 NTPSnippetsServiceLoaded()); | 286 NTPSnippetsServiceLoaded()); |
| 294 } | 287 } |
| 295 | 288 |
| 296 std::set<std::string> NTPSnippetsService::GetSuggestionsHosts() const { | 289 std::set<std::string> NTPSnippetsService::GetSuggestionsHosts() const { |
| 297 // |suggestions_service_| can be null in tests. | 290 // |suggestions_service_| can be null in tests. |
| 298 if (!suggestions_service_) | 291 if (!suggestions_service_) |
| 299 return std::set<std::string>(); | 292 return std::set<std::string>(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 310 auto it = | 303 auto it = |
| 311 std::find_if(snippets_.begin(), snippets_.end(), | 304 std::find_if(snippets_.begin(), snippets_.end(), |
| 312 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { | 305 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { |
| 313 return snippet->id() == snippet_id; | 306 return snippet->id() == snippet_id; |
| 314 }); | 307 }); |
| 315 if (it == snippets_.end()) | 308 if (it == snippets_.end()) |
| 316 return false; | 309 return false; |
| 317 | 310 |
| 318 (*it)->set_discarded(true); | 311 (*it)->set_discarded(true); |
| 319 | 312 |
| 320 database_->Save(**it); | 313 database_->SaveSnippet(**it); |
| 314 database_->DeleteImage((*it)->id()); |
| 321 | 315 |
| 322 discarded_snippets_.push_back(std::move(*it)); | 316 discarded_snippets_.push_back(std::move(*it)); |
| 323 snippets_.erase(it); | 317 snippets_.erase(it); |
| 324 | 318 |
| 325 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 319 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 326 NTPSnippetsServiceLoaded()); | 320 NTPSnippetsServiceLoaded()); |
| 327 return true; | 321 return true; |
| 328 } | 322 } |
| 329 | 323 |
| 330 void NTPSnippetsService::ClearDiscardedSnippets() { | 324 void NTPSnippetsService::ClearDiscardedSnippets() { |
| 331 if (!initialized()) | 325 if (!initialized()) |
| 332 return; | 326 return; |
| 333 | 327 |
| 334 database_->Delete(discarded_snippets_); | 328 database_->DeleteSnippets(discarded_snippets_); |
| 335 discarded_snippets_.clear(); | 329 discarded_snippets_.clear(); |
| 336 } | 330 } |
| 337 | 331 |
| 338 void NTPSnippetsService::AddObserver(NTPSnippetsServiceObserver* observer) { | 332 void NTPSnippetsService::AddObserver(NTPSnippetsServiceObserver* observer) { |
| 339 observers_.AddObserver(observer); | 333 observers_.AddObserver(observer); |
| 340 } | 334 } |
| 341 | 335 |
| 342 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) { | 336 void NTPSnippetsService::RemoveObserver(NTPSnippetsServiceObserver* observer) { |
| 343 observers_.RemoveObserver(observer); | 337 observers_.RemoveObserver(observer); |
| 344 } | 338 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 // Private methods | 374 // Private methods |
| 381 | 375 |
| 382 void NTPSnippetsService::OnStateChanged() { | 376 void NTPSnippetsService::OnStateChanged() { |
| 383 if (state_ == State::SHUT_DOWN) | 377 if (state_ == State::SHUT_DOWN) |
| 384 return; | 378 return; |
| 385 | 379 |
| 386 DVLOG(1) << "[OnStateChanged]"; | 380 DVLOG(1) << "[OnStateChanged]"; |
| 387 EnterState(GetStateForDependenciesStatus()); | 381 EnterState(GetStateForDependenciesStatus()); |
| 388 } | 382 } |
| 389 | 383 |
| 384 // image_fetcher::ImageFetcherDelegate implementation. |
| 385 void NTPSnippetsService::OnImageDataFetched(const std::string& snippet_id, |
| 386 const std::string& image_data) { |
| 387 if (image_data.empty()) |
| 388 return; |
| 389 |
| 390 // Only save the image if the corresponding snippet still exists. |
| 391 auto it = |
| 392 std::find_if(snippets_.begin(), snippets_.end(), |
| 393 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { |
| 394 return snippet->id() == snippet_id; |
| 395 }); |
| 396 if (it == snippets_.end()) |
| 397 return; |
| 398 |
| 399 database_->SaveImage(snippet_id, image_data); |
| 400 } |
| 401 |
| 390 void NTPSnippetsService::OnDatabaseLoaded(NTPSnippet::PtrVector snippets) { | 402 void NTPSnippetsService::OnDatabaseLoaded(NTPSnippet::PtrVector snippets) { |
| 391 DCHECK(state_ == State::NOT_INITED || state_ == State::SHUT_DOWN); | 403 DCHECK(state_ == State::NOT_INITED || state_ == State::SHUT_DOWN); |
| 392 if (state_ == State::SHUT_DOWN) | 404 if (state_ == State::SHUT_DOWN) |
| 393 return; | 405 return; |
| 394 | 406 |
| 395 DCHECK(snippets_.empty()); | 407 DCHECK(snippets_.empty()); |
| 396 DCHECK(discarded_snippets_.empty()); | 408 DCHECK(discarded_snippets_.empty()); |
| 397 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { | 409 for (std::unique_ptr<NTPSnippet>& snippet : snippets) { |
| 398 if (snippet->is_discarded()) | 410 if (snippet->is_discarded()) |
| 399 discarded_snippets_.emplace_back(std::move(snippet)); | 411 discarded_snippets_.emplace_back(std::move(snippet)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 422 // TODO(treib,maybelle): If there is another source with an allowed host, | 434 // TODO(treib,maybelle): If there is another source with an allowed host, |
| 423 // then we should fall back to that. | 435 // then we should fall back to that. |
| 424 // First, move them over into |to_delete|. | 436 // First, move them over into |to_delete|. |
| 425 NTPSnippet::PtrVector to_delete; | 437 NTPSnippet::PtrVector to_delete; |
| 426 for (std::unique_ptr<NTPSnippet>& snippet : snippets_) { | 438 for (std::unique_ptr<NTPSnippet>& snippet : snippets_) { |
| 427 if (!hosts.count(snippet->best_source().url.host())) | 439 if (!hosts.count(snippet->best_source().url.host())) |
| 428 to_delete.emplace_back(std::move(snippet)); | 440 to_delete.emplace_back(std::move(snippet)); |
| 429 } | 441 } |
| 430 Compact(&snippets_); | 442 Compact(&snippets_); |
| 431 // Then delete the removed snippets from the database. | 443 // Then delete the removed snippets from the database. |
| 432 database_->Delete(to_delete); | 444 database_->DeleteSnippets(to_delete); |
| 433 | 445 |
| 434 StoreSnippetHostsToPrefs(hosts); | 446 StoreSnippetHostsToPrefs(hosts); |
| 435 | 447 |
| 436 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 448 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 437 NTPSnippetsServiceLoaded()); | 449 NTPSnippetsServiceLoaded()); |
| 438 | 450 |
| 439 FetchSnippetsFromHosts(hosts); | 451 FetchSnippetsFromHosts(hosts); |
| 440 } | 452 } |
| 441 | 453 |
| 442 void NTPSnippetsService::OnFetchFinished( | 454 void NTPSnippetsService::OnFetchFinished( |
| 443 NTPSnippetsFetcher::OptionalSnippets snippets) { | 455 NTPSnippetsFetcher::OptionalSnippets snippets) { |
| 444 if (!ready()) | 456 if (!ready()) |
| 445 return; | 457 return; |
| 446 | 458 |
| 447 if (snippets) { | 459 if (snippets) { |
| 448 // Sparse histogram used because the number of snippets is small (bound by | 460 // Sparse histogram used because the number of snippets is small (bound by |
| 449 // kMaxSnippetCount). | 461 // kMaxSnippetCount). |
| 450 DCHECK_LE(snippets->size(), static_cast<size_t>(kMaxSnippetCount)); | 462 DCHECK_LE(snippets->size(), static_cast<size_t>(kMaxSnippetCount)); |
| 451 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticlesFetched", | 463 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticlesFetched", |
| 452 snippets->size()); | 464 snippets->size()); |
| 453 MergeSnippets(std::move(*snippets)); | 465 MergeSnippets(std::move(*snippets)); |
| 454 } | 466 } |
| 455 | 467 |
| 456 ClearExpiredSnippets(); | 468 ClearExpiredSnippets(); |
| 457 | 469 |
| 458 // If there are still more snippets than we want to show, move the extra ones | 470 // If there are more snippets than we want to show, delete the extra ones. |
| 459 // over into |to_delete|. | |
| 460 NTPSnippet::PtrVector to_delete; | |
| 461 if (snippets_.size() > kMaxSnippetCount) { | 471 if (snippets_.size() > kMaxSnippetCount) { |
| 462 to_delete.insert( | 472 NTPSnippet::PtrVector to_delete( |
| 463 to_delete.end(), | |
| 464 std::make_move_iterator(snippets_.begin() + kMaxSnippetCount), | 473 std::make_move_iterator(snippets_.begin() + kMaxSnippetCount), |
| 465 std::make_move_iterator(snippets_.end())); | 474 std::make_move_iterator(snippets_.end())); |
| 466 snippets_.resize(kMaxSnippetCount); | 475 snippets_.resize(kMaxSnippetCount); |
| 476 database_->DeleteSnippets(to_delete); |
| 467 } | 477 } |
| 468 database_->Delete(to_delete); | |
| 469 | 478 |
| 470 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", | 479 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles", |
| 471 snippets_.size()); | 480 snippets_.size()); |
| 472 if (snippets_.empty() && !discarded_snippets_.empty()) { | 481 if (snippets_.empty() && !discarded_snippets_.empty()) { |
| 473 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", | 482 UMA_HISTOGRAM_COUNTS("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded", |
| 474 discarded_snippets_.size()); | 483 discarded_snippets_.size()); |
| 475 } | 484 } |
| 476 | 485 |
| 477 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, | 486 FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_, |
| 478 NTPSnippetsServiceLoaded()); | 487 NTPSnippetsServiceLoaded()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 int num_snippets_discarded = num_new_snippets - new_snippets.size(); | 535 int num_snippets_discarded = num_new_snippets - new_snippets.size(); |
| 527 UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch", | 536 UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch", |
| 528 num_snippets_discarded > 0); | 537 num_snippets_discarded > 0); |
| 529 if (num_snippets_discarded > 0) { | 538 if (num_snippets_discarded > 0) { |
| 530 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets", | 539 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumIncompleteSnippets", |
| 531 num_snippets_discarded); | 540 num_snippets_discarded); |
| 532 } | 541 } |
| 533 } | 542 } |
| 534 | 543 |
| 535 // Save the new snippets to the DB. | 544 // Save the new snippets to the DB. |
| 536 database_->Save(new_snippets); | 545 database_->SaveSnippets(new_snippets); |
| 537 | 546 |
| 538 // Insert the new snippets at the front. | 547 // Insert the new snippets at the front. |
| 539 snippets_.insert(snippets_.begin(), | 548 snippets_.insert(snippets_.begin(), |
| 540 std::make_move_iterator(new_snippets.begin()), | 549 std::make_move_iterator(new_snippets.begin()), |
| 541 std::make_move_iterator(new_snippets.end())); | 550 std::make_move_iterator(new_snippets.end())); |
| 542 } | 551 } |
| 543 | 552 |
| 544 std::set<std::string> NTPSnippetsService::GetSnippetHostsFromPrefs() const { | 553 std::set<std::string> NTPSnippetsService::GetSnippetHostsFromPrefs() const { |
| 545 std::set<std::string> hosts; | 554 std::set<std::string> hosts; |
| 546 const base::ListValue* list = pref_service_->GetList(prefs::kSnippetHosts); | 555 const base::ListValue* list = pref_service_->GetList(prefs::kSnippetHosts); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 573 Compact(&snippets_); | 582 Compact(&snippets_); |
| 574 | 583 |
| 575 // Move expired discarded snippets over into |to_delete| as well. | 584 // Move expired discarded snippets over into |to_delete| as well. |
| 576 for (std::unique_ptr<NTPSnippet>& snippet : discarded_snippets_) { | 585 for (std::unique_ptr<NTPSnippet>& snippet : discarded_snippets_) { |
| 577 if (snippet->expiry_date() <= expiry) | 586 if (snippet->expiry_date() <= expiry) |
| 578 to_delete.emplace_back(std::move(snippet)); | 587 to_delete.emplace_back(std::move(snippet)); |
| 579 } | 588 } |
| 580 Compact(&discarded_snippets_); | 589 Compact(&discarded_snippets_); |
| 581 | 590 |
| 582 // Finally, actually delete the removed snippets from the DB. | 591 // Finally, actually delete the removed snippets from the DB. |
| 583 database_->Delete(to_delete); | 592 database_->DeleteSnippets(to_delete); |
| 584 | 593 |
| 585 // If there are any snippets left, schedule a timer for the next expiry. | 594 // If there are any snippets left, schedule a timer for the next expiry. |
| 586 if (snippets_.empty() && discarded_snippets_.empty()) | 595 if (snippets_.empty() && discarded_snippets_.empty()) |
| 587 return; | 596 return; |
| 588 | 597 |
| 589 base::Time next_expiry = base::Time::Max(); | 598 base::Time next_expiry = base::Time::Max(); |
| 590 for (const auto& snippet : snippets_) { | 599 for (const auto& snippet : snippets_) { |
| 591 if (snippet->expiry_date() < next_expiry) | 600 if (snippet->expiry_date() < next_expiry) |
| 592 next_expiry = snippet->expiry_date(); | 601 next_expiry = snippet->expiry_date(); |
| 593 } | 602 } |
| 594 for (const auto& snippet : discarded_snippets_) { | 603 for (const auto& snippet : discarded_snippets_) { |
| 595 if (snippet->expiry_date() < next_expiry) | 604 if (snippet->expiry_date() < next_expiry) |
| 596 next_expiry = snippet->expiry_date(); | 605 next_expiry = snippet->expiry_date(); |
| 597 } | 606 } |
| 598 DCHECK_GT(next_expiry, expiry); | 607 DCHECK_GT(next_expiry, expiry); |
| 599 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, | 608 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, |
| 600 base::Bind(&NTPSnippetsService::ClearExpiredSnippets, | 609 base::Bind(&NTPSnippetsService::ClearExpiredSnippets, |
| 601 base::Unretained(this))); | 610 base::Unretained(this))); |
| 602 } | 611 } |
| 603 | 612 |
| 613 void NTPSnippetsService::OnSnippetImageFetchedFromDatabase( |
| 614 const std::string& snippet_id, |
| 615 const ImageFetchedCallback& callback, |
| 616 std::string data) { |
| 617 // |image_decoder_| is null on iOS and in tests. |
| 618 if (image_decoder_ && !data.empty()) { |
| 619 image_decoder_->DecodeImage( |
| 620 std::move(data), |
| 621 base::Bind(&NTPSnippetsService::OnSnippetImageDecoded, |
| 622 base::Unretained(this), snippet_id, callback)); |
| 623 return; |
| 624 } |
| 625 |
| 626 // Fetching from the DB failed; start a network fetch. |
| 627 FetchSnippetImageFromNetwork(snippet_id, callback); |
| 628 } |
| 629 |
| 630 void NTPSnippetsService::OnSnippetImageDecoded( |
| 631 const std::string& snippet_id, |
| 632 const ImageFetchedCallback& callback, |
| 633 const gfx::Image& image) { |
| 634 if (!image.IsEmpty()) { |
| 635 callback.Run(snippet_id, image); |
| 636 return; |
| 637 } |
| 638 |
| 639 // If decoding the image failed, delete the DB entry. |
| 640 database_->DeleteImage(snippet_id); |
| 641 |
| 642 FetchSnippetImageFromNetwork(snippet_id, callback); |
| 643 } |
| 644 |
| 645 void NTPSnippetsService::FetchSnippetImageFromNetwork( |
| 646 const std::string& snippet_id, |
| 647 const ImageFetchedCallback& callback) { |
| 648 auto it = |
| 649 std::find_if(snippets_.begin(), snippets_.end(), |
| 650 [&snippet_id](const std::unique_ptr<NTPSnippet>& snippet) { |
| 651 return snippet->id() == snippet_id; |
| 652 }); |
| 653 if (it == snippets_.end()) { |
| 654 callback.Run(snippet_id, gfx::Image()); |
| 655 return; |
| 656 } |
| 657 |
| 658 const NTPSnippet& snippet = *it->get(); |
| 659 image_fetcher_->StartOrQueueNetworkRequest( |
| 660 snippet.id(), snippet.salient_image_url(), callback); |
| 661 } |
| 662 |
| 604 void NTPSnippetsService::EnterStateEnabled(bool fetch_snippets) { | 663 void NTPSnippetsService::EnterStateEnabled(bool fetch_snippets) { |
| 605 if (fetch_snippets) | 664 if (fetch_snippets) |
| 606 FetchSnippets(); | 665 FetchSnippets(); |
| 607 | 666 |
| 608 // If host restrictions are enabled, register for host list updates. | 667 // If host restrictions are enabled, register for host list updates. |
| 609 // |suggestions_service_| can be null in tests. | 668 // |suggestions_service_| can be null in tests. |
| 610 if (snippets_fetcher_->UsesHostRestrictions() && suggestions_service_) { | 669 if (snippets_fetcher_->UsesHostRestrictions() && suggestions_service_) { |
| 611 suggestions_service_subscription_ = | 670 suggestions_service_subscription_ = |
| 612 suggestions_service_->AddCallback(base::Bind( | 671 suggestions_service_->AddCallback(base::Bind( |
| 613 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this))); | 672 &NTPSnippetsService::OnSuggestionsChanged, base::Unretained(this))); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 636 suggestions_service_subscription_.reset(); | 695 suggestions_service_subscription_.reset(); |
| 637 | 696 |
| 638 if (sync_service_) | 697 if (sync_service_) |
| 639 sync_service_observer_.Remove(sync_service_); | 698 sync_service_observer_.Remove(sync_service_); |
| 640 } | 699 } |
| 641 | 700 |
| 642 void NTPSnippetsService::FinishInitialization() { | 701 void NTPSnippetsService::FinishInitialization() { |
| 643 snippets_fetcher_->SetCallback( | 702 snippets_fetcher_->SetCallback( |
| 644 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this))); | 703 base::Bind(&NTPSnippetsService::OnFetchFinished, base::Unretained(this))); |
| 645 | 704 |
| 705 // |image_fetcher_| can be null in tests. |
| 706 if (image_fetcher_) |
| 707 image_fetcher_->SetImageFetcherDelegate(this); |
| 708 |
| 646 // |sync_service_| can be null in tests or if sync is disabled. | 709 // |sync_service_| can be null in tests or if sync is disabled. |
| 647 // This is a service we want to keep listening to all the time, independently | 710 // This is a service we want to keep listening to all the time, independently |
| 648 // from the state, since it will allow us to enable or disable the snippets | 711 // from the state, since it will allow us to enable or disable the snippets |
| 649 // service. | 712 // service. |
| 650 if (sync_service_) | 713 if (sync_service_) |
| 651 sync_service_observer_.Add(sync_service_); | 714 sync_service_observer_.Add(sync_service_); |
| 652 | 715 |
| 653 // Change state after we started loading the snippets. During startup, the | 716 // Change state after we started loading the snippets. During startup, the |
| 654 // Sync service might not be completely loaded when we initialize this | 717 // Sync service might not be completely loaded when we initialize this |
| 655 // service, so we might stay in the NOT_INITED state until the sync state is | 718 // service, so we might stay in the NOT_INITED state until the sync state is |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 return; | 791 return; |
| 729 } | 792 } |
| 730 } | 793 } |
| 731 | 794 |
| 732 void NTPSnippetsService::ClearDeprecatedPrefs() { | 795 void NTPSnippetsService::ClearDeprecatedPrefs() { |
| 733 pref_service_->ClearPref(prefs::kDeprecatedSnippets); | 796 pref_service_->ClearPref(prefs::kDeprecatedSnippets); |
| 734 pref_service_->ClearPref(prefs::kDeprecatedDiscardedSnippets); | 797 pref_service_->ClearPref(prefs::kDeprecatedDiscardedSnippets); |
| 735 } | 798 } |
| 736 | 799 |
| 737 } // namespace ntp_snippets | 800 } // namespace ntp_snippets |
| OLD | NEW |