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.
5 #include "components/scheduler/renderer/user_model.h"
9 UserModel::UserModel() : pending_input_event_count_(0) {}
10 UserModel::~UserModel() {}
12 void UserModel::DidStartProcessingInputEvent(blink::WebInputEvent::Type type
,
13 const base::TimeTicks now
) {
14 last_input_signal_time_
= now
;
15 if (type
== blink::WebInputEvent::TouchStart
||
16 type
== blink::WebInputEvent::GestureScrollBegin
||
17 type
== blink::WebInputEvent::GesturePinchBegin
) {
18 last_gesture_start_time_
= now
;
21 // We need to track continuous gestures seperatly for scroll detection
22 // because taps should not be confused with scrolls.
23 if (type
== blink::WebInputEvent::GestureScrollBegin
||
24 type
== blink::WebInputEvent::GestureScrollEnd
||
25 type
== blink::WebInputEvent::GestureScrollUpdate
||
26 type
== blink::WebInputEvent::GestureFlingStart
||
27 type
== blink::WebInputEvent::GestureFlingCancel
||
28 type
== blink::WebInputEvent::GesturePinchBegin
||
29 type
== blink::WebInputEvent::GesturePinchEnd
||
30 type
== blink::WebInputEvent::GesturePinchUpdate
) {
31 last_continuous_gesture_time_
= now
;
34 pending_input_event_count_
++;
37 void UserModel::DidFinishProcessingInputEvent(const base::TimeTicks now
) {
38 last_input_signal_time_
= now
;
39 if (pending_input_event_count_
> 0)
40 pending_input_event_count_
--;
43 base::TimeDelta
UserModel::TimeLeftInUserGesture(base::TimeTicks now
) const {
44 base::TimeDelta escalated_priority_duration
=
45 base::TimeDelta::FromMilliseconds(kGestureEstimationLimitMillis
);
47 // If the input event is still pending, go into input prioritized policy and
49 if (pending_input_event_count_
> 0)
50 return escalated_priority_duration
;
51 if (last_input_signal_time_
.is_null() ||
52 last_input_signal_time_
+ escalated_priority_duration
< now
) {
53 return base::TimeDelta();
55 return last_input_signal_time_
+ escalated_priority_duration
- now
;
58 bool UserModel::IsGestureExpectedSoon(
59 RendererScheduler::UseCase use_case
,
60 const base::TimeTicks now
,
61 base::TimeDelta
* prediction_valid_duration
) const {
62 if (use_case
== RendererScheduler::UseCase::NONE
) {
63 // If we've scrolled recently then future scrolling is likely.
64 base::TimeDelta expect_subsequent_gesture_for
=
65 base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis
);
66 if (last_continuous_gesture_time_
.is_null() ||
67 last_continuous_gesture_time_
+ expect_subsequent_gesture_for
<= now
) {
70 *prediction_valid_duration
=
71 last_continuous_gesture_time_
+ expect_subsequent_gesture_for
- now
;
75 if (use_case
== RendererScheduler::UseCase::COMPOSITOR_GESTURE
||
76 use_case
== RendererScheduler::UseCase::MAIN_THREAD_GESTURE
) {
77 // If we've only just started scrolling then, then initiating a subsequent
78 // gesture is unlikely.
79 base::TimeDelta minimum_typical_scroll_duration
=
80 base::TimeDelta::FromMilliseconds(kMinimumTypicalScrollDurationMillis
);
81 if (last_gesture_start_time_
.is_null() ||
82 last_gesture_start_time_
+ minimum_typical_scroll_duration
<= now
) {
85 *prediction_valid_duration
=
86 last_gesture_start_time_
+ minimum_typical_scroll_duration
- now
;
92 void UserModel::Reset() {
93 last_input_signal_time_
= base::TimeTicks();
94 last_gesture_start_time_
= base::TimeTicks();
95 last_continuous_gesture_time_
= base::TimeTicks();
98 void UserModel::AsValueInto(base::trace_event::TracedValue
* state
) const {
99 state
->BeginDictionary("user_model");
100 state
->SetInteger("pending_input_event_count", pending_input_event_count_
);
102 "last_input_signal_time",
103 (last_input_signal_time_
- base::TimeTicks()).InMillisecondsF());
105 "last_touchstart_time",
106 (last_gesture_start_time_
- base::TimeTicks()).InMillisecondsF());
107 state
->EndDictionary();
110 } // namespace scheduler