| 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 "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h" | 5 #include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> |
| 8 | 9 |
| 9 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 10 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 11 #include "base/strings/utf_string_conversions.h" | |
| 12 #include "chrome/browser/after_startup_task_utils.h" | 12 #include "chrome/browser/after_startup_task_utils.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/search/most_visited_iframe_source.h" | |
| 15 #include "chrome/browser/search/search.h" | 14 #include "chrome/browser/search/search.h" |
| 16 #include "chrome/browser/sync/profile_sync_service_factory.h" | 15 #include "chrome/browser/sync/profile_sync_service_factory.h" |
| 17 #include "chrome/common/search/search_urls.h" | 16 #include "chrome/common/search/search_urls.h" |
| 18 #include "chrome/common/url_constants.h" | 17 #include "chrome/common/url_constants.h" |
| 19 #include "components/browser_sync/browser/profile_sync_service.h" | 18 #include "components/browser_sync/browser/profile_sync_service.h" |
| 20 #include "components/sync_sessions/sessions_sync_manager.h" | 19 #include "components/sync_sessions/sessions_sync_manager.h" |
| 21 #include "components/sync_sessions/sync_sessions_metrics.h" | 20 #include "components/sync_sessions/sync_sessions_metrics.h" |
| 22 #include "content/public/browser/navigation_details.h" | 21 #include "content/public/browser/navigation_details.h" |
| 23 #include "content/public/browser/navigation_entry.h" | 22 #include "content/public/browser/navigation_entry.h" |
| 24 #include "content/public/browser/user_metrics.h" | 23 #include "content/public/browser/user_metrics.h" |
| 25 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 26 | 25 |
| 27 // Macro to log UMA statistics related to the 8 tiles shown on the NTP. | |
| 28 #define UMA_HISTOGRAM_NTP_TILES(name, sample) \ | |
| 29 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 0, 8, 9) | |
| 30 | |
| 31 namespace { | 26 namespace { |
| 32 | 27 |
| 33 // Used to track if suggestions were issued by the client or the server. | |
| 34 enum SuggestionsType { | |
| 35 CLIENT_SIDE = 0, | |
| 36 SERVER_SIDE = 1, | |
| 37 SUGGESTIONS_TYPE_COUNT = 2 | |
| 38 }; | |
| 39 | |
| 40 // Number of Most Visited elements on the NTP for logging purposes. | 28 // Number of Most Visited elements on the NTP for logging purposes. |
| 41 const int kNumMostVisited = 8; | 29 const int kNumMostVisited = 8; |
| 42 | 30 |
| 43 // Name of the histogram keeping track of suggestion impressions. | 31 // Name of the histogram keeping track of suggestion impressions. |
| 44 const char kMostVisitedImpressionHistogramName[] = | 32 const char kMostVisitedImpressionHistogramName[] = |
| 45 "NewTabPage.SuggestionsImpression"; | 33 "NewTabPage.SuggestionsImpression"; |
| 46 | 34 |
| 47 // Format string to generate the name for the histogram keeping track of | 35 // Format string to generate the name for the histogram keeping track of |
| 48 // suggestion impressions. | 36 // suggestion impressions. |
| 49 const char kMostVisitedImpressionHistogramWithProvider[] = | 37 const char kMostVisitedImpressionHistogramWithProvider[] = |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 has_server_side_suggestions_ = true; | 109 has_server_side_suggestions_ = true; |
| 122 break; | 110 break; |
| 123 case NTP_CLIENT_SIDE_SUGGESTION: | 111 case NTP_CLIENT_SIDE_SUGGESTION: |
| 124 if (has_server_side_suggestions_) | 112 if (has_server_side_suggestions_) |
| 125 EmitNtpStatistics(EmitReason::INTERNAL_FLUSH); | 113 EmitNtpStatistics(EmitReason::INTERNAL_FLUSH); |
| 126 has_client_side_suggestions_ = true; | 114 has_client_side_suggestions_ = true; |
| 127 break; | 115 break; |
| 128 case NTP_TILE: | 116 case NTP_TILE: |
| 129 number_of_tiles_++; | 117 number_of_tiles_++; |
| 130 break; | 118 break; |
| 131 case NTP_THUMBNAIL_TILE: | |
| 132 number_of_thumbnail_tiles_++; | |
| 133 break; | |
| 134 case NTP_GRAY_TILE: | |
| 135 number_of_gray_tiles_++; | |
| 136 break; | |
| 137 case NTP_EXTERNAL_TILE: | |
| 138 number_of_external_tiles_++; | |
| 139 break; | |
| 140 case NTP_THUMBNAIL_ERROR: | |
| 141 number_of_thumbnail_errors_++; | |
| 142 break; | |
| 143 case NTP_GRAY_TILE_FALLBACK: | |
| 144 number_of_gray_tile_fallbacks_++; | |
| 145 break; | |
| 146 case NTP_EXTERNAL_TILE_FALLBACK: | |
| 147 number_of_external_tile_fallbacks_++; | |
| 148 break; | |
| 149 case NTP_TILE_LOADED: | 119 case NTP_TILE_LOADED: |
| 150 // The time at which the last tile has loaded (title, thumbnail or single) | 120 // The time at which the last tile has loaded (title, thumbnail or single) |
| 151 // is a good proxy for the total load time of the NTP, therefore we keep | 121 // is a good proxy for the total load time of the NTP, therefore we keep |
| 152 // the max as the load time. | 122 // the max as the load time. |
| 153 load_time_ = std::max(load_time_, time); | 123 load_time_ = std::max(load_time_, time); |
| 154 break; | 124 break; |
| 155 default: | 125 default: |
| 156 NOTREACHED(); | 126 NOTREACHED(); |
| 157 } | 127 } |
| 158 } | 128 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 188 kNumMostVisited, | 158 kNumMostVisited, |
| 189 kNumMostVisited + 1, | 159 kNumMostVisited + 1, |
| 190 base::Histogram::kUmaTargetedHistogramFlag); | 160 base::Histogram::kUmaTargetedHistogramFlag); |
| 191 counter->Add(position); | 161 counter->Add(position); |
| 192 | 162 |
| 193 // Records the action. This will be available as a time-stamped stream | 163 // Records the action. This will be available as a time-stamped stream |
| 194 // server-side and can be used to compute time-to-long-dwell. | 164 // server-side and can be used to compute time-to-long-dwell. |
| 195 content::RecordAction(base::UserMetricsAction("MostVisited_Clicked")); | 165 content::RecordAction(base::UserMetricsAction("MostVisited_Clicked")); |
| 196 } | 166 } |
| 197 | 167 |
| 198 // content::WebContentsObserver override | |
| 199 void NTPUserDataLogger::NavigationEntryCommitted( | |
| 200 const content::LoadCommittedDetails& load_details) { | |
| 201 if (!load_details.previous_url.is_valid()) | |
| 202 return; | |
| 203 | |
| 204 if (search::MatchesOriginAndPath(ntp_url_, load_details.previous_url)) { | |
| 205 EmitNtpStatistics(EmitReason::NAVIGATED_AWAY); | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void NTPUserDataLogger::TabDeactivated() { | 168 void NTPUserDataLogger::TabDeactivated() { |
| 210 EmitNtpStatistics(EmitReason::CLOSED); | 169 EmitNtpStatistics(EmitReason::CLOSED); |
| 211 } | 170 } |
| 212 | 171 |
| 213 void NTPUserDataLogger::MostVisitedItemsChanged() { | 172 void NTPUserDataLogger::MostVisitedItemsChanged() { |
| 214 EmitNtpStatistics(EmitReason::MV_CHANGED); | 173 EmitNtpStatistics(EmitReason::MV_CHANGED); |
| 215 } | 174 } |
| 216 | 175 |
| 217 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents) | 176 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents) |
| 218 : content::WebContentsObserver(contents), | 177 : content::WebContentsObserver(contents), |
| 219 has_server_side_suggestions_(false), | 178 has_server_side_suggestions_(false), |
| 220 has_client_side_suggestions_(false), | 179 has_client_side_suggestions_(false), |
| 221 number_of_tiles_(0), | 180 number_of_tiles_(0), |
| 222 number_of_thumbnail_tiles_(0), | |
| 223 number_of_gray_tiles_(0), | |
| 224 number_of_external_tiles_(0), | |
| 225 number_of_thumbnail_errors_(0), | |
| 226 number_of_gray_tile_fallbacks_(0), | |
| 227 number_of_external_tile_fallbacks_(0), | |
| 228 has_emitted_(false), | 181 has_emitted_(false), |
| 229 during_startup_(false) { | 182 during_startup_(false) { |
| 230 during_startup_ = !AfterStartupTaskUtils::IsBrowserStartupComplete(); | 183 during_startup_ = !AfterStartupTaskUtils::IsBrowserStartupComplete(); |
| 231 | 184 |
| 232 // We record metrics about session data here because when this class typically | 185 // We record metrics about session data here because when this class typically |
| 233 // emits metrics it is too late. This session data would theoretically have | 186 // emits metrics it is too late. This session data would theoretically have |
| 234 // been used to populate the page, and we want to learn about its state when | 187 // been used to populate the page, and we want to learn about its state when |
| 235 // the NTP is being generated. | 188 // the NTP is being generated. |
| 236 if (contents) { | 189 if (contents) { |
| 237 ProfileSyncService* sync = ProfileSyncServiceFactory::GetForProfile( | 190 ProfileSyncService* sync = ProfileSyncServiceFactory::GetForProfile( |
| 238 Profile::FromBrowserContext(contents->GetBrowserContext())); | 191 Profile::FromBrowserContext(contents->GetBrowserContext())); |
| 239 if (sync) { | 192 if (sync) { |
| 240 browser_sync::SessionsSyncManager* sessions = | 193 browser_sync::SessionsSyncManager* sessions = |
| 241 static_cast<browser_sync::SessionsSyncManager*>( | 194 static_cast<browser_sync::SessionsSyncManager*>( |
| 242 sync->GetSessionsSyncableService()); | 195 sync->GetSessionsSyncableService()); |
| 243 if (sessions) { | 196 if (sessions) { |
| 244 sync_sessions::SyncSessionsMetrics::RecordYoungestForeignTabAgeOnNTP( | 197 sync_sessions::SyncSessionsMetrics::RecordYoungestForeignTabAgeOnNTP( |
| 245 sessions); | 198 sessions); |
| 246 } | 199 } |
| 247 } | 200 } |
| 248 } | 201 } |
| 249 } | 202 } |
| 250 | 203 |
| 204 // content::WebContentsObserver override |
| 205 void NTPUserDataLogger::NavigationEntryCommitted( |
| 206 const content::LoadCommittedDetails& load_details) { |
| 207 if (!load_details.previous_url.is_valid()) |
| 208 return; |
| 209 |
| 210 if (search::MatchesOriginAndPath(ntp_url_, load_details.previous_url)) |
| 211 EmitNtpStatistics(EmitReason::NAVIGATED_AWAY); |
| 212 } |
| 213 |
| 251 void NTPUserDataLogger::EmitNtpStatistics(EmitReason reason) { | 214 void NTPUserDataLogger::EmitNtpStatistics(EmitReason reason) { |
| 252 // We only send statistics once per page. | 215 // We only send statistics once per page. |
| 253 // And we don't send if there are no tiles recorded. | 216 // And we don't send if there are no tiles recorded. |
| 254 if (has_emitted_ || !number_of_tiles_) | 217 if (has_emitted_ || !number_of_tiles_) |
| 255 return; | 218 return; |
| 256 | 219 |
| 257 // LoadTime only gets update once per page, so we don't have it on reloads. | 220 // LoadTime only gets update once per page, so we don't have it on reloads. |
| 258 if (load_time_ > base::TimeDelta::FromMilliseconds(0)) { | 221 if (load_time_ > base::TimeDelta::FromMilliseconds(0)) { |
| 259 logLoadTimeHistogram("NewTabPage.LoadTime", load_time_); | 222 logLoadTimeHistogram("NewTabPage.LoadTime", load_time_); |
| 260 | 223 |
| 261 // Split between ML and MV. | 224 // Split between ML and MV. |
| 262 std::string type = has_server_side_suggestions_ ? | 225 std::string type = has_server_side_suggestions_ ? |
| 263 "MostLikely" : "MostVisited"; | 226 "MostLikely" : "MostVisited"; |
| 264 logLoadTimeHistogram("NewTabPage.LoadTime." + type, load_time_); | 227 logLoadTimeHistogram("NewTabPage.LoadTime." + type, load_time_); |
| 265 // Split between Web and Local. | 228 // Split between Web and Local. |
| 266 std::string source = ntp_url_.SchemeIsHTTPOrHTTPS() ? "Web" : "LocalNTP"; | 229 std::string source = ntp_url_.SchemeIsHTTPOrHTTPS() ? "Web" : "LocalNTP"; |
| 267 logLoadTimeHistogram("NewTabPage.LoadTime." + source, load_time_); | 230 logLoadTimeHistogram("NewTabPage.LoadTime." + source, load_time_); |
| 268 | 231 |
| 269 // Split between Startup and non-startup. | 232 // Split between Startup and non-startup. |
| 270 std::string status = during_startup_ ? "Startup" : "NewTab"; | 233 std::string status = during_startup_ ? "Startup" : "NewTab"; |
| 271 logLoadTimeHistogram("NewTabPage.LoadTime." + status, load_time_); | 234 logLoadTimeHistogram("NewTabPage.LoadTime." + status, load_time_); |
| 272 | 235 |
| 273 load_time_ = base::TimeDelta::FromMilliseconds(0); | 236 load_time_ = base::TimeDelta::FromMilliseconds(0); |
| 274 } | 237 } |
| 275 UMA_HISTOGRAM_ENUMERATION( | |
| 276 "NewTabPage.SuggestionsType", | |
| 277 has_server_side_suggestions_ ? SERVER_SIDE : CLIENT_SIDE, | |
| 278 SUGGESTIONS_TYPE_COUNT); | |
| 279 has_server_side_suggestions_ = false; | 238 has_server_side_suggestions_ = false; |
| 280 has_client_side_suggestions_ = false; | 239 has_client_side_suggestions_ = false; |
| 281 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfTiles", number_of_tiles_); | 240 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 241 "NewTabPage.NumberOfTiles", number_of_tiles_, 0, kNumMostVisited, |
| 242 kNumMostVisited + 1); |
| 282 number_of_tiles_ = 0; | 243 number_of_tiles_ = 0; |
| 283 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfThumbnailTiles", | |
| 284 number_of_thumbnail_tiles_); | |
| 285 number_of_thumbnail_tiles_ = 0; | |
| 286 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfGrayTiles", | |
| 287 number_of_gray_tiles_); | |
| 288 number_of_gray_tiles_ = 0; | |
| 289 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfExternalTiles", | |
| 290 number_of_external_tiles_); | |
| 291 number_of_external_tiles_ = 0; | |
| 292 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfThumbnailErrors", | |
| 293 number_of_thumbnail_errors_); | |
| 294 number_of_thumbnail_errors_ = 0; | |
| 295 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfGrayTileFallbacks", | |
| 296 number_of_gray_tile_fallbacks_); | |
| 297 number_of_gray_tile_fallbacks_ = 0; | |
| 298 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfExternalTileFallbacks", | |
| 299 number_of_external_tile_fallbacks_); | |
| 300 number_of_external_tile_fallbacks_ = 0; | |
| 301 has_emitted_ = true; | 244 has_emitted_ = true; |
| 302 during_startup_ = false; | 245 during_startup_ = false; |
| 303 } | 246 } |
| OLD | NEW |