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

Unified Diff: components/ntp_snippets/remote/remote_suggestions_provider.cc

Issue 2558393004: Refactoring: Moves image fetching and caching into CachedImageFetcher (Closed)
Patch Set: 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 side-by-side diff with in-line comments
Download patch
Index: components/ntp_snippets/remote/remote_suggestions_provider.cc
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider.cc b/components/ntp_snippets/remote/remote_suggestions_provider.cc
index 4ff354f6b697750382057030828db4b3d856afab..4d14d243ebf8d3da45160bf41e9844c5b848f28e 100644
--- a/components/ntp_snippets/remote/remote_suggestions_provider.cc
+++ b/components/ntp_snippets/remote/remote_suggestions_provider.cc
@@ -221,6 +221,106 @@ void CallWithEmptyResults(const FetchDoneCallback& callback,
} // namespace
+CachedImageFetcher::CachedImageFetcher(
+ std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
+ std::unique_ptr<image_fetcher::ImageDecoder> image_decoder,
+ PrefService* pref_service,
+ RemoteSuggestionsDatabase* database)
+ : image_fetcher_(std::move(image_fetcher)),
+ image_decoder_(std::move(image_decoder)),
+ database_(database),
+ thumbnail_requests_throttler_(
+ pref_service,
+ RequestThrottler::RequestType::CONTENT_SUGGESTION_THUMBNAIL) {
+ // |image_fetcher_| can be null in tests.
+ if (image_fetcher_) {
+ image_fetcher_->SetImageFetcherDelegate(this);
+ image_fetcher_->SetDataUseServiceName(
+ data_use_measurement::DataUseUserData::NTP_SNIPPETS);
+ }
+}
+
+CachedImageFetcher::~CachedImageFetcher() {}
+
+void CachedImageFetcher::FetchSuggestionImage(
+ const ContentSuggestion::ID& suggestion_id,
+ const GURL& url,
+ const ImageFetchedCallback& callback) {
+ database_->LoadImage(
+ suggestion_id.id_within_category(),
+ base::Bind(&CachedImageFetcher::OnSnippetImageFetchedFromDatabase,
+ base::Unretained(this), callback, suggestion_id, url));
+}
+
+// This function gets only called for caching the image data received from the
+// network. The actual decoding is done in OnSnippetImageDecodedFromDatabase().
+void CachedImageFetcher::OnImageDataFetched(
+ const std::string& id_within_category,
+ const std::string& image_data) {
+ if (image_data.empty()) {
+ return;
+ }
+ database_->SaveImage(id_within_category, image_data);
+}
+
+void CachedImageFetcher::OnImageDecodingDone(
+ const ImageFetchedCallback& callback,
+ const std::string& id_within_category,
+ const gfx::Image& image) {
+ callback.Run(image);
+}
+
+void CachedImageFetcher::OnSnippetImageFetchedFromDatabase(
+ const ImageFetchedCallback& callback,
+ const ContentSuggestion::ID& suggestion_id,
+ const GURL& url,
+ std::string data) { // SnippetImageCallback requires nonconst reference.
+ // |image_decoder_| is null in tests.
+ if (image_decoder_ && !data.empty()) {
+ image_decoder_->DecodeImage(
+ data, base::Bind(
+ &CachedImageFetcher::OnSnippetImageDecodedFromDatabase,
+ base::Unretained(this), callback, suggestion_id, url));
+ return;
+ }
+ // Fetching from the DB failed; start a network fetch.
+ FetchSnippetImageFromNetwork(suggestion_id, url, callback);
+}
+
+void CachedImageFetcher::OnSnippetImageDecodedFromDatabase(
+ const ImageFetchedCallback& callback,
+ const ContentSuggestion::ID& suggestion_id,
+ const GURL& url,
+ const gfx::Image& image) {
+ if (!image.IsEmpty()) {
+ callback.Run(image);
+ return;
+ }
+ // If decoding the image failed, delete the DB entry.
+ database_->DeleteImage(suggestion_id.id_within_category());
+ FetchSnippetImageFromNetwork(suggestion_id, url, callback);
+};
+
+void CachedImageFetcher::FetchSnippetImageFromNetwork(
+ const ContentSuggestion::ID& suggestion_id,
+ const GURL& url,
+ const ImageFetchedCallback& callback) {
+ if (url.is_empty() ||
+ !thumbnail_requests_throttler_.DemandQuotaForRequest(
+ /*interactive_request=*/true)) {
+ // Return an empty image. Directly, this is never synchronous with the
+ // original FetchSuggestionImage() call - an asynchronous database query has
+ // happened in the meantime.
+ callback.Run(gfx::Image());
+ return;
+ }
+
+ image_fetcher_->StartOrQueueNetworkRequest(
+ suggestion_id.id_within_category(), url,
+ base::Bind(&CachedImageFetcher::OnImageDecodingDone,
+ base::Unretained(this), callback));
+}
+
RemoteSuggestionsProvider::RemoteSuggestionsProvider(
Observer* observer,
CategoryFactory* category_factory,
@@ -242,15 +342,14 @@ RemoteSuggestionsProvider::RemoteSuggestionsProvider(
user_classifier_(user_classifier),
scheduler_(scheduler),
snippets_fetcher_(std::move(snippets_fetcher)),
- image_fetcher_(std::move(image_fetcher)),
- image_decoder_(std::move(image_decoder)),
database_(std::move(database)),
+ image_fetcher_(std::move(image_fetcher),
+ std::move(image_decoder),
+ pref_service,
+ database_.get()),
status_service_(std::move(status_service)),
fetch_when_ready_(false),
nuke_when_initialized_(false),
- thumbnail_requests_throttler_(
- pref_service,
- RequestThrottler::RequestType::CONTENT_SUGGESTION_THUMBNAIL),
tick_clock_(base::MakeUnique<base::DefaultTickClock>()) {
pref_service_->ClearPref(kDeprecatedSnippetHostsPref);
@@ -449,15 +548,6 @@ void RemoteSuggestionsProvider::DismissSuggestion(
suggestion_id.id_within_category());
}
-void RemoteSuggestionsProvider::FetchSuggestionImage(
- const ContentSuggestion::ID& suggestion_id,
- const ImageFetchedCallback& callback) {
- database_->LoadImage(
- suggestion_id.id_within_category(),
- base::Bind(&RemoteSuggestionsProvider::OnSnippetImageFetchedFromDatabase,
- base::Unretained(this), callback, suggestion_id));
-}
-
void RemoteSuggestionsProvider::ClearHistory(
base::Time begin,
base::Time end,
@@ -556,31 +646,6 @@ GURL RemoteSuggestionsProvider::FindSnippetImageUrl(
return snippet->salient_image_url();
}
-// image_fetcher::ImageFetcherDelegate implementation.
-void RemoteSuggestionsProvider::OnImageDataFetched(
- const std::string& id_within_category,
- const std::string& image_data) {
- if (image_data.empty()) {
- return;
- }
-
- // Only save the image if the corresponding snippet still exists.
- bool found = false;
- for (const auto& entry : category_contents_) {
- if (entry.second.FindSnippet(id_within_category)) {
- found = true;
- break;
- }
- }
- if (!found) {
- return;
- }
-
- // Only cache the data in the DB, the actual serving is done in the callback
- // provided to |image_fetcher_| (OnSnippetImageDecodedFromNetwork()).
- database_->SaveImage(id_within_category, image_data);
-}
-
void RemoteSuggestionsProvider::OnDatabaseLoaded(
NTPSnippet::PtrVector snippets) {
if (state_ == State::ERROR_OCCURRED) {
@@ -946,71 +1011,15 @@ void RemoteSuggestionsProvider::NukeAllSnippets() {
StoreCategoriesToPrefs();
}
-void RemoteSuggestionsProvider::OnSnippetImageFetchedFromDatabase(
- const ImageFetchedCallback& callback,
- const ContentSuggestion::ID& suggestion_id,
- std::string data) { // SnippetImageCallback requires nonconst reference.
- // |image_decoder_| is null in tests.
- if (image_decoder_ && !data.empty()) {
- image_decoder_->DecodeImage(
- data, base::Bind(
- &RemoteSuggestionsProvider::OnSnippetImageDecodedFromDatabase,
- base::Unretained(this), callback, suggestion_id));
- return;
- }
-
- // Fetching from the DB failed; start a network fetch.
- FetchSnippetImageFromNetwork(suggestion_id, callback);
-}
-
-void RemoteSuggestionsProvider::OnSnippetImageDecodedFromDatabase(
- const ImageFetchedCallback& callback,
- const ContentSuggestion::ID& suggestion_id,
- const gfx::Image& image) {
- if (!image.IsEmpty()) {
- callback.Run(image);
- return;
- }
-
- // If decoding the image failed, delete the DB entry.
- database_->DeleteImage(suggestion_id.id_within_category());
-
- FetchSnippetImageFromNetwork(suggestion_id, callback);
-}
-
-void RemoteSuggestionsProvider::FetchSnippetImageFromNetwork(
+void RemoteSuggestionsProvider::FetchSuggestionImage(
const ContentSuggestion::ID& suggestion_id,
const ImageFetchedCallback& callback) {
if (!base::ContainsKey(category_contents_, suggestion_id.category())) {
- OnSnippetImageDecodedFromNetwork(
- callback, suggestion_id.id_within_category(), gfx::Image());
+ callback.Run(gfx::Image());
return;
}
-
GURL image_url = FindSnippetImageUrl(suggestion_id);
jkrcal 2016/12/12 09:01:11 What about empty |image_url| (because the snippet
tschumann 2016/12/13 20:59:09 interesting! The actual behavior is still the same
Marc Treib 2016/12/14 09:02:15 Yup, this SGTM - I don't see what a DB lookup with
-
- if (image_url.is_empty() ||
- !thumbnail_requests_throttler_.DemandQuotaForRequest(
- /*interactive_request=*/true)) {
- // Return an empty image. Directly, this is never synchronous with the
- // original FetchSuggestionImage() call - an asynchronous database query has
- // happened in the meantime.
- OnSnippetImageDecodedFromNetwork(
- callback, suggestion_id.id_within_category(), gfx::Image());
- return;
- }
-
- image_fetcher_->StartOrQueueNetworkRequest(
- suggestion_id.id_within_category(), image_url,
- base::Bind(&RemoteSuggestionsProvider::OnSnippetImageDecodedFromNetwork,
- base::Unretained(this), callback));
-}
-
-void RemoteSuggestionsProvider::OnSnippetImageDecodedFromNetwork(
- const ImageFetchedCallback& callback,
- const std::string& id_within_category,
- const gfx::Image& image) {
- callback.Run(image);
+ image_fetcher_.FetchSuggestionImage(suggestion_id, image_url, callback);
}
void RemoteSuggestionsProvider::EnterStateReady() {
@@ -1059,13 +1068,6 @@ void RemoteSuggestionsProvider::FinishInitialization() {
nuke_when_initialized_ = false;
}
- // |image_fetcher_| can be null in tests.
- if (image_fetcher_) {
- image_fetcher_->SetImageFetcherDelegate(this);
- image_fetcher_->SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_SNIPPETS);
- }
-
// Note: Initializing the status service will run the callback right away with
// the current state.
status_service_->Init(base::Bind(&RemoteSuggestionsProvider::OnStatusChanged,

Powered by Google App Engine
This is Rietveld 408576698