Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: chrome/browser/ui/webui/ntp/ntp_user_data_logger.cc

Issue 2124903003: Record impressions/navigations only once per tile. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include <string>
9 9
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 if (counter) 74 if (counter)
75 counter->AddTime(value); 75 counter->AddTime(value);
76 } 76 }
77 77
78 78
79 NTPUserDataLogger::~NTPUserDataLogger() {} 79 NTPUserDataLogger::~NTPUserDataLogger() {}
80 80
81 // static 81 // static
82 NTPUserDataLogger* NTPUserDataLogger::GetOrCreateFromWebContents( 82 NTPUserDataLogger* NTPUserDataLogger::GetOrCreateFromWebContents(
83 content::WebContents* content) { 83 content::WebContents* content) {
84 DCHECK(search::IsInstantNTP(content));
85
84 // Calling CreateForWebContents when an instance is already attached has no 86 // Calling CreateForWebContents when an instance is already attached has no
85 // effect, so we can do this. 87 // effect, so we can do this.
86 NTPUserDataLogger::CreateForWebContents(content); 88 NTPUserDataLogger::CreateForWebContents(content);
87 NTPUserDataLogger* logger = NTPUserDataLogger::FromWebContents(content); 89 NTPUserDataLogger* logger = NTPUserDataLogger::FromWebContents(content);
88 90
89 // We record the URL of this NTP in order to identify navigations that 91 // We record the URL of this NTP in order to identify navigations that
90 // originate from it. We use the NavigationController's URL since it might 92 // originate from it. We use the NavigationController's URL since it might
91 // differ from the WebContents URL which is usually chrome://newtab/. 93 // differ from the WebContents URL which is usually chrome://newtab/.
94 //
95 // We update the NTP URL every time this function is called, because the NTP
96 // URL sometimes changes while it is open, and we care about the final one for
97 // detecting when the user leaves or returns to the NTP. In particular, if the
98 // Google URL changes (e.g. google.com -> google.de), then we fall back to the
99 // local NTP.
92 const content::NavigationEntry* entry = 100 const content::NavigationEntry* entry =
93 content->GetController().GetVisibleEntry(); 101 content->GetController().GetVisibleEntry();
94 if (entry) 102 if (entry && (logger->ntp_url_ != entry->GetURL())) {
103 DVLOG(1) << "NTP URL changed from \"" << logger->ntp_url_ << "\" to \""
104 << entry->GetURL() << "\"";
95 logger->ntp_url_ = entry->GetURL(); 105 logger->ntp_url_ = entry->GetURL();
106 }
96 107
97 return logger; 108 return logger;
98 } 109 }
99 110
100 void NTPUserDataLogger::LogEvent(NTPLoggingEventType event, 111 void NTPUserDataLogger::LogEvent(NTPLoggingEventType event,
101 base::TimeDelta time) { 112 base::TimeDelta time) {
102 switch (event) { 113 switch (event) {
103 case NTP_SERVER_SIDE_SUGGESTION: 114 case NTP_SERVER_SIDE_SUGGESTION:
104 has_server_side_suggestions_ = true; 115 has_server_side_suggestions_ = true;
105 break; 116 break;
(...skipping 10 matching lines...) Expand all
116 case NTP_ALL_TILES_LOADED: 127 case NTP_ALL_TILES_LOADED:
117 EmitNtpStatistics(time); 128 EmitNtpStatistics(time);
118 break; 129 break;
119 default: 130 default:
120 NOTREACHED(); 131 NOTREACHED();
121 } 132 }
122 } 133 }
123 134
124 void NTPUserDataLogger::LogMostVisitedImpression( 135 void NTPUserDataLogger::LogMostVisitedImpression(
125 int position, NTPLoggingTileSource tile_source) { 136 int position, NTPLoggingTileSource tile_source) {
137 if ((position >= static_cast<int>(impression_was_logged_.size())) ||
138 (impression_was_logged_[position])) {
139 return;
140 }
141 impression_was_logged_[position] = true;
142
126 UMA_HISTOGRAM_ENUMERATION(kMostVisitedImpressionHistogramName, position, 143 UMA_HISTOGRAM_ENUMERATION(kMostVisitedImpressionHistogramName, position,
127 kNumMostVisited); 144 kNumMostVisited);
128 145
129 // Cannot rely on UMA histograms macro because the name of the histogram is 146 // Cannot rely on UMA histograms macro because the name of the histogram is
130 // generated dynamically. 147 // generated dynamically.
131 base::HistogramBase* counter = base::LinearHistogram::FactoryGet( 148 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
132 base::StringPrintf(kMostVisitedImpressionHistogramWithProvider, 149 base::StringPrintf(kMostVisitedImpressionHistogramWithProvider,
133 GetSourceName(tile_source).c_str()), 150 GetSourceName(tile_source).c_str()),
134 1, 151 1,
135 kNumMostVisited, 152 kNumMostVisited,
(...skipping 17 matching lines...) Expand all
153 kNumMostVisited + 1, 170 kNumMostVisited + 1,
154 base::Histogram::kUmaTargetedHistogramFlag); 171 base::Histogram::kUmaTargetedHistogramFlag);
155 counter->Add(position); 172 counter->Add(position);
156 173
157 // Records the action. This will be available as a time-stamped stream 174 // Records the action. This will be available as a time-stamped stream
158 // server-side and can be used to compute time-to-long-dwell. 175 // server-side and can be used to compute time-to-long-dwell.
159 content::RecordAction(base::UserMetricsAction("MostVisited_Clicked")); 176 content::RecordAction(base::UserMetricsAction("MostVisited_Clicked"));
160 } 177 }
161 178
162 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents) 179 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents)
163 : has_server_side_suggestions_(false), 180 : content::WebContentsObserver(contents),
181 has_server_side_suggestions_(false),
164 has_client_side_suggestions_(false), 182 has_client_side_suggestions_(false),
165 number_of_tiles_(0), 183 number_of_tiles_(0),
166 has_emitted_(false), 184 has_emitted_(false),
167 during_startup_(false) { 185 during_startup_(false) {
168 during_startup_ = !AfterStartupTaskUtils::IsBrowserStartupComplete(); 186 during_startup_ = !AfterStartupTaskUtils::IsBrowserStartupComplete();
169 187
170 // We record metrics about session data here because when this class typically 188 // We record metrics about session data here because when this class typically
171 // emits metrics it is too late. This session data would theoretically have 189 // emits metrics it is too late. This session data would theoretically have
172 // been used to populate the page, and we want to learn about its state when 190 // been used to populate the page, and we want to learn about its state when
173 // the NTP is being generated. 191 // the NTP is being generated.
174 if (contents) { 192 if (contents) {
175 ProfileSyncService* sync = ProfileSyncServiceFactory::GetForProfile( 193 ProfileSyncService* sync = ProfileSyncServiceFactory::GetForProfile(
176 Profile::FromBrowserContext(contents->GetBrowserContext())); 194 Profile::FromBrowserContext(contents->GetBrowserContext()));
177 if (sync) { 195 if (sync) {
178 browser_sync::SessionsSyncManager* sessions = 196 browser_sync::SessionsSyncManager* sessions =
179 static_cast<browser_sync::SessionsSyncManager*>( 197 static_cast<browser_sync::SessionsSyncManager*>(
180 sync->GetSessionsSyncableService()); 198 sync->GetSessionsSyncableService());
181 if (sessions) { 199 if (sessions) {
182 sync_sessions::SyncSessionsMetrics::RecordYoungestForeignTabAgeOnNTP( 200 sync_sessions::SyncSessionsMetrics::RecordYoungestForeignTabAgeOnNTP(
183 sessions); 201 sessions);
184 } 202 }
185 } 203 }
186 } 204 }
187 } 205 }
188 206
207 // content::WebContentsObserver override
208 void NTPUserDataLogger::NavigationEntryCommitted(
209 const content::LoadCommittedDetails& load_details) {
210 // User is returning to NTP, probably via the back button; reset stats.
211 if (load_details.previous_url.is_valid() &&
212 load_details.entry->GetURL().is_valid() &&
213 (load_details.entry->GetURL() == ntp_url_)) {
214 DVLOG(1) << "Returning to New Tab Page";
215 impression_was_logged_.reset();
216 has_emitted_ = false;
217 number_of_tiles_ = 0;
218 has_server_side_suggestions_ = true;
219 has_client_side_suggestions_ = true;
Marc Treib 2016/07/15 10:04:46 These should be set to false
sfiera 2016/07/15 10:26:00 Hein, that's embarrassing. I had looked for a way
Marc Treib 2016/07/15 11:47:37 Nice, I actually find that easier to read than the
220 }
221 }
222
189 void NTPUserDataLogger::EmitNtpStatistics(base::TimeDelta load_time) { 223 void NTPUserDataLogger::EmitNtpStatistics(base::TimeDelta load_time) {
190 // We only send statistics once per page. 224 // We only send statistics once per page.
191 if (has_emitted_) 225 if (has_emitted_)
192 return; 226 return;
227 DVLOG(1) << "Emitting NTP load time: " << load_time << ", "
228 << "number of tiles: " << number_of_tiles_;
193 229
194 logLoadTimeHistogram("NewTabPage.LoadTime", load_time); 230 logLoadTimeHistogram("NewTabPage.LoadTime", load_time);
195 231
196 // Split between ML and MV. 232 // Split between ML and MV.
197 std::string type = has_server_side_suggestions_ ? 233 std::string type = has_server_side_suggestions_ ?
198 "MostLikely" : "MostVisited"; 234 "MostLikely" : "MostVisited";
199 logLoadTimeHistogram("NewTabPage.LoadTime." + type, load_time); 235 logLoadTimeHistogram("NewTabPage.LoadTime." + type, load_time);
200 // Split between Web and Local. 236 // Split between Web and Local.
201 std::string source = ntp_url_.SchemeIsHTTPOrHTTPS() ? "Web" : "LocalNTP"; 237 std::string source = ntp_url_.SchemeIsHTTPOrHTTPS() ? "Web" : "LocalNTP";
202 logLoadTimeHistogram("NewTabPage.LoadTime." + source, load_time); 238 logLoadTimeHistogram("NewTabPage.LoadTime." + source, load_time);
203 239
204 // Split between Startup and non-startup. 240 // Split between Startup and non-startup.
205 std::string status = during_startup_ ? "Startup" : "NewTab"; 241 std::string status = during_startup_ ? "Startup" : "NewTab";
206 logLoadTimeHistogram("NewTabPage.LoadTime." + status, load_time); 242 logLoadTimeHistogram("NewTabPage.LoadTime." + status, load_time);
207 243
208 has_server_side_suggestions_ = false; 244 has_server_side_suggestions_ = false;
209 has_client_side_suggestions_ = false; 245 has_client_side_suggestions_ = false;
210 UMA_HISTOGRAM_CUSTOM_COUNTS( 246 UMA_HISTOGRAM_CUSTOM_COUNTS(
211 "NewTabPage.NumberOfTiles", number_of_tiles_, 0, kNumMostVisited, 247 "NewTabPage.NumberOfTiles", number_of_tiles_, 0, kNumMostVisited,
212 kNumMostVisited + 1); 248 kNumMostVisited + 1);
213 number_of_tiles_ = 0; 249 number_of_tiles_ = 0;
214 has_emitted_ = true; 250 has_emitted_ = true;
215 during_startup_ = false; 251 during_startup_ = false;
216 } 252 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698