| 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 synchronous_ack_for_next_event_(AckState::PENDING) { |
| 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 { |
| 350 if (queue_events_) { | 351 event->DisableSynchronousHandling(); |
| 352 if (synchronous_ack_for_next_event_ != AckState::PENDING) { |
| 353 ui::GestureRecognizer::Get()->AckSyncTouchEvent( |
| 354 *event, synchronous_ack_for_next_event_ == AckState::CONSUMED |
| 355 ? ui::ER_CONSUMED |
| 356 : ui::ER_UNHANDLED, |
| 357 window_); |
| 358 synchronous_ack_for_next_event_ = AckState::PENDING; |
| 359 } |
| 360 if (queue_events_) |
| 351 queue_.push(new ui::TouchEvent(*event, window_, window_)); | 361 queue_.push(new ui::TouchEvent(*event, window_, window_)); |
| 352 event->StopPropagation(); | |
| 353 } | |
| 354 } | 362 } |
| 355 | 363 |
| 356 void ReceivedAck() { | 364 void ReceivedAck() { |
| 357 ReceivedAckImpl(false); | 365 ReceivedAckImpl(false); |
| 358 } | 366 } |
| 359 | 367 |
| 360 void ReceivedAckPreventDefaulted() { | 368 void ReceivedAckPreventDefaulted() { |
| 361 ReceivedAckImpl(true); | 369 ReceivedAckImpl(true); |
| 362 } | 370 } |
| 363 | 371 |
| 364 void set_window(Window* w) { window_ = w; } | 372 void set_window(Window* w) { window_ = w; } |
| 365 void set_queue_events(bool queue) { queue_events_ = queue; } | 373 void set_queue_events(bool queue) { queue_events_ = queue; } |
| 374 void set_synchronous_ack_for_next_event(bool consumed) { |
| 375 DCHECK(synchronous_ack_for_next_event_ == AckState::PENDING); |
| 376 synchronous_ack_for_next_event_ = |
| 377 consumed ? AckState::CONSUMED : AckState::UNCONSUMED; |
| 378 } |
| 366 | 379 |
| 367 private: | 380 private: |
| 381 enum class AckState { |
| 382 PENDING, |
| 383 CONSUMED, |
| 384 UNCONSUMED, |
| 385 }; |
| 386 |
| 368 void ReceivedAckImpl(bool prevent_defaulted) { | 387 void ReceivedAckImpl(bool prevent_defaulted) { |
| 369 scoped_ptr<ui::TouchEvent> event(queue_.front()); | 388 scoped_ptr<ui::TouchEvent> event(queue_.front()); |
| 370 dispatcher_->ProcessedTouchEvent(event.get(), window_, | 389 dispatcher_->ProcessedTouchEvent(event.get(), window_, |
| 371 prevent_defaulted ? ui::ER_HANDLED : ui::ER_UNHANDLED); | 390 prevent_defaulted ? ui::ER_HANDLED : ui::ER_UNHANDLED); |
| 372 queue_.pop(); | 391 queue_.pop(); |
| 373 } | 392 } |
| 374 | 393 |
| 375 std::queue<ui::TouchEvent*> queue_; | 394 std::queue<ui::TouchEvent*> queue_; |
| 376 Window* window_; | 395 Window* window_; |
| 377 WindowEventDispatcher* dispatcher_; | 396 WindowEventDispatcher* dispatcher_; |
| 378 bool queue_events_; | 397 bool queue_events_; |
| 398 AckState synchronous_ack_for_next_event_; |
| 379 | 399 |
| 380 DISALLOW_COPY_AND_ASSIGN(QueueTouchEventDelegate); | 400 DISALLOW_COPY_AND_ASSIGN(QueueTouchEventDelegate); |
| 381 }; | 401 }; |
| 382 | 402 |
| 383 // A delegate that ignores gesture events but keeps track of [synthetic] mouse | 403 // A delegate that ignores gesture events but keeps track of [synthetic] mouse |
| 384 // events. | 404 // events. |
| 385 class GestureEventSynthDelegate : public TestWindowDelegate { | 405 class GestureEventSynthDelegate : public TestWindowDelegate { |
| 386 public: | 406 public: |
| 387 GestureEventSynthDelegate() | 407 GestureEventSynthDelegate() |
| 388 : mouse_enter_(false), | 408 : 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), | 4260 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(65, 202), |
| 4241 kTouchId1, tes.Now()); | 4261 kTouchId1, tes.Now()); |
| 4242 DispatchEventUsingWindowDispatcher(&move2); | 4262 DispatchEventUsingWindowDispatcher(&move2); |
| 4243 EXPECT_2_EVENTS(delegate->events(), | 4263 EXPECT_2_EVENTS(delegate->events(), |
| 4244 ui::ET_GESTURE_SCROLL_UPDATE, | 4264 ui::ET_GESTURE_SCROLL_UPDATE, |
| 4245 ui::ET_GESTURE_PINCH_UPDATE); | 4265 ui::ET_GESTURE_PINCH_UPDATE); |
| 4246 } | 4266 } |
| 4247 | 4267 |
| 4248 // Tests that delaying the ack of a touch release doesn't trigger a long press | 4268 // Tests that delaying the ack of a touch release doesn't trigger a long press |
| 4249 // gesture. | 4269 // gesture. |
| 4250 TEST_F(GestureRecognizerTest, DISABLED_EagerGestureDetection) { | 4270 TEST_F(GestureRecognizerTest, EagerGestureDetection) { |
| 4251 scoped_ptr<QueueTouchEventDelegate> delegate( | 4271 scoped_ptr<QueueTouchEventDelegate> delegate( |
| 4252 new QueueTouchEventDelegate(host()->dispatcher())); | 4272 new QueueTouchEventDelegate(host()->dispatcher())); |
| 4253 TimedEvents tes; | 4273 TimedEvents tes; |
| 4254 const int kTouchId = 2; | 4274 const int kTouchId = 2; |
| 4255 gfx::Rect bounds(100, 200, 100, 100); | 4275 gfx::Rect bounds(100, 200, 100, 100); |
| 4256 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | 4276 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( |
| 4257 delegate.get(), -1234, bounds, root_window())); | 4277 delegate.get(), -1234, bounds, root_window())); |
| 4258 delegate->set_window(window.get()); | 4278 delegate->set_window(window.get()); |
| 4259 | 4279 |
| 4260 delegate->Reset(); | 4280 delegate->Reset(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4273 delegate->Reset(); | 4293 delegate->Reset(); |
| 4274 // Wait until the long press event would fire (if we weren't eager). | 4294 // Wait until the long press event would fire (if we weren't eager). |
| 4275 DelayByLongPressTimeout(); | 4295 DelayByLongPressTimeout(); |
| 4276 | 4296 |
| 4277 // Ack the touch release. | 4297 // Ack the touch release. |
| 4278 delegate->ReceivedAck(); | 4298 delegate->ReceivedAck(); |
| 4279 EXPECT_TRUE(delegate->tap()); | 4299 EXPECT_TRUE(delegate->tap()); |
| 4280 EXPECT_FALSE(delegate->long_press()); | 4300 EXPECT_FALSE(delegate->long_press()); |
| 4281 } | 4301 } |
| 4282 | 4302 |
| 4283 // This tests crbug.com/405519, in which events which the gesture detector | 4303 // This tests crbug.com/405519, in which touch events which the gesture detector |
| 4284 // ignores cause future events to also be thrown away. | 4304 // ignores interfere with gesture recognition. |
| 4285 TEST_F(GestureRecognizerTest, IgnoredEventsDontPreventFutureEvents) { | 4305 TEST_F(GestureRecognizerTest, IgnoredEventsDontBreakGestureRecognition) { |
| 4286 scoped_ptr<QueueTouchEventDelegate> delegate( | 4306 scoped_ptr<QueueTouchEventDelegate> delegate( |
| 4287 new QueueTouchEventDelegate(host()->dispatcher())); | 4307 new QueueTouchEventDelegate(host()->dispatcher())); |
| 4288 TimedEvents tes; | 4308 TimedEvents tes; |
| 4289 const int kWindowWidth = 300; | 4309 const int kWindowWidth = 300; |
| 4290 const int kWindowHeight = 400; | 4310 const int kWindowHeight = 400; |
| 4291 const int kTouchId1 = 3; | 4311 const int kTouchId1 = 3; |
| 4292 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | 4312 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); |
| 4293 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | 4313 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( |
| 4294 delegate.get(), -1234, bounds, root_window())); | 4314 delegate.get(), -1234, bounds, root_window())); |
| 4295 delegate->set_window(window.get()); | 4315 delegate->set_window(window.get()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4308 ui::ET_TOUCH_MOVED, gfx::Point(65, 201), kTouchId1, tes.Now()); | 4328 ui::ET_TOUCH_MOVED, gfx::Point(65, 201), kTouchId1, tes.Now()); |
| 4309 DispatchEventUsingWindowDispatcher(&move1); | 4329 DispatchEventUsingWindowDispatcher(&move1); |
| 4310 delegate->ReceivedAck(); | 4330 delegate->ReceivedAck(); |
| 4311 | 4331 |
| 4312 EXPECT_3_EVENTS(delegate->events(), | 4332 EXPECT_3_EVENTS(delegate->events(), |
| 4313 ui::ET_GESTURE_TAP_CANCEL, | 4333 ui::ET_GESTURE_TAP_CANCEL, |
| 4314 ui::ET_GESTURE_SCROLL_BEGIN, | 4334 ui::ET_GESTURE_SCROLL_BEGIN, |
| 4315 ui::ET_GESTURE_SCROLL_UPDATE); | 4335 ui::ET_GESTURE_SCROLL_UPDATE); |
| 4316 | 4336 |
| 4317 delegate->Reset(); | 4337 delegate->Reset(); |
| 4338 |
| 4339 // Send a valid event, but don't ack it. |
| 4318 ui::TouchEvent move2( | 4340 ui::TouchEvent move2( |
| 4319 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); | 4341 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); |
| 4320 DispatchEventUsingWindowDispatcher(&move2); | 4342 DispatchEventUsingWindowDispatcher(&move2); |
| 4343 EXPECT_0_EVENTS(delegate->events()); |
| 4321 | 4344 |
| 4322 // Send a touchmove event at the same location as the previous touchmove | 4345 // Send a touchmove event at the same location as the previous touchmove |
| 4323 // event. This shouldn't do anything. | 4346 // event. This shouldn't do anything. |
| 4324 ui::TouchEvent move3( | 4347 ui::TouchEvent move3( |
| 4325 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); | 4348 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); |
| 4326 DispatchEventUsingWindowDispatcher(&move3); | 4349 DispatchEventUsingWindowDispatcher(&move3); |
| 4327 | 4350 |
| 4351 // Ack the previous valid event. The intermediary invalid event shouldn't |
| 4352 // interfere. |
| 4328 delegate->ReceivedAck(); | 4353 delegate->ReceivedAck(); |
| 4329 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | 4354 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); |
| 4330 } | 4355 } |
| 4331 | 4356 |
| 4357 // Tests that an event stream can have a mix of sync and async acks. |
| 4358 TEST_F(GestureRecognizerTest, |
| 4359 MixedSyncAndAsyncAcksDontCauseOutOfOrderDispatch) { |
| 4360 scoped_ptr<QueueTouchEventDelegate> delegate( |
| 4361 new QueueTouchEventDelegate(host()->dispatcher())); |
| 4362 TimedEvents tes; |
| 4363 const int kWindowWidth = 300; |
| 4364 const int kWindowHeight = 400; |
| 4365 const int kTouchId1 = 3; |
| 4366 gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); |
| 4367 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( |
| 4368 delegate.get(), -1234, bounds, root_window())); |
| 4369 delegate->set_window(window.get()); |
| 4370 |
| 4371 // Start a scroll gesture. |
| 4372 ui::TouchEvent press1( |
| 4373 ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId1, tes.Now()); |
| 4374 DispatchEventUsingWindowDispatcher(&press1); |
| 4375 delegate->ReceivedAck(); |
| 4376 |
| 4377 ui::TouchEvent move1( |
| 4378 ui::ET_TOUCH_MOVED, gfx::Point(100, 100), kTouchId1, tes.Now()); |
| 4379 DispatchEventUsingWindowDispatcher(&move1); |
| 4380 delegate->ReceivedAck(); |
| 4381 |
| 4382 delegate->Reset(); |
| 4383 // Dispatch a synchronously consumed touch move, which should be ignored. |
| 4384 delegate->set_synchronous_ack_for_next_event(true); |
| 4385 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(200, 200), kTouchId1, |
| 4386 tes.Now()); |
| 4387 DispatchEventUsingWindowDispatcher(&move2); |
| 4388 EXPECT_0_EVENTS(delegate->events()); |
| 4389 |
| 4390 // Dispatch a touch move, but don't ack it. |
| 4391 ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(300, 300), kTouchId1, |
| 4392 tes.Now()); |
| 4393 DispatchEventUsingWindowDispatcher(&move3); |
| 4394 |
| 4395 // Dispatch two synchronously consumed touch moves, which should be ignored. |
| 4396 delegate->set_synchronous_ack_for_next_event(true); |
| 4397 ui::TouchEvent move4( |
| 4398 ui::ET_TOUCH_MOVED, gfx::Point(400, 400), kTouchId1, tes.Now()); |
| 4399 DispatchEventUsingWindowDispatcher(&move4); |
| 4400 |
| 4401 delegate->set_synchronous_ack_for_next_event(true); |
| 4402 ui::TouchEvent move5( |
| 4403 ui::ET_TOUCH_MOVED, gfx::Point(500, 500), kTouchId1, tes.Now()); |
| 4404 DispatchEventUsingWindowDispatcher(&move5); |
| 4405 |
| 4406 EXPECT_0_EVENTS(delegate->events()); |
| 4407 EXPECT_EQ(100, delegate->bounding_box().x()); |
| 4408 // Ack the pending touch move, and ensure the most recent gesture event |
| 4409 // used its co-ordinates. |
| 4410 delegate->ReceivedAck(); |
| 4411 EXPECT_EQ(300, delegate->bounding_box().x()); |
| 4412 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); |
| 4413 |
| 4414 // Dispatch a touch move, but don't ack it. |
| 4415 delegate->Reset(); |
| 4416 ui::TouchEvent move6(ui::ET_TOUCH_MOVED, gfx::Point(600, 600), kTouchId1, |
| 4417 tes.Now()); |
| 4418 DispatchEventUsingWindowDispatcher(&move6); |
| 4419 |
| 4420 // Dispatch a synchronously unconsumed touch move. |
| 4421 delegate->set_synchronous_ack_for_next_event(false); |
| 4422 ui::TouchEvent move7( |
| 4423 ui::ET_TOUCH_MOVED, gfx::Point(700, 700), kTouchId1, tes.Now()); |
| 4424 DispatchEventUsingWindowDispatcher(&move7); |
| 4425 |
| 4426 // The synchronous ack is stuck behind the pending touch move. |
| 4427 EXPECT_0_EVENTS(delegate->events()); |
| 4428 |
| 4429 delegate->ReceivedAck(); |
| 4430 EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE, |
| 4431 ui::ET_GESTURE_SCROLL_UPDATE); |
| 4432 } |
| 4433 |
| 4332 } // namespace test | 4434 } // namespace test |
| 4333 } // namespace aura | 4435 } // namespace aura |
| OLD | NEW |