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

Side by Side Diff: content/browser/android/overscroll_refresh_unittest.cc

Issue 679493002: [Android] Add a native pull-to-refresh overscroll effect (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tests! Created 6 years, 1 month 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 2014 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 "cc/layers/layer.h"
6 #include "content/browser/android/overscroll_refresh.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/base/android/system_ui_resource_manager.h"
9
10 namespace content {
11
12 gfx::SizeF DefaultViewportSize() {
13 return gfx::SizeF(512, 512);
14 }
15
16 class OverscrollRefreshTest : public OverscrollRefreshClient,
17 public ui::SystemUIResourceManager,
18 public testing::Test {
19 public:
20 OverscrollRefreshTest() : refresh_triggered_(false) {}
21
22 protected:
23 bool GetAndResetRefreshTriggered() {
24 bool triggered = refresh_triggered_;
25 refresh_triggered_ = false;
26 return triggered;
27 }
28
29 // MockOverscrollRefreshClient implementation.
30 void TriggerRefresh() override { refresh_triggered_ = true; }
31
32 bool IsTriggeredRefreshActive() const override { return true; }
Ted C 2014/10/31 23:52:06 Should this return refresh_triggered_ instead?
jdduke (slow) 2014/11/06 00:10:37 Oops, yeah, I had a test for this codepath earlier
33
34 // SystemUIResoruceManager implementation.
35 void PreloadResource(ui::SystemUIResourceType) override {}
36
37 cc::UIResourceId GetUIResourceId(ui::SystemUIResourceType) override {
38 return 0;
39 }
40
41 private:
42 bool refresh_triggered_;
43 };
44
45 TEST_F(OverscrollRefreshTest, Basic) {
46 OverscrollRefresh effect(this, this);
47
48 gfx::Vector2dF origin_scroll_offset;
49 effect.UpdateDisplay(DefaultViewportSize(), origin_scroll_offset);
50 EXPECT_FALSE(effect.IsActive());
51 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
52
53 effect.OnScrollBegin();
54 EXPECT_FALSE(effect.IsActive());
55 EXPECT_TRUE(effect.IsPendingScrollUpdateAck());
56
57 // The initial scroll should not be consumed, as it should first be offered
58 // to content.
59 gfx::Vector2dF scroll_up(0, 10);
60 EXPECT_FALSE(effect.WillHandleScrollUpdate(scroll_up));
61 EXPECT_FALSE(effect.IsActive());
62 EXPECT_TRUE(effect.IsPendingScrollUpdateAck());
63
64 // The unconsumed, overscrolling scroll will trigger the effect.
65 bool consumed = false;
66 effect.OnScrollUpdateAck(consumed);
67 EXPECT_TRUE(effect.IsActive());
68 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
69
70 // Further scrolls will be consumed.
71 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
72 EXPECT_TRUE(effect.IsActive());
73
74 // Even scrolls in the down direction should be consumed.
75 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, -50)));
76 EXPECT_TRUE(effect.IsActive());
77
78 // Feed enough scrolls to the effect to exceeds tht threshold.
79 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 100)));
80 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 100)));
81 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 100)));
82 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 100)));
83 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 100)));
84 EXPECT_TRUE(effect.IsActive());
85
86 // Ending the scroll while beyond the threshold should trigger a refresh.
87 gfx::Vector2dF zero_velocity;
88 EXPECT_FALSE(GetAndResetRefreshTriggered());
89 effect.OnScrollEnd(zero_velocity);
90 EXPECT_TRUE(effect.IsActive());
91 EXPECT_TRUE(GetAndResetRefreshTriggered());
92
93 // Ensure animation doesn't explode.
94 base::TimeTicks initial_time = base::TimeTicks::Now();
95 base::TimeTicks current_time = initial_time;
96 scoped_refptr<cc::Layer> layer = cc::Layer::Create();
97 while (effect.Animate(current_time, layer.get()))
98 current_time += base::TimeDelta::FromMilliseconds(16);
99
100 // The effect should terminate in a timely fashion.
101 EXPECT_GT(current_time.ToInternalValue(), initial_time.ToInternalValue());
102 EXPECT_LE(
103 current_time.ToInternalValue(),
104 (initial_time + base::TimeDelta::FromSeconds(10)).ToInternalValue());
105 EXPECT_FALSE(effect.IsActive());
106 }
107
108 TEST_F(OverscrollRefreshTest, NotTriggeredIfBelowThreshold) {
109 OverscrollRefresh effect(this, this);
110 effect.UpdateDisplay(DefaultViewportSize(), gfx::Vector2dF());
111 effect.OnScrollBegin();
112 ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
113 ASSERT_TRUE(effect.IsPendingScrollUpdateAck());
114 effect.OnScrollUpdateAck(false);
115 ASSERT_TRUE(effect.IsActive());
116
117 // Terminating the pull before it exceeds the threshold will prevent refresh.
118 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
119 effect.OnScrollEnd(gfx::Vector2dF());
120 EXPECT_FALSE(GetAndResetRefreshTriggered());
121 }
122
123 TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialYOffsetIsZero) {
Ted C 2014/10/31 23:52:05 Is[Not]Zero?
jdduke (slow) 2014/11/06 00:10:37 Done.
Ted C 2014/11/06 19:25:40 Really?
jdduke (slow) 2014/11/07 18:33:44 No :( I'm a bad person.
124 OverscrollRefresh effect(this, this);
125
126 // A positive y scroll offset at the start of scroll will prevent activation,
127 // even if the subsequent scroll overscrolls upward.
128 gfx::Vector2dF nonzero_offset(0, 10);
129 effect.UpdateDisplay(DefaultViewportSize(), nonzero_offset);
130 effect.OnScrollBegin();
131
132 effect.UpdateDisplay(DefaultViewportSize(), gfx::Vector2dF());
133 ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
134 EXPECT_FALSE(effect.IsActive());
135 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
136 effect.OnScrollUpdateAck(false);
137 EXPECT_FALSE(effect.IsActive());
138 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
139 EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
140 effect.OnScrollEnd(gfx::Vector2dF());
141 EXPECT_FALSE(GetAndResetRefreshTriggered());
142 }
143
144 TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialScrollDownward) {
145 OverscrollRefresh effect(this, this);
146 effect.UpdateDisplay(DefaultViewportSize(), gfx::Vector2dF());
147 effect.OnScrollBegin();
148
149 // A downward initial scroll will prevent activation, even if the subsequent
150 // scroll overscrolls upward.
151 ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, -10)));
152 EXPECT_FALSE(effect.IsActive());
153 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
154
155 effect.OnScrollUpdateAck(false);
156 EXPECT_FALSE(effect.IsActive());
157 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
158 EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
159 effect.OnScrollEnd(gfx::Vector2dF());
160 EXPECT_FALSE(GetAndResetRefreshTriggered());
161 }
162
163 TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialScrollConsumed) {
164 OverscrollRefresh effect(this, this);
165 effect.UpdateDisplay(DefaultViewportSize(), gfx::Vector2dF());
166 effect.OnScrollBegin();
167 ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
168 ASSERT_TRUE(effect.IsPendingScrollUpdateAck());
169
170 // Consumption of the initial scroll should prevent future activation.
171 effect.OnScrollUpdateAck(true);
172 EXPECT_FALSE(effect.IsActive());
173 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
174 EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
175 effect.OnScrollUpdateAck(false);
176 EXPECT_FALSE(effect.IsActive());
177 EXPECT_FALSE(effect.IsPendingScrollUpdateAck());
178 EXPECT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
179 effect.OnScrollEnd(gfx::Vector2dF());
180 EXPECT_FALSE(GetAndResetRefreshTriggered());
181 }
182
183 TEST_F(OverscrollRefreshTest, NotTriggeredIfInitialScrollsJanked) {
184 OverscrollRefresh effect(this, this);
185 effect.UpdateDisplay(DefaultViewportSize(), gfx::Vector2dF());
186 effect.OnScrollBegin();
187 ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
188 ASSERT_TRUE(effect.IsPendingScrollUpdateAck());
189 effect.OnScrollUpdateAck(false);
190 ASSERT_TRUE(effect.IsActive());
191
192 // It should take more than just one or two large scrolls to trigger,
193 // mitigating likelihood of jank triggering the effect.
194 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
195 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 500)));
196 effect.OnScrollEnd(gfx::Vector2dF());
197 EXPECT_FALSE(GetAndResetRefreshTriggered());
198 }
199
200 TEST_F(OverscrollRefreshTest, NotTriggeredIfFlungDownward) {
201 OverscrollRefresh effect(this, this);
202 effect.UpdateDisplay(DefaultViewportSize(), gfx::Vector2dF());
203 effect.OnScrollBegin();
204 ASSERT_FALSE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 10)));
205 ASSERT_TRUE(effect.IsPendingScrollUpdateAck());
206 effect.OnScrollUpdateAck(false);
207 ASSERT_TRUE(effect.IsActive());
208
209 // Ensure the pull exceeds the necessary threshold.
210 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
211 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
212 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
213 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
214 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
215 EXPECT_TRUE(effect.WillHandleScrollUpdate(gfx::Vector2dF(0, 50)));
216
217 // Terminating the pull with a down-directed fling should prevent triggering.
218 effect.OnScrollEnd(gfx::Vector2dF(0, -1000));
219 EXPECT_FALSE(GetAndResetRefreshTriggered());
220 }
221
222 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698