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 |