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

Side by Side Diff: components/ntp_snippets/ntp_snippets_service.cc

Issue 2047713002: [NTP Snippets] Cache images in a LevelDB (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@protodb_get
Patch Set: add TODOs Created 4 years, 6 months 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/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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « components/ntp_snippets/ntp_snippets_service.h ('k') | components/ntp_snippets/ntp_snippets_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698