| OLD | NEW |
| (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/input/input_handler.h" | |
| 6 #include "content/renderer/input/input_scroll_elasticity_controller.h" | |
| 7 #include "testing/gtest/include/gtest/gtest.h" | |
| 8 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
| 9 | |
| 10 namespace content { | |
| 11 namespace { | |
| 12 | |
| 13 enum Phase { | |
| 14 PhaseNone = blink::WebMouseWheelEvent::PhaseNone, | |
| 15 PhaseBegan = blink::WebMouseWheelEvent::PhaseBegan, | |
| 16 PhaseStationary = blink::WebMouseWheelEvent::PhaseStationary, | |
| 17 PhaseChanged = blink::WebMouseWheelEvent::PhaseChanged, | |
| 18 PhaseEnded = blink::WebMouseWheelEvent::PhaseEnded, | |
| 19 PhaseCancelled = blink::WebMouseWheelEvent::PhaseCancelled, | |
| 20 PhaseMayBegin = blink::WebMouseWheelEvent::PhaseMayBegin, | |
| 21 }; | |
| 22 | |
| 23 class MockScrollElasticityHelper : public cc::ScrollElasticityHelper { | |
| 24 public: | |
| 25 MockScrollElasticityHelper() | |
| 26 : is_user_scrollable_(true), | |
| 27 set_stretch_amount_count_(0), | |
| 28 request_animate_count_(0) {} | |
| 29 ~MockScrollElasticityHelper() override {} | |
| 30 | |
| 31 // cc::ScrollElasticityHelper implementation: | |
| 32 bool IsUserScrollable() const override { return is_user_scrollable_; } | |
| 33 gfx::Vector2dF StretchAmount() const override { return stretch_amount_; } | |
| 34 void SetStretchAmount(const gfx::Vector2dF& stretch_amount) override { | |
| 35 set_stretch_amount_count_ += 1; | |
| 36 stretch_amount_ = stretch_amount; | |
| 37 } | |
| 38 gfx::ScrollOffset ScrollOffset() const override { return scroll_offset_; } | |
| 39 gfx::ScrollOffset MaxScrollOffset() const override { | |
| 40 return max_scroll_offset_; | |
| 41 } | |
| 42 void ScrollBy(const gfx::Vector2dF& delta) override { | |
| 43 scroll_offset_ += gfx::ScrollOffset(delta); | |
| 44 } | |
| 45 void RequestAnimate() override { request_animate_count_ += 1; } | |
| 46 | |
| 47 // Counters for number of times functions were called. | |
| 48 int request_animate_count() const { return request_animate_count_; } | |
| 49 int set_stretch_amount_count() const { return set_stretch_amount_count_; } | |
| 50 | |
| 51 void SetScrollOffsetAndMaxScrollOffset( | |
| 52 const gfx::ScrollOffset& scroll_offset, | |
| 53 const gfx::ScrollOffset& max_scroll_offset) { | |
| 54 scroll_offset_ = scroll_offset; | |
| 55 max_scroll_offset_ = max_scroll_offset; | |
| 56 } | |
| 57 void SetUserScrollable(bool is_user_scrollable) { | |
| 58 is_user_scrollable_ = is_user_scrollable; | |
| 59 } | |
| 60 | |
| 61 private: | |
| 62 bool is_user_scrollable_; | |
| 63 gfx::Vector2dF stretch_amount_; | |
| 64 int set_stretch_amount_count_; | |
| 65 int request_animate_count_; | |
| 66 | |
| 67 gfx::ScrollOffset scroll_offset_; | |
| 68 gfx::ScrollOffset max_scroll_offset_; | |
| 69 }; | |
| 70 | |
| 71 class ScrollElasticityControllerTest : public testing::Test { | |
| 72 public: | |
| 73 ScrollElasticityControllerTest() | |
| 74 : controller_(&helper_), | |
| 75 input_event_count_(0), | |
| 76 current_time_(base::TimeTicks::FromInternalValue(100000000ull)) {} | |
| 77 ~ScrollElasticityControllerTest() override {} | |
| 78 | |
| 79 void SendMouseWheelEvent( | |
| 80 Phase phase, | |
| 81 Phase momentum_phase, | |
| 82 const gfx::Vector2dF& event_delta = gfx::Vector2dF(), | |
| 83 const gfx::Vector2dF& overscroll_delta = gfx::Vector2dF()) { | |
| 84 blink::WebMouseWheelEvent event; | |
| 85 event.phase = static_cast<blink::WebMouseWheelEvent::Phase>(phase); | |
| 86 event.momentumPhase = | |
| 87 static_cast<blink::WebMouseWheelEvent::Phase>(momentum_phase); | |
| 88 event.deltaX = -event_delta.x(); | |
| 89 event.deltaY = -event_delta.y(); | |
| 90 TickCurrentTime(); | |
| 91 event.timeStampSeconds = (current_time_ - base::TimeTicks()).InSecondsF(); | |
| 92 | |
| 93 cc::InputHandlerScrollResult scroll_result; | |
| 94 scroll_result.did_overscroll_root = !overscroll_delta.IsZero(); | |
| 95 scroll_result.unused_scroll_delta = overscroll_delta; | |
| 96 | |
| 97 controller_.ObserveWheelEventAndResult(event, scroll_result); | |
| 98 input_event_count_ += 1; | |
| 99 } | |
| 100 | |
| 101 const base::TimeTicks& TickCurrentTime() { | |
| 102 current_time_ += base::TimeDelta::FromSecondsD(1 / 60.f); | |
| 103 return current_time_; | |
| 104 } | |
| 105 void TickCurrentTimeAndAnimate() { | |
| 106 TickCurrentTime(); | |
| 107 controller_.Animate(current_time_); | |
| 108 } | |
| 109 | |
| 110 MockScrollElasticityHelper helper_; | |
| 111 InputScrollElasticityController controller_; | |
| 112 int input_event_count_; | |
| 113 base::TimeTicks current_time_; | |
| 114 }; | |
| 115 | |
| 116 // Verify that stretching only occurs in one axis at a time, and that it | |
| 117 // is biased to the Y axis. | |
| 118 TEST_F(ScrollElasticityControllerTest, Axis) { | |
| 119 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0), | |
| 120 gfx::ScrollOffset(0, 0)); | |
| 121 | |
| 122 // If we push equally in the X and Y directions, we should see a stretch only | |
| 123 // in the Y direction. | |
| 124 SendMouseWheelEvent(PhaseBegan, PhaseNone); | |
| 125 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(10, 10), | |
| 126 gfx::Vector2dF(10, 10)); | |
| 127 EXPECT_EQ(1, helper_.set_stretch_amount_count()); | |
| 128 EXPECT_EQ(0.f, helper_.StretchAmount().x()); | |
| 129 EXPECT_LT(0.f, helper_.StretchAmount().y()); | |
| 130 helper_.SetStretchAmount(gfx::Vector2dF()); | |
| 131 EXPECT_EQ(2, helper_.set_stretch_amount_count()); | |
| 132 SendMouseWheelEvent(PhaseEnded, PhaseNone); | |
| 133 EXPECT_EQ(0, helper_.request_animate_count()); | |
| 134 | |
| 135 // If we push more in the X direction than the Y direction, we should see a | |
| 136 // stretch only in the X direction. This decision should be based on the | |
| 137 // input delta, not the actual overscroll delta. | |
| 138 SendMouseWheelEvent(PhaseBegan, PhaseNone); | |
| 139 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(-25, 10), | |
| 140 gfx::Vector2dF(-25, 40)); | |
| 141 EXPECT_EQ(3, helper_.set_stretch_amount_count()); | |
| 142 EXPECT_GT(0.f, helper_.StretchAmount().x()); | |
| 143 EXPECT_EQ(0.f, helper_.StretchAmount().y()); | |
| 144 helper_.SetStretchAmount(gfx::Vector2dF()); | |
| 145 EXPECT_EQ(4, helper_.set_stretch_amount_count()); | |
| 146 SendMouseWheelEvent(PhaseEnded, PhaseNone); | |
| 147 EXPECT_EQ(0, helper_.request_animate_count()); | |
| 148 } | |
| 149 | |
| 150 // Verify that we need a total overscroll delta of at least 10 in a pinned | |
| 151 // direction before we start stretching. | |
| 152 TEST_F(ScrollElasticityControllerTest, MinimumDeltaBeforeStretch) { | |
| 153 // We should not start stretching while we are not pinned in the direction | |
| 154 // of the scroll (even if there is an overscroll delta). We have to wait for | |
| 155 // the regular scroll to eat all of the events. | |
| 156 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5), | |
| 157 gfx::ScrollOffset(10, 10)); | |
| 158 SendMouseWheelEvent(PhaseMayBegin, PhaseNone); | |
| 159 SendMouseWheelEvent(PhaseBegan, PhaseNone); | |
| 160 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10), | |
| 161 gfx::Vector2dF(0, 10)); | |
| 162 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10), | |
| 163 gfx::Vector2dF(0, 10)); | |
| 164 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 165 | |
| 166 // Now pin the -X and +Y direction. The first event will not generate a | |
| 167 // stretch | |
| 168 // because it is below the delta threshold of 10. | |
| 169 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 10), | |
| 170 gfx::ScrollOffset(10, 10)); | |
| 171 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10), | |
| 172 gfx::Vector2dF(0, 8)); | |
| 173 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 174 | |
| 175 // Make the next scroll be in the -X direction more than the +Y direction, | |
| 176 // which will erase the memory of the previous unused delta of 8. | |
| 177 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(-10, 5), | |
| 178 gfx::Vector2dF(-8, 10)); | |
| 179 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 180 | |
| 181 // Now push against the pinned +Y direction again by 8. We reset the | |
| 182 // previous delta, so this will not generate a stretch. | |
| 183 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10), | |
| 184 gfx::Vector2dF(0, 8)); | |
| 185 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 186 | |
| 187 // Push against +Y by another 8. This gets us above the delta threshold of | |
| 188 // 10, so we should now have had the stretch set, and it should be in the | |
| 189 // +Y direction. The scroll in the -X direction should have been forgotten. | |
| 190 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10), | |
| 191 gfx::Vector2dF(0, 8)); | |
| 192 EXPECT_EQ(1, helper_.set_stretch_amount_count()); | |
| 193 EXPECT_EQ(0.f, helper_.StretchAmount().x()); | |
| 194 EXPECT_LT(0.f, helper_.StretchAmount().y()); | |
| 195 | |
| 196 // End the gesture. Because there is a non-zero stretch, we should be in the | |
| 197 // animated state, and should have had a frame requested. | |
| 198 EXPECT_EQ(0, helper_.request_animate_count()); | |
| 199 SendMouseWheelEvent(PhaseEnded, PhaseNone); | |
| 200 EXPECT_EQ(1, helper_.request_animate_count()); | |
| 201 } | |
| 202 | |
| 203 // Verify that an stretch caused by a momentum scroll will switch to the | |
| 204 // animating mode, where input events are ignored, and the stretch is updated | |
| 205 // while animating. | |
| 206 TEST_F(ScrollElasticityControllerTest, MomentumAnimate) { | |
| 207 // Do an active scroll, then switch to the momentum phase and scroll for a | |
| 208 // bit. | |
| 209 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5), | |
| 210 gfx::ScrollOffset(10, 10)); | |
| 211 SendMouseWheelEvent(PhaseBegan, PhaseNone); | |
| 212 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80), | |
| 213 gfx::Vector2dF(0, 0)); | |
| 214 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80), | |
| 215 gfx::Vector2dF(0, 0)); | |
| 216 SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80), | |
| 217 gfx::Vector2dF(0, 0)); | |
| 218 SendMouseWheelEvent(PhaseEnded, PhaseNone); | |
| 219 SendMouseWheelEvent(PhaseNone, PhaseBegan); | |
| 220 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80), | |
| 221 gfx::Vector2dF(0, 0)); | |
| 222 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80), | |
| 223 gfx::Vector2dF(0, 0)); | |
| 224 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80), | |
| 225 gfx::Vector2dF(0, 0)); | |
| 226 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 227 | |
| 228 // Hit the -Y edge and overscroll slightly, but not enough to go over the | |
| 229 // threshold to cause a stretch. | |
| 230 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 0), | |
| 231 gfx::ScrollOffset(10, 10)); | |
| 232 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80), | |
| 233 gfx::Vector2dF(0, -8)); | |
| 234 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 235 EXPECT_EQ(0, helper_.request_animate_count()); | |
| 236 | |
| 237 // Take another step, this time going over the threshold. This should update | |
| 238 // the stretch amount, and then switch to the animating mode. | |
| 239 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80), | |
| 240 gfx::Vector2dF(0, -80)); | |
| 241 EXPECT_EQ(1, helper_.set_stretch_amount_count()); | |
| 242 EXPECT_EQ(1, helper_.request_animate_count()); | |
| 243 EXPECT_GT(-1.f, helper_.StretchAmount().y()); | |
| 244 | |
| 245 // Subsequent momentum events should do nothing. | |
| 246 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80), | |
| 247 gfx::Vector2dF(0, -80)); | |
| 248 SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80), | |
| 249 gfx::Vector2dF(0, -80)); | |
| 250 SendMouseWheelEvent(PhaseNone, PhaseEnded, gfx::Vector2dF(0, -80), | |
| 251 gfx::Vector2dF(0, -80)); | |
| 252 EXPECT_EQ(1, helper_.set_stretch_amount_count()); | |
| 253 EXPECT_EQ(1, helper_.request_animate_count()); | |
| 254 | |
| 255 // Subsequent animate events should update the stretch amount and request | |
| 256 // another frame. | |
| 257 TickCurrentTimeAndAnimate(); | |
| 258 EXPECT_EQ(2, helper_.set_stretch_amount_count()); | |
| 259 EXPECT_EQ(2, helper_.request_animate_count()); | |
| 260 EXPECT_GT(-1.f, helper_.StretchAmount().y()); | |
| 261 | |
| 262 // Touching the trackpad (a PhaseMayBegin event) should disable animation. | |
| 263 SendMouseWheelEvent(PhaseMayBegin, PhaseNone); | |
| 264 TickCurrentTimeAndAnimate(); | |
| 265 EXPECT_EQ(2, helper_.set_stretch_amount_count()); | |
| 266 EXPECT_EQ(2, helper_.request_animate_count()); | |
| 267 | |
| 268 // Releasing the trackpad should re-enable animation. | |
| 269 SendMouseWheelEvent(PhaseCancelled, PhaseNone); | |
| 270 EXPECT_EQ(2, helper_.set_stretch_amount_count()); | |
| 271 EXPECT_EQ(3, helper_.request_animate_count()); | |
| 272 TickCurrentTimeAndAnimate(); | |
| 273 EXPECT_EQ(3, helper_.set_stretch_amount_count()); | |
| 274 EXPECT_EQ(4, helper_.request_animate_count()); | |
| 275 | |
| 276 // Keep animating frames until the stretch returns to rest. | |
| 277 int stretch_count = 3; | |
| 278 int animate_count = 4; | |
| 279 while (1) { | |
| 280 TickCurrentTimeAndAnimate(); | |
| 281 if (helper_.StretchAmount().IsZero()) { | |
| 282 stretch_count += 1; | |
| 283 EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count()); | |
| 284 EXPECT_EQ(animate_count, helper_.request_animate_count()); | |
| 285 break; | |
| 286 } | |
| 287 stretch_count += 1; | |
| 288 animate_count += 1; | |
| 289 EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count()); | |
| 290 EXPECT_EQ(animate_count, helper_.request_animate_count()); | |
| 291 } | |
| 292 | |
| 293 // After coming to rest, no subsequent animate calls change anything. | |
| 294 TickCurrentTimeAndAnimate(); | |
| 295 EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count()); | |
| 296 EXPECT_EQ(animate_count, helper_.request_animate_count()); | |
| 297 } | |
| 298 | |
| 299 // Verify that an stretch opposing a scroll is correctly resolved. | |
| 300 TEST_F(ScrollElasticityControllerTest, ReconcileStretchAndScroll) { | |
| 301 SendMouseWheelEvent(PhaseBegan, PhaseNone); | |
| 302 | |
| 303 // Verify completely knocking out the scroll in the -Y direction. | |
| 304 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5), | |
| 305 gfx::ScrollOffset(10, 10)); | |
| 306 helper_.SetStretchAmount(gfx::Vector2dF(0, -10)); | |
| 307 controller_.ReconcileStretchAndScroll(); | |
| 308 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, -5)); | |
| 309 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 0)); | |
| 310 | |
| 311 // Verify partially knocking out the scroll in the -Y direction. | |
| 312 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 8), | |
| 313 gfx::ScrollOffset(10, 10)); | |
| 314 helper_.SetStretchAmount(gfx::Vector2dF(0, -5)); | |
| 315 controller_.ReconcileStretchAndScroll(); | |
| 316 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0)); | |
| 317 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 3)); | |
| 318 | |
| 319 // Verify completely knocking out the scroll in the +X direction. | |
| 320 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5), | |
| 321 gfx::ScrollOffset(10, 10)); | |
| 322 helper_.SetStretchAmount(gfx::Vector2dF(10, 0)); | |
| 323 controller_.ReconcileStretchAndScroll(); | |
| 324 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(5, 0)); | |
| 325 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(10, 5)); | |
| 326 | |
| 327 // Verify partially knocking out the scroll in the +X and +Y directions. | |
| 328 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(2, 3), | |
| 329 gfx::ScrollOffset(10, 10)); | |
| 330 helper_.SetStretchAmount(gfx::Vector2dF(5, 5)); | |
| 331 controller_.ReconcileStretchAndScroll(); | |
| 332 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0)); | |
| 333 EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(7, 8)); | |
| 334 } | |
| 335 | |
| 336 // Verify that stretching only happens when the area is user scrollable. | |
| 337 TEST_F(ScrollElasticityControllerTest, UserScrollableRequiredForStretch) { | |
| 338 helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0), | |
| 339 gfx::ScrollOffset(10, 10)); | |
| 340 gfx::Vector2dF delta(0, -15); | |
| 341 | |
| 342 // Do an active scroll, and ensure that the stretch amount doesn't change, | |
| 343 // and also that the stretch amount isn't even ever changed. | |
| 344 helper_.SetUserScrollable(false); | |
| 345 SendMouseWheelEvent(PhaseBegan, PhaseNone); | |
| 346 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta); | |
| 347 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta); | |
| 348 SendMouseWheelEvent(PhaseEnded, PhaseNone); | |
| 349 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0)); | |
| 350 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 351 SendMouseWheelEvent(PhaseNone, PhaseBegan); | |
| 352 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta); | |
| 353 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta); | |
| 354 SendMouseWheelEvent(PhaseNone, PhaseEnded); | |
| 355 EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0)); | |
| 356 EXPECT_EQ(0, helper_.set_stretch_amount_count()); | |
| 357 | |
| 358 // Re-enable user scrolling and ensure that stretching is re-enabled. | |
| 359 helper_.SetUserScrollable(true); | |
| 360 SendMouseWheelEvent(PhaseBegan, PhaseNone); | |
| 361 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta); | |
| 362 SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta); | |
| 363 SendMouseWheelEvent(PhaseEnded, PhaseNone); | |
| 364 EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0)); | |
| 365 EXPECT_GT(helper_.set_stretch_amount_count(), 0); | |
| 366 SendMouseWheelEvent(PhaseNone, PhaseBegan); | |
| 367 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta); | |
| 368 SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta); | |
| 369 SendMouseWheelEvent(PhaseNone, PhaseEnded); | |
| 370 EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0)); | |
| 371 EXPECT_GT(helper_.set_stretch_amount_count(), 0); | |
| 372 | |
| 373 // Disable user scrolling and tick the timer until the stretch goes back | |
| 374 // to zero. Ensure that the return to zero doesn't happen immediately. | |
| 375 helper_.SetUserScrollable(false); | |
| 376 int ticks_to_zero = 0; | |
| 377 while (1) { | |
| 378 TickCurrentTimeAndAnimate(); | |
| 379 if (helper_.StretchAmount().IsZero()) | |
| 380 break; | |
| 381 ticks_to_zero += 1; | |
| 382 } | |
| 383 EXPECT_GT(ticks_to_zero, 3); | |
| 384 } | |
| 385 | |
| 386 } // namespace | |
| 387 } // namespace content | |
| OLD | NEW |