| 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 |