Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / webui / ntp / ntp_user_data_logger.cc
blob79d9ef03d7793492fc7af8a963648cc7501b9448
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
7 #include "base/metrics/histogram.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/after_startup_task_utils.h"
11 #include "chrome/browser/search/most_visited_iframe_source.h"
12 #include "chrome/browser/search/search.h"
13 #include "chrome/common/search_urls.h"
14 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/navigation_details.h"
16 #include "content/public/browser/navigation_entry.h"
17 #include "content/public/browser/user_metrics.h"
18 #include "content/public/browser/web_contents.h"
20 // Macro to log UMA statistics related to the 8 tiles shown on the NTP.
21 #define UMA_HISTOGRAM_NTP_TILES(name, sample) \
22 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 0, 8, 9)
24 namespace {
26 // Used to track if suggestions were issued by the client or the server.
27 enum SuggestionsType {
28 CLIENT_SIDE = 0,
29 SERVER_SIDE = 1,
30 SUGGESTIONS_TYPE_COUNT = 2
33 // Number of Most Visited elements on the NTP for logging purposes.
34 const int kNumMostVisited = 8;
36 // Name of the histogram keeping track of Most Visited impressions.
37 const char kMostVisitedImpressionHistogramName[] =
38 "NewTabPage.SuggestionsImpression";
40 // Format string to generate the name for the histogram keeping track of
41 // suggestion impressions.
42 const char kMostVisitedImpressionHistogramWithProvider[] =
43 "NewTabPage.SuggestionsImpression.%s";
45 // Name of the histogram keeping track of Most Visited navigations.
46 const char kMostVisitedNavigationHistogramName[] =
47 "NewTabPage.MostVisited";
49 // Format string to generate the name for the histogram keeping track of
50 // suggestion navigations.
51 const char kMostVisitedNavigationHistogramWithProvider[] =
52 "NewTabPage.MostVisited.%s";
54 } // namespace
56 DEFINE_WEB_CONTENTS_USER_DATA_KEY(NTPUserDataLogger);
59 // Log a time event for a given |histogram| at a given |value|. This
60 // routine exists because regular histogram macros are cached thus can't be used
61 // if the name of the histogram will change at a given call site.
62 void logLoadTimeHistogram(const std::string& histogram, base::TimeDelta value) {
63 base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
64 histogram,
65 base::TimeDelta::FromMilliseconds(1),
66 base::TimeDelta::FromSeconds(60), 100,
67 base::Histogram::kUmaTargetedHistogramFlag);
68 if (counter)
69 counter->AddTime(value);
73 NTPUserDataLogger::~NTPUserDataLogger() {}
75 // static
76 NTPUserDataLogger* NTPUserDataLogger::GetOrCreateFromWebContents(
77 content::WebContents* content) {
78 // Calling CreateForWebContents when an instance is already attached has no
79 // effect, so we can do this.
80 NTPUserDataLogger::CreateForWebContents(content);
81 NTPUserDataLogger* logger = NTPUserDataLogger::FromWebContents(content);
83 // We record the URL of this NTP in order to identify navigations that
84 // originate from it. We use the NavigationController's URL since it might
85 // differ from the WebContents URL which is usually chrome://newtab/.
86 const content::NavigationEntry* entry =
87 content->GetController().GetVisibleEntry();
88 if (entry)
89 logger->ntp_url_ = entry->GetURL();
91 return logger;
94 // static
95 std::string NTPUserDataLogger::GetMostVisitedImpressionHistogramNameForProvider(
96 const std::string& provider) {
97 return base::StringPrintf(kMostVisitedImpressionHistogramWithProvider,
98 provider.c_str());
101 // static
102 std::string NTPUserDataLogger::GetMostVisitedNavigationHistogramNameForProvider(
103 const std::string& provider) {
104 return base::StringPrintf(kMostVisitedNavigationHistogramWithProvider,
105 provider.c_str());
108 void NTPUserDataLogger::EmitNtpStatistics() {
109 UMA_HISTOGRAM_COUNTS("NewTabPage.NumberOfMouseOvers", number_of_mouseovers_);
110 number_of_mouseovers_ = 0;
112 // We only send statistics once per page.
113 // And we don't send if there are no tiles recorded.
114 if (has_emitted_ || !number_of_tiles_)
115 return;
117 // LoadTime only gets update once per page, so we don't have it on reloads.
118 if (load_time_ > base::TimeDelta::FromMilliseconds(0)) {
119 logLoadTimeHistogram("NewTabPage.LoadTime", load_time_);
121 // Split between ML and MV.
122 std::string type = has_server_side_suggestions_ ?
123 "MostLikely" : "MostVisited";
124 logLoadTimeHistogram("NewTabPage.LoadTime." + type, load_time_);
125 // Split between Web and Local.
126 std::string source = ntp_url_.SchemeIsHTTPOrHTTPS() ? "Web" : "LocalNTP";
127 logLoadTimeHistogram("NewTabPage.LoadTime." + source, load_time_);
129 // Split between Startup and non-startup.
130 std::string status = during_startup_ ? "Startup" : "NewTab";
131 logLoadTimeHistogram("NewTabPage.LoadTime." + status, load_time_);
133 load_time_ = base::TimeDelta::FromMilliseconds(0);
135 UMA_HISTOGRAM_ENUMERATION(
136 "NewTabPage.SuggestionsType",
137 has_server_side_suggestions_ ? SERVER_SIDE : CLIENT_SIDE,
138 SUGGESTIONS_TYPE_COUNT);
139 has_server_side_suggestions_ = false;
140 has_client_side_suggestions_ = false;
141 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfTiles", number_of_tiles_);
142 number_of_tiles_ = 0;
143 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfThumbnailTiles",
144 number_of_thumbnail_tiles_);
145 number_of_thumbnail_tiles_ = 0;
146 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfGrayTiles",
147 number_of_gray_tiles_);
148 number_of_gray_tiles_ = 0;
149 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfExternalTiles",
150 number_of_external_tiles_);
151 number_of_external_tiles_ = 0;
152 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfThumbnailErrors",
153 number_of_thumbnail_errors_);
154 number_of_thumbnail_errors_ = 0;
155 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfGrayTileFallbacks",
156 number_of_gray_tile_fallbacks_);
157 number_of_gray_tile_fallbacks_ = 0;
158 UMA_HISTOGRAM_NTP_TILES("NewTabPage.NumberOfExternalTileFallbacks",
159 number_of_external_tile_fallbacks_);
160 number_of_external_tile_fallbacks_ = 0;
161 has_emitted_ = true;
162 during_startup_ = false;
165 void NTPUserDataLogger::LogEvent(NTPLoggingEventType event,
166 base::TimeDelta time) {
167 switch (event) {
168 // It is possible that our page gets update with a different set of
169 // suggestions if the NTP is left open enough time.
170 // In either case, we want to flush our stats before recounting again.
171 case NTP_SERVER_SIDE_SUGGESTION:
172 if (has_client_side_suggestions_)
173 EmitNtpStatistics();
174 has_server_side_suggestions_ = true;
175 break;
176 case NTP_CLIENT_SIDE_SUGGESTION:
177 if (has_server_side_suggestions_)
178 EmitNtpStatistics();
179 has_client_side_suggestions_ = true;
180 break;
181 case NTP_TILE:
182 number_of_tiles_++;
183 break;
184 case NTP_THUMBNAIL_TILE:
185 number_of_thumbnail_tiles_++;
186 break;
187 case NTP_GRAY_TILE:
188 number_of_gray_tiles_++;
189 break;
190 case NTP_EXTERNAL_TILE:
191 number_of_external_tiles_++;
192 break;
193 case NTP_THUMBNAIL_ERROR:
194 number_of_thumbnail_errors_++;
195 break;
196 case NTP_GRAY_TILE_FALLBACK:
197 number_of_gray_tile_fallbacks_++;
198 break;
199 case NTP_EXTERNAL_TILE_FALLBACK:
200 number_of_external_tile_fallbacks_++;
201 break;
202 case NTP_MOUSEOVER:
203 number_of_mouseovers_++;
204 break;
205 case NTP_TILE_LOADED:
206 // The time at which the last tile has loaded (title, thumbnail or single)
207 // is a good proxy for the total load time of the NTP, therefore we keep
208 // the max as the load time.
209 load_time_ = std::max(load_time_, time);
210 break;
211 default:
212 NOTREACHED();
216 void NTPUserDataLogger::LogMostVisitedImpression(
217 int position, const base::string16& provider) {
218 // Log the Most Visited navigation for navigations that have providers and
219 // those that dont.
220 UMA_HISTOGRAM_ENUMERATION(kMostVisitedImpressionHistogramName, position,
221 kNumMostVisited);
223 // If a provider is specified, log the metric specific to it.
224 if (!provider.empty()) {
225 // Cannot rely on UMA histograms macro because the name of the histogram is
226 // generated dynamically.
227 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
228 GetMostVisitedImpressionHistogramNameForProvider(
229 base::UTF16ToUTF8(provider)),
231 kNumMostVisited,
232 kNumMostVisited + 1,
233 base::Histogram::kUmaTargetedHistogramFlag);
234 counter->Add(position);
238 void NTPUserDataLogger::LogMostVisitedNavigation(
239 int position, const base::string16& provider) {
240 // Log the Most Visited navigation for navigations that have providers and
241 // those that dont.
242 UMA_HISTOGRAM_ENUMERATION(kMostVisitedNavigationHistogramName, position,
243 kNumMostVisited);
245 // If a provider is specified, log the metric specific to it.
246 if (!provider.empty()) {
247 // Cannot rely on UMA histograms macro because the name of the histogram is
248 // generated dynamically.
249 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
250 GetMostVisitedNavigationHistogramNameForProvider(
251 base::UTF16ToUTF8(provider)),
253 kNumMostVisited,
254 kNumMostVisited + 1,
255 base::Histogram::kUmaTargetedHistogramFlag);
256 counter->Add(position);
259 // Records the action. This will be available as a time-stamped stream
260 // server-side and can be used to compute time-to-long-dwell.
261 content::RecordAction(base::UserMetricsAction("MostVisited_Clicked"));
264 // content::WebContentsObserver override
265 void NTPUserDataLogger::NavigationEntryCommitted(
266 const content::LoadCommittedDetails& load_details) {
267 if (!load_details.previous_url.is_valid())
268 return;
270 if (search::MatchesOriginAndPath(ntp_url_, load_details.previous_url)) {
271 EmitNtpStatistics();
275 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents)
276 : content::WebContentsObserver(contents),
277 has_server_side_suggestions_(false),
278 has_client_side_suggestions_(false),
279 number_of_tiles_(0),
280 number_of_thumbnail_tiles_(0),
281 number_of_gray_tiles_(0),
282 number_of_external_tiles_(0),
283 number_of_thumbnail_errors_(0),
284 number_of_gray_tile_fallbacks_(0),
285 number_of_external_tile_fallbacks_(0),
286 number_of_mouseovers_(0),
287 has_emitted_(false),
288 during_startup_(false) {
289 during_startup_ = !AfterStartupTaskUtils::IsBrowserStartupComplete();