| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/content_suggestions_service.h" | 5 #include "components/ntp_snippets/content_suggestions_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
| 17 #include "base/time/default_clock.h" | 18 #include "base/time/default_clock.h" |
| 18 #include "base/values.h" | 19 #include "base/values.h" |
| 19 #include "components/favicon/core/large_icon_service.h" | 20 #include "components/favicon/core/large_icon_service.h" |
| 20 #include "components/favicon_base/fallback_icon_style.h" | 21 #include "components/favicon_base/fallback_icon_style.h" |
| 21 #include "components/favicon_base/favicon_types.h" | 22 #include "components/favicon_base/favicon_types.h" |
| 22 #include "components/ntp_snippets/pref_names.h" | 23 #include "components/ntp_snippets/pref_names.h" |
| 23 #include "components/prefs/pref_registry_simple.h" | 24 #include "components/prefs/pref_registry_simple.h" |
| 24 #include "components/prefs/pref_service.h" | 25 #include "components/prefs/pref_service.h" |
| 25 #include "ui/gfx/image/image.h" | 26 #include "ui/gfx/image/image.h" |
| 26 | 27 |
| 27 namespace ntp_snippets { | 28 namespace ntp_snippets { |
| 28 | 29 |
| 30 namespace { |
| 31 |
| 32 // Enumeration listing all possible outcomes for fetch attempts of favicons for |
| 33 // content suggestions. Used for UMA histograms, so do not change existing |
| 34 // values. Insert new values at the end, and update the histogram definition. |
| 35 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ntp.snippets |
| 36 enum class FaviconFetchResult { |
| 37 SUCCESS_CACHED = 0, |
| 38 SUCCESS_FETCHED = 1, |
| 39 FAILURE = 2, |
| 40 COUNT = 3 |
| 41 }; |
| 42 |
| 43 void RecordFaviconFetchResult(FaviconFetchResult result) { |
| 44 UMA_HISTOGRAM_ENUMERATION( |
| 45 "NewTabPage.ContentSuggestions.ArticleFaviconFetchResult", result, |
| 46 FaviconFetchResult::COUNT); |
| 47 } |
| 48 |
| 49 } // namespace |
| 50 |
| 29 ContentSuggestionsService::ContentSuggestionsService( | 51 ContentSuggestionsService::ContentSuggestionsService( |
| 30 State state, | 52 State state, |
| 31 SigninManagerBase* signin_manager, | 53 SigninManagerBase* signin_manager, |
| 32 history::HistoryService* history_service, | 54 history::HistoryService* history_service, |
| 33 favicon::LargeIconService* large_icon_service, | 55 favicon::LargeIconService* large_icon_service, |
| 34 PrefService* pref_service, | 56 PrefService* pref_service, |
| 35 std::unique_ptr<CategoryRanker> category_ranker, | 57 std::unique_ptr<CategoryRanker> category_ranker, |
| 36 std::unique_ptr<UserClassifier> user_classifier, | 58 std::unique_ptr<UserClassifier> user_classifier, |
| 37 std::unique_ptr<RemoteSuggestionsScheduler> remote_suggestions_scheduler) | 59 std::unique_ptr<RemoteSuggestionsScheduler> remote_suggestions_scheduler) |
| 38 : state_(state), | 60 : state_(state), |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 std::vector<ContentSuggestion>* suggestions = | 164 std::vector<ContentSuggestion>* suggestions = |
| 143 &suggestions_by_category_[suggestion_id.category()]; | 165 &suggestions_by_category_[suggestion_id.category()]; |
| 144 auto position = | 166 auto position = |
| 145 std::find_if(suggestions->begin(), suggestions->end(), | 167 std::find_if(suggestions->begin(), suggestions->end(), |
| 146 [&suggestion_id](const ContentSuggestion& suggestion) { | 168 [&suggestion_id](const ContentSuggestion& suggestion) { |
| 147 return suggestion_id == suggestion.id(); | 169 return suggestion_id == suggestion.id(); |
| 148 }); | 170 }); |
| 149 if (position == suggestions->end() || !large_icon_service_) { | 171 if (position == suggestions->end() || !large_icon_service_) { |
| 150 base::ThreadTaskRunnerHandle::Get()->PostTask( | 172 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 151 FROM_HERE, base::Bind(callback, gfx::Image())); | 173 FROM_HERE, base::Bind(callback, gfx::Image())); |
| 174 RecordFaviconFetchResult(FaviconFetchResult::FAILURE); |
| 152 return; | 175 return; |
| 153 } | 176 } |
| 154 | 177 |
| 155 const GURL& publisher_url = position->url().GetWithEmptyPath(); | 178 const GURL& publisher_url = position->url().GetWithEmptyPath(); |
| 156 | 179 |
| 157 // TODO(jkrcal): Create a general wrapper function in LargeIconService that | 180 // TODO(jkrcal): Create a general wrapper function in LargeIconService that |
| 158 // does handle the get-from-cache-and-fallback-to-google-server functionality | 181 // does handle the get-from-cache-and-fallback-to-google-server functionality |
| 159 // in one shot (for all clients that do not need to react in between). | 182 // in one shot (for all clients that do not need to react in between). |
| 160 large_icon_service_->GetLargeIconImageOrFallbackStyle( | 183 large_icon_service_->GetLargeIconImageOrFallbackStyle( |
| 161 publisher_url, minimum_size_in_pixel, desired_size_in_pixel, | 184 publisher_url, minimum_size_in_pixel, desired_size_in_pixel, |
| 162 base::Bind(&ContentSuggestionsService::OnGetFaviconFromCacheFinished, | 185 base::Bind(&ContentSuggestionsService::OnGetFaviconFromCacheFinished, |
| 163 base::Unretained(this), publisher_url, minimum_size_in_pixel, | 186 base::Unretained(this), publisher_url, minimum_size_in_pixel, |
| 164 desired_size_in_pixel, callback, | 187 desired_size_in_pixel, callback, |
| 165 /*continue_to_google_server=*/true), | 188 /*continue_to_google_server=*/true), |
| 166 &favicons_task_tracker_); | 189 &favicons_task_tracker_); |
| 167 } | 190 } |
| 168 | 191 |
| 169 void ContentSuggestionsService::OnGetFaviconFromCacheFinished( | 192 void ContentSuggestionsService::OnGetFaviconFromCacheFinished( |
| 170 const GURL& publisher_url, | 193 const GURL& publisher_url, |
| 171 int minimum_size_in_pixel, | 194 int minimum_size_in_pixel, |
| 172 int desired_size_in_pixel, | 195 int desired_size_in_pixel, |
| 173 const ImageFetchedCallback& callback, | 196 const ImageFetchedCallback& callback, |
| 174 bool continue_to_google_server, | 197 bool continue_to_google_server, |
| 175 const favicon_base::LargeIconImageResult& result) { | 198 const favicon_base::LargeIconImageResult& result) { |
| 176 if (!result.image.IsEmpty()) { | 199 if (!result.image.IsEmpty()) { |
| 177 callback.Run(result.image); | 200 callback.Run(result.image); |
| 201 // The icon is from cache if we haven't gone to Google server yet. The icon |
| 202 // is freshly fetched, otherwise. |
| 203 RecordFaviconFetchResult(continue_to_google_server |
| 204 ? FaviconFetchResult::SUCCESS_CACHED |
| 205 : FaviconFetchResult::SUCCESS_FETCHED); |
| 178 return; | 206 return; |
| 179 } | 207 } |
| 180 | 208 |
| 181 if (!continue_to_google_server || | 209 if (!continue_to_google_server || |
| 182 (result.fallback_icon_style && | 210 (result.fallback_icon_style && |
| 183 !result.fallback_icon_style->is_default_background_color)) { | 211 !result.fallback_icon_style->is_default_background_color)) { |
| 184 // We cannot download from the server if there is some small icon in the | 212 // We cannot download from the server if there is some small icon in the |
| 185 // cache (resulting in non-default bakground color) or if we already did so. | 213 // cache (resulting in non-default background color) or if we already did |
| 214 // so. |
| 186 callback.Run(gfx::Image()); | 215 callback.Run(gfx::Image()); |
| 216 RecordFaviconFetchResult(FaviconFetchResult::FAILURE); |
| 187 return; | 217 return; |
| 188 } | 218 } |
| 189 | 219 |
| 190 // Try to fetch the favicon from a Google favicon server. | 220 // Try to fetch the favicon from a Google favicon server. |
| 191 large_icon_service_ | 221 large_icon_service_ |
| 192 ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache( | 222 ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache( |
| 193 publisher_url, minimum_size_in_pixel, | 223 publisher_url, minimum_size_in_pixel, |
| 194 base::Bind( | 224 base::Bind( |
| 195 &ContentSuggestionsService::OnGetFaviconFromGoogleServerFinished, | 225 &ContentSuggestionsService::OnGetFaviconFromGoogleServerFinished, |
| 196 base::Unretained(this), publisher_url, minimum_size_in_pixel, | 226 base::Unretained(this), publisher_url, minimum_size_in_pixel, |
| 197 desired_size_in_pixel, callback)); | 227 desired_size_in_pixel, callback)); |
| 198 } | 228 } |
| 199 | 229 |
| 200 void ContentSuggestionsService::OnGetFaviconFromGoogleServerFinished( | 230 void ContentSuggestionsService::OnGetFaviconFromGoogleServerFinished( |
| 201 const GURL& publisher_url, | 231 const GURL& publisher_url, |
| 202 int minimum_size_in_pixel, | 232 int minimum_size_in_pixel, |
| 203 int desired_size_in_pixel, | 233 int desired_size_in_pixel, |
| 204 const ImageFetchedCallback& callback, | 234 const ImageFetchedCallback& callback, |
| 205 bool success) { | 235 bool success) { |
| 206 if (!success) { | 236 if (!success) { |
| 207 callback.Run(gfx::Image()); | 237 callback.Run(gfx::Image()); |
| 238 RecordFaviconFetchResult(FaviconFetchResult::FAILURE); |
| 208 return; | 239 return; |
| 209 } | 240 } |
| 210 | 241 |
| 211 // Get the freshly downloaded icon from the cache. | 242 // Get the freshly downloaded icon from the cache. |
| 212 large_icon_service_->GetLargeIconImageOrFallbackStyle( | 243 large_icon_service_->GetLargeIconImageOrFallbackStyle( |
| 213 publisher_url, minimum_size_in_pixel, desired_size_in_pixel, | 244 publisher_url, minimum_size_in_pixel, desired_size_in_pixel, |
| 214 base::Bind(&ContentSuggestionsService::OnGetFaviconFromCacheFinished, | 245 base::Bind(&ContentSuggestionsService::OnGetFaviconFromCacheFinished, |
| 215 base::Unretained(this), publisher_url, minimum_size_in_pixel, | 246 base::Unretained(this), publisher_url, minimum_size_in_pixel, |
| 216 desired_size_in_pixel, callback, | 247 desired_size_in_pixel, callback, |
| 217 /*continue_to_google_server=*/false), | 248 /*continue_to_google_server=*/false), |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 void ContentSuggestionsService::StoreDismissedCategoriesToPrefs() { | 650 void ContentSuggestionsService::StoreDismissedCategoriesToPrefs() { |
| 620 base::ListValue list; | 651 base::ListValue list; |
| 621 for (const auto& category_provider_pair : dismissed_providers_by_category_) { | 652 for (const auto& category_provider_pair : dismissed_providers_by_category_) { |
| 622 list.AppendInteger(category_provider_pair.first.id()); | 653 list.AppendInteger(category_provider_pair.first.id()); |
| 623 } | 654 } |
| 624 | 655 |
| 625 pref_service_->Set(prefs::kDismissedCategories, list); | 656 pref_service_->Set(prefs::kDismissedCategories, list); |
| 626 } | 657 } |
| 627 | 658 |
| 628 } // namespace ntp_snippets | 659 } // namespace ntp_snippets |
| OLD | NEW |