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"
7 #include "base/test/simple_test_tick_clock.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
13 class UserModelTest
: public testing::Test
{
16 ~UserModelTest() override
{}
18 void SetUp() override
{
19 clock_
.reset(new base::SimpleTestTickClock());
20 clock_
->Advance(base::TimeDelta::FromMicroseconds(5000));
22 user_model_
.reset(new UserModel());
26 static base::TimeDelta
priority_escalation_after_input_duration() {
27 return base::TimeDelta::FromMilliseconds(
28 UserModel::kGestureEstimationLimitMillis
);
31 static base::TimeDelta
subsequent_input_expected_after_input_duration() {
32 return base::TimeDelta::FromMilliseconds(
33 UserModel::kExpectSubsequentGestureMillis
);
36 static base::TimeDelta
minimum_typical_scroll_duration_millis() {
37 return base::TimeDelta::FromMilliseconds(
38 UserModel::kMinimumTypicalScrollDurationMillis
);
41 scoped_ptr
<base::SimpleTestTickClock
> clock_
;
42 scoped_ptr
<UserModel
> user_model_
;
45 TEST_F(UserModelTest
, TimeLeftInUserGesture_NoInput
) {
46 EXPECT_EQ(base::TimeDelta(),
47 user_model_
->TimeLeftInUserGesture(clock_
->NowTicks()));
50 TEST_F(UserModelTest
, TimeLeftInUserGesture_ImmediatelyAfterInput
) {
51 user_model_
->DidStartProcessingInputEvent(
52 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
53 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
54 EXPECT_EQ(priority_escalation_after_input_duration(),
55 user_model_
->TimeLeftInUserGesture(clock_
->NowTicks()));
58 TEST_F(UserModelTest
, TimeLeftInUserGesture_ShortlyAfterInput
) {
59 user_model_
->DidStartProcessingInputEvent(
60 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
61 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
62 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
63 clock_
->Advance(delta
);
64 EXPECT_EQ(priority_escalation_after_input_duration() - delta
,
65 user_model_
->TimeLeftInUserGesture(clock_
->NowTicks()));
68 TEST_F(UserModelTest
, TimeLeftInUserGesture_LongAfterInput
) {
69 user_model_
->DidStartProcessingInputEvent(
70 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
71 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
72 clock_
->Advance(priority_escalation_after_input_duration() * 2);
73 EXPECT_EQ(base::TimeDelta(),
74 user_model_
->TimeLeftInUserGesture(clock_
->NowTicks()));
77 TEST_F(UserModelTest
, DidFinishProcessingInputEvent_Delayed
) {
78 user_model_
->DidStartProcessingInputEvent(
79 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
80 clock_
->Advance(priority_escalation_after_input_duration() * 10);
82 EXPECT_EQ(priority_escalation_after_input_duration(),
83 user_model_
->TimeLeftInUserGesture(clock_
->NowTicks()));
85 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
86 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
87 clock_
->Advance(delta
);
89 EXPECT_EQ(priority_escalation_after_input_duration() - delta
,
90 user_model_
->TimeLeftInUserGesture(clock_
->NowTicks()));
93 TEST_F(UserModelTest
, GestureExpectedSoon_UseCase_NONE_NoRecentInput
) {
94 base::TimeDelta prediction_valid_duration
;
95 EXPECT_FALSE(user_model_
->IsGestureExpectedSoon(
96 RendererScheduler::UseCase::NONE
, clock_
->NowTicks(),
97 &prediction_valid_duration
));
98 EXPECT_EQ(base::TimeDelta(), prediction_valid_duration
);
101 TEST_F(UserModelTest
, GestureExpectedSoon_UseCase_NONE_ImmediatelyAfterInput
) {
102 user_model_
->DidStartProcessingInputEvent(
103 blink::WebInputEvent::Type::GestureScrollEnd
, clock_
->NowTicks());
104 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
106 base::TimeDelta prediction_valid_duration
;
107 EXPECT_TRUE(user_model_
->IsGestureExpectedSoon(
108 RendererScheduler::UseCase::NONE
, clock_
->NowTicks(),
109 &prediction_valid_duration
));
110 EXPECT_EQ(subsequent_input_expected_after_input_duration(),
111 prediction_valid_duration
);
114 TEST_F(UserModelTest
, GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput
) {
115 user_model_
->DidStartProcessingInputEvent(
116 blink::WebInputEvent::Type::GestureScrollEnd
, clock_
->NowTicks());
117 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
119 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
120 clock_
->Advance(delta
);
122 base::TimeDelta prediction_valid_duration
;
123 EXPECT_TRUE(user_model_
->IsGestureExpectedSoon(
124 RendererScheduler::UseCase::NONE
, clock_
->NowTicks(),
125 &prediction_valid_duration
));
126 EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta
,
127 prediction_valid_duration
);
130 TEST_F(UserModelTest
, GestureExpectedSoon_UseCase_NONE_LongAfterInput
) {
131 user_model_
->DidStartProcessingInputEvent(
132 blink::WebInputEvent::Type::GestureScrollEnd
, clock_
->NowTicks());
133 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
134 clock_
->Advance(subsequent_input_expected_after_input_duration() * 2);
136 base::TimeDelta prediction_valid_duration
;
137 EXPECT_FALSE(user_model_
->IsGestureExpectedSoon(
138 RendererScheduler::UseCase::NONE
, clock_
->NowTicks(),
139 &prediction_valid_duration
));
140 EXPECT_EQ(base::TimeDelta(), prediction_valid_duration
);
143 TEST_F(UserModelTest
,
144 GestureExpectedSoon_COMPOSITOR_GESTURE_ImmediatelyAfterInput
) {
145 user_model_
->DidStartProcessingInputEvent(
146 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
147 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
149 base::TimeDelta prediction_valid_duration
;
150 EXPECT_FALSE(user_model_
->IsGestureExpectedSoon(
151 RendererScheduler::UseCase::COMPOSITOR_GESTURE
, clock_
->NowTicks(),
152 &prediction_valid_duration
));
153 EXPECT_EQ(minimum_typical_scroll_duration_millis(),
154 prediction_valid_duration
);
157 TEST_F(UserModelTest
,
158 GestureExpectedSoon_COMPOSITOR_GESTURE_ShortlyAfterInput
) {
159 user_model_
->DidStartProcessingInputEvent(
160 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
161 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
163 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
164 clock_
->Advance(delta
);
166 base::TimeDelta prediction_valid_duration
;
167 EXPECT_FALSE(user_model_
->IsGestureExpectedSoon(
168 RendererScheduler::UseCase::COMPOSITOR_GESTURE
, clock_
->NowTicks(),
169 &prediction_valid_duration
));
170 EXPECT_EQ(minimum_typical_scroll_duration_millis() - delta
,
171 prediction_valid_duration
);
174 TEST_F(UserModelTest
, GestureExpectedSoon_COMPOSITOR_GESTURE_LongAfterInput
) {
175 user_model_
->DidStartProcessingInputEvent(
176 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
177 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
179 clock_
->Advance(minimum_typical_scroll_duration_millis() * 2);
181 base::TimeDelta prediction_valid_duration
;
182 // Note this isn't a bug, the UseCase will change to NONE eventually so it's
183 // OK for this to always be true after minimum_typical_scroll_duration_millis
184 EXPECT_TRUE(user_model_
->IsGestureExpectedSoon(
185 RendererScheduler::UseCase::COMPOSITOR_GESTURE
, clock_
->NowTicks(),
186 &prediction_valid_duration
));
187 EXPECT_EQ(base::TimeDelta(), prediction_valid_duration
);
190 TEST_F(UserModelTest
,
191 GestureExpectedSoon_MAIN_THREAD_GESTURE_ImmediatelyAfterInput
) {
192 user_model_
->DidStartProcessingInputEvent(
193 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
195 // DidFinishProcessingInputEvent is always a little bit delayed.
196 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(5));
197 clock_
->Advance(delay
);
198 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
200 base::TimeDelta prediction_valid_duration
;
201 EXPECT_FALSE(user_model_
->IsGestureExpectedSoon(
202 RendererScheduler::UseCase::MAIN_THREAD_GESTURE
, clock_
->NowTicks(),
203 &prediction_valid_duration
));
204 EXPECT_EQ(minimum_typical_scroll_duration_millis() - delay
,
205 prediction_valid_duration
);
208 TEST_F(UserModelTest
,
209 GestureExpectedSoon_MAIN_THREAD_GESTURE_ShortlyAfterInput
) {
210 user_model_
->DidStartProcessingInputEvent(
211 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
212 // DidFinishProcessingInputEvent is always a little bit delayed.
213 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(5));
214 clock_
->Advance(delay
);
215 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
217 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
218 clock_
->Advance(delta
);
220 base::TimeDelta prediction_valid_duration
;
221 EXPECT_FALSE(user_model_
->IsGestureExpectedSoon(
222 RendererScheduler::UseCase::MAIN_THREAD_GESTURE
, clock_
->NowTicks(),
223 &prediction_valid_duration
));
224 EXPECT_EQ(minimum_typical_scroll_duration_millis() - delta
- delay
,
225 prediction_valid_duration
);
228 TEST_F(UserModelTest
, GestureExpectedSoon_MAIN_THREAD_GESTURE_LongAfterInput
) {
229 user_model_
->DidStartProcessingInputEvent(
230 blink::WebInputEvent::Type::TouchStart
, clock_
->NowTicks());
232 // DidFinishProcessingInputEvent is always a little bit delayed.
233 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(5));
234 clock_
->Advance(delay
);
235 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
237 clock_
->Advance(minimum_typical_scroll_duration_millis() * 2);
239 base::TimeDelta prediction_valid_duration
;
240 // Note this isn't a bug, the UseCase will change to NONE eventually so it's
241 // OK for this to always be true after minimum_typical_scroll_duration_millis
242 EXPECT_TRUE(user_model_
->IsGestureExpectedSoon(
243 RendererScheduler::UseCase::MAIN_THREAD_GESTURE
, clock_
->NowTicks(),
244 &prediction_valid_duration
));
245 EXPECT_EQ(base::TimeDelta(), prediction_valid_duration
);
248 TEST_F(UserModelTest
,
249 GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput_GestureScrollBegin
) {
250 user_model_
->DidStartProcessingInputEvent(
251 blink::WebInputEvent::Type::GestureScrollBegin
, clock_
->NowTicks());
252 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
254 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
255 clock_
->Advance(delta
);
257 base::TimeDelta prediction_valid_duration
;
258 EXPECT_TRUE(user_model_
->IsGestureExpectedSoon(
259 RendererScheduler::UseCase::NONE
, clock_
->NowTicks(),
260 &prediction_valid_duration
));
261 EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta
,
262 prediction_valid_duration
);
265 TEST_F(UserModelTest
,
266 GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput_GesturePinchBegin
) {
267 user_model_
->DidStartProcessingInputEvent(
268 blink::WebInputEvent::Type::GestureScrollBegin
, clock_
->NowTicks());
269 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
271 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
272 clock_
->Advance(delta
);
274 base::TimeDelta prediction_valid_duration
;
275 EXPECT_TRUE(user_model_
->IsGestureExpectedSoon(
276 RendererScheduler::UseCase::NONE
, clock_
->NowTicks(),
277 &prediction_valid_duration
));
278 EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta
,
279 prediction_valid_duration
);
282 TEST_F(UserModelTest
,
283 GestureExpectedSoon_UseCase_NONE_ShortlyAfterInput_GestureTap
) {
284 user_model_
->DidStartProcessingInputEvent(
285 blink::WebInputEvent::Type::GestureTap
, clock_
->NowTicks());
286 user_model_
->DidFinishProcessingInputEvent(clock_
->NowTicks());
288 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
289 clock_
->Advance(delta
);
291 base::TimeDelta prediction_valid_duration
;
292 EXPECT_FALSE(user_model_
->IsGestureExpectedSoon(
293 RendererScheduler::UseCase::NONE
, clock_
->NowTicks(),
294 &prediction_valid_duration
));
295 EXPECT_EQ(base::TimeDelta(), prediction_valid_duration
);
298 } // namespace scheduler