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 "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h"
6 
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"
10 
11 namespace blink {
12 namespace scheduler {
13 
14 class UserModelTest : public testing::Test {
15  public:
16   UserModelTest() = default;
17   ~UserModelTest() override = default;
18 
SetUp()19   void SetUp() override {
20     clock_.reset(new base::SimpleTestTickClock());
21     clock_->Advance(base::TimeDelta::FromMicroseconds(5000));
22 
23     user_model_.reset(new UserModel());
24   }
25 
26  protected:
priority_escalation_after_input_duration()27   static base::TimeDelta priority_escalation_after_input_duration() {
28     return base::TimeDelta::FromMilliseconds(
29         UserModel::kGestureEstimationLimitMillis);
30   }
31 
subsequent_input_expected_after_input_duration()32   static base::TimeDelta subsequent_input_expected_after_input_duration() {
33     return base::TimeDelta::FromMilliseconds(
34         UserModel::kExpectSubsequentGestureMillis);
35   }
36 
37   std::unique_ptr<base::SimpleTestTickClock> clock_;
38   std::unique_ptr<UserModel> user_model_;
39 };
40 
TEST_F(UserModelTest,TimeLeftInUserGesture_NoInput)41 TEST_F(UserModelTest, TimeLeftInUserGesture_NoInput) {
42   EXPECT_EQ(base::TimeDelta(),
43             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
44 }
45 
TEST_F(UserModelTest,TimeLeftInUserGesture_ImmediatelyAfterInput)46 TEST_F(UserModelTest, TimeLeftInUserGesture_ImmediatelyAfterInput) {
47   user_model_->DidStartProcessingInputEvent(
48       blink::WebInputEvent::Type::kTouchStart, clock_->NowTicks());
49   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
50   EXPECT_EQ(priority_escalation_after_input_duration(),
51             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
52 }
53 
TEST_F(UserModelTest,TimeLeftInUserGesture_ShortlyAfterInput)54 TEST_F(UserModelTest, TimeLeftInUserGesture_ShortlyAfterInput) {
55   user_model_->DidStartProcessingInputEvent(
56       blink::WebInputEvent::Type::kTouchStart, clock_->NowTicks());
57   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
58   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
59   clock_->Advance(delta);
60   EXPECT_EQ(priority_escalation_after_input_duration() - delta,
61             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
62 }
63 
TEST_F(UserModelTest,TimeLeftInUserGesture_LongAfterInput)64 TEST_F(UserModelTest, TimeLeftInUserGesture_LongAfterInput) {
65   user_model_->DidStartProcessingInputEvent(
66       blink::WebInputEvent::Type::kTouchStart, clock_->NowTicks());
67   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
68   clock_->Advance(priority_escalation_after_input_duration() * 2);
69   EXPECT_EQ(base::TimeDelta(),
70             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
71 }
72 
TEST_F(UserModelTest,DidFinishProcessingInputEvent_Delayed)73 TEST_F(UserModelTest, DidFinishProcessingInputEvent_Delayed) {
74   user_model_->DidStartProcessingInputEvent(
75       blink::WebInputEvent::Type::kTouchStart, clock_->NowTicks());
76   clock_->Advance(priority_escalation_after_input_duration() * 10);
77 
78   EXPECT_EQ(priority_escalation_after_input_duration(),
79             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
80 
81   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
82   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
83   clock_->Advance(delta);
84 
85   EXPECT_EQ(priority_escalation_after_input_duration() - delta,
86             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
87 }
88 
TEST_F(UserModelTest,GestureExpectedSoon_NoRecentInput)89 TEST_F(UserModelTest, GestureExpectedSoon_NoRecentInput) {
90   base::TimeDelta prediction_valid_duration;
91   EXPECT_FALSE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
92                                                   &prediction_valid_duration));
93   EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
94 }
95 
TEST_F(UserModelTest,GestureExpectedSoon_ShortlyAfter_GestureScrollBegin)96 TEST_F(UserModelTest, GestureExpectedSoon_ShortlyAfter_GestureScrollBegin) {
97   user_model_->DidStartProcessingInputEvent(
98       blink::WebInputEvent::Type::kGestureScrollBegin, clock_->NowTicks());
99   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
100 
101   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
102   clock_->Advance(delta);
103 
104   base::TimeDelta prediction_valid_duration;
105   EXPECT_FALSE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
106                                                   &prediction_valid_duration));
107   EXPECT_EQ(base::TimeDelta::FromMilliseconds(
108                 UserModel::kMedianGestureDurationMillis) -
109                 delta,
110             prediction_valid_duration);
111 }
112 
TEST_F(UserModelTest,GestureExpectedSoon_LongAfter_GestureScrollBegin)113 TEST_F(UserModelTest, GestureExpectedSoon_LongAfter_GestureScrollBegin) {
114   user_model_->DidStartProcessingInputEvent(
115       blink::WebInputEvent::Type::kGestureScrollBegin, clock_->NowTicks());
116   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
117 
118   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(
119       UserModel::kMedianGestureDurationMillis * 2));
120   clock_->Advance(delta);
121 
122   base::TimeDelta prediction_valid_duration;
123   EXPECT_TRUE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
124                                                  &prediction_valid_duration));
125   EXPECT_EQ(base::TimeDelta::FromMilliseconds(
126                 UserModel::kExpectSubsequentGestureMillis),
127             prediction_valid_duration);
128 }
129 
TEST_F(UserModelTest,GestureExpectedSoon_ImmediatelyAfter_GestureScrollEnd)130 TEST_F(UserModelTest, GestureExpectedSoon_ImmediatelyAfter_GestureScrollEnd) {
131   user_model_->DidStartProcessingInputEvent(
132       blink::WebInputEvent::Type::kGestureScrollEnd, clock_->NowTicks());
133   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
134 
135   base::TimeDelta prediction_valid_duration;
136   EXPECT_TRUE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
137                                                  &prediction_valid_duration));
138   EXPECT_EQ(subsequent_input_expected_after_input_duration(),
139             prediction_valid_duration);
140 }
141 
TEST_F(UserModelTest,GestureExpectedSoon_ShortlyAfter_GestureScrollEnd)142 TEST_F(UserModelTest, GestureExpectedSoon_ShortlyAfter_GestureScrollEnd) {
143   user_model_->DidStartProcessingInputEvent(
144       blink::WebInputEvent::Type::kGestureScrollEnd, clock_->NowTicks());
145   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
146 
147   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
148   clock_->Advance(delta);
149 
150   base::TimeDelta prediction_valid_duration;
151   EXPECT_TRUE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
152                                                  &prediction_valid_duration));
153   EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta,
154             prediction_valid_duration);
155 }
156 
TEST_F(UserModelTest,GestureExpectedSoon_LongAfter_GestureScrollEnd)157 TEST_F(UserModelTest, GestureExpectedSoon_LongAfter_GestureScrollEnd) {
158   user_model_->DidStartProcessingInputEvent(
159       blink::WebInputEvent::Type::kGestureScrollEnd, clock_->NowTicks());
160   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
161   clock_->Advance(subsequent_input_expected_after_input_duration() * 2);
162 
163   base::TimeDelta prediction_valid_duration;
164   EXPECT_FALSE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
165                                                   &prediction_valid_duration));
166   EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
167 }
168 
TEST_F(UserModelTest,GestureExpectedSoon_ShortlyAfter_GesturePinchEnd)169 TEST_F(UserModelTest, GestureExpectedSoon_ShortlyAfter_GesturePinchEnd) {
170   user_model_->DidStartProcessingInputEvent(
171       blink::WebInputEvent::Type::kGesturePinchEnd, clock_->NowTicks());
172   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
173 
174   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
175   clock_->Advance(delta);
176 
177   base::TimeDelta prediction_valid_duration;
178   EXPECT_TRUE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
179                                                  &prediction_valid_duration));
180   EXPECT_EQ(subsequent_input_expected_after_input_duration() - delta,
181             prediction_valid_duration);
182 }
183 
TEST_F(UserModelTest,GestureExpectedSoon_ShortlyAfterInput_GestureTap)184 TEST_F(UserModelTest, GestureExpectedSoon_ShortlyAfterInput_GestureTap) {
185   user_model_->DidStartProcessingInputEvent(
186       blink::WebInputEvent::Type::kGestureTap, clock_->NowTicks());
187   user_model_->DidFinishProcessingInputEvent(clock_->NowTicks());
188 
189   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
190   clock_->Advance(delta);
191 
192   base::TimeDelta prediction_valid_duration;
193   EXPECT_FALSE(user_model_->IsGestureExpectedSoon(clock_->NowTicks(),
194                                                   &prediction_valid_duration));
195   EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
196 }
197 
TEST_F(UserModelTest,IsGestureExpectedToContinue_NoGesture)198 TEST_F(UserModelTest, IsGestureExpectedToContinue_NoGesture) {
199   base::TimeDelta prediction_valid_duration;
200   EXPECT_FALSE(user_model_->IsGestureExpectedToContinue(
201       clock_->NowTicks(), &prediction_valid_duration));
202   EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
203 }
204 
TEST_F(UserModelTest,IsGestureExpectedToContinue_GestureJustStarted)205 TEST_F(UserModelTest, IsGestureExpectedToContinue_GestureJustStarted) {
206   user_model_->DidStartProcessingInputEvent(
207       blink::WebInputEvent::Type::kGestureScrollBegin, clock_->NowTicks());
208   base::TimeDelta prediction_valid_duration;
209   EXPECT_TRUE(user_model_->IsGestureExpectedToContinue(
210       clock_->NowTicks(), &prediction_valid_duration));
211   EXPECT_EQ(base::TimeDelta::FromMilliseconds(
212                 UserModel::kMedianGestureDurationMillis),
213             prediction_valid_duration);
214 }
215 
TEST_F(UserModelTest,IsGestureExpectedToContinue_GestureJustEnded)216 TEST_F(UserModelTest, IsGestureExpectedToContinue_GestureJustEnded) {
217   user_model_->DidStartProcessingInputEvent(
218       blink::WebInputEvent::Type::kGestureScrollEnd, clock_->NowTicks());
219   base::TimeDelta prediction_valid_duration;
220   EXPECT_FALSE(user_model_->IsGestureExpectedToContinue(
221       clock_->NowTicks(), &prediction_valid_duration));
222   EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
223 }
224 
TEST_F(UserModelTest,IsGestureExpectedToContinue_ShortlyAfterGestureStarted)225 TEST_F(UserModelTest, IsGestureExpectedToContinue_ShortlyAfterGestureStarted) {
226   user_model_->DidStartProcessingInputEvent(
227       blink::WebInputEvent::Type::kGestureScrollBegin, clock_->NowTicks());
228 
229   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10));
230   clock_->Advance(delta);
231 
232   base::TimeDelta prediction_valid_duration;
233   EXPECT_TRUE(user_model_->IsGestureExpectedToContinue(
234       clock_->NowTicks(), &prediction_valid_duration));
235   EXPECT_EQ(base::TimeDelta::FromMilliseconds(
236                 UserModel::kMedianGestureDurationMillis) -
237                 delta,
238             prediction_valid_duration);
239 }
240 
TEST_F(UserModelTest,IsGestureExpectedToContinue_LongAfterGestureStarted)241 TEST_F(UserModelTest, IsGestureExpectedToContinue_LongAfterGestureStarted) {
242   user_model_->DidStartProcessingInputEvent(
243       blink::WebInputEvent::Type::kGestureScrollBegin, clock_->NowTicks());
244 
245   base::TimeDelta delta(base::TimeDelta::FromMilliseconds(
246       UserModel::kMedianGestureDurationMillis * 2));
247   clock_->Advance(delta);
248 
249   base::TimeDelta prediction_valid_duration;
250   EXPECT_FALSE(user_model_->IsGestureExpectedToContinue(
251       clock_->NowTicks(), &prediction_valid_duration));
252   EXPECT_EQ(base::TimeDelta(), prediction_valid_duration);
253 }
254 
TEST_F(UserModelTest,ResetPendingInputCount)255 TEST_F(UserModelTest, ResetPendingInputCount) {
256   user_model_->DidStartProcessingInputEvent(
257       blink::WebInputEvent::Type::kGestureScrollBegin, clock_->NowTicks());
258   EXPECT_EQ(priority_escalation_after_input_duration(),
259             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
260   user_model_->Reset(clock_->NowTicks());
261   EXPECT_EQ(base::TimeDelta(),
262             user_model_->TimeLeftInUserGesture(clock_->NowTicks()));
263 }
264 
265 }  // namespace scheduler
266 }  // namespace blink
267