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

Side by Side Diff: chrome/browser/page_load_metrics/user_input_tracker.cc

Issue 2540183003: Add UserInputTracker, which keeps track of recent user input events. (Closed)
Patch Set: Created 4 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
OLDNEW
(Empty)
1 // Copyright 2016 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/page_load_metrics/user_input_tracker.h"
6
7 #include <algorithm>
8
9 #include "third_party/WebKit/public/platform/WebInputEvent.h"
10
11 namespace page_load_metrics {
12
13 namespace {
14
15 // Blink's UserGestureIndicator allows events to be associated with gestures
16 // that are up to 1 second old, based on guidance in the HTML spec:
17 // https://html.spec.whatwg.org/multipage/interaction.html#triggered-by-user-act ivation.
18 const int kMaxEventAgeSeconds = 1;
19
20 bool IsInterestingInputEvent(const blink::WebInputEvent& event) {
21 // Ignore synthesized auto repeat events.
22 if (event.modifiers & blink::WebInputEvent::IsAutoRepeat)
23 return false;
24
25 switch (event.type) {
26 case blink::WebInputEvent::MouseDown:
27 case blink::WebInputEvent::MouseUp:
28 case blink::WebInputEvent::RawKeyDown:
29 case blink::WebInputEvent::KeyDown:
30 case blink::WebInputEvent::Char:
31 case blink::WebInputEvent::TouchStart:
32 case blink::WebInputEvent::TouchEnd:
33 return true;
34 default:
35 return false;
36 }
37 }
38
39 } // namespace
40
41 UserInputTracker::UserInputTracker() {}
42 UserInputTracker::~UserInputTracker() {}
43
44 // static
45 base::TimeTicks UserInputTracker::GetEventTime(
46 const blink::WebInputEvent& event) {
47 return base::TimeTicks() +
Charlie Harrison 2016/12/02 02:58:44 Can you document why this conversion is correct?
Bryan McQuade 2016/12/02 20:43:01 Done
48 base::TimeDelta::FromSecondsD(event.timeStampSeconds);
49 }
50
51 void UserInputTracker::OnInputEvent(const blink::WebInputEvent& event) {
52 RemoveOldInputEvents();
53
54 if (!IsInterestingInputEvent(event))
55 return;
56
57 // TODO(bmcquade): ideally we'd limit tracking to events generated by a user
58 // action, as opposed to those generated from JavaScript. The JS API isTrusted
59 // can be used to distinguish these cases. isTrusted isn't yet a property of
60 // WebInputEvent. We should consider adding it.
61
Charlie Harrison 2016/12/02 02:58:44 Should we trim event_times_ here too, to avoid it
Bryan McQuade 2016/12/02 20:43:01 Yep - moved to the rate limiting model we talked a
62 event_times_.insert(GetEventTime(event));
63 }
64
65 base::TimeTicks UserInputTracker::FindMostRecentUserInputEventBefore(
66 base::TimeTicks time) {
67 RemoveOldInputEvents();
68
69 if (event_times_.empty())
70 return base::TimeTicks();
71
72 // lower_bound finds the first element >= |time|.
73 auto it = event_times_.lower_bound(time);
74
75 // If all times are after the requested time, then we don't have a time to
76 // return.
77 if (it == event_times_.begin())
78 return base::TimeTicks();
79
80 // |it| points to the first event >= the specified time, so decrement once to
81 // find the greatest event before the specified time.
82 --it;
83 base::TimeTicks candidate = *it;
84 DCHECK(candidate < time);
85
86 // If the most recent event is too old, then don't return it.
87 if (candidate < time - base::TimeDelta::FromSeconds(kMaxEventAgeSeconds))
88 return base::TimeTicks();
89
90 return candidate;
91 }
92
93 void UserInputTracker::ConsumeUserInputEventsUpTo(base::TimeTicks time) {
94 RemoveInputEventsUpTo(std::max(time, GetOldestAllowedEventTime()));
95 }
96
97 void UserInputTracker::RemoveOldInputEvents() {
98 RemoveInputEventsUpTo(GetOldestAllowedEventTime());
99 }
100
101 void UserInputTracker::RemoveInputEventsUpTo(base::TimeTicks cutoff) {
102 event_times_.erase(event_times_.begin(), event_times_.upper_bound(cutoff));
103 }
104
105 // static
106 base::TimeTicks UserInputTracker::GetOldestAllowedEventTime() {
Charlie Harrison 2016/12/02 02:58:44 Why don't we limit to 1s old instead of 2s old eve
Bryan McQuade 2016/12/02 20:43:01 The idea here is that if someone calls FindMostRec
107 // Allow for up to 2x the oldest time. This allows consumers to continue to
108 // find events for timestamps up to 1 second in the past.
109 return base::TimeTicks::Now() -
110 base::TimeDelta::FromSeconds(kMaxEventAgeSeconds * 2);
111 }
112
113 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698