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

Side by Side Diff: content/renderer/render_widget.cc

Issue 1474443002: Add UMA metrics to determine the usefulness of passive event listeners. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master_passive_uma
Patch Set: Fix time calculation Created 5 years 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
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/renderer/render_widget.h" 5 #include "content/renderer/render_widget.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 const ui::LatencyInfo& latency_info) { 234 const ui::LatencyInfo& latency_info) {
235 LogInputEventLatencyUmaImpl(event.type, event.timeStampSeconds, now); 235 LogInputEventLatencyUmaImpl(event.type, event.timeStampSeconds, now);
236 for (size_t i = 0; i < latency_info.coalesced_events_size(); i++) { 236 for (size_t i = 0; i < latency_info.coalesced_events_size(); i++) {
237 LogInputEventLatencyUmaImpl( 237 LogInputEventLatencyUmaImpl(
238 event.type, 238 event.type,
239 latency_info.timestamps_of_coalesced_events()[i], 239 latency_info.timestamps_of_coalesced_events()[i],
240 now); 240 now);
241 } 241 }
242 } 242 }
243 243
244 void LogPassiveLatency(int64 latency) {
245 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.PassiveListeners.Latency", latency, 1,
246 10000000, 100);
247 }
248
249 void LogPassiveEventListenersUma(WebInputEventResult result,
250 bool passive,
251 bool cancelable,
252 double event_timestamp,
253 const ui::LatencyInfo& latency_info) {
254 enum {
255 PASSIVE_LISTENER_UMA_ENUM_PASSIVE,
256 PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE,
257 PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED,
258 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE,
259 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED,
260 PASSIVE_LISTENER_UMA_ENUM_COUNT
261 };
262
263 int enum_value;
264 if (passive)
265 enum_value = PASSIVE_LISTENER_UMA_ENUM_PASSIVE;
266 else if (!cancelable)
267 enum_value = PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE;
268 else if (result == WebInputEventResult::HandledApplication)
269 enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED;
270 else if (result == WebInputEventResult::HandledSuppressed)
271 enum_value = PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED;
272 else
273 enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE;
274
275 UMA_HISTOGRAM_ENUMERATION("Event.PassiveListeners", enum_value,
276 PASSIVE_LISTENER_UMA_ENUM_COUNT);
277
278 if (enum_value == PASSIVE_LISTENER_UMA_ENUM_CANCELABLE &&
279 base::TimeTicks::IsHighResolution()) {
280 base::TimeTicks now = base::TimeTicks::Now();
281 LogPassiveLatency(GetEventLatencyMicros(event_timestamp, now));
282 for (size_t i = 0; i < latency_info.coalesced_events_size(); i++)
283 LogPassiveLatency(GetEventLatencyMicros(
284 latency_info.timestamps_of_coalesced_events()[i], now));
285 }
286 }
287
244 } // namespace 288 } // namespace
245 289
246 namespace content { 290 namespace content {
247 291
248 // RenderWidget::ScreenMetricsEmulator ---------------------------------------- 292 // RenderWidget::ScreenMetricsEmulator ----------------------------------------
249 293
250 class RenderWidget::ScreenMetricsEmulator { 294 class RenderWidget::ScreenMetricsEmulator {
251 public: 295 public:
252 ScreenMetricsEmulator( 296 ScreenMetricsEmulator(
253 RenderWidget* widget, 297 RenderWidget* widget,
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete"); 1130 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete");
1087 1131
1088 // Notify subclasses that composited rendering was flushed to the screen. 1132 // Notify subclasses that composited rendering was flushed to the screen.
1089 DidFlushPaint(); 1133 DidFlushPaint();
1090 } 1134 }
1091 1135
1092 void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event, 1136 void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event,
1093 const ui::LatencyInfo& latency_info) { 1137 const ui::LatencyInfo& latency_info) {
1094 if (!input_event) 1138 if (!input_event)
1095 return; 1139 return;
1140
1141 // TODO(dtapuska): Passive support not implemented yet crbug.com/489802
1142 bool passive = false;
1096 base::AutoReset<bool> handling_input_event_resetter(&handling_input_event_, 1143 base::AutoReset<bool> handling_input_event_resetter(&handling_input_event_,
1097 true); 1144 true);
1098 base::AutoReset<WebInputEvent::Type> handling_event_type_resetter( 1145 base::AutoReset<WebInputEvent::Type> handling_event_type_resetter(
1099 &handling_event_type_, input_event->type); 1146 &handling_event_type_, input_event->type);
1100 1147
1101 // Calls into |didOverscroll()| while handling this event will populate 1148 // Calls into |didOverscroll()| while handling this event will populate
1102 // |event_overscroll|, which in turn will be bundled with the event ack. 1149 // |event_overscroll|, which in turn will be bundled with the event ack.
1103 scoped_ptr<DidOverscrollParams> event_overscroll; 1150 scoped_ptr<DidOverscrollParams> event_overscroll;
1104 base::AutoReset<scoped_ptr<DidOverscrollParams>*> 1151 base::AutoReset<scoped_ptr<DidOverscrollParams>*>
1105 handling_event_overscroll_resetter(&handling_event_overscroll_, 1152 handling_event_overscroll_resetter(&handling_event_overscroll_,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 #endif 1218 #endif
1172 } 1219 }
1173 1220
1174 if (WebInputEvent::isGestureEventType(input_event->type)) { 1221 if (WebInputEvent::isGestureEventType(input_event->type)) {
1175 const WebGestureEvent& gesture_event = 1222 const WebGestureEvent& gesture_event =
1176 *static_cast<const WebGestureEvent*>(input_event); 1223 *static_cast<const WebGestureEvent*>(input_event);
1177 context_menu_source_type_ = ui::MENU_SOURCE_TOUCH; 1224 context_menu_source_type_ = ui::MENU_SOURCE_TOUCH;
1178 prevent_default = prevent_default || WillHandleGestureEvent(gesture_event); 1225 prevent_default = prevent_default || WillHandleGestureEvent(gesture_event);
1179 } 1226 }
1180 1227
1181 bool processed = prevent_default; 1228 WebInputEventResult processed =
1229 prevent_default ? WebInputEventResult::HandledSuppressed
1230 : WebInputEventResult::NotHandled;
1182 if (input_event->type != WebInputEvent::Char || !suppress_next_char_events_) { 1231 if (input_event->type != WebInputEvent::Char || !suppress_next_char_events_) {
1183 suppress_next_char_events_ = false; 1232 suppress_next_char_events_ = false;
1184 if (!processed && webwidget_) 1233 if (processed == WebInputEventResult::NotHandled && webwidget_)
1185 processed = webwidget_->handleInputEvent(*input_event) != 1234 processed = webwidget_->handleInputEvent(*input_event);
1186 WebInputEventResult::NotHandled; 1235 }
1236
1237 // TODO(dtapuska): Use the input_event->timeStampSeconds as the start
1238 // ideally this should be when the event was sent by the compositor to the
1239 // renderer. crbug.com/565348
1240 if (input_event->type == WebInputEvent::TouchStart ||
1241 input_event->type == WebInputEvent::TouchMove ||
1242 input_event->type == WebInputEvent::TouchEnd) {
1243 LogPassiveEventListenersUma(
1244 processed, passive,
1245 static_cast<const WebTouchEvent*>(input_event)->cancelable,
1246 input_event->timeStampSeconds, latency_info);
1247 } else if (input_event->type == WebInputEvent::MouseWheel) {
1248 LogPassiveEventListenersUma(processed, passive, !passive,
1249 input_event->timeStampSeconds, latency_info);
1187 } 1250 }
1188 1251
1189 // If this RawKeyDown event corresponds to a browser keyboard shortcut and 1252 // If this RawKeyDown event corresponds to a browser keyboard shortcut and
1190 // it's not processed by webkit, then we need to suppress the upcoming Char 1253 // it's not processed by webkit, then we need to suppress the upcoming Char
1191 // events. 1254 // events.
1192 bool is_keyboard_shortcut = 1255 bool is_keyboard_shortcut =
1193 input_event->type == WebInputEvent::RawKeyDown && 1256 input_event->type == WebInputEvent::RawKeyDown &&
1194 static_cast<const WebKeyboardEvent*>(input_event)->isBrowserShortcut; 1257 static_cast<const WebKeyboardEvent*>(input_event)->isBrowserShortcut;
1195 if (!processed && is_keyboard_shortcut) 1258 if (processed == WebInputEventResult::NotHandled && is_keyboard_shortcut)
1196 suppress_next_char_events_ = true; 1259 suppress_next_char_events_ = true;
1197 1260
1198 InputEventAckState ack_result = processed ? 1261 InputEventAckState ack_result = processed == WebInputEventResult::NotHandled
1199 INPUT_EVENT_ACK_STATE_CONSUMED : INPUT_EVENT_ACK_STATE_NOT_CONSUMED; 1262 ? INPUT_EVENT_ACK_STATE_NOT_CONSUMED
1200 if (!processed && input_event->type == WebInputEvent::TouchStart) { 1263 : INPUT_EVENT_ACK_STATE_CONSUMED;
1264 if (processed == WebInputEventResult::NotHandled &&
1265 input_event->type == WebInputEvent::TouchStart) {
1201 const WebTouchEvent& touch_event = 1266 const WebTouchEvent& touch_event =
1202 *static_cast<const WebTouchEvent*>(input_event); 1267 *static_cast<const WebTouchEvent*>(input_event);
1203 // Hit-test for all the pressed touch points. If there is a touch-handler 1268 // Hit-test for all the pressed touch points. If there is a touch-handler
1204 // for any of the touch points, then the renderer should continue to receive 1269 // for any of the touch points, then the renderer should continue to receive
1205 // touch events. 1270 // touch events.
1206 ack_result = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; 1271 ack_result = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
1207 for (size_t i = 0; i < touch_event.touchesLength; ++i) { 1272 for (size_t i = 0; i < touch_event.touchesLength; ++i) {
1208 if (touch_event.touches[i].state == WebTouchPoint::StatePressed && 1273 if (touch_event.touches[i].state == WebTouchPoint::StatePressed &&
1209 HasTouchEventHandlersAt( 1274 HasTouchEventHandlersAt(
1210 gfx::ToFlooredPoint(touch_event.touches[i].position))) { 1275 gfx::ToFlooredPoint(touch_event.touches[i].position))) {
1211 ack_result = INPUT_EVENT_ACK_STATE_NOT_CONSUMED; 1276 ack_result = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1212 break; 1277 break;
1213 } 1278 }
1214 } 1279 }
1215 } 1280 }
1216 1281
1217 // Send mouse wheel events and their disposition to the compositor thread, so 1282 // Send mouse wheel events and their disposition to the compositor thread, so
1218 // that they can be used to produce the elastic overscroll effect on Mac. 1283 // that they can be used to produce the elastic overscroll effect on Mac.
1219 if (input_event->type == WebInputEvent::MouseWheel) { 1284 if (input_event->type == WebInputEvent::MouseWheel) {
1220 ObserveWheelEventAndResult( 1285 ObserveWheelEventAndResult(
1221 static_cast<const WebMouseWheelEvent&>(*input_event), 1286 static_cast<const WebMouseWheelEvent&>(*input_event),
1222 event_overscroll ? event_overscroll->latest_overscroll_delta 1287 event_overscroll ? event_overscroll->latest_overscroll_delta
1223 : gfx::Vector2dF(), 1288 : gfx::Vector2dF(),
1224 processed); 1289 processed != WebInputEventResult::NotHandled);
1225 } 1290 }
1226 1291
1227 bool frame_pending = compositor_ && compositor_->BeginMainFrameRequested(); 1292 bool frame_pending = compositor_ && compositor_->BeginMainFrameRequested();
1228 1293
1229 // If we don't have a fast and accurate Now(), we assume the input handlers 1294 // If we don't have a fast and accurate Now(), we assume the input handlers
1230 // are heavy and rate limit them. 1295 // are heavy and rate limit them.
1231 bool rate_limiting_wanted = 1296 bool rate_limiting_wanted =
1232 input_event->type == WebInputEvent::MouseMove || 1297 input_event->type == WebInputEvent::MouseMove ||
1233 input_event->type == WebInputEvent::MouseWheel; 1298 input_event->type == WebInputEvent::MouseWheel;
1234 if (rate_limiting_wanted && !start_time.is_null()) { 1299 if (rate_limiting_wanted && !start_time.is_null()) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 RenderThreadImpl::current() 1346 RenderThreadImpl::current()
1282 ->GetRendererScheduler() 1347 ->GetRendererScheduler()
1283 ->DidHandleInputEventOnMainThread(*input_event); 1348 ->DidHandleInputEventOnMainThread(*input_event);
1284 } 1349 }
1285 if (input_event->type == WebInputEvent::MouseMove) 1350 if (input_event->type == WebInputEvent::MouseMove)
1286 ignore_ack_for_mouse_move_from_debugger_ = false; 1351 ignore_ack_for_mouse_move_from_debugger_ = false;
1287 1352
1288 #if defined(OS_ANDROID) 1353 #if defined(OS_ANDROID)
1289 // Allow the IME to be shown when the focus changes as a consequence 1354 // Allow the IME to be shown when the focus changes as a consequence
1290 // of a processed touch end event. 1355 // of a processed touch end event.
1291 if (input_event->type == WebInputEvent::TouchEnd && processed) 1356 if (input_event->type == WebInputEvent::TouchEnd &&
1357 processed != WebInputEventResult::NotHandled) {
1292 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME); 1358 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME);
1359 }
1293 #elif defined(USE_AURA) 1360 #elif defined(USE_AURA)
1294 // Show the virtual keyboard if enabled and a user gesture triggers a focus 1361 // Show the virtual keyboard if enabled and a user gesture triggers a focus
1295 // change. 1362 // change.
1296 if (processed && (input_event->type == WebInputEvent::TouchEnd || 1363 if (processed != WebInputEventResult::NotHandled &&
1297 input_event->type == WebInputEvent::MouseUp)) { 1364 (input_event->type == WebInputEvent::TouchEnd ||
1365 input_event->type == WebInputEvent::MouseUp)) {
1298 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_IME); 1366 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_IME);
1299 } 1367 }
1300 #endif 1368 #endif
1301 1369
1302 if (!prevent_default) { 1370 if (!prevent_default) {
1303 if (WebInputEvent::isKeyboardEventType(input_event->type)) 1371 if (WebInputEvent::isKeyboardEventType(input_event->type))
1304 DidHandleKeyEvent(); 1372 DidHandleKeyEvent();
1305 } 1373 }
1306 1374
1307 // TODO(rouslan): Fix ChromeOS and Windows 8 behavior of autofill popup with 1375 // TODO(rouslan): Fix ChromeOS and Windows 8 behavior of autofill popup with
1308 // virtual keyboard. 1376 // virtual keyboard.
1309 #if !defined(OS_ANDROID) 1377 #if !defined(OS_ANDROID)
1310 // Virtual keyboard is not supported, so react to focus change immediately. 1378 // Virtual keyboard is not supported, so react to focus change immediately.
1311 if (processed && (input_event->type == WebInputEvent::TouchEnd || 1379 if (processed != WebInputEventResult::NotHandled &&
1312 input_event->type == WebInputEvent::MouseUp)) { 1380 (input_event->type == WebInputEvent::TouchEnd ||
1381 input_event->type == WebInputEvent::MouseUp)) {
1313 FocusChangeComplete(); 1382 FocusChangeComplete();
1314 } 1383 }
1315 #endif 1384 #endif
1316 } 1385 }
1317 1386
1318 void RenderWidget::OnCursorVisibilityChange(bool is_visible) { 1387 void RenderWidget::OnCursorVisibilityChange(bool is_visible) {
1319 if (webwidget_) 1388 if (webwidget_)
1320 webwidget_->setCursorVisibilityState(is_visible); 1389 webwidget_->setCursorVisibilityState(is_visible);
1321 } 1390 }
1322 1391
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2453 void RenderWidget::RegisterVideoHoleFrame(RenderFrameImpl* frame) { 2522 void RenderWidget::RegisterVideoHoleFrame(RenderFrameImpl* frame) {
2454 video_hole_frames_.AddObserver(frame); 2523 video_hole_frames_.AddObserver(frame);
2455 } 2524 }
2456 2525
2457 void RenderWidget::UnregisterVideoHoleFrame(RenderFrameImpl* frame) { 2526 void RenderWidget::UnregisterVideoHoleFrame(RenderFrameImpl* frame) {
2458 video_hole_frames_.RemoveObserver(frame); 2527 video_hole_frames_.RemoveObserver(frame);
2459 } 2528 }
2460 #endif // defined(VIDEO_HOLE) 2529 #endif // defined(VIDEO_HOLE)
2461 2530
2462 } // namespace content 2531 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698