• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
6 
7 #include "base/metrics/histogram.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/search/most_visited_iframe_source.h"
11 #include "chrome/browser/search/search.h"
12 #include "chrome/common/search_urls.h"
13 #include "chrome/common/url_constants.h"
14 #include "content/public/browser/navigation_details.h"
15 #include "content/public/browser/navigation_entry.h"
16 #include "content/public/browser/web_contents.h"
17 
18 namespace {
19 
20 // Used to track if suggestions were issued by the client or the server.
21 enum SuggestionsType {
22   CLIENT_SIDE = 0,
23   SERVER_SIDE = 1,
24   SUGGESTIONS_TYPE_COUNT = 2
25 };
26 
27 // Format string to generate the name for the histogram keeping track of
28 // suggestion impressions.
29 const char kImpressionHistogramWithProvider[] =
30     "NewTabPage.SuggestionsImpression.%s";
31 
32 }  // namespace
33 
34 DEFINE_WEB_CONTENTS_USER_DATA_KEY(NTPUserDataLogger);
35 
~NTPUserDataLogger()36 NTPUserDataLogger::~NTPUserDataLogger() {}
37 
38 // static
GetOrCreateFromWebContents(content::WebContents * content)39 NTPUserDataLogger* NTPUserDataLogger::GetOrCreateFromWebContents(
40       content::WebContents* content) {
41   // Calling CreateForWebContents when an instance is already attached has no
42   // effect, so we can do this.
43   NTPUserDataLogger::CreateForWebContents(content);
44   NTPUserDataLogger* logger = NTPUserDataLogger::FromWebContents(content);
45 
46   // We record the URL of this NTP in order to identify navigations that
47   // originate from it. We use the NavigationController's URL since it might
48   // differ from the WebContents URL which is usually chrome://newtab/.
49   const content::NavigationEntry* entry =
50       content->GetController().GetVisibleEntry();
51   if (entry)
52     logger->ntp_url_ = entry->GetURL();
53 
54   return logger;
55 }
56 
EmitThumbnailErrorRate()57 void NTPUserDataLogger::EmitThumbnailErrorRate() {
58   DCHECK_LE(number_of_thumbnail_errors_, number_of_thumbnail_attempts_);
59   if (number_of_thumbnail_attempts_ != 0) {
60     UMA_HISTOGRAM_PERCENTAGE(
61       "NewTabPage.ThumbnailErrorRate",
62       GetPercentError(number_of_thumbnail_errors_,
63                       number_of_thumbnail_attempts_));
64   }
65   DCHECK_LE(number_of_fallback_thumbnails_used_,
66             number_of_fallback_thumbnails_requested_);
67   if (number_of_fallback_thumbnails_requested_ != 0) {
68     UMA_HISTOGRAM_PERCENTAGE(
69         "NewTabPage.ThumbnailFallbackRate",
70         GetPercentError(number_of_fallback_thumbnails_used_,
71                         number_of_fallback_thumbnails_requested_));
72   }
73   number_of_thumbnail_attempts_ = 0;
74   number_of_thumbnail_errors_ = 0;
75   number_of_fallback_thumbnails_requested_ = 0;
76   number_of_fallback_thumbnails_used_ = 0;
77 }
78 
EmitNtpStatistics()79 void NTPUserDataLogger::EmitNtpStatistics() {
80   UMA_HISTOGRAM_COUNTS("NewTabPage.NumberOfMouseOvers", number_of_mouseovers_);
81   number_of_mouseovers_ = 0;
82   UMA_HISTOGRAM_COUNTS("NewTabPage.NumberOfExternalTiles",
83                        number_of_external_tiles_);
84   number_of_external_tiles_ = 0;
85   UMA_HISTOGRAM_ENUMERATION(
86       "NewTabPage.SuggestionsType",
87       server_side_suggestions_ ? SERVER_SIDE : CLIENT_SIDE,
88       SUGGESTIONS_TYPE_COUNT);
89   server_side_suggestions_ = false;
90 }
91 
LogEvent(NTPLoggingEventType event)92 void NTPUserDataLogger::LogEvent(NTPLoggingEventType event) {
93   switch (event) {
94     case NTP_MOUSEOVER:
95       number_of_mouseovers_++;
96       break;
97     case NTP_THUMBNAIL_ATTEMPT:
98       number_of_thumbnail_attempts_++;
99       break;
100     case NTP_THUMBNAIL_ERROR:
101       number_of_thumbnail_errors_++;
102       break;
103     case NTP_FALLBACK_THUMBNAIL_REQUESTED:
104       number_of_fallback_thumbnails_requested_++;
105       break;
106     case NTP_FALLBACK_THUMBNAIL_USED:
107       number_of_fallback_thumbnails_used_++;
108       break;
109     case NTP_SERVER_SIDE_SUGGESTION:
110       server_side_suggestions_ = true;
111       break;
112     case NTP_CLIENT_SIDE_SUGGESTION:
113       // We should never get a mix of server and client side suggestions,
114       // otherwise there could be a race condition depending on the order in
115       // which the iframes call this method.
116       DCHECK(!server_side_suggestions_);
117     break;
118     case NTP_EXTERNAL_TILE:
119       number_of_external_tiles_++;
120       break;
121     default:
122       NOTREACHED();
123   }
124 }
125 
LogImpression(int position,const base::string16 & provider)126 void NTPUserDataLogger::LogImpression(int position,
127                                       const base::string16& provider) {
128   // Cannot rely on UMA histograms macro because the name of the histogram is
129   // generated dynamically.
130   base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
131       base::StringPrintf(kImpressionHistogramWithProvider,
132                          UTF16ToUTF8(provider).c_str()),
133       1, MostVisitedIframeSource::kNumMostVisited,
134       MostVisitedIframeSource::kNumMostVisited + 1,
135       base::Histogram::kUmaTargetedHistogramFlag);
136   counter->Add(position);
137 }
138 
139 // content::WebContentsObserver override
NavigationEntryCommitted(const content::LoadCommittedDetails & load_details)140 void NTPUserDataLogger::NavigationEntryCommitted(
141     const content::LoadCommittedDetails& load_details) {
142   if (!load_details.previous_url.is_valid())
143     return;
144 
145   if (search::MatchesOriginAndPath(ntp_url_, load_details.previous_url)) {
146     EmitNtpStatistics();
147     // Only log thumbnail error rates for Instant NTP pages, as we do not have
148     // this data for non-Instant NTPs.
149     if (ntp_url_ != GURL(chrome::kChromeUINewTabURL))
150       EmitThumbnailErrorRate();
151   }
152 }
153 
NTPUserDataLogger(content::WebContents * contents)154 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents)
155     : content::WebContentsObserver(contents),
156       number_of_mouseovers_(0),
157       number_of_thumbnail_attempts_(0),
158       number_of_thumbnail_errors_(0),
159       number_of_fallback_thumbnails_requested_(0),
160       number_of_fallback_thumbnails_used_(0),
161       number_of_external_tiles_(0),
162       server_side_suggestions_(false) {
163 }
164 
GetPercentError(size_t errors,size_t events) const165 size_t NTPUserDataLogger::GetPercentError(size_t errors, size_t events) const {
166   return (100 * errors) / events;
167 }
168