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

Side by Side Diff: components/scheduler/renderer/user_model.cc

Issue 2118903002: scheduler: Move the Blink scheduler into Blink (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 4 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
(Empty)
1 // Copyright 2015 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 "components/scheduler/renderer/user_model.h"
6
7 #include "base/metrics/histogram_macros.h"
8
9 namespace scheduler {
10
11 namespace {
12 // This enum is used to back a histogram, and should therefore be treated as
13 // append-only.
14 enum GesturePredictionResult {
15 GESTURE_OCCURED_WAS_PREDICTED = 0,
16 GESTURE_OCCURED_BUT_NOT_PREDICTED = 1,
17 GESTURE_PREDICTED_BUT_DID_NOT_OCCUR = 2,
18 GESTURE_PREDICTION_RESULT_COUNT = 3
19 };
20
21 void RecordGesturePrediction(GesturePredictionResult result) {
22 UMA_HISTOGRAM_ENUMERATION(
23 "RendererScheduler.UserModel.GesturePredictedCorrectly", result,
24 GESTURE_PREDICTION_RESULT_COUNT);
25 }
26
27 } // namespace
28
29 UserModel::UserModel()
30 : pending_input_event_count_(0),
31 is_gesture_active_(false),
32 is_gesture_expected_(false) {}
33 UserModel::~UserModel() {}
34
35 void UserModel::DidStartProcessingInputEvent(blink::WebInputEvent::Type type,
36 const base::TimeTicks now) {
37 last_input_signal_time_ = now;
38 if (type == blink::WebInputEvent::TouchStart ||
39 type == blink::WebInputEvent::GestureScrollBegin ||
40 type == blink::WebInputEvent::GesturePinchBegin) {
41 // Only update stats once per gesture.
42 if (!is_gesture_active_) {
43 last_gesture_start_time_ = now;
44
45 RecordGesturePrediction(is_gesture_expected_
46 ? GESTURE_OCCURED_WAS_PREDICTED
47 : GESTURE_OCCURED_BUT_NOT_PREDICTED);
48
49 if (!last_reset_time_.is_null()) {
50 base::TimeDelta time_since_reset = now - last_reset_time_;
51 UMA_HISTOGRAM_MEDIUM_TIMES(
52 "RendererScheduler.UserModel.GestureStartTimeSinceModelReset",
53 time_since_reset);
54 }
55
56 // If there has been a previous gesture, record a UMA metric for the time
57 // interval between then and now.
58 if (!last_continuous_gesture_time_.is_null()) {
59 base::TimeDelta time_since_last_gesture =
60 now - last_continuous_gesture_time_;
61 UMA_HISTOGRAM_MEDIUM_TIMES(
62 "RendererScheduler.UserModel.TimeBetweenGestures",
63 time_since_last_gesture);
64 }
65 }
66
67 is_gesture_active_ = true;
68 }
69
70 // We need to track continuous gestures seperatly for scroll detection
71 // because taps should not be confused with scrolls.
72 if (type == blink::WebInputEvent::GestureScrollBegin ||
73 type == blink::WebInputEvent::GestureScrollEnd ||
74 type == blink::WebInputEvent::GestureScrollUpdate ||
75 type == blink::WebInputEvent::GestureFlingStart ||
76 type == blink::WebInputEvent::GestureFlingCancel ||
77 type == blink::WebInputEvent::GesturePinchBegin ||
78 type == blink::WebInputEvent::GesturePinchEnd ||
79 type == blink::WebInputEvent::GesturePinchUpdate) {
80 last_continuous_gesture_time_ = now;
81 }
82
83 // If the gesture has ended, clear |is_gesture_active_| and record a UMA
84 // metric that tracks its duration.
85 if (type == blink::WebInputEvent::GestureScrollEnd ||
86 type == blink::WebInputEvent::GesturePinchEnd ||
87 type == blink::WebInputEvent::GestureFlingStart ||
88 type == blink::WebInputEvent::TouchEnd) {
89 // Only update stats once per gesture.
90 if (is_gesture_active_) {
91 base::TimeDelta duration = now - last_gesture_start_time_;
92 UMA_HISTOGRAM_TIMES("RendererScheduler.UserModel.GestureDuration",
93 duration);
94 }
95 is_gesture_active_ = false;
96 }
97
98 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
99 "is_gesture_active", is_gesture_active_);
100
101 pending_input_event_count_++;
102 }
103
104 void UserModel::DidFinishProcessingInputEvent(const base::TimeTicks now) {
105 last_input_signal_time_ = now;
106 if (pending_input_event_count_ > 0)
107 pending_input_event_count_--;
108 }
109
110 base::TimeDelta UserModel::TimeLeftInUserGesture(base::TimeTicks now) const {
111 base::TimeDelta escalated_priority_duration =
112 base::TimeDelta::FromMilliseconds(kGestureEstimationLimitMillis);
113
114 // If the input event is still pending, go into input prioritized policy and
115 // check again later.
116 if (pending_input_event_count_ > 0)
117 return escalated_priority_duration;
118 if (last_input_signal_time_.is_null() ||
119 last_input_signal_time_ + escalated_priority_duration < now) {
120 return base::TimeDelta();
121 }
122 return last_input_signal_time_ + escalated_priority_duration - now;
123 }
124
125 bool UserModel::IsGestureExpectedSoon(
126 const base::TimeTicks now,
127 base::TimeDelta* prediction_valid_duration) {
128 bool was_gesture_expected = is_gesture_expected_;
129 is_gesture_expected_ =
130 IsGestureExpectedSoonImpl(now, prediction_valid_duration);
131
132 // Track when we start expecting a gesture so we can work out later if a
133 // gesture actually happened.
134 if (!was_gesture_expected && is_gesture_expected_)
135 last_gesture_expected_start_time_ = now;
136
137 if (was_gesture_expected && !is_gesture_expected_ &&
138 last_gesture_expected_start_time_ > last_gesture_start_time_) {
139 RecordGesturePrediction(GESTURE_PREDICTED_BUT_DID_NOT_OCCUR);
140 }
141 return is_gesture_expected_;
142 }
143
144 bool UserModel::IsGestureExpectedSoonImpl(
145 const base::TimeTicks now,
146 base::TimeDelta* prediction_valid_duration) const {
147 if (is_gesture_active_) {
148 if (IsGestureExpectedToContinue(now, prediction_valid_duration)) {
149 return false;
150 } else {
151 // If a gesture is not expected to continue then we expect a subsequent
152 // gesture soon.
153 *prediction_valid_duration =
154 base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis);
155 return true;
156 }
157 } else {
158 // If we've have a finished a gesture then a subsequent gesture is deemed
159 // likely.
160 base::TimeDelta expect_subsequent_gesture_for =
161 base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis);
162 if (last_continuous_gesture_time_.is_null() ||
163 last_continuous_gesture_time_ + expect_subsequent_gesture_for <= now) {
164 return false;
165 }
166 *prediction_valid_duration =
167 last_continuous_gesture_time_ + expect_subsequent_gesture_for - now;
168 return true;
169 }
170 }
171
172 bool UserModel::IsGestureExpectedToContinue(
173 const base::TimeTicks now,
174 base::TimeDelta* prediction_valid_duration) const {
175 if (!is_gesture_active_)
176 return false;
177
178 base::TimeDelta median_gesture_duration =
179 base::TimeDelta::FromMilliseconds(kMedianGestureDurationMillis);
180 base::TimeTicks expected_gesture_end_time =
181 last_gesture_start_time_ + median_gesture_duration;
182
183 if (expected_gesture_end_time > now) {
184 *prediction_valid_duration = expected_gesture_end_time - now;
185 return true;
186 }
187 return false;
188 }
189
190 void UserModel::Reset(base::TimeTicks now) {
191 last_input_signal_time_ = base::TimeTicks();
192 last_gesture_start_time_ = base::TimeTicks();
193 last_continuous_gesture_time_ = base::TimeTicks();
194 last_gesture_expected_start_time_ = base::TimeTicks();
195 last_reset_time_ = now;
196 is_gesture_active_ = false;
197 is_gesture_expected_ = false;
198 }
199
200 void UserModel::AsValueInto(base::trace_event::TracedValue* state) const {
201 state->BeginDictionary("user_model");
202 state->SetInteger("pending_input_event_count", pending_input_event_count_);
203 state->SetDouble(
204 "last_input_signal_time",
205 (last_input_signal_time_ - base::TimeTicks()).InMillisecondsF());
206 state->SetDouble(
207 "last_gesture_start_time",
208 (last_gesture_start_time_ - base::TimeTicks()).InMillisecondsF());
209 state->SetDouble(
210 "last_continuous_gesture_time",
211 (last_continuous_gesture_time_ - base::TimeTicks()).InMillisecondsF());
212 state->SetDouble("last_gesture_expected_start_time",
213 (last_gesture_expected_start_time_ - base::TimeTicks())
214 .InMillisecondsF());
215 state->SetDouble("last_reset_time",
216 (last_reset_time_ - base::TimeTicks()).InMillisecondsF());
217 state->SetBoolean("is_gesture_expected", is_gesture_expected_);
218 state->SetBoolean("is_gesture_active", is_gesture_active_);
219 state->EndDictionary();
220 }
221
222 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/renderer/user_model.h ('k') | components/scheduler/renderer/user_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698