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

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.
100 //
101 // TODO(sfiera): move to a world where the Google NTP is at chrome://newtab/
102 // to begin with and we don't need any such fallback behavior.
92 const content::NavigationEntry* entry = 103 const content::NavigationEntry* entry =
93 content->GetController().GetVisibleEntry(); 104 content->GetController().GetVisibleEntry();
94 if (entry) 105 if (entry && (logger->ntp_url_ != entry->GetURL())) {
106 DVLOG(1) << "NTP URL changed from \"" << logger->ntp_url_ << "\" to \""
107 << entry->GetURL() << "\"";
95 logger->ntp_url_ = entry->GetURL(); 108 logger->ntp_url_ = entry->GetURL();
109 }
96 110
97 return logger; 111 return logger;
98 } 112 }
99 113
100 void NTPUserDataLogger::LogEvent(NTPLoggingEventType event, 114 void NTPUserDataLogger::LogEvent(NTPLoggingEventType event,
101 base::TimeDelta time) { 115 base::TimeDelta time) {
102 switch (event) { 116 switch (event) {
103 case NTP_SERVER_SIDE_SUGGESTION: 117 case NTP_SERVER_SIDE_SUGGESTION:
104 has_server_side_suggestions_ = true; 118 has_server_side_suggestions_ = true;
105 break; 119 break;
(...skipping 10 matching lines...) Expand all
116 case NTP_ALL_TILES_LOADED: 130 case NTP_ALL_TILES_LOADED:
117 EmitNtpStatistics(time); 131 EmitNtpStatistics(time);
118 break; 132 break;
119 default: 133 default:
120 NOTREACHED(); 134 NOTREACHED();
121 } 135 }
122 } 136 }
123 137
124 void NTPUserDataLogger::LogMostVisitedImpression( 138 void NTPUserDataLogger::LogMostVisitedImpression(
125 int position, NTPLoggingTileSource tile_source) { 139 int position, NTPLoggingTileSource tile_source) {
140 if (position >= static_cast<int>(impression_was_logged_.size())) {
141 impression_was_logged_.resize(position + 1);
142 } else if (impression_was_logged_[position]) {
143 return;
144 }
145 impression_was_logged_[position] = true;
146
126 UMA_HISTOGRAM_ENUMERATION(kMostVisitedImpressionHistogramName, position, 147 UMA_HISTOGRAM_ENUMERATION(kMostVisitedImpressionHistogramName, position,
127 kNumMostVisited); 148 kNumMostVisited);
128 149
129 // Cannot rely on UMA histograms macro because the name of the histogram is 150 // Cannot rely on UMA histograms macro because the name of the histogram is
130 // generated dynamically. 151 // generated dynamically.
131 base::HistogramBase* counter = base::LinearHistogram::FactoryGet( 152 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
132 base::StringPrintf(kMostVisitedImpressionHistogramWithProvider, 153 base::StringPrintf(kMostVisitedImpressionHistogramWithProvider,
133 GetSourceName(tile_source).c_str()), 154 GetSourceName(tile_source).c_str()),
134 1, 155 1,
135 kNumMostVisited, 156 kNumMostVisited,
(...skipping 17 matching lines...) Expand all
153 kNumMostVisited + 1, 174 kNumMostVisited + 1,
154 base::Histogram::kUmaTargetedHistogramFlag); 175 base::Histogram::kUmaTargetedHistogramFlag);
155 counter->Add(position); 176 counter->Add(position);
156 177
157 // Records the action. This will be available as a time-stamped stream 178 // 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. 179 // server-side and can be used to compute time-to-long-dwell.
159 content::RecordAction(base::UserMetricsAction("MostVisited_Clicked")); 180 content::RecordAction(base::UserMetricsAction("MostVisited_Clicked"));
160 } 181 }
161 182
162 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents) 183 NTPUserDataLogger::NTPUserDataLogger(content::WebContents* contents)
163 : has_server_side_suggestions_(false), 184 : content::WebContentsObserver(contents),
185 has_server_side_suggestions_(false),
164 has_client_side_suggestions_(false), 186 has_client_side_suggestions_(false),
165 number_of_tiles_(0), 187 number_of_tiles_(0),
166 has_emitted_(false), 188 has_emitted_(false),
167 during_startup_(false) { 189 during_startup_(false) {
168 during_startup_ = !AfterStartupTaskUtils::IsBrowserStartupComplete(); 190 during_startup_ = !AfterStartupTaskUtils::IsBrowserStartupComplete();
169 191
170 // We record metrics about session data here because when this class typically 192 // 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 193 // 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 194 // been used to populate the page, and we want to learn about its state when
173 // the NTP is being generated. 195 // the NTP is being generated.
174 if (contents) { 196 if (contents) {
175 ProfileSyncService* sync = ProfileSyncServiceFactory::GetForProfile( 197 ProfileSyncService* sync = ProfileSyncServiceFactory::GetForProfile(
176 Profile::FromBrowserContext(contents->GetBrowserContext())); 198 Profile::FromBrowserContext(contents->GetBrowserContext()));
177 if (sync) { 199 if (sync) {
178 browser_sync::SessionsSyncManager* sessions = 200 browser_sync::SessionsSyncManager* sessions =
179 static_cast<browser_sync::SessionsSyncManager*>( 201 static_cast<browser_sync::SessionsSyncManager*>(
180 sync->GetSessionsSyncableService()); 202 sync->GetSessionsSyncableService());
181 if (sessions) { 203 if (sessions) {
182 sync_sessions::SyncSessionsMetrics::RecordYoungestForeignTabAgeOnNTP( 204 sync_sessions::SyncSessionsMetrics::RecordYoungestForeignTabAgeOnNTP(
183 sessions); 205 sessions);
184 } 206 }
185 } 207 }
186 } 208 }
187 } 209 }
188 210
211 // content::WebContentsObserver override
212 void NTPUserDataLogger::NavigationEntryCommitted(
213 const content::LoadCommittedDetails& load_details) {
214 // User is returning to NTP, probably via the back button; reset stats.
215 if (load_details.previous_url.is_valid() &&
216 load_details.entry->GetURL().is_valid() &&
217 (load_details.entry->GetURL() == ntp_url_)) {
218 DVLOG(1) << "Returning to New Tab Page";
219 impression_was_logged_.clear();
220 has_emitted_ = false;
221 number_of_tiles_ = 0;
Marc Treib 2016/07/14 14:40:52 I was gonna say "Also reset has_[server|client]_si
sfiera 2016/07/15 09:55:10 Done.
Marc Treib 2016/07/15 10:04:46 Acknowledged.
222 }
223 }
224
189 void NTPUserDataLogger::EmitNtpStatistics(base::TimeDelta load_time) { 225 void NTPUserDataLogger::EmitNtpStatistics(base::TimeDelta load_time) {
190 // We only send statistics once per page. 226 // We only send statistics once per page.
191 if (has_emitted_) 227 if (has_emitted_)
192 return; 228 return;
229 DVLOG(1) << "Emitting NTP load time: " << load_time << ", "
230 << "number of tiles: " << number_of_tiles_;
193 231
194 logLoadTimeHistogram("NewTabPage.LoadTime", load_time); 232 logLoadTimeHistogram("NewTabPage.LoadTime", load_time);
195 233
196 // Split between ML and MV. 234 // Split between ML and MV.
197 std::string type = has_server_side_suggestions_ ? 235 std::string type = has_server_side_suggestions_ ?
198 "MostLikely" : "MostVisited"; 236 "MostLikely" : "MostVisited";
199 logLoadTimeHistogram("NewTabPage.LoadTime." + type, load_time); 237 logLoadTimeHistogram("NewTabPage.LoadTime." + type, load_time);
200 // Split between Web and Local. 238 // Split between Web and Local.
201 std::string source = ntp_url_.SchemeIsHTTPOrHTTPS() ? "Web" : "LocalNTP"; 239 std::string source = ntp_url_.SchemeIsHTTPOrHTTPS() ? "Web" : "LocalNTP";
202 logLoadTimeHistogram("NewTabPage.LoadTime." + source, load_time); 240 logLoadTimeHistogram("NewTabPage.LoadTime." + source, load_time);
203 241
204 // Split between Startup and non-startup. 242 // Split between Startup and non-startup.
205 std::string status = during_startup_ ? "Startup" : "NewTab"; 243 std::string status = during_startup_ ? "Startup" : "NewTab";
206 logLoadTimeHistogram("NewTabPage.LoadTime." + status, load_time); 244 logLoadTimeHistogram("NewTabPage.LoadTime." + status, load_time);
207 245
208 has_server_side_suggestions_ = false; 246 has_server_side_suggestions_ = false;
209 has_client_side_suggestions_ = false; 247 has_client_side_suggestions_ = false;
210 UMA_HISTOGRAM_CUSTOM_COUNTS( 248 UMA_HISTOGRAM_CUSTOM_COUNTS(
211 "NewTabPage.NumberOfTiles", number_of_tiles_, 0, kNumMostVisited, 249 "NewTabPage.NumberOfTiles", number_of_tiles_, 0, kNumMostVisited,
212 kNumMostVisited + 1); 250 kNumMostVisited + 1);
213 number_of_tiles_ = 0; 251 number_of_tiles_ = 0;
214 has_emitted_ = true; 252 has_emitted_ = true;
215 during_startup_ = false; 253 during_startup_ = false;
216 } 254 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698