OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
6 #include "base/memory/scoped_vector.h" | 6 #include "base/memory/scoped_vector.h" |
7 #include "base/run_loop.h" | 7 #include "base/run_loop.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/timer/timer.h" | 9 #include "base/timer/timer.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 ui::EventType wait_until_event_; | 330 ui::EventType wait_until_event_; |
331 | 331 |
332 DISALLOW_COPY_AND_ASSIGN(GestureEventConsumeDelegate); | 332 DISALLOW_COPY_AND_ASSIGN(GestureEventConsumeDelegate); |
333 }; | 333 }; |
334 | 334 |
335 class QueueTouchEventDelegate : public GestureEventConsumeDelegate { | 335 class QueueTouchEventDelegate : public GestureEventConsumeDelegate { |
336 public: | 336 public: |
337 explicit QueueTouchEventDelegate(WindowEventDispatcher* dispatcher) | 337 explicit QueueTouchEventDelegate(WindowEventDispatcher* dispatcher) |
338 : window_(NULL), | 338 : window_(NULL), |
339 dispatcher_(dispatcher), | 339 dispatcher_(dispatcher), |
340 queue_events_(true) { | 340 queue_events_(true), |
| 341 treat_next_event_as_invalid_(false) { |
341 } | 342 } |
342 ~QueueTouchEventDelegate() override { | 343 ~QueueTouchEventDelegate() override { |
343 while(!queue_.empty()) { | 344 while(!queue_.empty()) { |
344 delete queue_.front(); | 345 delete queue_.front(); |
345 queue_.pop(); | 346 queue_.pop(); |
346 } | 347 } |
347 } | 348 } |
348 | 349 |
349 void OnTouchEvent(ui::TouchEvent* event) override { | 350 void OnTouchEvent(ui::TouchEvent* event) override { |
| 351 event->DisableSynchronousHandling(); |
| 352 if (treat_next_event_as_invalid_) { |
| 353 treat_next_event_as_invalid_ = false; |
| 354 dispatcher_->IgnoreLastTouchEvent(window_); |
| 355 } |
350 if (queue_events_) { | 356 if (queue_events_) { |
351 queue_.push(new ui::TouchEvent(*event, window_, window_)); | 357 queue_.push(new ui::TouchEvent(*event, window_, window_)); |
352 event->StopPropagation(); | |
353 } | 358 } |
354 } | 359 } |
355 | 360 |
356 void ReceivedAck() { | 361 void ReceivedAck() { |
357 ReceivedAckImpl(false); | 362 ReceivedAckImpl(false); |
358 } | 363 } |
359 | 364 |
360 void ReceivedAckPreventDefaulted() { | 365 void ReceivedAckPreventDefaulted() { |
361 ReceivedAckImpl(true); | 366 ReceivedAckImpl(true); |
362 } | 367 } |
363 | 368 |
364 void set_window(Window* w) { window_ = w; } | 369 void set_window(Window* w) { window_ = w; } |
365 void set_queue_events(bool queue) { queue_events_ = queue; } | 370 void set_queue_events(bool queue) { queue_events_ = queue; } |
| 371 void treat_next_event_as_invalid() { |
| 372 treat_next_event_as_invalid_ = true; |
| 373 } |
366 | 374 |
367 private: | 375 private: |
368 void ReceivedAckImpl(bool prevent_defaulted) { | 376 void ReceivedAckImpl(bool prevent_defaulted) { |
369 scoped_ptr<ui::TouchEvent> event(queue_.front()); | 377 scoped_ptr<ui::TouchEvent> event(queue_.front()); |
370 dispatcher_->ProcessedTouchEvent(event.get(), window_, | 378 dispatcher_->ProcessedTouchEvent(event.get(), window_, |
371 prevent_defaulted ? ui::ER_HANDLED : ui::ER_UNHANDLED); | 379 prevent_defaulted ? ui::ER_HANDLED : ui::ER_UNHANDLED); |
372 queue_.pop(); | 380 queue_.pop(); |
373 } | 381 } |
374 | 382 |
375 std::queue<ui::TouchEvent*> queue_; | 383 std::queue<ui::TouchEvent*> queue_; |
376 Window* window_; | 384 Window* window_; |
377 WindowEventDispatcher* dispatcher_; | 385 WindowEventDispatcher* dispatcher_; |
378 bool queue_events_; | 386 bool queue_events_; |
| 387 bool treat_next_event_as_invalid_; |
379 | 388 |
380 DISALLOW_COPY_AND_ASSIGN(QueueTouchEventDelegate); | 389 DISALLOW_COPY_AND_ASSIGN(QueueTouchEventDelegate); |
381 }; | 390 }; |
382 | 391 |
383 // A delegate that ignores gesture events but keeps track of [synthetic] mouse | 392 // A delegate that ignores gesture events but keeps track of [synthetic] mouse |
384 // events. | 393 // events. |
385 class GestureEventSynthDelegate : public TestWindowDelegate { | 394 class GestureEventSynthDelegate : public TestWindowDelegate { |
386 public: | 395 public: |
387 GestureEventSynthDelegate() | 396 GestureEventSynthDelegate() |
388 : mouse_enter_(false), | 397 : mouse_enter_(false), |
(...skipping 3851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4240 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(65, 202), | 4249 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(65, 202), |
4241 kTouchId1, tes.Now()); | 4250 kTouchId1, tes.Now()); |
4242 DispatchEventUsingWindowDispatcher(&move2); | 4251 DispatchEventUsingWindowDispatcher(&move2); |
4243 EXPECT_2_EVENTS(delegate->events(), | 4252 EXPECT_2_EVENTS(delegate->events(), |
4244 ui::ET_GESTURE_SCROLL_UPDATE, | 4253 ui::ET_GESTURE_SCROLL_UPDATE, |
4245 ui::ET_GESTURE_PINCH_UPDATE); | 4254 ui::ET_GESTURE_PINCH_UPDATE); |
4246 } | 4255 } |
4247 | 4256 |
4248 // Tests that delaying the ack of a touch release doesn't trigger a long press | 4257 // Tests that delaying the ack of a touch release doesn't trigger a long press |
4249 // gesture. | 4258 // gesture. |
4250 TEST_F(GestureRecognizerTest, DISABLED_EagerGestureDetection) { | 4259 TEST_F(GestureRecognizerTest, EagerGestureDetection) { |
4251 scoped_ptr<QueueTouchEventDelegate> delegate( | 4260 scoped_ptr<QueueTouchEventDelegate> delegate( |
4252 new QueueTouchEventDelegate(host()->dispatcher())); | 4261 new QueueTouchEventDelegate(host()->dispatcher())); |
4253 TimedEvents tes; | 4262 TimedEvents tes; |
4254 const int kTouchId = 2; | 4263 const int kTouchId = 2; |
4255 gfx::Rect bounds(100, 200, 100, 100); | 4264 gfx::Rect bounds(100, 200, 100, 100); |
4256 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | 4265 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( |
4257 delegate.get(), -1234, bounds, root_window())); | 4266 delegate.get(), -1234, bounds, root_window())); |
4258 delegate->set_window(window.get()); | 4267 delegate->set_window(window.get()); |
4259 | 4268 |
4260 delegate->Reset(); | 4269 delegate->Reset(); |
(...skipping 12 matching lines...) Expand all Loading... |
4273 delegate->Reset(); | 4282 delegate->Reset(); |
4274 // Wait until the long press event would fire (if we weren't eager). | 4283 // Wait until the long press event would fire (if we weren't eager). |
4275 DelayByLongPressTimeout(); | 4284 DelayByLongPressTimeout(); |
4276 | 4285 |
4277 // Ack the touch release. | 4286 // Ack the touch release. |
4278 delegate->ReceivedAck(); | 4287 delegate->ReceivedAck(); |
4279 EXPECT_TRUE(delegate->tap()); | 4288 EXPECT_TRUE(delegate->tap()); |
4280 EXPECT_FALSE(delegate->long_press()); | 4289 EXPECT_FALSE(delegate->long_press()); |
4281 } | 4290 } |
4282 | 4291 |
4283 // This tests crbug.com/405519, in which events which the gesture detector | 4292 // This tests crbug.com/405519, in which touch events which the gesture detector |
4284 // ignores cause future events to also be thrown away. | 4293 // ignores interfere with gesture recognition. |
4285 TEST_F(GestureRecognizerTest, IgnoredEventsDontPreventFutureEvents) { | 4294 TEST_F(GestureRecognizerTest, IgnoredEventsDontBreakGestureRecognition) { |
4286 scoped_ptr<QueueTouchEventDelegate> delegate( | 4295 scoped_ptr<QueueTouchEventDelegate> delegate( |
4287 new QueueTouchEventDelegate(host()->dispatcher())); | 4296 new QueueTouchEventDelegate(host()->dispatcher())); |
4288 TimedEvents tes; | 4297 TimedEvents tes; |
4289 const int kWindowWidth = 300; | 4298 const int kWindowWidth = 300; |
4290 const int kWindowHeight = 400; | 4299 const int kWindowHeight = 400; |
4291 const int kTouchId1 = 3; | 4300 const int kTouchId1 = 3; |
4292 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | 4301 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); |
4293 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | 4302 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( |
4294 delegate.get(), -1234, bounds, root_window())); | 4303 delegate.get(), -1234, bounds, root_window())); |
4295 delegate->set_window(window.get()); | 4304 delegate->set_window(window.get()); |
(...skipping 12 matching lines...) Expand all Loading... |
4308 ui::ET_TOUCH_MOVED, gfx::Point(65, 201), kTouchId1, tes.Now()); | 4317 ui::ET_TOUCH_MOVED, gfx::Point(65, 201), kTouchId1, tes.Now()); |
4309 DispatchEventUsingWindowDispatcher(&move1); | 4318 DispatchEventUsingWindowDispatcher(&move1); |
4310 delegate->ReceivedAck(); | 4319 delegate->ReceivedAck(); |
4311 | 4320 |
4312 EXPECT_3_EVENTS(delegate->events(), | 4321 EXPECT_3_EVENTS(delegate->events(), |
4313 ui::ET_GESTURE_TAP_CANCEL, | 4322 ui::ET_GESTURE_TAP_CANCEL, |
4314 ui::ET_GESTURE_SCROLL_BEGIN, | 4323 ui::ET_GESTURE_SCROLL_BEGIN, |
4315 ui::ET_GESTURE_SCROLL_UPDATE); | 4324 ui::ET_GESTURE_SCROLL_UPDATE); |
4316 | 4325 |
4317 delegate->Reset(); | 4326 delegate->Reset(); |
| 4327 |
| 4328 // Send a valid event, but don't ack it. |
4318 ui::TouchEvent move2( | 4329 ui::TouchEvent move2( |
4319 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); | 4330 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); |
4320 DispatchEventUsingWindowDispatcher(&move2); | 4331 DispatchEventUsingWindowDispatcher(&move2); |
| 4332 EXPECT_0_EVENTS(delegate->events()); |
4321 | 4333 |
4322 // Send a touchmove event at the same location as the previous touchmove | 4334 // Send a touchmove event at the same location as the previous touchmove |
4323 // event. This shouldn't do anything. | 4335 // event. This shouldn't do anything. |
4324 ui::TouchEvent move3( | 4336 ui::TouchEvent move3( |
4325 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); | 4337 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); |
4326 DispatchEventUsingWindowDispatcher(&move3); | 4338 DispatchEventUsingWindowDispatcher(&move3); |
4327 | 4339 |
| 4340 // Ack the previous valid event. The intermediary invalid event shouldn't |
| 4341 // interfere. |
4328 delegate->ReceivedAck(); | 4342 delegate->ReceivedAck(); |
4329 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | 4343 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); |
4330 } | 4344 } |
4331 | 4345 |
| 4346 // Tests that an event found invalid after gesture recognition has |
| 4347 // taken place can't cause out of order acks. |
| 4348 TEST_F(GestureRecognizerTest, IgnoredEventsAfterGRDontCauseOutOfOrderAcks) { |
| 4349 scoped_ptr<QueueTouchEventDelegate> delegate( |
| 4350 new QueueTouchEventDelegate(host()->dispatcher())); |
| 4351 TimedEvents tes; |
| 4352 const int kWindowWidth = 300; |
| 4353 const int kWindowHeight = 400; |
| 4354 const int kTouchId1 = 3; |
| 4355 gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); |
| 4356 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( |
| 4357 delegate.get(), -1234, bounds, root_window())); |
| 4358 delegate->set_window(window.get()); |
| 4359 |
| 4360 // Start a scroll gesture. |
| 4361 ui::TouchEvent press1( |
| 4362 ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId1, tes.Now()); |
| 4363 DispatchEventUsingWindowDispatcher(&press1); |
| 4364 delegate->ReceivedAck(); |
| 4365 |
| 4366 ui::TouchEvent move1( |
| 4367 ui::ET_TOUCH_MOVED, gfx::Point(100, 100), kTouchId1, tes.Now()); |
| 4368 DispatchEventUsingWindowDispatcher(&move1); |
| 4369 delegate->ReceivedAck(); |
| 4370 |
| 4371 delegate->Reset(); |
| 4372 // Dispatch an invalid touch move, which should be ignored. |
| 4373 delegate->treat_next_event_as_invalid(); |
| 4374 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(200, 200), kTouchId1, |
| 4375 tes.Now()); |
| 4376 DispatchEventUsingWindowDispatcher(&move2); |
| 4377 EXPECT_0_EVENTS(delegate->events()); |
| 4378 |
| 4379 // Dispatch a valid touch move, but don't ack it. |
| 4380 ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(300, 300), kTouchId1, |
| 4381 tes.Now()); |
| 4382 DispatchEventUsingWindowDispatcher(&move3); |
| 4383 |
| 4384 // Dispatch two invalid touch moves, which should be ignored. |
| 4385 delegate->treat_next_event_as_invalid(); |
| 4386 ui::TouchEvent move4( |
| 4387 ui::ET_TOUCH_MOVED, gfx::Point(400, 400), kTouchId1, tes.Now()); |
| 4388 DispatchEventUsingWindowDispatcher(&move4); |
| 4389 |
| 4390 delegate->treat_next_event_as_invalid(); |
| 4391 ui::TouchEvent move5( |
| 4392 ui::ET_TOUCH_MOVED, gfx::Point(500, 500), kTouchId1, tes.Now()); |
| 4393 DispatchEventUsingWindowDispatcher(&move5); |
| 4394 |
| 4395 EXPECT_0_EVENTS(delegate->events()); |
| 4396 EXPECT_EQ(100, delegate->bounding_box().x()); |
| 4397 // Ack the valid touch, and ensure the most recent gesture event |
| 4398 // used its co-ordinates. |
| 4399 delegate->ReceivedAck(); |
| 4400 EXPECT_EQ(300, delegate->bounding_box().x()); |
| 4401 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); |
| 4402 } |
| 4403 |
4332 } // namespace test | 4404 } // namespace test |
4333 } // namespace aura | 4405 } // namespace aura |
OLD | NEW |