OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_tiles/most_visited_sites.h" | 5 #include "components/ntp_tiles/most_visited_sites.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/feature_list.h" | 13 #include "base/feature_list.h" |
14 #include "base/metrics/field_trial.h" | 14 #include "base/metrics/field_trial.h" |
15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
16 #include "base/metrics/sparse_histogram.h" | 16 #include "base/metrics/sparse_histogram.h" |
17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
21 #include "base/time/time.h" | 21 #include "base/time/time.h" |
22 #include "components/history/core/browser/top_sites.h" | 22 #include "components/history/core/browser/top_sites.h" |
23 #include "components/ntp_tiles/constants.h" | 23 #include "components/ntp_tiles/constants.h" |
24 #include "components/ntp_tiles/pref_names.h" | 24 #include "components/ntp_tiles/pref_names.h" |
25 #include "components/ntp_tiles/switches.h" | 25 #include "components/ntp_tiles/switches.h" |
26 #include "components/pref_registry/pref_registry_syncable.h" | 26 #include "components/pref_registry/pref_registry_syncable.h" |
27 #include "components/prefs/pref_service.h" | 27 #include "components/prefs/pref_service.h" |
28 #include "ui/gfx/codec/jpeg_codec.h" | |
29 #include "url/gurl.h" | 28 #include "url/gurl.h" |
30 | 29 |
31 using history::TopSites; | 30 using history::TopSites; |
32 using suggestions::ChromeSuggestion; | 31 using suggestions::ChromeSuggestion; |
33 using suggestions::SuggestionsProfile; | 32 using suggestions::SuggestionsProfile; |
34 using suggestions::SuggestionsService; | 33 using suggestions::SuggestionsService; |
35 | 34 |
36 namespace ntp_tiles { | 35 namespace ntp_tiles { |
37 | 36 |
38 namespace { | 37 namespace { |
39 | 38 |
40 // Identifiers for the various tile sources. | 39 // Identifiers for the various tile sources. |
41 const char kHistogramClientName[] = "client"; | 40 const char kHistogramClientName[] = "client"; |
42 const char kHistogramServerName[] = "server"; | 41 const char kHistogramServerName[] = "server"; |
43 const char kHistogramServerFormat[] = "server%d"; | |
44 const char kHistogramPopularName[] = "popular"; | 42 const char kHistogramPopularName[] = "popular"; |
45 const char kHistogramWhitelistName[] = "whitelist"; | 43 const char kHistogramWhitelistName[] = "whitelist"; |
46 | 44 |
47 const base::Feature kDisplaySuggestionsServiceTiles{ | 45 const base::Feature kDisplaySuggestionsServiceTiles{ |
48 "DisplaySuggestionsServiceTiles", base::FEATURE_ENABLED_BY_DEFAULT}; | 46 "DisplaySuggestionsServiceTiles", base::FEATURE_ENABLED_BY_DEFAULT}; |
49 | 47 |
50 // Log an event for a given |histogram| at a given element |position|. This | 48 // Log an event for a given |histogram| at a given element |position|. This |
51 // routine exists because regular histogram macros are cached thus can't be used | 49 // routine exists because regular histogram macros are cached thus can't be used |
52 // if the name of the histogram will change at a given call site. | 50 // if the name of the histogram will change at a given call site. |
53 void LogHistogramEvent(const std::string& histogram, | 51 void LogHistogramEvent(const std::string& histogram, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 } | 93 } |
96 // The whole grid is already filled with personal suggestions, no point in | 94 // The whole grid is already filled with personal suggestions, no point in |
97 // bothering with popular ones. | 95 // bothering with popular ones. |
98 return false; | 96 return false; |
99 } | 97 } |
100 | 98 |
101 bool AreURLsEquivalent(const GURL& url1, const GURL& url2) { | 99 bool AreURLsEquivalent(const GURL& url1, const GURL& url2) { |
102 return url1.host() == url2.host() && url1.path() == url2.path(); | 100 return url1.host() == url2.host() && url1.path() == url2.path(); |
103 } | 101 } |
104 | 102 |
105 std::string GetSourceHistogramName(int source, int provider_index) { | 103 std::string GetSourceHistogramName(int source) { |
106 switch (source) { | 104 switch (source) { |
107 case MostVisitedSites::TOP_SITES: | 105 case MostVisitedSites::TOP_SITES: |
108 return kHistogramClientName; | 106 return kHistogramClientName; |
109 case MostVisitedSites::POPULAR: | 107 case MostVisitedSites::POPULAR: |
110 return kHistogramPopularName; | 108 return kHistogramPopularName; |
111 case MostVisitedSites::WHITELIST: | 109 case MostVisitedSites::WHITELIST: |
112 return kHistogramWhitelistName; | 110 return kHistogramWhitelistName; |
113 case MostVisitedSites::SUGGESTIONS_SERVICE: | 111 case MostVisitedSites::SUGGESTIONS_SERVICE: |
114 return provider_index >= 0 | 112 return kHistogramServerName; |
115 ? base::StringPrintf(kHistogramServerFormat, provider_index) | |
116 : kHistogramServerName; | |
117 } | 113 } |
118 NOTREACHED(); | 114 NOTREACHED(); |
119 return std::string(); | 115 return std::string(); |
120 } | 116 } |
121 | 117 |
122 std::string GetSourceHistogramNameFromSuggestion( | |
123 const MostVisitedSites::Suggestion& suggestion) { | |
124 return GetSourceHistogramName(suggestion.source, suggestion.provider_index); | |
125 } | |
126 | |
127 void AppendSuggestions(MostVisitedSites::SuggestionsVector src, | 118 void AppendSuggestions(MostVisitedSites::SuggestionsVector src, |
128 MostVisitedSites::SuggestionsVector* dst) { | 119 MostVisitedSites::SuggestionsVector* dst) { |
129 dst->insert(dst->end(), | 120 dst->insert(dst->end(), |
130 std::make_move_iterator(src.begin()), | 121 std::make_move_iterator(src.begin()), |
131 std::make_move_iterator(src.end())); | 122 std::make_move_iterator(src.end())); |
132 } | 123 } |
133 | 124 |
134 } // namespace | 125 } // namespace |
135 | 126 |
136 MostVisitedSites::Suggestion::Suggestion() : provider_index(-1) {} | 127 MostVisitedSites::Suggestion::Suggestion() {} |
137 | 128 |
138 MostVisitedSites::Suggestion::~Suggestion() {} | 129 MostVisitedSites::Suggestion::~Suggestion() {} |
139 | 130 |
140 MostVisitedSites::Suggestion::Suggestion(Suggestion&&) = default; | 131 MostVisitedSites::Suggestion::Suggestion(Suggestion&&) = default; |
141 MostVisitedSites::Suggestion& | 132 MostVisitedSites::Suggestion& |
142 MostVisitedSites::Suggestion::operator=(Suggestion&&) = default; | 133 MostVisitedSites::Suggestion::operator=(Suggestion&&) = default; |
143 | 134 |
144 MostVisitedSites::MostVisitedSites( | 135 MostVisitedSites::MostVisitedSites( |
145 scoped_refptr<base::SequencedWorkerPool> blocking_pool, | 136 scoped_refptr<base::SequencedWorkerPool> blocking_pool, |
146 PrefService* prefs, | 137 PrefService* prefs, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 if (mv_source_ == SUGGESTIONS_SERVICE) { | 221 if (mv_source_ == SUGGESTIONS_SERVICE) { |
231 if (add_url) | 222 if (add_url) |
232 suggestions_service_->BlacklistURL(url); | 223 suggestions_service_->BlacklistURL(url); |
233 else | 224 else |
234 suggestions_service_->UndoBlacklistURL(url); | 225 suggestions_service_->UndoBlacklistURL(url); |
235 } | 226 } |
236 } | 227 } |
237 | 228 |
238 void MostVisitedSites::RecordTileTypeMetrics( | 229 void MostVisitedSites::RecordTileTypeMetrics( |
239 const std::vector<int>& tile_types, | 230 const std::vector<int>& tile_types, |
240 const std::vector<int>& sources, | 231 const std::vector<int>& sources) { |
241 const std::vector<int>& provider_indices) { | |
242 int counts_per_type[NUM_TILE_TYPES] = {0}; | 232 int counts_per_type[NUM_TILE_TYPES] = {0}; |
243 for (size_t i = 0; i < tile_types.size(); ++i) { | 233 for (size_t i = 0; i < tile_types.size(); ++i) { |
244 int tile_type = tile_types[i]; | 234 int tile_type = tile_types[i]; |
245 ++counts_per_type[tile_type]; | 235 ++counts_per_type[tile_type]; |
246 std::string histogram = base::StringPrintf( | 236 std::string histogram = base::StringPrintf( |
247 "NewTabPage.TileType.%s", | 237 "NewTabPage.TileType.%s", |
248 GetSourceHistogramName(sources[i], provider_indices[i]).c_str()); | 238 GetSourceHistogramName(sources[i]).c_str()); |
249 LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES); | 239 LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES); |
250 } | 240 } |
251 | 241 |
252 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsReal", | 242 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsReal", |
253 counts_per_type[ICON_REAL]); | 243 counts_per_type[ICON_REAL]); |
254 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsColor", | 244 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsColor", |
255 counts_per_type[ICON_COLOR]); | 245 counts_per_type[ICON_COLOR]); |
256 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsGray", | 246 UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.IconsGray", |
257 counts_per_type[ICON_DEFAULT]); | 247 counts_per_type[ICON_DEFAULT]); |
258 } | 248 } |
259 | 249 |
260 void MostVisitedSites::RecordOpenedMostVisitedItem(int index, int tile_type) { | 250 void MostVisitedSites::RecordOpenedMostVisitedItem(int index, int tile_type) { |
261 // TODO(treib): |current_suggestions_| could be updated before this function | 251 // TODO(treib): |current_suggestions_| could be updated before this function |
262 // is called, leading to DCHECKs and/or memory corruption. Adjust this | 252 // is called, leading to DCHECKs and/or memory corruption. Adjust this |
263 // function to work with asynchronous UI. | 253 // function to work with asynchronous UI. |
264 DCHECK_GE(index, 0); | 254 DCHECK_GE(index, 0); |
265 DCHECK_LT(index, static_cast<int>(current_suggestions_.size())); | 255 DCHECK_LT(index, static_cast<int>(current_suggestions_.size())); |
266 std::string histogram = base::StringPrintf( | 256 std::string histogram = base::StringPrintf( |
267 "NewTabPage.MostVisited.%s", | 257 "NewTabPage.MostVisited.%s", |
268 GetSourceHistogramNameFromSuggestion(current_suggestions_[index]) | 258 GetSourceHistogramName(current_suggestions_[index].source).c_str()); |
269 .c_str()); | |
270 LogHistogramEvent(histogram, index, num_sites_); | 259 LogHistogramEvent(histogram, index, num_sites_); |
271 | 260 |
272 histogram = base::StringPrintf( | 261 histogram = base::StringPrintf( |
273 "NewTabPage.TileTypeClicked.%s", | 262 "NewTabPage.TileTypeClicked.%s", |
274 GetSourceHistogramNameFromSuggestion(current_suggestions_[index]) | 263 GetSourceHistogramName(current_suggestions_[index].source).c_str()); |
275 .c_str()); | |
276 LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES); | 264 LogHistogramEvent(histogram, tile_type, NUM_TILE_TYPES); |
277 } | 265 } |
278 | 266 |
279 void MostVisitedSites::OnBlockedSitesChanged() { | 267 void MostVisitedSites::OnBlockedSitesChanged() { |
280 BuildCurrentSuggestions(); | 268 BuildCurrentSuggestions(); |
281 } | 269 } |
282 | 270 |
283 // static | 271 // static |
284 void MostVisitedSites::RegisterProfilePrefs( | 272 void MostVisitedSites::RegisterProfilePrefs( |
285 user_prefs::PrefRegistrySyncable* registry) { | 273 user_prefs::PrefRegistrySyncable* registry) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 const ChromeSuggestion& suggestion = suggestions_profile.suggestions(i); | 350 const ChromeSuggestion& suggestion = suggestions_profile.suggestions(i); |
363 if (supervisor_->IsBlocked(GURL(suggestion.url()))) | 351 if (supervisor_->IsBlocked(GURL(suggestion.url()))) |
364 continue; | 352 continue; |
365 | 353 |
366 Suggestion generated_suggestion; | 354 Suggestion generated_suggestion; |
367 generated_suggestion.title = base::UTF8ToUTF16(suggestion.title()); | 355 generated_suggestion.title = base::UTF8ToUTF16(suggestion.title()); |
368 generated_suggestion.url = GURL(suggestion.url()); | 356 generated_suggestion.url = GURL(suggestion.url()); |
369 generated_suggestion.source = SUGGESTIONS_SERVICE; | 357 generated_suggestion.source = SUGGESTIONS_SERVICE; |
370 generated_suggestion.whitelist_icon_path = | 358 generated_suggestion.whitelist_icon_path = |
371 GetWhitelistLargeIconPath(GURL(suggestion.url())); | 359 GetWhitelistLargeIconPath(GURL(suggestion.url())); |
372 if (suggestion.providers_size() > 0) | |
373 generated_suggestion.provider_index = suggestion.providers(0); | |
374 | 360 |
375 suggestions.push_back(std::move(generated_suggestion)); | 361 suggestions.push_back(std::move(generated_suggestion)); |
376 } | 362 } |
377 | 363 |
378 received_most_visited_sites_ = true; | 364 received_most_visited_sites_ = true; |
379 mv_source_ = SUGGESTIONS_SERVICE; | 365 mv_source_ = SUGGESTIONS_SERVICE; |
380 SaveNewSuggestions(std::move(suggestions)); | 366 SaveNewSuggestions(std::move(suggestions)); |
381 NotifyMostVisitedURLsObserver(); | 367 NotifyMostVisitedURLsObserver(); |
382 } | 368 } |
383 | 369 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 observer_->OnPopularURLsAvailable(popular_sites_->sites()); | 526 observer_->OnPopularURLsAvailable(popular_sites_->sites()); |
541 | 527 |
542 // Re-build the suggestions list. Once done, this will notify the observer. | 528 // Re-build the suggestions list. Once done, this will notify the observer. |
543 BuildCurrentSuggestions(); | 529 BuildCurrentSuggestions(); |
544 } | 530 } |
545 | 531 |
546 void MostVisitedSites::RecordImpressionUMAMetrics() { | 532 void MostVisitedSites::RecordImpressionUMAMetrics() { |
547 for (size_t i = 0; i < current_suggestions_.size(); i++) { | 533 for (size_t i = 0; i < current_suggestions_.size(); i++) { |
548 std::string histogram = base::StringPrintf( | 534 std::string histogram = base::StringPrintf( |
549 "NewTabPage.SuggestionsImpression.%s", | 535 "NewTabPage.SuggestionsImpression.%s", |
550 GetSourceHistogramNameFromSuggestion(current_suggestions_[i]).c_str()); | 536 GetSourceHistogramName(current_suggestions_[i].source).c_str()); |
551 LogHistogramEvent(histogram, static_cast<int>(i), num_sites_); | 537 LogHistogramEvent(histogram, static_cast<int>(i), num_sites_); |
552 } | 538 } |
553 } | 539 } |
554 | 540 |
555 void MostVisitedSites::TopSitesLoaded(TopSites* top_sites) {} | 541 void MostVisitedSites::TopSitesLoaded(TopSites* top_sites) {} |
556 | 542 |
557 void MostVisitedSites::TopSitesChanged(TopSites* top_sites, | 543 void MostVisitedSites::TopSitesChanged(TopSites* top_sites, |
558 ChangeReason change_reason) { | 544 ChangeReason change_reason) { |
559 if (mv_source_ == TOP_SITES) { | 545 if (mv_source_ == TOP_SITES) { |
560 // The displayed suggestions are invalidated. | 546 // The displayed suggestions are invalidated. |
561 InitiateTopSitesQuery(); | 547 InitiateTopSitesQuery(); |
562 } | 548 } |
563 } | 549 } |
564 | 550 |
565 } // namespace ntp_tiles | 551 } // namespace ntp_tiles |
OLD | NEW |