| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/command_line.h" | |
| 6 #include "base/memory/scoped_vector.h" | |
| 7 #include "base/run_loop.h" | |
| 8 #include "base/strings/string_number_conversions.h" | |
| 9 #include "base/timer/timer.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 #include "ui/aura/env.h" | |
| 12 #include "ui/aura/test/aura_test_base.h" | |
| 13 #include "ui/aura/test/test_window_delegate.h" | |
| 14 #include "ui/aura/test/test_windows.h" | |
| 15 #include "ui/aura/window.h" | |
| 16 #include "ui/aura/window_event_dispatcher.h" | |
| 17 #include "ui/base/hit_test.h" | |
| 18 #include "ui/base/ui_base_switches.h" | |
| 19 #include "ui/events/event.h" | |
| 20 #include "ui/events/event_switches.h" | |
| 21 #include "ui/events/event_utils.h" | |
| 22 #include "ui/events/gestures/gesture_configuration.h" | |
| 23 #include "ui/events/gestures/gesture_recognizer_impl.h" | |
| 24 #include "ui/events/gestures/gesture_types.h" | |
| 25 #include "ui/events/test/event_generator.h" | |
| 26 #include "ui/events/test/events_test_utils.h" | |
| 27 #include "ui/gfx/point.h" | |
| 28 #include "ui/gfx/rect.h" | |
| 29 | |
| 30 #include <queue> | |
| 31 | |
| 32 namespace aura { | |
| 33 namespace test { | |
| 34 | |
| 35 namespace { | |
| 36 | |
| 37 std::string WindowIDAsString(ui::GestureConsumer* consumer) { | |
| 38 return consumer ? | |
| 39 base::IntToString(static_cast<Window*>(consumer)->id()) : "?"; | |
| 40 } | |
| 41 | |
| 42 #define EXPECT_0_EVENTS(events) \ | |
| 43 EXPECT_EQ(0u, events.size()) | |
| 44 | |
| 45 #define EXPECT_1_EVENT(events, e0) \ | |
| 46 EXPECT_EQ(1u, events.size()); \ | |
| 47 EXPECT_EQ(e0, events[0]) | |
| 48 | |
| 49 #define EXPECT_2_EVENTS(events, e0, e1) \ | |
| 50 EXPECT_EQ(2u, events.size()); \ | |
| 51 EXPECT_EQ(e0, events[0]); \ | |
| 52 EXPECT_EQ(e1, events[1]) | |
| 53 | |
| 54 #define EXPECT_3_EVENTS(events, e0, e1, e2) \ | |
| 55 EXPECT_EQ(3u, events.size()); \ | |
| 56 EXPECT_EQ(e0, events[0]); \ | |
| 57 EXPECT_EQ(e1, events[1]); \ | |
| 58 EXPECT_EQ(e2, events[2]) | |
| 59 | |
| 60 #define EXPECT_4_EVENTS(events, e0, e1, e2, e3) \ | |
| 61 EXPECT_EQ(4u, events.size()); \ | |
| 62 EXPECT_EQ(e0, events[0]); \ | |
| 63 EXPECT_EQ(e1, events[1]); \ | |
| 64 EXPECT_EQ(e2, events[2]); \ | |
| 65 EXPECT_EQ(e3, events[3]) | |
| 66 | |
| 67 // A delegate that keeps track of gesture events. | |
| 68 class GestureEventConsumeDelegate : public TestWindowDelegate { | |
| 69 public: | |
| 70 GestureEventConsumeDelegate() | |
| 71 : tap_(false), | |
| 72 tap_down_(false), | |
| 73 tap_cancel_(false), | |
| 74 begin_(false), | |
| 75 end_(false), | |
| 76 scroll_begin_(false), | |
| 77 scroll_update_(false), | |
| 78 scroll_end_(false), | |
| 79 pinch_begin_(false), | |
| 80 pinch_update_(false), | |
| 81 pinch_end_(false), | |
| 82 long_press_(false), | |
| 83 fling_(false), | |
| 84 two_finger_tap_(false), | |
| 85 show_press_(false), | |
| 86 swipe_left_(false), | |
| 87 swipe_right_(false), | |
| 88 swipe_up_(false), | |
| 89 swipe_down_(false), | |
| 90 scroll_x_(0), | |
| 91 scroll_y_(0), | |
| 92 scroll_velocity_x_(0), | |
| 93 scroll_velocity_y_(0), | |
| 94 velocity_x_(0), | |
| 95 velocity_y_(0), | |
| 96 scroll_x_hint_(0), | |
| 97 scroll_y_hint_(0), | |
| 98 tap_count_(0), | |
| 99 flags_(0), | |
| 100 wait_until_event_(ui::ET_UNKNOWN) {} | |
| 101 | |
| 102 virtual ~GestureEventConsumeDelegate() {} | |
| 103 | |
| 104 void Reset() { | |
| 105 events_.clear(); | |
| 106 tap_ = false; | |
| 107 tap_down_ = false; | |
| 108 tap_cancel_ = false; | |
| 109 begin_ = false; | |
| 110 end_ = false; | |
| 111 scroll_begin_ = false; | |
| 112 scroll_update_ = false; | |
| 113 scroll_end_ = false; | |
| 114 pinch_begin_ = false; | |
| 115 pinch_update_ = false; | |
| 116 pinch_end_ = false; | |
| 117 long_press_ = false; | |
| 118 fling_ = false; | |
| 119 two_finger_tap_ = false; | |
| 120 show_press_ = false; | |
| 121 swipe_left_ = false; | |
| 122 swipe_right_ = false; | |
| 123 swipe_up_ = false; | |
| 124 swipe_down_ = false; | |
| 125 | |
| 126 scroll_begin_position_.SetPoint(0, 0); | |
| 127 tap_location_.SetPoint(0, 0); | |
| 128 gesture_end_location_.SetPoint(0, 0); | |
| 129 | |
| 130 scroll_x_ = 0; | |
| 131 scroll_y_ = 0; | |
| 132 scroll_velocity_x_ = 0; | |
| 133 scroll_velocity_y_ = 0; | |
| 134 velocity_x_ = 0; | |
| 135 velocity_y_ = 0; | |
| 136 scroll_x_hint_ = 0; | |
| 137 scroll_y_hint_ = 0; | |
| 138 tap_count_ = 0; | |
| 139 scale_ = 0; | |
| 140 flags_ = 0; | |
| 141 latency_info_.Clear(); | |
| 142 } | |
| 143 | |
| 144 const std::vector<ui::EventType>& events() const { return events_; }; | |
| 145 | |
| 146 bool tap() const { return tap_; } | |
| 147 bool tap_down() const { return tap_down_; } | |
| 148 bool tap_cancel() const { return tap_cancel_; } | |
| 149 bool begin() const { return begin_; } | |
| 150 bool end() const { return end_; } | |
| 151 bool scroll_begin() const { return scroll_begin_; } | |
| 152 bool scroll_update() const { return scroll_update_; } | |
| 153 bool scroll_end() const { return scroll_end_; } | |
| 154 bool pinch_begin() const { return pinch_begin_; } | |
| 155 bool pinch_update() const { return pinch_update_; } | |
| 156 bool pinch_end() const { return pinch_end_; } | |
| 157 bool long_press() const { return long_press_; } | |
| 158 bool long_tap() const { return long_tap_; } | |
| 159 bool fling() const { return fling_; } | |
| 160 bool two_finger_tap() const { return two_finger_tap_; } | |
| 161 bool show_press() const { return show_press_; } | |
| 162 bool swipe_left() const { return swipe_left_; } | |
| 163 bool swipe_right() const { return swipe_right_; } | |
| 164 bool swipe_up() const { return swipe_up_; } | |
| 165 bool swipe_down() const { return swipe_down_; } | |
| 166 | |
| 167 const gfx::Point& scroll_begin_position() const { | |
| 168 return scroll_begin_position_; | |
| 169 } | |
| 170 | |
| 171 const gfx::Point& tap_location() const { | |
| 172 return tap_location_; | |
| 173 } | |
| 174 | |
| 175 const gfx::Point& gesture_end_location() const { | |
| 176 return gesture_end_location_; | |
| 177 } | |
| 178 | |
| 179 float scroll_x() const { return scroll_x_; } | |
| 180 float scroll_y() const { return scroll_y_; } | |
| 181 float scroll_velocity_x() const { return scroll_velocity_x_; } | |
| 182 float scroll_velocity_y() const { return scroll_velocity_y_; } | |
| 183 float velocity_x() const { return velocity_x_; } | |
| 184 float velocity_y() const { return velocity_y_; } | |
| 185 float scroll_x_hint() const { return scroll_x_hint_; } | |
| 186 float scroll_y_hint() const { return scroll_y_hint_; } | |
| 187 float scale() const { return scale_; } | |
| 188 const gfx::Rect& bounding_box() const { return bounding_box_; } | |
| 189 int tap_count() const { return tap_count_; } | |
| 190 int flags() const { return flags_; } | |
| 191 const ui::LatencyInfo& latency_info() const { return latency_info_; } | |
| 192 | |
| 193 void WaitUntilReceivedGesture(ui::EventType type) { | |
| 194 wait_until_event_ = type; | |
| 195 run_loop_.reset(new base::RunLoop()); | |
| 196 run_loop_->Run(); | |
| 197 } | |
| 198 | |
| 199 virtual void OnGestureEvent(ui::GestureEvent* gesture) override { | |
| 200 events_.push_back(gesture->type()); | |
| 201 bounding_box_ = gesture->details().bounding_box(); | |
| 202 flags_ = gesture->flags(); | |
| 203 latency_info_ = *gesture->latency(); | |
| 204 switch (gesture->type()) { | |
| 205 case ui::ET_GESTURE_TAP: | |
| 206 tap_location_ = gesture->location(); | |
| 207 tap_count_ = gesture->details().tap_count(); | |
| 208 tap_ = true; | |
| 209 break; | |
| 210 case ui::ET_GESTURE_TAP_DOWN: | |
| 211 tap_down_ = true; | |
| 212 break; | |
| 213 case ui::ET_GESTURE_TAP_CANCEL: | |
| 214 tap_cancel_ = true; | |
| 215 break; | |
| 216 case ui::ET_GESTURE_BEGIN: | |
| 217 begin_ = true; | |
| 218 break; | |
| 219 case ui::ET_GESTURE_END: | |
| 220 end_ = true; | |
| 221 gesture_end_location_ = gesture->location(); | |
| 222 break; | |
| 223 case ui::ET_GESTURE_SCROLL_BEGIN: | |
| 224 scroll_begin_ = true; | |
| 225 scroll_begin_position_ = gesture->location(); | |
| 226 scroll_x_hint_ = gesture->details().scroll_x_hint(); | |
| 227 scroll_y_hint_ = gesture->details().scroll_y_hint(); | |
| 228 break; | |
| 229 case ui::ET_GESTURE_SCROLL_UPDATE: | |
| 230 scroll_update_ = true; | |
| 231 scroll_x_ += gesture->details().scroll_x(); | |
| 232 scroll_y_ += gesture->details().scroll_y(); | |
| 233 break; | |
| 234 case ui::ET_GESTURE_SCROLL_END: | |
| 235 EXPECT_TRUE(velocity_x_ == 0 && velocity_y_ == 0); | |
| 236 scroll_end_ = true; | |
| 237 break; | |
| 238 case ui::ET_GESTURE_PINCH_BEGIN: | |
| 239 pinch_begin_ = true; | |
| 240 break; | |
| 241 case ui::ET_GESTURE_PINCH_UPDATE: | |
| 242 pinch_update_ = true; | |
| 243 scale_ = gesture->details().scale(); | |
| 244 break; | |
| 245 case ui::ET_GESTURE_PINCH_END: | |
| 246 pinch_end_ = true; | |
| 247 break; | |
| 248 case ui::ET_GESTURE_LONG_PRESS: | |
| 249 long_press_ = true; | |
| 250 break; | |
| 251 case ui::ET_GESTURE_LONG_TAP: | |
| 252 long_tap_ = true; | |
| 253 break; | |
| 254 case ui::ET_SCROLL_FLING_START: | |
| 255 EXPECT_TRUE(gesture->details().velocity_x() != 0 || | |
| 256 gesture->details().velocity_y() != 0); | |
| 257 EXPECT_FALSE(scroll_end_); | |
| 258 fling_ = true; | |
| 259 velocity_x_ = gesture->details().velocity_x(); | |
| 260 velocity_y_ = gesture->details().velocity_y(); | |
| 261 break; | |
| 262 case ui::ET_GESTURE_TWO_FINGER_TAP: | |
| 263 two_finger_tap_ = true; | |
| 264 break; | |
| 265 case ui::ET_GESTURE_SHOW_PRESS: | |
| 266 show_press_ = true; | |
| 267 break; | |
| 268 case ui::ET_GESTURE_SWIPE: | |
| 269 swipe_left_ = gesture->details().swipe_left(); | |
| 270 swipe_right_ = gesture->details().swipe_right(); | |
| 271 swipe_up_ = gesture->details().swipe_up(); | |
| 272 swipe_down_ = gesture->details().swipe_down(); | |
| 273 break; | |
| 274 case ui::ET_SCROLL_FLING_CANCEL: | |
| 275 // Only used in unified gesture detection. | |
| 276 break; | |
| 277 default: | |
| 278 NOTREACHED(); | |
| 279 } | |
| 280 if (wait_until_event_ == gesture->type() && run_loop_) { | |
| 281 run_loop_->Quit(); | |
| 282 wait_until_event_ = ui::ET_UNKNOWN; | |
| 283 } | |
| 284 gesture->StopPropagation(); | |
| 285 } | |
| 286 | |
| 287 private: | |
| 288 scoped_ptr<base::RunLoop> run_loop_; | |
| 289 std::vector<ui::EventType> events_; | |
| 290 | |
| 291 bool tap_; | |
| 292 bool tap_down_; | |
| 293 bool tap_cancel_; | |
| 294 bool begin_; | |
| 295 bool end_; | |
| 296 bool scroll_begin_; | |
| 297 bool scroll_update_; | |
| 298 bool scroll_end_; | |
| 299 bool pinch_begin_; | |
| 300 bool pinch_update_; | |
| 301 bool pinch_end_; | |
| 302 bool long_press_; | |
| 303 bool long_tap_; | |
| 304 bool fling_; | |
| 305 bool two_finger_tap_; | |
| 306 bool show_press_; | |
| 307 bool swipe_left_; | |
| 308 bool swipe_right_; | |
| 309 bool swipe_up_; | |
| 310 bool swipe_down_; | |
| 311 | |
| 312 gfx::Point scroll_begin_position_; | |
| 313 gfx::Point tap_location_; | |
| 314 gfx::Point gesture_end_location_; | |
| 315 | |
| 316 float scroll_x_; | |
| 317 float scroll_y_; | |
| 318 float scroll_velocity_x_; | |
| 319 float scroll_velocity_y_; | |
| 320 float velocity_x_; | |
| 321 float velocity_y_; | |
| 322 float scroll_x_hint_; | |
| 323 float scroll_y_hint_; | |
| 324 float scale_; | |
| 325 gfx::Rect bounding_box_; | |
| 326 int tap_count_; | |
| 327 int flags_; | |
| 328 ui::LatencyInfo latency_info_; | |
| 329 | |
| 330 ui::EventType wait_until_event_; | |
| 331 | |
| 332 DISALLOW_COPY_AND_ASSIGN(GestureEventConsumeDelegate); | |
| 333 }; | |
| 334 | |
| 335 class QueueTouchEventDelegate : public GestureEventConsumeDelegate { | |
| 336 public: | |
| 337 explicit QueueTouchEventDelegate(WindowEventDispatcher* dispatcher) | |
| 338 : window_(NULL), | |
| 339 dispatcher_(dispatcher), | |
| 340 queue_events_(true) { | |
| 341 } | |
| 342 virtual ~QueueTouchEventDelegate() { | |
| 343 while(!queue_.empty()) { | |
| 344 delete queue_.front(); | |
| 345 queue_.pop(); | |
| 346 } | |
| 347 } | |
| 348 | |
| 349 virtual void OnTouchEvent(ui::TouchEvent* event) override { | |
| 350 if (queue_events_) { | |
| 351 queue_.push(new ui::TouchEvent(*event, window_, window_)); | |
| 352 event->StopPropagation(); | |
| 353 } | |
| 354 } | |
| 355 | |
| 356 void ReceivedAck() { | |
| 357 ReceivedAckImpl(false); | |
| 358 } | |
| 359 | |
| 360 void ReceivedAckPreventDefaulted() { | |
| 361 ReceivedAckImpl(true); | |
| 362 } | |
| 363 | |
| 364 void set_window(Window* w) { window_ = w; } | |
| 365 void set_queue_events(bool queue) { queue_events_ = queue; } | |
| 366 | |
| 367 private: | |
| 368 void ReceivedAckImpl(bool prevent_defaulted) { | |
| 369 scoped_ptr<ui::TouchEvent> event(queue_.front()); | |
| 370 dispatcher_->ProcessedTouchEvent(event.get(), window_, | |
| 371 prevent_defaulted ? ui::ER_HANDLED : ui::ER_UNHANDLED); | |
| 372 queue_.pop(); | |
| 373 } | |
| 374 | |
| 375 std::queue<ui::TouchEvent*> queue_; | |
| 376 Window* window_; | |
| 377 WindowEventDispatcher* dispatcher_; | |
| 378 bool queue_events_; | |
| 379 | |
| 380 DISALLOW_COPY_AND_ASSIGN(QueueTouchEventDelegate); | |
| 381 }; | |
| 382 | |
| 383 // A delegate that ignores gesture events but keeps track of [synthetic] mouse | |
| 384 // events. | |
| 385 class GestureEventSynthDelegate : public TestWindowDelegate { | |
| 386 public: | |
| 387 GestureEventSynthDelegate() | |
| 388 : mouse_enter_(false), | |
| 389 mouse_exit_(false), | |
| 390 mouse_press_(false), | |
| 391 mouse_release_(false), | |
| 392 mouse_move_(false), | |
| 393 double_click_(false) { | |
| 394 } | |
| 395 | |
| 396 void Reset() { | |
| 397 mouse_enter_ = false; | |
| 398 mouse_exit_ = false; | |
| 399 mouse_press_ = false; | |
| 400 mouse_release_ = false; | |
| 401 mouse_move_ = false; | |
| 402 double_click_ = false; | |
| 403 } | |
| 404 | |
| 405 bool mouse_enter() const { return mouse_enter_; } | |
| 406 bool mouse_exit() const { return mouse_exit_; } | |
| 407 bool mouse_press() const { return mouse_press_; } | |
| 408 bool mouse_move() const { return mouse_move_; } | |
| 409 bool mouse_release() const { return mouse_release_; } | |
| 410 bool double_click() const { return double_click_; } | |
| 411 | |
| 412 virtual void OnMouseEvent(ui::MouseEvent* event) override { | |
| 413 switch (event->type()) { | |
| 414 case ui::ET_MOUSE_PRESSED: | |
| 415 double_click_ = event->flags() & ui::EF_IS_DOUBLE_CLICK; | |
| 416 mouse_press_ = true; | |
| 417 break; | |
| 418 case ui::ET_MOUSE_RELEASED: | |
| 419 mouse_release_ = true; | |
| 420 break; | |
| 421 case ui::ET_MOUSE_MOVED: | |
| 422 mouse_move_ = true; | |
| 423 break; | |
| 424 case ui::ET_MOUSE_ENTERED: | |
| 425 mouse_enter_ = true; | |
| 426 break; | |
| 427 case ui::ET_MOUSE_EXITED: | |
| 428 mouse_exit_ = true; | |
| 429 break; | |
| 430 default: | |
| 431 NOTREACHED(); | |
| 432 } | |
| 433 event->SetHandled(); | |
| 434 } | |
| 435 | |
| 436 private: | |
| 437 bool mouse_enter_; | |
| 438 bool mouse_exit_; | |
| 439 bool mouse_press_; | |
| 440 bool mouse_release_; | |
| 441 bool mouse_move_; | |
| 442 bool double_click_; | |
| 443 | |
| 444 DISALLOW_COPY_AND_ASSIGN(GestureEventSynthDelegate); | |
| 445 }; | |
| 446 | |
| 447 class ScopedGestureRecognizerSetter { | |
| 448 public: | |
| 449 // Takes ownership of |new_gr|. | |
| 450 explicit ScopedGestureRecognizerSetter(ui::GestureRecognizer* new_gr) | |
| 451 : new_gr_(new_gr) { | |
| 452 original_gr_ = ui::GestureRecognizer::Get(); | |
| 453 ui::SetGestureRecognizerForTesting(new_gr_.get()); | |
| 454 } | |
| 455 | |
| 456 virtual ~ScopedGestureRecognizerSetter() { | |
| 457 ui::SetGestureRecognizerForTesting(original_gr_); | |
| 458 } | |
| 459 | |
| 460 private: | |
| 461 ui::GestureRecognizer* original_gr_; | |
| 462 scoped_ptr<ui::GestureRecognizer> new_gr_; | |
| 463 | |
| 464 DISALLOW_COPY_AND_ASSIGN(ScopedGestureRecognizerSetter); | |
| 465 }; | |
| 466 | |
| 467 class TimedEvents { | |
| 468 private: | |
| 469 int simulated_now_; | |
| 470 | |
| 471 public: | |
| 472 // Use a non-zero start time to pass DCHECKs which ensure events have had a | |
| 473 // time assigned. | |
| 474 TimedEvents() : simulated_now_(1) { | |
| 475 } | |
| 476 | |
| 477 base::TimeDelta Now() { | |
| 478 base::TimeDelta t = base::TimeDelta::FromMilliseconds(simulated_now_); | |
| 479 simulated_now_++; | |
| 480 return t; | |
| 481 } | |
| 482 | |
| 483 base::TimeDelta LeapForward(int time_in_millis) { | |
| 484 simulated_now_ += time_in_millis; | |
| 485 return base::TimeDelta::FromMilliseconds(simulated_now_); | |
| 486 } | |
| 487 | |
| 488 base::TimeDelta InFuture(int time_in_millis) { | |
| 489 return base::TimeDelta::FromMilliseconds(simulated_now_ + time_in_millis); | |
| 490 } | |
| 491 | |
| 492 void SendScrollEvents(ui::EventProcessor* dispatcher, | |
| 493 float x_start, | |
| 494 float y_start, | |
| 495 int dx, | |
| 496 int dy, | |
| 497 int touch_id, | |
| 498 int time_step, | |
| 499 int num_steps, | |
| 500 GestureEventConsumeDelegate* delegate) { | |
| 501 float x = x_start; | |
| 502 float y = y_start; | |
| 503 | |
| 504 for (int i = 0; i < num_steps; i++) { | |
| 505 x += dx; | |
| 506 y += dy; | |
| 507 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::PointF(x, y), | |
| 508 touch_id, | |
| 509 base::TimeDelta::FromMilliseconds(simulated_now_)); | |
| 510 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move); | |
| 511 ASSERT_FALSE(details.dispatcher_destroyed); | |
| 512 simulated_now_ += time_step; | |
| 513 } | |
| 514 } | |
| 515 | |
| 516 void SendScrollEvent(ui::EventProcessor* dispatcher, | |
| 517 float x, | |
| 518 float y, | |
| 519 int touch_id, | |
| 520 GestureEventConsumeDelegate* delegate) { | |
| 521 delegate->Reset(); | |
| 522 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::PointF(x, y), | |
| 523 touch_id, | |
| 524 base::TimeDelta::FromMilliseconds(simulated_now_)); | |
| 525 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move); | |
| 526 ASSERT_FALSE(details.dispatcher_destroyed); | |
| 527 simulated_now_++; | |
| 528 } | |
| 529 }; | |
| 530 | |
| 531 // An event handler to keep track of events. | |
| 532 class TestEventHandler : public ui::EventHandler { | |
| 533 public: | |
| 534 TestEventHandler() | |
| 535 : touch_released_count_(0), | |
| 536 touch_pressed_count_(0), | |
| 537 touch_moved_count_(0) {} | |
| 538 | |
| 539 virtual ~TestEventHandler() {} | |
| 540 | |
| 541 virtual void OnTouchEvent(ui::TouchEvent* event) override { | |
| 542 switch (event->type()) { | |
| 543 case ui::ET_TOUCH_RELEASED: | |
| 544 touch_released_count_++; | |
| 545 break; | |
| 546 case ui::ET_TOUCH_PRESSED: | |
| 547 touch_pressed_count_++; | |
| 548 break; | |
| 549 case ui::ET_TOUCH_MOVED: | |
| 550 touch_moved_count_++; | |
| 551 break; | |
| 552 case ui::ET_TOUCH_CANCELLED: | |
| 553 cancelled_touch_points_.push_back(event->location()); | |
| 554 break; | |
| 555 default: | |
| 556 break; | |
| 557 } | |
| 558 } | |
| 559 | |
| 560 void Reset() { | |
| 561 touch_released_count_ = 0; | |
| 562 touch_pressed_count_ = 0; | |
| 563 touch_moved_count_ = 0; | |
| 564 cancelled_touch_points_.clear(); | |
| 565 } | |
| 566 | |
| 567 int touch_released_count() const { return touch_released_count_; } | |
| 568 int touch_pressed_count() const { return touch_pressed_count_; } | |
| 569 int touch_moved_count() const { return touch_moved_count_; } | |
| 570 int touch_cancelled_count() const { | |
| 571 return static_cast<int>(cancelled_touch_points_.size()); | |
| 572 } | |
| 573 const std::vector<gfx::PointF>& cancelled_touch_points() const { | |
| 574 return cancelled_touch_points_; | |
| 575 } | |
| 576 | |
| 577 private: | |
| 578 int touch_released_count_; | |
| 579 int touch_pressed_count_; | |
| 580 int touch_moved_count_; | |
| 581 std::vector<gfx::PointF> cancelled_touch_points_; | |
| 582 | |
| 583 DISALLOW_COPY_AND_ASSIGN(TestEventHandler); | |
| 584 }; | |
| 585 | |
| 586 // Removes the target window from its parent when it receives a touch-cancel | |
| 587 // event. | |
| 588 class RemoveOnTouchCancelHandler : public TestEventHandler { | |
| 589 public: | |
| 590 RemoveOnTouchCancelHandler() {} | |
| 591 virtual ~RemoveOnTouchCancelHandler() {} | |
| 592 | |
| 593 private: | |
| 594 // ui::EventHandler: | |
| 595 virtual void OnTouchEvent(ui::TouchEvent* event) override { | |
| 596 TestEventHandler::OnTouchEvent(event); | |
| 597 if (event->type() == ui::ET_TOUCH_CANCELLED) { | |
| 598 Window* target = static_cast<Window*>(event->target()); | |
| 599 // This is tiptoeing around crbug.com/310172. If this event handler isn't | |
| 600 // removed, we enter an infinite loop. | |
| 601 target->RemovePreTargetHandler(this); | |
| 602 target->parent()->RemoveChild(target); | |
| 603 } | |
| 604 } | |
| 605 | |
| 606 DISALLOW_COPY_AND_ASSIGN(RemoveOnTouchCancelHandler); | |
| 607 }; | |
| 608 | |
| 609 void DelayByLongPressTimeout() { | |
| 610 ui::GestureProvider::Config config; | |
| 611 base::RunLoop run_loop; | |
| 612 base::MessageLoop::current()->PostDelayedTask( | |
| 613 FROM_HERE, | |
| 614 run_loop.QuitClosure(), | |
| 615 config.gesture_detector_config.longpress_timeout * 2); | |
| 616 run_loop.Run(); | |
| 617 } | |
| 618 | |
| 619 void DelayByShowPressTimeout() { | |
| 620 ui::GestureProvider::Config config; | |
| 621 base::RunLoop run_loop; | |
| 622 base::MessageLoop::current()->PostDelayedTask( | |
| 623 FROM_HERE, | |
| 624 run_loop.QuitClosure(), | |
| 625 config.gesture_detector_config.showpress_timeout * 2); | |
| 626 run_loop.Run(); | |
| 627 } | |
| 628 | |
| 629 } // namespace | |
| 630 | |
| 631 class GestureRecognizerTest : public AuraTestBase, | |
| 632 public ::testing::WithParamInterface<bool> { | |
| 633 public: | |
| 634 GestureRecognizerTest() {} | |
| 635 | |
| 636 virtual void SetUp() override { | |
| 637 AuraTestBase::SetUp(); | |
| 638 ui::GestureConfiguration::set_show_press_delay_in_ms(2); | |
| 639 ui::GestureConfiguration::set_long_press_time_in_ms(3); | |
| 640 } | |
| 641 | |
| 642 DISALLOW_COPY_AND_ASSIGN(GestureRecognizerTest); | |
| 643 }; | |
| 644 | |
| 645 // Check that appropriate touch events generate tap gesture events. | |
| 646 TEST_F(GestureRecognizerTest, GestureEventTap) { | |
| 647 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 648 new GestureEventConsumeDelegate()); | |
| 649 TimedEvents tes; | |
| 650 const int kWindowWidth = 123; | |
| 651 const int kWindowHeight = 45; | |
| 652 const int kTouchId = 2; | |
| 653 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 654 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 655 delegate.get(), -1234, bounds, root_window())); | |
| 656 | |
| 657 delegate->Reset(); | |
| 658 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 659 kTouchId, tes.Now()); | |
| 660 DispatchEventUsingWindowDispatcher(&press); | |
| 661 EXPECT_FALSE(delegate->tap()); | |
| 662 EXPECT_FALSE(delegate->show_press()); | |
| 663 EXPECT_TRUE(delegate->tap_down()); | |
| 664 EXPECT_FALSE(delegate->tap_cancel()); | |
| 665 EXPECT_TRUE(delegate->begin()); | |
| 666 EXPECT_FALSE(delegate->scroll_begin()); | |
| 667 EXPECT_FALSE(delegate->scroll_update()); | |
| 668 EXPECT_FALSE(delegate->scroll_end()); | |
| 669 EXPECT_FALSE(delegate->long_press()); | |
| 670 | |
| 671 delegate->Reset(); | |
| 672 delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_SHOW_PRESS); | |
| 673 EXPECT_TRUE(delegate->show_press()); | |
| 674 EXPECT_FALSE(delegate->tap_down()); | |
| 675 | |
| 676 // Make sure there is enough delay before the touch is released so that it is | |
| 677 // recognized as a tap. | |
| 678 delegate->Reset(); | |
| 679 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 680 kTouchId, tes.LeapForward(50)); | |
| 681 | |
| 682 DispatchEventUsingWindowDispatcher(&release); | |
| 683 EXPECT_TRUE(delegate->tap()); | |
| 684 EXPECT_FALSE(delegate->tap_down()); | |
| 685 EXPECT_FALSE(delegate->tap_cancel()); | |
| 686 EXPECT_FALSE(delegate->begin()); | |
| 687 EXPECT_TRUE(delegate->end()); | |
| 688 EXPECT_FALSE(delegate->scroll_begin()); | |
| 689 EXPECT_FALSE(delegate->scroll_update()); | |
| 690 EXPECT_FALSE(delegate->scroll_end()); | |
| 691 | |
| 692 EXPECT_EQ(1, delegate->tap_count()); | |
| 693 } | |
| 694 | |
| 695 // Check that appropriate touch events generate tap gesture events | |
| 696 // when information about the touch radii are provided. | |
| 697 TEST_F(GestureRecognizerTest, GestureEventTapRegion) { | |
| 698 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 699 new GestureEventConsumeDelegate()); | |
| 700 TimedEvents tes; | |
| 701 const int kWindowWidth = 800; | |
| 702 const int kWindowHeight = 600; | |
| 703 const int kTouchId = 2; | |
| 704 gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); | |
| 705 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 706 delegate.get(), -1234, bounds, root_window())); | |
| 707 | |
| 708 // Test with no ET_TOUCH_MOVED events. | |
| 709 { | |
| 710 delegate->Reset(); | |
| 711 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 712 kTouchId, tes.Now()); | |
| 713 press.set_radius_x(5); | |
| 714 press.set_radius_y(12); | |
| 715 DispatchEventUsingWindowDispatcher(&press); | |
| 716 EXPECT_FALSE(delegate->tap()); | |
| 717 EXPECT_TRUE(delegate->tap_down()); | |
| 718 EXPECT_FALSE(delegate->tap_cancel()); | |
| 719 EXPECT_TRUE(delegate->begin()); | |
| 720 EXPECT_FALSE(delegate->scroll_begin()); | |
| 721 EXPECT_FALSE(delegate->scroll_update()); | |
| 722 EXPECT_FALSE(delegate->scroll_end()); | |
| 723 EXPECT_FALSE(delegate->long_press()); | |
| 724 | |
| 725 // Make sure there is enough delay before the touch is released so that it | |
| 726 // is recognized as a tap. | |
| 727 delegate->Reset(); | |
| 728 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 729 kTouchId, tes.LeapForward(50)); | |
| 730 release.set_radius_x(5); | |
| 731 release.set_radius_y(12); | |
| 732 | |
| 733 DispatchEventUsingWindowDispatcher(&release); | |
| 734 EXPECT_TRUE(delegate->tap()); | |
| 735 EXPECT_FALSE(delegate->tap_down()); | |
| 736 EXPECT_FALSE(delegate->tap_cancel()); | |
| 737 EXPECT_FALSE(delegate->begin()); | |
| 738 EXPECT_TRUE(delegate->end()); | |
| 739 EXPECT_FALSE(delegate->scroll_begin()); | |
| 740 EXPECT_FALSE(delegate->scroll_update()); | |
| 741 EXPECT_FALSE(delegate->scroll_end()); | |
| 742 | |
| 743 EXPECT_EQ(1, delegate->tap_count()); | |
| 744 gfx::Point actual_point(delegate->tap_location()); | |
| 745 EXPECT_EQ(24, delegate->bounding_box().width()); | |
| 746 EXPECT_EQ(24, delegate->bounding_box().height()); | |
| 747 EXPECT_EQ(101, actual_point.x()); | |
| 748 EXPECT_EQ(201, actual_point.y()); | |
| 749 } | |
| 750 | |
| 751 // Test with no ET_TOUCH_MOVED events but different touch points and radii. | |
| 752 { | |
| 753 delegate->Reset(); | |
| 754 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(365, 290), | |
| 755 kTouchId, tes.Now()); | |
| 756 press.set_radius_x(8); | |
| 757 press.set_radius_y(14); | |
| 758 DispatchEventUsingWindowDispatcher(&press); | |
| 759 EXPECT_FALSE(delegate->tap()); | |
| 760 EXPECT_TRUE(delegate->tap_down()); | |
| 761 EXPECT_FALSE(delegate->tap_cancel()); | |
| 762 EXPECT_TRUE(delegate->begin()); | |
| 763 EXPECT_FALSE(delegate->scroll_begin()); | |
| 764 EXPECT_FALSE(delegate->scroll_update()); | |
| 765 EXPECT_FALSE(delegate->scroll_end()); | |
| 766 EXPECT_FALSE(delegate->long_press()); | |
| 767 | |
| 768 delegate->Reset(); | |
| 769 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(367, 291), | |
| 770 kTouchId, tes.LeapForward(50)); | |
| 771 release.set_radius_x(20); | |
| 772 release.set_radius_y(13); | |
| 773 | |
| 774 DispatchEventUsingWindowDispatcher(&release); | |
| 775 EXPECT_TRUE(delegate->tap()); | |
| 776 EXPECT_FALSE(delegate->tap_down()); | |
| 777 EXPECT_FALSE(delegate->tap_cancel()); | |
| 778 EXPECT_FALSE(delegate->begin()); | |
| 779 EXPECT_TRUE(delegate->end()); | |
| 780 EXPECT_FALSE(delegate->scroll_begin()); | |
| 781 EXPECT_FALSE(delegate->scroll_update()); | |
| 782 EXPECT_FALSE(delegate->scroll_end()); | |
| 783 | |
| 784 EXPECT_EQ(1, delegate->tap_count()); | |
| 785 gfx::Point actual_point(delegate->tap_location()); | |
| 786 EXPECT_EQ(40, delegate->bounding_box().width()); | |
| 787 EXPECT_EQ(40, delegate->bounding_box().height()); | |
| 788 EXPECT_EQ(367, actual_point.x()); | |
| 789 EXPECT_EQ(291, actual_point.y()); | |
| 790 } | |
| 791 | |
| 792 // Test with a single ET_TOUCH_MOVED event. | |
| 793 { | |
| 794 delegate->Reset(); | |
| 795 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(46, 205), | |
| 796 kTouchId, tes.Now()); | |
| 797 press.set_radius_x(6); | |
| 798 press.set_radius_y(10); | |
| 799 DispatchEventUsingWindowDispatcher(&press); | |
| 800 EXPECT_FALSE(delegate->tap()); | |
| 801 EXPECT_TRUE(delegate->tap_down()); | |
| 802 EXPECT_FALSE(delegate->tap_cancel()); | |
| 803 EXPECT_TRUE(delegate->begin()); | |
| 804 EXPECT_FALSE(delegate->tap_cancel()); | |
| 805 EXPECT_FALSE(delegate->scroll_begin()); | |
| 806 EXPECT_FALSE(delegate->scroll_update()); | |
| 807 EXPECT_FALSE(delegate->scroll_end()); | |
| 808 EXPECT_FALSE(delegate->long_press()); | |
| 809 | |
| 810 delegate->Reset(); | |
| 811 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(49, 204), | |
| 812 kTouchId, tes.LeapForward(50)); | |
| 813 move.set_radius_x(8); | |
| 814 move.set_radius_y(12); | |
| 815 DispatchEventUsingWindowDispatcher(&move); | |
| 816 EXPECT_FALSE(delegate->tap()); | |
| 817 EXPECT_FALSE(delegate->tap_down()); | |
| 818 EXPECT_FALSE(delegate->tap_cancel()); | |
| 819 EXPECT_FALSE(delegate->begin()); | |
| 820 EXPECT_FALSE(delegate->scroll_begin()); | |
| 821 EXPECT_FALSE(delegate->scroll_update()); | |
| 822 EXPECT_FALSE(delegate->scroll_end()); | |
| 823 EXPECT_FALSE(delegate->long_press()); | |
| 824 | |
| 825 delegate->Reset(); | |
| 826 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(49, 204), | |
| 827 kTouchId, tes.LeapForward(50)); | |
| 828 release.set_radius_x(4); | |
| 829 release.set_radius_y(8); | |
| 830 | |
| 831 DispatchEventUsingWindowDispatcher(&release); | |
| 832 EXPECT_TRUE(delegate->tap()); | |
| 833 EXPECT_FALSE(delegate->tap_down()); | |
| 834 EXPECT_FALSE(delegate->tap_cancel()); | |
| 835 EXPECT_FALSE(delegate->begin()); | |
| 836 EXPECT_TRUE(delegate->end()); | |
| 837 EXPECT_FALSE(delegate->scroll_begin()); | |
| 838 EXPECT_FALSE(delegate->scroll_update()); | |
| 839 EXPECT_FALSE(delegate->scroll_end()); | |
| 840 | |
| 841 EXPECT_EQ(1, delegate->tap_count()); | |
| 842 gfx::Point actual_point(delegate->tap_location()); | |
| 843 EXPECT_EQ(16, delegate->bounding_box().width()); | |
| 844 EXPECT_EQ(16, delegate->bounding_box().height()); | |
| 845 EXPECT_EQ(49, actual_point.x()); | |
| 846 EXPECT_EQ(204, actual_point.y()); | |
| 847 } | |
| 848 | |
| 849 // Test with a few ET_TOUCH_MOVED events. | |
| 850 { | |
| 851 delegate->Reset(); | |
| 852 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(400, 150), | |
| 853 kTouchId, tes.Now()); | |
| 854 press.set_radius_x(7); | |
| 855 press.set_radius_y(10); | |
| 856 DispatchEventUsingWindowDispatcher(&press); | |
| 857 EXPECT_FALSE(delegate->tap()); | |
| 858 EXPECT_TRUE(delegate->tap_down()); | |
| 859 EXPECT_FALSE(delegate->tap_cancel()); | |
| 860 EXPECT_TRUE(delegate->begin()); | |
| 861 EXPECT_FALSE(delegate->scroll_begin()); | |
| 862 EXPECT_FALSE(delegate->scroll_update()); | |
| 863 EXPECT_FALSE(delegate->scroll_end()); | |
| 864 EXPECT_FALSE(delegate->long_press()); | |
| 865 | |
| 866 delegate->Reset(); | |
| 867 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(397, 151), | |
| 868 kTouchId, tes.LeapForward(50)); | |
| 869 move.set_radius_x(13); | |
| 870 move.set_radius_y(12); | |
| 871 DispatchEventUsingWindowDispatcher(&move); | |
| 872 EXPECT_FALSE(delegate->tap()); | |
| 873 EXPECT_FALSE(delegate->tap_down()); | |
| 874 EXPECT_FALSE(delegate->tap_cancel()); | |
| 875 EXPECT_FALSE(delegate->begin()); | |
| 876 EXPECT_FALSE(delegate->scroll_begin()); | |
| 877 EXPECT_FALSE(delegate->scroll_update()); | |
| 878 EXPECT_FALSE(delegate->scroll_end()); | |
| 879 EXPECT_FALSE(delegate->long_press()); | |
| 880 | |
| 881 delegate->Reset(); | |
| 882 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(397, 149), | |
| 883 kTouchId, tes.LeapForward(50)); | |
| 884 move1.set_radius_x(16); | |
| 885 move1.set_radius_y(16); | |
| 886 DispatchEventUsingWindowDispatcher(&move1); | |
| 887 EXPECT_FALSE(delegate->tap()); | |
| 888 EXPECT_FALSE(delegate->tap_down()); | |
| 889 EXPECT_FALSE(delegate->tap_cancel()); | |
| 890 EXPECT_FALSE(delegate->begin()); | |
| 891 EXPECT_FALSE(delegate->scroll_begin()); | |
| 892 EXPECT_FALSE(delegate->scroll_update()); | |
| 893 EXPECT_FALSE(delegate->scroll_end()); | |
| 894 EXPECT_FALSE(delegate->long_press()); | |
| 895 | |
| 896 delegate->Reset(); | |
| 897 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(400, 150), | |
| 898 kTouchId, tes.LeapForward(50)); | |
| 899 move2.set_radius_x(14); | |
| 900 move2.set_radius_y(10); | |
| 901 DispatchEventUsingWindowDispatcher(&move2); | |
| 902 EXPECT_FALSE(delegate->tap()); | |
| 903 EXPECT_FALSE(delegate->tap_down()); | |
| 904 EXPECT_FALSE(delegate->tap_cancel()); | |
| 905 EXPECT_FALSE(delegate->begin()); | |
| 906 EXPECT_FALSE(delegate->scroll_begin()); | |
| 907 EXPECT_FALSE(delegate->scroll_update()); | |
| 908 EXPECT_FALSE(delegate->scroll_end()); | |
| 909 EXPECT_FALSE(delegate->long_press()); | |
| 910 | |
| 911 delegate->Reset(); | |
| 912 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(401, 149), | |
| 913 kTouchId, tes.LeapForward(50)); | |
| 914 release.set_radius_x(8); | |
| 915 release.set_radius_y(9); | |
| 916 | |
| 917 DispatchEventUsingWindowDispatcher(&release); | |
| 918 EXPECT_TRUE(delegate->tap()); | |
| 919 EXPECT_FALSE(delegate->tap_down()); | |
| 920 EXPECT_FALSE(delegate->tap_cancel()); | |
| 921 EXPECT_FALSE(delegate->begin()); | |
| 922 EXPECT_TRUE(delegate->end()); | |
| 923 EXPECT_FALSE(delegate->scroll_begin()); | |
| 924 EXPECT_FALSE(delegate->scroll_update()); | |
| 925 EXPECT_FALSE(delegate->scroll_end()); | |
| 926 | |
| 927 EXPECT_EQ(1, delegate->tap_count()); | |
| 928 gfx::Point actual_point(delegate->tap_location()); | |
| 929 EXPECT_EQ(18, delegate->bounding_box().width()); | |
| 930 EXPECT_EQ(18, delegate->bounding_box().height()); | |
| 931 EXPECT_EQ(401, actual_point.x()); | |
| 932 EXPECT_EQ(149, actual_point.y()); | |
| 933 } | |
| 934 } | |
| 935 | |
| 936 // Check that appropriate touch events generate scroll gesture events. | |
| 937 TEST_F(GestureRecognizerTest, GestureEventScroll) { | |
| 938 // We'll start by moving the touch point by (10.5, 10.5). We want 5 dips of | |
| 939 // that distance to be consumed by the slop, so we set the slop radius to | |
| 940 // sqrt(5 * 5 + 5 * 5). | |
| 941 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click( | |
| 942 sqrt(5.f * 5 + 5 * 5)); | |
| 943 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 944 new GestureEventConsumeDelegate()); | |
| 945 TimedEvents tes; | |
| 946 const int kWindowWidth = 123; | |
| 947 const int kWindowHeight = 45; | |
| 948 const int kTouchId = 5; | |
| 949 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 950 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 951 delegate.get(), -1234, bounds, root_window())); | |
| 952 | |
| 953 delegate->Reset(); | |
| 954 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 955 kTouchId, tes.Now()); | |
| 956 DispatchEventUsingWindowDispatcher(&press); | |
| 957 EXPECT_2_EVENTS(delegate->events(), | |
| 958 ui::ET_GESTURE_BEGIN, | |
| 959 ui::ET_GESTURE_TAP_DOWN); | |
| 960 | |
| 961 // Move the touch-point enough so that it is considered as a scroll. This | |
| 962 // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. | |
| 963 // The first movement is diagonal, to ensure that we have a free scroll, | |
| 964 // and not a rail scroll. | |
| 965 tes.SendScrollEvent(event_processor(), 111.5, 211.5, kTouchId, | |
| 966 delegate.get()); | |
| 967 EXPECT_3_EVENTS(delegate->events(), | |
| 968 ui::ET_GESTURE_TAP_CANCEL, | |
| 969 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 970 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 971 // The slop consumed 5 dips | |
| 972 EXPECT_FLOAT_EQ(5.5, delegate->scroll_x()); | |
| 973 EXPECT_FLOAT_EQ(5.5, delegate->scroll_y()); | |
| 974 EXPECT_EQ(gfx::Point(1, 1).ToString(), | |
| 975 delegate->scroll_begin_position().ToString()); | |
| 976 | |
| 977 // When scrolling with a single finger, the bounding box of the gesture should | |
| 978 // be empty, since it's a single point and the radius for testing is zero. | |
| 979 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 980 | |
| 981 // Move some more to generate a few more scroll updates. Make sure that we get | |
| 982 // out of the snap channel for the unified GR. | |
| 983 tes.SendScrollEvent(event_processor(), 20, 120, kTouchId, delegate.get()); | |
| 984 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 985 EXPECT_FLOAT_EQ(-91.5, delegate->scroll_x()); | |
| 986 EXPECT_FLOAT_EQ(-91.5, delegate->scroll_y()); | |
| 987 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 988 | |
| 989 tes.SendScrollEvent(event_processor(), 50, 124, kTouchId, delegate.get()); | |
| 990 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 991 EXPECT_EQ(30, delegate->scroll_x()); | |
| 992 EXPECT_EQ(4, delegate->scroll_y()); | |
| 993 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 994 | |
| 995 // Release the touch. This should end the scroll. | |
| 996 delegate->Reset(); | |
| 997 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 998 kTouchId, | |
| 999 tes.LeapForward(50)); | |
| 1000 DispatchEventUsingWindowDispatcher(&release); | |
| 1001 EXPECT_2_EVENTS(delegate->events(), | |
| 1002 ui::ET_SCROLL_FLING_START, | |
| 1003 ui::ET_GESTURE_END); | |
| 1004 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 1005 } | |
| 1006 | |
| 1007 // Check that predicted scroll update positions are correct. | |
| 1008 TEST_F(GestureRecognizerTest, GestureEventScrollPrediction) { | |
| 1009 // We'll start by moving the touch point by (5, 5). We want all of that | |
| 1010 // distance to be consumed by the slop, so we set the slop radius to | |
| 1011 // sqrt(5 * 5 + 5 * 5). | |
| 1012 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click( | |
| 1013 sqrt(5.f * 5 + 5 * 5)); | |
| 1014 | |
| 1015 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1016 new GestureEventConsumeDelegate()); | |
| 1017 TimedEvents tes; | |
| 1018 const int kWindowWidth = 123; | |
| 1019 const int kWindowHeight = 45; | |
| 1020 const int kTouchId = 5; | |
| 1021 gfx::Rect bounds(95, 195, kWindowWidth, kWindowHeight); | |
| 1022 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1023 delegate.get(), -1234, bounds, root_window())); | |
| 1024 | |
| 1025 delegate->Reset(); | |
| 1026 // Tracks the total scroll since we want to verify that the correct position | |
| 1027 // will be scrolled to throughout the prediction. | |
| 1028 gfx::Vector2dF total_scroll; | |
| 1029 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(96, 196), | |
| 1030 kTouchId, tes.Now()); | |
| 1031 DispatchEventUsingWindowDispatcher(&press); | |
| 1032 EXPECT_2_EVENTS(delegate->events(), | |
| 1033 ui::ET_GESTURE_BEGIN, | |
| 1034 ui::ET_GESTURE_TAP_DOWN); | |
| 1035 delegate->Reset(); | |
| 1036 | |
| 1037 // Get rid of touch slop. | |
| 1038 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(111, 211), | |
| 1039 kTouchId, tes.Now()); | |
| 1040 DispatchEventUsingWindowDispatcher(&move); | |
| 1041 EXPECT_3_EVENTS(delegate->events(), | |
| 1042 ui::ET_GESTURE_TAP_CANCEL, | |
| 1043 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 1044 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 1045 total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); | |
| 1046 total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); | |
| 1047 | |
| 1048 // Move the touch-point enough so that it is considered as a scroll. This | |
| 1049 // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. | |
| 1050 // The first movement is diagonal, to ensure that we have a free scroll, | |
| 1051 // and not a rail scroll. | |
| 1052 tes.LeapForward(30); | |
| 1053 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); | |
| 1054 EXPECT_1_EVENT(delegate->events(), | |
| 1055 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 1056 total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); | |
| 1057 total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); | |
| 1058 | |
| 1059 // Move some more to generate a few more scroll updates. | |
| 1060 tes.LeapForward(30); | |
| 1061 tes.SendScrollEvent(event_processor(), 110, 211, kTouchId, delegate.get()); | |
| 1062 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 1063 total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); | |
| 1064 total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); | |
| 1065 | |
| 1066 tes.LeapForward(30); | |
| 1067 tes.SendScrollEvent(event_processor(), 140, 215, kTouchId, delegate.get()); | |
| 1068 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 1069 total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); | |
| 1070 total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); | |
| 1071 | |
| 1072 // Release the touch. This should end the scroll. | |
| 1073 delegate->Reset(); | |
| 1074 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1075 kTouchId, | |
| 1076 tes.LeapForward(50)); | |
| 1077 DispatchEventUsingWindowDispatcher(&release); | |
| 1078 } | |
| 1079 | |
| 1080 // Check that the bounding box during a scroll event is correct. | |
| 1081 TEST_F(GestureRecognizerTest, GestureEventScrollBoundingBox) { | |
| 1082 TimedEvents tes; | |
| 1083 for (float radius = 1; radius <= 10; ++radius) { | |
| 1084 ui::GestureConfiguration::set_default_radius(radius); | |
| 1085 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1086 new GestureEventConsumeDelegate()); | |
| 1087 const int kWindowWidth = 123; | |
| 1088 const int kWindowHeight = 45; | |
| 1089 const int kTouchId = 5; | |
| 1090 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 1091 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1092 delegate.get(), -1234, bounds, root_window())); | |
| 1093 | |
| 1094 const float kPositionX = 101; | |
| 1095 const float kPositionY = 201; | |
| 1096 delegate->Reset(); | |
| 1097 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, | |
| 1098 gfx::PointF(kPositionX, kPositionY), | |
| 1099 kTouchId, | |
| 1100 tes.Now()); | |
| 1101 DispatchEventUsingWindowDispatcher(&press); | |
| 1102 EXPECT_EQ(gfx::RectF(kPositionX - radius, | |
| 1103 kPositionY - radius, | |
| 1104 radius * 2, | |
| 1105 radius * 2), | |
| 1106 delegate->bounding_box()); | |
| 1107 | |
| 1108 const int kScrollAmount = 50; | |
| 1109 tes.SendScrollEvents(event_processor(), kPositionX, kPositionY, | |
| 1110 1, 1, kTouchId, 1, kScrollAmount, delegate.get()); | |
| 1111 EXPECT_EQ(gfx::Point(1, 1).ToString(), | |
| 1112 delegate->scroll_begin_position().ToString()); | |
| 1113 EXPECT_EQ(gfx::RectF(kPositionX + kScrollAmount - radius, | |
| 1114 kPositionY + kScrollAmount - radius, | |
| 1115 radius * 2, | |
| 1116 radius * 2), | |
| 1117 delegate->bounding_box()); | |
| 1118 | |
| 1119 // Release the touch. This should end the scroll. | |
| 1120 delegate->Reset(); | |
| 1121 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, | |
| 1122 gfx::PointF(kPositionX + kScrollAmount, | |
| 1123 kPositionY + kScrollAmount), | |
| 1124 kTouchId, press.time_stamp() + | |
| 1125 base::TimeDelta::FromMilliseconds(50)); | |
| 1126 DispatchEventUsingWindowDispatcher(&release); | |
| 1127 EXPECT_EQ(gfx::RectF(kPositionX + kScrollAmount - radius, | |
| 1128 kPositionY + kScrollAmount - radius, | |
| 1129 radius * 2, | |
| 1130 radius * 2), | |
| 1131 delegate->bounding_box()); | |
| 1132 } | |
| 1133 ui::GestureConfiguration::set_default_radius(0); | |
| 1134 } | |
| 1135 | |
| 1136 // Check Scroll End Events report correct velocities | |
| 1137 // if the user was on a horizontal rail | |
| 1138 TEST_F(GestureRecognizerTest, GestureEventHorizontalRailFling) { | |
| 1139 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1140 new GestureEventConsumeDelegate()); | |
| 1141 TimedEvents tes; | |
| 1142 const int kTouchId = 7; | |
| 1143 gfx::Rect bounds(0, 0, 1000, 1000); | |
| 1144 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1145 delegate.get(), -1234, bounds, root_window())); | |
| 1146 | |
| 1147 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 1148 kTouchId, tes.Now()); | |
| 1149 DispatchEventUsingWindowDispatcher(&press); | |
| 1150 | |
| 1151 // Get rid of touch slop. | |
| 1152 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 0), | |
| 1153 kTouchId, tes.Now()); | |
| 1154 DispatchEventUsingWindowDispatcher(&move); | |
| 1155 delegate->Reset(); | |
| 1156 | |
| 1157 | |
| 1158 // Move the touch-point horizontally enough that it is considered a | |
| 1159 // horizontal scroll. | |
| 1160 tes.SendScrollEvent(event_processor(), 30, 1, kTouchId, delegate.get()); | |
| 1161 EXPECT_FLOAT_EQ(0, delegate->scroll_y()); | |
| 1162 EXPECT_FLOAT_EQ(20, delegate->scroll_x()); | |
| 1163 | |
| 1164 // Get a high x velocity, while still staying on the rail | |
| 1165 const int kScrollAmount = 8; | |
| 1166 tes.SendScrollEvents(event_processor(), | |
| 1167 1, | |
| 1168 1, | |
| 1169 100, | |
| 1170 10, | |
| 1171 kTouchId, | |
| 1172 1, | |
| 1173 kScrollAmount, | |
| 1174 delegate.get()); | |
| 1175 | |
| 1176 delegate->Reset(); | |
| 1177 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1178 kTouchId, tes.Now()); | |
| 1179 DispatchEventUsingWindowDispatcher(&release); | |
| 1180 | |
| 1181 EXPECT_TRUE(delegate->fling()); | |
| 1182 EXPECT_FALSE(delegate->scroll_end()); | |
| 1183 EXPECT_GT(delegate->velocity_x(), 0); | |
| 1184 EXPECT_EQ(0, delegate->velocity_y()); | |
| 1185 } | |
| 1186 | |
| 1187 // Check Scroll End Events report correct velocities | |
| 1188 // if the user was on a vertical rail | |
| 1189 TEST_F(GestureRecognizerTest, GestureEventVerticalRailFling) { | |
| 1190 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1191 new GestureEventConsumeDelegate()); | |
| 1192 TimedEvents tes; | |
| 1193 const int kTouchId = 7; | |
| 1194 gfx::Rect bounds(0, 0, 1000, 1000); | |
| 1195 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1196 delegate.get(), -1234, bounds, root_window())); | |
| 1197 | |
| 1198 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 1199 kTouchId, tes.Now()); | |
| 1200 DispatchEventUsingWindowDispatcher(&press); | |
| 1201 | |
| 1202 // Get rid of touch slop. | |
| 1203 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(0, 10), | |
| 1204 kTouchId, tes.Now()); | |
| 1205 DispatchEventUsingWindowDispatcher(&move); | |
| 1206 delegate->Reset(); | |
| 1207 | |
| 1208 // Move the touch-point vertically enough that it is considered a | |
| 1209 // vertical scroll. | |
| 1210 tes.SendScrollEvent(event_processor(), 1, 30, kTouchId, delegate.get()); | |
| 1211 EXPECT_EQ(20, delegate->scroll_y()); | |
| 1212 EXPECT_EQ(0, delegate->scroll_x()); | |
| 1213 EXPECT_EQ(0, delegate->scroll_velocity_x()); | |
| 1214 | |
| 1215 // Get a high y velocity, while still staying on the rail | |
| 1216 const int kScrollAmount = 8; | |
| 1217 tes.SendScrollEvents(event_processor(), | |
| 1218 1, | |
| 1219 6, | |
| 1220 10, | |
| 1221 100, | |
| 1222 kTouchId, | |
| 1223 1, | |
| 1224 kScrollAmount, | |
| 1225 delegate.get()); | |
| 1226 EXPECT_EQ(0, delegate->scroll_velocity_x()); | |
| 1227 | |
| 1228 delegate->Reset(); | |
| 1229 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 206), | |
| 1230 kTouchId, tes.Now()); | |
| 1231 DispatchEventUsingWindowDispatcher(&release); | |
| 1232 | |
| 1233 EXPECT_TRUE(delegate->fling()); | |
| 1234 EXPECT_FALSE(delegate->scroll_end()); | |
| 1235 EXPECT_EQ(0, delegate->velocity_x()); | |
| 1236 EXPECT_GT(delegate->velocity_y(), 0); | |
| 1237 } | |
| 1238 | |
| 1239 // Check Scroll End Events report non-zero velocities if the user is not on a | |
| 1240 // rail | |
| 1241 TEST_F(GestureRecognizerTest, GestureEventNonRailFling) { | |
| 1242 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0); | |
| 1243 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1244 new GestureEventConsumeDelegate()); | |
| 1245 TimedEvents tes; | |
| 1246 const int kTouchId = 7; | |
| 1247 gfx::Rect bounds(0, 0, 1000, 1000); | |
| 1248 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1249 delegate.get(), -1234, bounds, root_window())); | |
| 1250 | |
| 1251 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 1252 kTouchId, tes.Now()); | |
| 1253 DispatchEventUsingWindowDispatcher(&press); | |
| 1254 | |
| 1255 // Move the touch-point such that a non-rail scroll begins, and we're outside | |
| 1256 // the snap channel for the unified GR. | |
| 1257 tes.SendScrollEvent(event_processor(), 50, 50, kTouchId, delegate.get()); | |
| 1258 EXPECT_EQ(50, delegate->scroll_y()); | |
| 1259 EXPECT_EQ(50, delegate->scroll_x()); | |
| 1260 | |
| 1261 const int kScrollAmount = 8; | |
| 1262 tes.SendScrollEvents(event_processor(), | |
| 1263 1, | |
| 1264 1, | |
| 1265 10, | |
| 1266 100, | |
| 1267 kTouchId, | |
| 1268 1, | |
| 1269 kScrollAmount, | |
| 1270 delegate.get()); | |
| 1271 | |
| 1272 delegate->Reset(); | |
| 1273 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1274 kTouchId, tes.Now()); | |
| 1275 DispatchEventUsingWindowDispatcher(&release); | |
| 1276 | |
| 1277 EXPECT_TRUE(delegate->fling()); | |
| 1278 EXPECT_FALSE(delegate->scroll_end()); | |
| 1279 EXPECT_GT(delegate->velocity_x(), 0); | |
| 1280 EXPECT_GT(delegate->velocity_y(), 0); | |
| 1281 } | |
| 1282 | |
| 1283 // Check that appropriate touch events generate long press events | |
| 1284 TEST_F(GestureRecognizerTest, GestureEventLongPress) { | |
| 1285 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1286 new GestureEventConsumeDelegate()); | |
| 1287 const int kWindowWidth = 123; | |
| 1288 const int kWindowHeight = 45; | |
| 1289 const int kTouchId = 2; | |
| 1290 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 1291 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1292 delegate.get(), -1234, bounds, root_window())); | |
| 1293 | |
| 1294 delegate->Reset(); | |
| 1295 | |
| 1296 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, | |
| 1297 gfx::Point(101, 201), | |
| 1298 kTouchId, | |
| 1299 ui::EventTimeForNow()); | |
| 1300 DispatchEventUsingWindowDispatcher(&press1); | |
| 1301 EXPECT_TRUE(delegate->tap_down()); | |
| 1302 EXPECT_TRUE(delegate->begin()); | |
| 1303 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1304 | |
| 1305 // We haven't pressed long enough for a long press to occur | |
| 1306 EXPECT_FALSE(delegate->long_press()); | |
| 1307 | |
| 1308 // Wait until the timer runs out | |
| 1309 delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); | |
| 1310 EXPECT_TRUE(delegate->long_press()); | |
| 1311 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1312 | |
| 1313 delegate->Reset(); | |
| 1314 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, | |
| 1315 gfx::Point(101, 201), | |
| 1316 kTouchId, | |
| 1317 ui::EventTimeForNow()); | |
| 1318 DispatchEventUsingWindowDispatcher(&release1); | |
| 1319 EXPECT_FALSE(delegate->long_press()); | |
| 1320 | |
| 1321 // Note the tap cancel isn't dispatched until the release | |
| 1322 EXPECT_TRUE(delegate->tap_cancel()); | |
| 1323 EXPECT_FALSE(delegate->tap()); | |
| 1324 } | |
| 1325 | |
| 1326 // Check that scrolling prevents a long press. | |
| 1327 TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { | |
| 1328 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1329 new GestureEventConsumeDelegate()); | |
| 1330 TimedEvents tes; | |
| 1331 const int kWindowWidth = 123; | |
| 1332 const int kWindowHeight = 45; | |
| 1333 const int kTouchId = 6; | |
| 1334 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 1335 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1336 delegate.get(), -1234, bounds, root_window())); | |
| 1337 | |
| 1338 delegate->Reset(); | |
| 1339 | |
| 1340 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 1341 kTouchId, tes.Now()); | |
| 1342 DispatchEventUsingWindowDispatcher(&press1); | |
| 1343 EXPECT_TRUE(delegate->tap_down()); | |
| 1344 | |
| 1345 // We haven't pressed long enough for a long press to occur | |
| 1346 EXPECT_FALSE(delegate->long_press()); | |
| 1347 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1348 | |
| 1349 // Scroll around, to cancel the long press | |
| 1350 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); | |
| 1351 | |
| 1352 // Wait until a long press event would have fired, if it hadn't been | |
| 1353 // cancelled. | |
| 1354 DelayByLongPressTimeout(); | |
| 1355 | |
| 1356 EXPECT_FALSE(delegate->long_press()); | |
| 1357 EXPECT_TRUE(delegate->tap_cancel()); | |
| 1358 | |
| 1359 delegate->Reset(); | |
| 1360 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1361 kTouchId, tes.LeapForward(10)); | |
| 1362 DispatchEventUsingWindowDispatcher(&release1); | |
| 1363 EXPECT_FALSE(delegate->long_press()); | |
| 1364 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1365 } | |
| 1366 | |
| 1367 // Check that appropriate touch events generate long tap events | |
| 1368 TEST_F(GestureRecognizerTest, GestureEventLongTap) { | |
| 1369 ui::GestureConfiguration::set_max_touch_down_duration_for_click_in_ms(3); | |
| 1370 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1371 new GestureEventConsumeDelegate()); | |
| 1372 const int kWindowWidth = 123; | |
| 1373 const int kWindowHeight = 45; | |
| 1374 const int kTouchId = 2; | |
| 1375 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 1376 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1377 delegate.get(), -1234, bounds, root_window())); | |
| 1378 | |
| 1379 delegate->Reset(); | |
| 1380 | |
| 1381 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, | |
| 1382 gfx::Point(101, 201), | |
| 1383 kTouchId, | |
| 1384 ui::EventTimeForNow()); | |
| 1385 DispatchEventUsingWindowDispatcher(&press1); | |
| 1386 EXPECT_TRUE(delegate->tap_down()); | |
| 1387 EXPECT_TRUE(delegate->begin()); | |
| 1388 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1389 | |
| 1390 // We haven't pressed long enough for a long press to occur | |
| 1391 EXPECT_FALSE(delegate->long_press()); | |
| 1392 | |
| 1393 // Wait until the timer runs out | |
| 1394 delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); | |
| 1395 EXPECT_TRUE(delegate->long_press()); | |
| 1396 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1397 | |
| 1398 delegate->Reset(); | |
| 1399 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, | |
| 1400 gfx::Point(101, 201), | |
| 1401 kTouchId, | |
| 1402 ui::EventTimeForNow()); | |
| 1403 DispatchEventUsingWindowDispatcher(&release1); | |
| 1404 EXPECT_FALSE(delegate->long_press()); | |
| 1405 EXPECT_TRUE(delegate->long_tap()); | |
| 1406 | |
| 1407 // Note the tap cancel isn't dispatched until the release | |
| 1408 EXPECT_TRUE(delegate->tap_cancel()); | |
| 1409 EXPECT_FALSE(delegate->tap()); | |
| 1410 } | |
| 1411 | |
| 1412 // Check that second tap cancels a long press | |
| 1413 TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) { | |
| 1414 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1415 new GestureEventConsumeDelegate()); | |
| 1416 TimedEvents tes; | |
| 1417 const int kWindowWidth = 300; | |
| 1418 const int kWindowHeight = 400; | |
| 1419 const int kTouchId1 = 8; | |
| 1420 const int kTouchId2 = 2; | |
| 1421 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | |
| 1422 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1423 delegate.get(), -1234, bounds, root_window())); | |
| 1424 | |
| 1425 delegate->Reset(); | |
| 1426 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 1427 kTouchId1, tes.Now()); | |
| 1428 DispatchEventUsingWindowDispatcher(&press); | |
| 1429 EXPECT_TRUE(delegate->tap_down()); | |
| 1430 EXPECT_TRUE(delegate->begin()); | |
| 1431 | |
| 1432 // We haven't pressed long enough for a long press to occur | |
| 1433 EXPECT_FALSE(delegate->long_press()); | |
| 1434 | |
| 1435 // Second tap, to cancel the long press | |
| 1436 delegate->Reset(); | |
| 1437 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 1438 kTouchId2, tes.Now()); | |
| 1439 DispatchEventUsingWindowDispatcher(&press2); | |
| 1440 EXPECT_FALSE(delegate->tap_down()); // no touch down for second tap. | |
| 1441 EXPECT_TRUE(delegate->tap_cancel()); | |
| 1442 EXPECT_TRUE(delegate->begin()); | |
| 1443 | |
| 1444 // Wait until the timer runs out | |
| 1445 DelayByLongPressTimeout(); | |
| 1446 | |
| 1447 // No long press occurred | |
| 1448 EXPECT_FALSE(delegate->long_press()); | |
| 1449 | |
| 1450 delegate->Reset(); | |
| 1451 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1452 kTouchId1, tes.Now()); | |
| 1453 DispatchEventUsingWindowDispatcher(&release1); | |
| 1454 EXPECT_FALSE(delegate->long_press()); | |
| 1455 EXPECT_TRUE(delegate->two_finger_tap()); | |
| 1456 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1457 } | |
| 1458 | |
| 1459 // Check that horizontal scroll gestures cause scrolls on horizontal rails. | |
| 1460 // Also tests that horizontal rails can be broken. | |
| 1461 TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { | |
| 1462 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1463 new GestureEventConsumeDelegate()); | |
| 1464 TimedEvents tes; | |
| 1465 const int kTouchId = 7; | |
| 1466 gfx::Rect bounds(0, 0, 1000, 1000); | |
| 1467 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1468 delegate.get(), -1234, bounds, root_window())); | |
| 1469 | |
| 1470 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 1471 kTouchId, tes.Now()); | |
| 1472 DispatchEventUsingWindowDispatcher(&press); | |
| 1473 | |
| 1474 // Get rid of touch slop. | |
| 1475 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(5, 0), | |
| 1476 kTouchId, tes.Now()); | |
| 1477 | |
| 1478 DispatchEventUsingWindowDispatcher(&move); | |
| 1479 delegate->Reset(); | |
| 1480 | |
| 1481 // Move the touch-point horizontally enough that it is considered a | |
| 1482 // horizontal scroll. | |
| 1483 tes.SendScrollEvent(event_processor(), 25, 0, kTouchId, delegate.get()); | |
| 1484 EXPECT_EQ(0, delegate->scroll_y()); | |
| 1485 EXPECT_EQ(20, delegate->scroll_x()); | |
| 1486 | |
| 1487 tes.SendScrollEvent(event_processor(), 30, 6, kTouchId, delegate.get()); | |
| 1488 EXPECT_TRUE(delegate->scroll_update()); | |
| 1489 EXPECT_EQ(5, delegate->scroll_x()); | |
| 1490 // y shouldn't change, as we're on a horizontal rail. | |
| 1491 EXPECT_EQ(0, delegate->scroll_y()); | |
| 1492 | |
| 1493 // Send enough information that a velocity can be calculated for the gesture, | |
| 1494 // and we can break the rail | |
| 1495 const int kScrollAmount = 8; | |
| 1496 tes.SendScrollEvents(event_processor(), | |
| 1497 1, | |
| 1498 1, | |
| 1499 6, | |
| 1500 100, | |
| 1501 kTouchId, | |
| 1502 1, | |
| 1503 kScrollAmount, | |
| 1504 delegate.get()); | |
| 1505 | |
| 1506 tes.SendScrollEvent(event_processor(), 5, 0, kTouchId, delegate.get()); | |
| 1507 tes.SendScrollEvent(event_processor(), 10, 5, kTouchId, delegate.get()); | |
| 1508 | |
| 1509 // The rail should be broken | |
| 1510 EXPECT_TRUE(delegate->scroll_update()); | |
| 1511 EXPECT_EQ(5, delegate->scroll_x()); | |
| 1512 EXPECT_EQ(5, delegate->scroll_y()); | |
| 1513 } | |
| 1514 | |
| 1515 // Check that vertical scroll gestures cause scrolls on vertical rails. | |
| 1516 // Also tests that vertical rails can be broken. | |
| 1517 TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) { | |
| 1518 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1519 new GestureEventConsumeDelegate()); | |
| 1520 TimedEvents tes; | |
| 1521 const int kTouchId = 7; | |
| 1522 gfx::Rect bounds(0, 0, 1000, 1000); | |
| 1523 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1524 delegate.get(), -1234, bounds, root_window())); | |
| 1525 | |
| 1526 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 1527 kTouchId, tes.Now()); | |
| 1528 DispatchEventUsingWindowDispatcher(&press); | |
| 1529 | |
| 1530 // Get rid of touch slop. | |
| 1531 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(0, 5), | |
| 1532 kTouchId, tes.Now()); | |
| 1533 DispatchEventUsingWindowDispatcher(&move); | |
| 1534 delegate->Reset(); | |
| 1535 | |
| 1536 // Move the touch-point vertically enough that it is considered a | |
| 1537 // vertical scroll. | |
| 1538 tes.SendScrollEvent(event_processor(), 0, 25, kTouchId, delegate.get()); | |
| 1539 EXPECT_EQ(0, delegate->scroll_x()); | |
| 1540 EXPECT_EQ(20, delegate->scroll_y()); | |
| 1541 | |
| 1542 tes.SendScrollEvent(event_processor(), 6, 30, kTouchId, delegate.get()); | |
| 1543 EXPECT_TRUE(delegate->scroll_update()); | |
| 1544 EXPECT_EQ(5, delegate->scroll_y()); | |
| 1545 // x shouldn't change, as we're on a vertical rail. | |
| 1546 EXPECT_EQ(0, delegate->scroll_x()); | |
| 1547 EXPECT_EQ(0, delegate->scroll_velocity_x()); | |
| 1548 | |
| 1549 // Send enough information that a velocity can be calculated for the gesture, | |
| 1550 // and we can break the rail | |
| 1551 const int kScrollAmount = 8; | |
| 1552 tes.SendScrollEvents(event_processor(), | |
| 1553 1, | |
| 1554 6, | |
| 1555 100, | |
| 1556 1, | |
| 1557 kTouchId, | |
| 1558 1, | |
| 1559 kScrollAmount, | |
| 1560 delegate.get()); | |
| 1561 | |
| 1562 tes.SendScrollEvent(event_processor(), 0, 5, kTouchId, delegate.get()); | |
| 1563 tes.SendScrollEvent(event_processor(), 5, 10, kTouchId, delegate.get()); | |
| 1564 | |
| 1565 // The rail should be broken | |
| 1566 EXPECT_TRUE(delegate->scroll_update()); | |
| 1567 EXPECT_EQ(5, delegate->scroll_x()); | |
| 1568 EXPECT_EQ(5, delegate->scroll_y()); | |
| 1569 } | |
| 1570 | |
| 1571 TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { | |
| 1572 // We'll start by moving the touch point by (5, 5). We want all of that | |
| 1573 // distance to be consumed by the slop, so we set the slop radius to | |
| 1574 // sqrt(5 * 5 + 5 * 5). | |
| 1575 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click( | |
| 1576 sqrt(5.f * 5 + 5 * 5)); | |
| 1577 | |
| 1578 // First, tap. Then, do a scroll using the same touch-id. | |
| 1579 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1580 new GestureEventConsumeDelegate()); | |
| 1581 TimedEvents tes; | |
| 1582 const int kWindowWidth = 123; | |
| 1583 const int kWindowHeight = 45; | |
| 1584 const int kTouchId = 3; | |
| 1585 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 1586 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1587 delegate.get(), -1234, bounds, root_window())); | |
| 1588 | |
| 1589 delegate->Reset(); | |
| 1590 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 1591 kTouchId, tes.Now()); | |
| 1592 DispatchEventUsingWindowDispatcher(&press); | |
| 1593 EXPECT_FALSE(delegate->tap()); | |
| 1594 EXPECT_TRUE(delegate->tap_down()); | |
| 1595 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1596 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1597 EXPECT_FALSE(delegate->scroll_update()); | |
| 1598 EXPECT_FALSE(delegate->scroll_end()); | |
| 1599 | |
| 1600 // Make sure there is enough delay before the touch is released so that it is | |
| 1601 // recognized as a tap. | |
| 1602 delegate->Reset(); | |
| 1603 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1604 kTouchId, tes.LeapForward(50)); | |
| 1605 DispatchEventUsingWindowDispatcher(&release); | |
| 1606 EXPECT_TRUE(delegate->tap()); | |
| 1607 EXPECT_FALSE(delegate->tap_down()); | |
| 1608 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1609 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1610 EXPECT_FALSE(delegate->scroll_update()); | |
| 1611 EXPECT_FALSE(delegate->scroll_end()); | |
| 1612 | |
| 1613 // Now, do a scroll gesture. Delay it sufficiently so that it doesn't trigger | |
| 1614 // a double-tap. | |
| 1615 delegate->Reset(); | |
| 1616 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 1617 kTouchId, tes.LeapForward(1000)); | |
| 1618 DispatchEventUsingWindowDispatcher(&press1); | |
| 1619 EXPECT_FALSE(delegate->tap()); | |
| 1620 EXPECT_TRUE(delegate->tap_down()); | |
| 1621 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1622 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1623 EXPECT_FALSE(delegate->scroll_update()); | |
| 1624 EXPECT_FALSE(delegate->scroll_end()); | |
| 1625 | |
| 1626 // Get rid of touch slop. | |
| 1627 ui::TouchEvent move_remove_slop(ui::ET_TOUCH_MOVED, gfx::Point(116, 216), | |
| 1628 kTouchId, tes.Now()); | |
| 1629 DispatchEventUsingWindowDispatcher(&move_remove_slop); | |
| 1630 EXPECT_TRUE(delegate->tap_cancel()); | |
| 1631 EXPECT_TRUE(delegate->scroll_begin()); | |
| 1632 EXPECT_TRUE(delegate->scroll_update()); | |
| 1633 EXPECT_EQ(15, delegate->scroll_x_hint()); | |
| 1634 EXPECT_EQ(15, delegate->scroll_y_hint()); | |
| 1635 | |
| 1636 delegate->Reset(); | |
| 1637 | |
| 1638 // Move the touch-point enough so that it is considered as a scroll. This | |
| 1639 // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. | |
| 1640 // The first movement is diagonal, to ensure that we have a free scroll, | |
| 1641 // and not a rail scroll. | |
| 1642 delegate->Reset(); | |
| 1643 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(135, 235), | |
| 1644 kTouchId, tes.Now()); | |
| 1645 DispatchEventUsingWindowDispatcher(&move); | |
| 1646 EXPECT_FALSE(delegate->tap()); | |
| 1647 EXPECT_FALSE(delegate->tap_down()); | |
| 1648 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1649 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1650 EXPECT_TRUE(delegate->scroll_update()); | |
| 1651 EXPECT_FALSE(delegate->scroll_end()); | |
| 1652 EXPECT_EQ(19, delegate->scroll_x()); | |
| 1653 EXPECT_EQ(19, delegate->scroll_y()); | |
| 1654 | |
| 1655 // Move some more to generate a few more scroll updates. | |
| 1656 delegate->Reset(); | |
| 1657 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(115, 216), | |
| 1658 kTouchId, tes.Now()); | |
| 1659 DispatchEventUsingWindowDispatcher(&move1); | |
| 1660 EXPECT_FALSE(delegate->tap()); | |
| 1661 EXPECT_FALSE(delegate->tap_down()); | |
| 1662 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1663 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1664 EXPECT_TRUE(delegate->scroll_update()); | |
| 1665 EXPECT_FALSE(delegate->scroll_end()); | |
| 1666 EXPECT_EQ(-20, delegate->scroll_x()); | |
| 1667 EXPECT_EQ(-19, delegate->scroll_y()); | |
| 1668 EXPECT_EQ(0, delegate->scroll_x_hint()); | |
| 1669 EXPECT_EQ(0, delegate->scroll_y_hint()); | |
| 1670 | |
| 1671 delegate->Reset(); | |
| 1672 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(145, 220), | |
| 1673 kTouchId, tes.Now()); | |
| 1674 DispatchEventUsingWindowDispatcher(&move2); | |
| 1675 EXPECT_FALSE(delegate->tap()); | |
| 1676 EXPECT_FALSE(delegate->tap_down()); | |
| 1677 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1678 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1679 EXPECT_TRUE(delegate->scroll_update()); | |
| 1680 EXPECT_FALSE(delegate->scroll_end()); | |
| 1681 EXPECT_EQ(30, delegate->scroll_x()); | |
| 1682 EXPECT_EQ(4, delegate->scroll_y()); | |
| 1683 | |
| 1684 // Release the touch. This should end the scroll. | |
| 1685 delegate->Reset(); | |
| 1686 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1687 kTouchId, tes.Now()); | |
| 1688 DispatchEventUsingWindowDispatcher(&release1); | |
| 1689 EXPECT_FALSE(delegate->tap()); | |
| 1690 EXPECT_FALSE(delegate->tap_down()); | |
| 1691 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1692 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1693 EXPECT_FALSE(delegate->scroll_update()); | |
| 1694 EXPECT_FALSE(delegate->scroll_end()); | |
| 1695 EXPECT_TRUE(delegate->fling()); | |
| 1696 } | |
| 1697 | |
| 1698 TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { | |
| 1699 scoped_ptr<QueueTouchEventDelegate> queued_delegate( | |
| 1700 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 1701 TimedEvents tes; | |
| 1702 const int kWindowWidth = 123; | |
| 1703 const int kWindowHeight = 45; | |
| 1704 const int kTouchId1 = 6; | |
| 1705 const int kTouchId2 = 4; | |
| 1706 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 1707 scoped_ptr<aura::Window> queue(CreateTestWindowWithDelegate( | |
| 1708 queued_delegate.get(), -1234, bounds, root_window())); | |
| 1709 | |
| 1710 queued_delegate->set_window(queue.get()); | |
| 1711 | |
| 1712 // Touch down on the window. This should not generate any gesture event. | |
| 1713 queued_delegate->Reset(); | |
| 1714 ui::TouchEvent press( | |
| 1715 ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); | |
| 1716 DispatchEventUsingWindowDispatcher(&press); | |
| 1717 EXPECT_FALSE(queued_delegate->tap()); | |
| 1718 EXPECT_FALSE(queued_delegate->tap_down()); | |
| 1719 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1720 EXPECT_FALSE(queued_delegate->begin()); | |
| 1721 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1722 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1723 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1724 | |
| 1725 // Introduce some delay before the touch is released so that it is recognized | |
| 1726 // as a tap. However, this still should not create any gesture events. | |
| 1727 queued_delegate->Reset(); | |
| 1728 ui::TouchEvent release( | |
| 1729 ui::ET_TOUCH_RELEASED, | |
| 1730 gfx::Point(101, 201), | |
| 1731 kTouchId1, | |
| 1732 press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); | |
| 1733 DispatchEventUsingWindowDispatcher(&release); | |
| 1734 EXPECT_FALSE(queued_delegate->tap()); | |
| 1735 EXPECT_FALSE(queued_delegate->tap_down()); | |
| 1736 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1737 EXPECT_FALSE(queued_delegate->begin()); | |
| 1738 EXPECT_FALSE(queued_delegate->end()); | |
| 1739 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1740 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1741 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1742 | |
| 1743 // Create another window, and place a touch-down on it. This should create a | |
| 1744 // tap-down gesture. | |
| 1745 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1746 new GestureEventConsumeDelegate()); | |
| 1747 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1748 delegate.get(), -2345, gfx::Rect(0, 0, 50, 50), root_window())); | |
| 1749 delegate->Reset(); | |
| 1750 ui::TouchEvent press2( | |
| 1751 ui::ET_TOUCH_PRESSED, gfx::Point(10, 20), kTouchId2, tes.Now()); | |
| 1752 DispatchEventUsingWindowDispatcher(&press2); | |
| 1753 EXPECT_FALSE(delegate->tap()); | |
| 1754 EXPECT_TRUE(delegate->tap_down()); | |
| 1755 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1756 EXPECT_FALSE(queued_delegate->begin()); | |
| 1757 EXPECT_FALSE(queued_delegate->end()); | |
| 1758 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1759 EXPECT_FALSE(delegate->scroll_update()); | |
| 1760 EXPECT_FALSE(delegate->scroll_end()); | |
| 1761 | |
| 1762 ui::TouchEvent release2( | |
| 1763 ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), kTouchId2, tes.Now()); | |
| 1764 DispatchEventUsingWindowDispatcher(&release2); | |
| 1765 | |
| 1766 // Process the first queued event. | |
| 1767 queued_delegate->Reset(); | |
| 1768 queued_delegate->ReceivedAck(); | |
| 1769 EXPECT_FALSE(queued_delegate->tap()); | |
| 1770 EXPECT_TRUE(queued_delegate->tap_down()); | |
| 1771 EXPECT_TRUE(queued_delegate->begin()); | |
| 1772 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1773 EXPECT_FALSE(queued_delegate->end()); | |
| 1774 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1775 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1776 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1777 | |
| 1778 // Now, process the second queued event. | |
| 1779 queued_delegate->Reset(); | |
| 1780 queued_delegate->ReceivedAck(); | |
| 1781 EXPECT_TRUE(queued_delegate->tap()); | |
| 1782 EXPECT_FALSE(queued_delegate->tap_down()); | |
| 1783 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1784 EXPECT_FALSE(queued_delegate->begin()); | |
| 1785 EXPECT_TRUE(queued_delegate->end()); | |
| 1786 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1787 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1788 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1789 | |
| 1790 // Start all over. Press on the first window, then press again on the second | |
| 1791 // window. The second press should still go to the first window. | |
| 1792 queued_delegate->Reset(); | |
| 1793 ui::TouchEvent press3( | |
| 1794 ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); | |
| 1795 DispatchEventUsingWindowDispatcher(&press3); | |
| 1796 EXPECT_FALSE(queued_delegate->tap()); | |
| 1797 EXPECT_FALSE(queued_delegate->tap_down()); | |
| 1798 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1799 EXPECT_FALSE(queued_delegate->begin()); | |
| 1800 EXPECT_FALSE(queued_delegate->end()); | |
| 1801 EXPECT_FALSE(queued_delegate->begin()); | |
| 1802 EXPECT_FALSE(queued_delegate->end()); | |
| 1803 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1804 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1805 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1806 | |
| 1807 queued_delegate->Reset(); | |
| 1808 delegate->Reset(); | |
| 1809 ui::TouchEvent press4( | |
| 1810 ui::ET_TOUCH_PRESSED, gfx::Point(103, 203), kTouchId2, tes.Now()); | |
| 1811 DispatchEventUsingWindowDispatcher(&press4); | |
| 1812 EXPECT_FALSE(delegate->tap()); | |
| 1813 EXPECT_FALSE(delegate->tap_down()); | |
| 1814 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1815 EXPECT_FALSE(delegate->begin()); | |
| 1816 EXPECT_FALSE(delegate->end()); | |
| 1817 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1818 EXPECT_FALSE(delegate->scroll_update()); | |
| 1819 EXPECT_FALSE(delegate->scroll_end()); | |
| 1820 EXPECT_FALSE(queued_delegate->tap()); | |
| 1821 EXPECT_FALSE(queued_delegate->tap_down()); | |
| 1822 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1823 EXPECT_FALSE(queued_delegate->begin()); | |
| 1824 EXPECT_FALSE(queued_delegate->end()); | |
| 1825 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1826 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1827 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1828 | |
| 1829 // Move the second touch-point enough so that it is considered a pinch. This | |
| 1830 // should generate both SCROLL_BEGIN and PINCH_BEGIN gestures. | |
| 1831 queued_delegate->Reset(); | |
| 1832 delegate->Reset(); | |
| 1833 ui::TouchEvent move( | |
| 1834 ui::ET_TOUCH_MOVED, | |
| 1835 gfx::PointF( | |
| 1836 203 + ui::GestureConfiguration::max_touch_move_in_pixels_for_click(), | |
| 1837 303), | |
| 1838 kTouchId2, | |
| 1839 tes.Now()); | |
| 1840 DispatchEventUsingWindowDispatcher(&move); | |
| 1841 EXPECT_FALSE(delegate->tap()); | |
| 1842 EXPECT_FALSE(delegate->tap_down()); | |
| 1843 EXPECT_FALSE(delegate->tap_cancel()); | |
| 1844 EXPECT_FALSE(delegate->begin()); | |
| 1845 EXPECT_FALSE(delegate->scroll_begin()); | |
| 1846 EXPECT_FALSE(delegate->scroll_update()); | |
| 1847 EXPECT_FALSE(delegate->scroll_end()); | |
| 1848 EXPECT_FALSE(queued_delegate->tap()); | |
| 1849 EXPECT_FALSE(queued_delegate->tap_down()); | |
| 1850 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1851 EXPECT_FALSE(queued_delegate->begin()); | |
| 1852 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1853 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1854 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1855 | |
| 1856 queued_delegate->Reset(); | |
| 1857 queued_delegate->ReceivedAck(); | |
| 1858 EXPECT_FALSE(queued_delegate->tap()); | |
| 1859 EXPECT_TRUE(queued_delegate->tap_down()); | |
| 1860 EXPECT_TRUE(queued_delegate->begin()); | |
| 1861 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1862 EXPECT_FALSE(queued_delegate->end()); | |
| 1863 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1864 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1865 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1866 | |
| 1867 queued_delegate->Reset(); | |
| 1868 queued_delegate->ReceivedAck(); | |
| 1869 EXPECT_FALSE(queued_delegate->tap()); | |
| 1870 EXPECT_FALSE(queued_delegate->tap_down()); // no touch down for second tap. | |
| 1871 EXPECT_TRUE(queued_delegate->tap_cancel()); | |
| 1872 EXPECT_TRUE(queued_delegate->begin()); | |
| 1873 EXPECT_FALSE(queued_delegate->end()); | |
| 1874 EXPECT_FALSE(queued_delegate->scroll_begin()); | |
| 1875 EXPECT_FALSE(queued_delegate->scroll_update()); | |
| 1876 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1877 EXPECT_FALSE(queued_delegate->pinch_begin()); | |
| 1878 EXPECT_FALSE(queued_delegate->pinch_update()); | |
| 1879 EXPECT_FALSE(queued_delegate->pinch_end()); | |
| 1880 | |
| 1881 queued_delegate->Reset(); | |
| 1882 queued_delegate->ReceivedAck(); | |
| 1883 EXPECT_FALSE(queued_delegate->tap()); | |
| 1884 EXPECT_FALSE(queued_delegate->tap_down()); | |
| 1885 EXPECT_FALSE(queued_delegate->tap_cancel()); | |
| 1886 EXPECT_FALSE(queued_delegate->begin()); | |
| 1887 EXPECT_FALSE(queued_delegate->end()); | |
| 1888 EXPECT_TRUE(queued_delegate->scroll_begin()); | |
| 1889 | |
| 1890 EXPECT_TRUE(queued_delegate->scroll_update()); | |
| 1891 EXPECT_FALSE(queued_delegate->scroll_end()); | |
| 1892 EXPECT_TRUE(queued_delegate->pinch_begin()); | |
| 1893 EXPECT_FALSE(queued_delegate->pinch_update()); | |
| 1894 EXPECT_FALSE(queued_delegate->pinch_end()); | |
| 1895 } | |
| 1896 | |
| 1897 // Check that appropriate touch events generate pinch gesture events. | |
| 1898 TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { | |
| 1899 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1900 new GestureEventConsumeDelegate()); | |
| 1901 TimedEvents tes; | |
| 1902 const int kWindowWidth = 300; | |
| 1903 const int kWindowHeight = 400; | |
| 1904 const int kTouchId1 = 5; | |
| 1905 const int kTouchId2 = 3; | |
| 1906 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | |
| 1907 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1908 delegate.get(), -1234, bounds, root_window())); | |
| 1909 | |
| 1910 delegate->Reset(); | |
| 1911 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 1912 kTouchId1, tes.Now()); | |
| 1913 DispatchEventUsingWindowDispatcher(&press); | |
| 1914 EXPECT_2_EVENTS(delegate->events(), | |
| 1915 ui::ET_GESTURE_BEGIN, | |
| 1916 ui::ET_GESTURE_TAP_DOWN); | |
| 1917 | |
| 1918 // Move the touch-point enough so that it is considered as a scroll. This | |
| 1919 // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. | |
| 1920 delegate->Reset(); | |
| 1921 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 301), | |
| 1922 kTouchId1, tes.Now()); | |
| 1923 DispatchEventUsingWindowDispatcher(&move); | |
| 1924 EXPECT_3_EVENTS(delegate->events(), | |
| 1925 ui::ET_GESTURE_TAP_CANCEL, | |
| 1926 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 1927 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 1928 | |
| 1929 // Press the second finger. It should cause pinch-begin. Note that we will not | |
| 1930 // transition to two finger tap here because the touch points are far enough. | |
| 1931 delegate->Reset(); | |
| 1932 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 1933 kTouchId2, tes.Now()); | |
| 1934 DispatchEventUsingWindowDispatcher(&press2); | |
| 1935 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_BEGIN); | |
| 1936 EXPECT_EQ(gfx::Rect(10, 10, 120, 291).ToString(), | |
| 1937 delegate->bounding_box().ToString()); | |
| 1938 | |
| 1939 // Move the first finger. | |
| 1940 delegate->Reset(); | |
| 1941 ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(95, 201), | |
| 1942 kTouchId1, tes.Now()); | |
| 1943 DispatchEventUsingWindowDispatcher(&move3); | |
| 1944 EXPECT_2_EVENTS(delegate->events(), | |
| 1945 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 1946 ui::ET_GESTURE_PINCH_BEGIN); | |
| 1947 EXPECT_EQ(gfx::Rect(10, 10, 85, 191).ToString(), | |
| 1948 delegate->bounding_box().ToString()); | |
| 1949 | |
| 1950 // Now move the second finger. | |
| 1951 delegate->Reset(); | |
| 1952 ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), | |
| 1953 kTouchId2, tes.Now()); | |
| 1954 DispatchEventUsingWindowDispatcher(&move4); | |
| 1955 EXPECT_2_EVENTS(delegate->events(), | |
| 1956 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 1957 ui::ET_GESTURE_PINCH_UPDATE); | |
| 1958 EXPECT_EQ(gfx::Rect(55, 15, 40, 186).ToString(), | |
| 1959 delegate->bounding_box().ToString()); | |
| 1960 | |
| 1961 // Release the first finger. This should end pinch. | |
| 1962 delegate->Reset(); | |
| 1963 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 1964 kTouchId1, tes.Now()); | |
| 1965 DispatchEventUsingWindowDispatcher(&release); | |
| 1966 EXPECT_2_EVENTS(delegate->events(), | |
| 1967 ui::ET_GESTURE_PINCH_END, | |
| 1968 ui::ET_GESTURE_END); | |
| 1969 EXPECT_EQ(gfx::Rect(55, 15, 46, 186).ToString(), | |
| 1970 delegate->bounding_box().ToString()); | |
| 1971 | |
| 1972 // Move the second finger. This should still generate a scroll. | |
| 1973 delegate->Reset(); | |
| 1974 ui::TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), | |
| 1975 kTouchId2, tes.Now()); | |
| 1976 DispatchEventUsingWindowDispatcher(&move5); | |
| 1977 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 1978 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 1979 } | |
| 1980 | |
| 1981 TEST_F(GestureRecognizerTest, GestureEventPinchFromScrollFromPinch) { | |
| 1982 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 1983 new GestureEventConsumeDelegate()); | |
| 1984 TimedEvents tes; | |
| 1985 const int kWindowWidth = 300; | |
| 1986 const int kWindowHeight = 400; | |
| 1987 const int kTouchId1 = 5; | |
| 1988 const int kTouchId2 = 3; | |
| 1989 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | |
| 1990 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 1991 delegate.get(), -1234, bounds, root_window())); | |
| 1992 | |
| 1993 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 301), | |
| 1994 kTouchId1, tes.Now()); | |
| 1995 DispatchEventUsingWindowDispatcher(&press); | |
| 1996 delegate->Reset(); | |
| 1997 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 1998 kTouchId2, tes.Now()); | |
| 1999 DispatchEventUsingWindowDispatcher(&press2); | |
| 2000 EXPECT_FALSE(delegate->pinch_begin()); | |
| 2001 | |
| 2002 // Touch move triggers pinch begin. | |
| 2003 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId1, delegate.get()); | |
| 2004 EXPECT_TRUE(delegate->pinch_begin()); | |
| 2005 EXPECT_FALSE(delegate->pinch_update()); | |
| 2006 | |
| 2007 // Touch move triggers pinch update. | |
| 2008 tes.SendScrollEvent(event_processor(), 160, 200, kTouchId1, delegate.get()); | |
| 2009 EXPECT_FALSE(delegate->pinch_begin()); | |
| 2010 EXPECT_TRUE(delegate->pinch_update()); | |
| 2011 | |
| 2012 // Pinch has started, now release the second finger | |
| 2013 delegate->Reset(); | |
| 2014 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2015 kTouchId1, tes.Now()); | |
| 2016 DispatchEventUsingWindowDispatcher(&release); | |
| 2017 EXPECT_TRUE(delegate->pinch_end()); | |
| 2018 | |
| 2019 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId2, delegate.get()); | |
| 2020 EXPECT_TRUE(delegate->scroll_update()); | |
| 2021 | |
| 2022 // Pinch again | |
| 2023 delegate->Reset(); | |
| 2024 ui::TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 2025 kTouchId1, tes.Now()); | |
| 2026 DispatchEventUsingWindowDispatcher(&press3); | |
| 2027 // Now the touch points are close. So we will go into two finger tap. | |
| 2028 // Move the touch-point enough to break two-finger-tap and enter pinch. | |
| 2029 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(101, 50), | |
| 2030 kTouchId1, tes.Now()); | |
| 2031 DispatchEventUsingWindowDispatcher(&move2); | |
| 2032 EXPECT_TRUE(delegate->pinch_begin()); | |
| 2033 | |
| 2034 tes.SendScrollEvent(event_processor(), 350, 350, kTouchId1, delegate.get()); | |
| 2035 EXPECT_TRUE(delegate->pinch_update()); | |
| 2036 } | |
| 2037 | |
| 2038 TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { | |
| 2039 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2040 new GestureEventConsumeDelegate()); | |
| 2041 TimedEvents tes; | |
| 2042 const int kWindowWidth = 300; | |
| 2043 const int kWindowHeight = 400; | |
| 2044 const int kTouchId1 = 3; | |
| 2045 const int kTouchId2 = 5; | |
| 2046 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | |
| 2047 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2048 delegate.get(), -1234, bounds, root_window())); | |
| 2049 | |
| 2050 delegate->Reset(); | |
| 2051 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 301), | |
| 2052 kTouchId1, tes.Now()); | |
| 2053 DispatchEventUsingWindowDispatcher(&press); | |
| 2054 EXPECT_2_EVENTS(delegate->events(), | |
| 2055 ui::ET_GESTURE_BEGIN, | |
| 2056 ui::ET_GESTURE_TAP_DOWN); | |
| 2057 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 2058 | |
| 2059 // Press the second finger far enough to break two finger tap. | |
| 2060 delegate->Reset(); | |
| 2061 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 2062 kTouchId2, tes.Now()); | |
| 2063 DispatchEventUsingWindowDispatcher(&press2); | |
| 2064 EXPECT_2_EVENTS(delegate->events(), | |
| 2065 ui::ET_GESTURE_TAP_CANCEL, | |
| 2066 ui::ET_GESTURE_BEGIN); | |
| 2067 EXPECT_EQ(gfx::Rect(10, 10, 91, 291).ToString(), | |
| 2068 delegate->bounding_box().ToString()); | |
| 2069 | |
| 2070 // Move the first finger. | |
| 2071 delegate->Reset(); | |
| 2072 ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(65, 201), | |
| 2073 kTouchId1, tes.Now()); | |
| 2074 DispatchEventUsingWindowDispatcher(&move3); | |
| 2075 EXPECT_3_EVENTS(delegate->events(), | |
| 2076 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 2077 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 2078 ui::ET_GESTURE_PINCH_BEGIN); | |
| 2079 EXPECT_EQ(gfx::Rect(10, 10, 55, 191).ToString(), | |
| 2080 delegate->bounding_box().ToString()); | |
| 2081 | |
| 2082 // Now move the second finger. | |
| 2083 delegate->Reset(); | |
| 2084 ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), | |
| 2085 kTouchId2, tes.Now()); | |
| 2086 DispatchEventUsingWindowDispatcher(&move4); | |
| 2087 EXPECT_2_EVENTS(delegate->events(), | |
| 2088 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 2089 ui::ET_GESTURE_PINCH_UPDATE); | |
| 2090 EXPECT_EQ(gfx::Rect(55, 15, 10, 186).ToString(), | |
| 2091 delegate->bounding_box().ToString()); | |
| 2092 | |
| 2093 // Release the first finger. This should end pinch. | |
| 2094 delegate->Reset(); | |
| 2095 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2096 kTouchId1, tes.LeapForward(10)); | |
| 2097 DispatchEventUsingWindowDispatcher(&release); | |
| 2098 EXPECT_2_EVENTS(delegate->events(), | |
| 2099 ui::ET_GESTURE_PINCH_END, | |
| 2100 ui::ET_GESTURE_END); | |
| 2101 EXPECT_EQ(gfx::Rect(55, 15, 46, 186).ToString(), | |
| 2102 delegate->bounding_box().ToString()); | |
| 2103 | |
| 2104 // Move the second finger. This should still generate a scroll. | |
| 2105 delegate->Reset(); | |
| 2106 ui::TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), | |
| 2107 kTouchId2, tes.Now()); | |
| 2108 DispatchEventUsingWindowDispatcher(&move5); | |
| 2109 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 2110 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 2111 } | |
| 2112 | |
| 2113 TEST_F(GestureRecognizerTest, GestureEventIgnoresDisconnectedEvents) { | |
| 2114 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2115 new GestureEventConsumeDelegate()); | |
| 2116 TimedEvents tes; | |
| 2117 | |
| 2118 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2119 6, tes.Now()); | |
| 2120 DispatchEventUsingWindowDispatcher(&release1); | |
| 2121 EXPECT_FALSE(delegate->tap()); | |
| 2122 EXPECT_FALSE(delegate->tap_down()); | |
| 2123 } | |
| 2124 | |
| 2125 // Check that a touch is locked to the window of the closest current touch | |
| 2126 // within max_separation_for_gesture_touches_in_pixels | |
| 2127 TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { | |
| 2128 ui::GestureRecognizer* gesture_recognizer = new ui::GestureRecognizerImpl(); | |
| 2129 TimedEvents tes; | |
| 2130 ScopedGestureRecognizerSetter gr_setter(gesture_recognizer); | |
| 2131 | |
| 2132 ui::GestureConsumer* target; | |
| 2133 const int kNumWindows = 4; | |
| 2134 | |
| 2135 scoped_ptr<GestureEventConsumeDelegate*[]> delegates( | |
| 2136 new GestureEventConsumeDelegate*[kNumWindows]); | |
| 2137 | |
| 2138 ui::GestureConfiguration:: | |
| 2139 set_max_separation_for_gesture_touches_in_pixels(499); | |
| 2140 | |
| 2141 scoped_ptr<gfx::Rect[]> window_bounds(new gfx::Rect[kNumWindows]); | |
| 2142 window_bounds[0] = gfx::Rect(0, 0, 1, 1); | |
| 2143 window_bounds[1] = gfx::Rect(500, 0, 1, 1); | |
| 2144 window_bounds[2] = gfx::Rect(0, 500, 1, 1); | |
| 2145 window_bounds[3] = gfx::Rect(500, 500, 1, 1); | |
| 2146 | |
| 2147 scoped_ptr<aura::Window*[]> windows(new aura::Window*[kNumWindows]); | |
| 2148 | |
| 2149 // Instantiate windows with |window_bounds| and touch each window at | |
| 2150 // its origin. | |
| 2151 for (int i = 0; i < kNumWindows; ++i) { | |
| 2152 delegates[i] = new GestureEventConsumeDelegate(); | |
| 2153 windows[i] = CreateTestWindowWithDelegate( | |
| 2154 delegates[i], i, window_bounds[i], root_window()); | |
| 2155 windows[i]->set_id(i); | |
| 2156 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, window_bounds[i].origin(), | |
| 2157 i, tes.Now()); | |
| 2158 DispatchEventUsingWindowDispatcher(&press); | |
| 2159 } | |
| 2160 | |
| 2161 // Touches should now be associated with the closest touch within | |
| 2162 // ui::GestureConfiguration::max_separation_for_gesture_touches_in_pixels | |
| 2163 target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 11), -1); | |
| 2164 EXPECT_EQ("0", WindowIDAsString(target)); | |
| 2165 target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 11), -1); | |
| 2166 EXPECT_EQ("1", WindowIDAsString(target)); | |
| 2167 target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 511), -1); | |
| 2168 EXPECT_EQ("2", WindowIDAsString(target)); | |
| 2169 target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 511), -1); | |
| 2170 EXPECT_EQ("3", WindowIDAsString(target)); | |
| 2171 | |
| 2172 // Add a touch in the middle associated with windows[2] | |
| 2173 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 500), | |
| 2174 kNumWindows, tes.Now()); | |
| 2175 DispatchEventUsingWindowDispatcher(&press); | |
| 2176 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(250, 250), | |
| 2177 kNumWindows, tes.Now()); | |
| 2178 DispatchEventUsingWindowDispatcher(&move); | |
| 2179 | |
| 2180 target = gesture_recognizer->GetTargetForLocation(gfx::Point(250, 250), -1); | |
| 2181 EXPECT_EQ("2", WindowIDAsString(target)); | |
| 2182 | |
| 2183 // Make sure that ties are broken by distance to a current touch | |
| 2184 // Closer to the point in the bottom right. | |
| 2185 target = gesture_recognizer->GetTargetForLocation(gfx::Point(380, 380), -1); | |
| 2186 EXPECT_EQ("3", WindowIDAsString(target)); | |
| 2187 | |
| 2188 // This touch is closer to the point in the middle | |
| 2189 target = gesture_recognizer->GetTargetForLocation(gfx::Point(300, 300), -1); | |
| 2190 EXPECT_EQ("2", WindowIDAsString(target)); | |
| 2191 | |
| 2192 // A touch too far from other touches won't be locked to anything | |
| 2193 target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000), -1); | |
| 2194 EXPECT_TRUE(target == NULL); | |
| 2195 | |
| 2196 // Move a touch associated with windows[2] to 1000, 1000 | |
| 2197 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(1000, 1000), | |
| 2198 kNumWindows, tes.Now()); | |
| 2199 DispatchEventUsingWindowDispatcher(&move2); | |
| 2200 | |
| 2201 target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000), -1); | |
| 2202 EXPECT_EQ("2", WindowIDAsString(target)); | |
| 2203 | |
| 2204 for (int i = 0; i < kNumWindows; ++i) { | |
| 2205 // Delete windows before deleting delegates. | |
| 2206 delete windows[i]; | |
| 2207 delete delegates[i]; | |
| 2208 } | |
| 2209 } | |
| 2210 | |
| 2211 // Check that a touch's target will not be effected by a touch on a different | |
| 2212 // screen. | |
| 2213 TEST_F(GestureRecognizerTest, GestureEventTouchLockIgnoresOtherScreens) { | |
| 2214 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2215 new GestureEventConsumeDelegate()); | |
| 2216 gfx::Rect bounds(0, 0, 10, 10); | |
| 2217 scoped_ptr<aura::Window> window( | |
| 2218 CreateTestWindowWithDelegate(delegate.get(), 0, bounds, root_window())); | |
| 2219 | |
| 2220 const int kTouchId1 = 8; | |
| 2221 const int kTouchId2 = 2; | |
| 2222 TimedEvents tes; | |
| 2223 | |
| 2224 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(5, 5), | |
| 2225 kTouchId1, tes.Now()); | |
| 2226 ui::EventTestApi test_press1(&press1); | |
| 2227 test_press1.set_source_device_id(1); | |
| 2228 DispatchEventUsingWindowDispatcher(&press1); | |
| 2229 | |
| 2230 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), | |
| 2231 kTouchId2, tes.Now()); | |
| 2232 ui::EventTestApi test_press2(&press2); | |
| 2233 test_press2.set_source_device_id(2); | |
| 2234 DispatchEventUsingWindowDispatcher(&press2); | |
| 2235 | |
| 2236 // The second press should not have been locked to the same target as the | |
| 2237 // first, as they occured on different displays. | |
| 2238 EXPECT_NE( | |
| 2239 ui::GestureRecognizer::Get()->GetTouchLockedTarget(press1), | |
| 2240 ui::GestureRecognizer::Get()->GetTouchLockedTarget(press2)); | |
| 2241 } | |
| 2242 | |
| 2243 // Check that touch events outside the root window are still handled | |
| 2244 // by the root window's gesture sequence. | |
| 2245 TEST_F(GestureRecognizerTest, GestureEventOutsideRootWindowTap) { | |
| 2246 TimedEvents tes; | |
| 2247 scoped_ptr<aura::Window> window(CreateTestWindowWithBounds( | |
| 2248 gfx::Rect(-100, -100, 2000, 2000), root_window())); | |
| 2249 | |
| 2250 gfx::Point pos1(-10, -10); | |
| 2251 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, pos1, 0, tes.Now()); | |
| 2252 DispatchEventUsingWindowDispatcher(&press1); | |
| 2253 | |
| 2254 gfx::Point pos2(1000, 1000); | |
| 2255 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, pos2, 1, tes.Now()); | |
| 2256 DispatchEventUsingWindowDispatcher(&press2); | |
| 2257 | |
| 2258 // As these presses were outside the root window, they should be | |
| 2259 // associated with the root window. | |
| 2260 EXPECT_EQ(root_window(), | |
| 2261 static_cast<aura::Window*>( | |
| 2262 ui::GestureRecognizer::Get()->GetTouchLockedTarget(press1))); | |
| 2263 EXPECT_EQ(root_window(), | |
| 2264 static_cast<aura::Window*>( | |
| 2265 ui::GestureRecognizer::Get()->GetTouchLockedTarget(press2))); | |
| 2266 } | |
| 2267 | |
| 2268 TEST_F(GestureRecognizerTest, NoTapWithPreventDefaultedRelease) { | |
| 2269 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 2270 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 2271 TimedEvents tes; | |
| 2272 const int kTouchId = 2; | |
| 2273 gfx::Rect bounds(100, 200, 100, 100); | |
| 2274 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2275 delegate.get(), -1234, bounds, root_window())); | |
| 2276 delegate->set_window(window.get()); | |
| 2277 | |
| 2278 delegate->Reset(); | |
| 2279 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2280 kTouchId, tes.Now()); | |
| 2281 DispatchEventUsingWindowDispatcher(&press); | |
| 2282 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2283 kTouchId, tes.LeapForward(50)); | |
| 2284 DispatchEventUsingWindowDispatcher(&release); | |
| 2285 | |
| 2286 delegate->Reset(); | |
| 2287 delegate->ReceivedAck(); | |
| 2288 EXPECT_TRUE(delegate->tap_down()); | |
| 2289 delegate->Reset(); | |
| 2290 delegate->ReceivedAckPreventDefaulted(); | |
| 2291 EXPECT_FALSE(delegate->tap()); | |
| 2292 EXPECT_TRUE(delegate->tap_cancel()); | |
| 2293 } | |
| 2294 | |
| 2295 TEST_F(GestureRecognizerTest, PinchScrollWithPreventDefaultedRelease) { | |
| 2296 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 2297 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 2298 TimedEvents tes; | |
| 2299 const int kTouchId1 = 7; | |
| 2300 const int kTouchId2 = 5; | |
| 2301 gfx::Rect bounds(10, 20, 100, 100); | |
| 2302 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2303 delegate.get(), -1234, bounds, root_window())); | |
| 2304 delegate->set_window(window.get()); | |
| 2305 | |
| 2306 { | |
| 2307 delegate->Reset(); | |
| 2308 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(15, 25), kTouchId1, | |
| 2309 tes.Now()); | |
| 2310 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(20, 95), kTouchId1, | |
| 2311 tes.LeapForward(200)); | |
| 2312 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(15, 25), kTouchId1, | |
| 2313 tes.LeapForward(50)); | |
| 2314 DispatchEventUsingWindowDispatcher(&press); | |
| 2315 DispatchEventUsingWindowDispatcher(&move); | |
| 2316 DispatchEventUsingWindowDispatcher(&release); | |
| 2317 delegate->Reset(); | |
| 2318 | |
| 2319 // Ack the press event. | |
| 2320 delegate->ReceivedAck(); | |
| 2321 EXPECT_2_EVENTS( | |
| 2322 delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); | |
| 2323 delegate->Reset(); | |
| 2324 | |
| 2325 // Ack the move event. | |
| 2326 delegate->ReceivedAck(); | |
| 2327 EXPECT_3_EVENTS(delegate->events(), | |
| 2328 ui::ET_GESTURE_TAP_CANCEL, | |
| 2329 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 2330 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 2331 delegate->Reset(); | |
| 2332 | |
| 2333 // Ack the release event. Although the release event has been processed, it | |
| 2334 // should still generate a scroll-end event. | |
| 2335 delegate->ReceivedAckPreventDefaulted(); | |
| 2336 EXPECT_2_EVENTS( | |
| 2337 delegate->events(), ui::ET_GESTURE_SCROLL_END, ui::ET_GESTURE_END); | |
| 2338 } | |
| 2339 | |
| 2340 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(15, 25), kTouchId1, | |
| 2341 tes.Now()); | |
| 2342 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(20, 95), kTouchId1, | |
| 2343 tes.LeapForward(200)); | |
| 2344 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(15, 25), kTouchId1, | |
| 2345 tes.LeapForward(50)); | |
| 2346 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(55, 25), kTouchId2, | |
| 2347 tes.Now()); | |
| 2348 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(145, 85), kTouchId2, | |
| 2349 tes.LeapForward(1000)); | |
| 2350 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(145, 85), kTouchId2, | |
| 2351 tes.LeapForward(14)); | |
| 2352 | |
| 2353 // Do a pinch. | |
| 2354 DispatchEventUsingWindowDispatcher(&press); | |
| 2355 DispatchEventUsingWindowDispatcher(&move); | |
| 2356 DispatchEventUsingWindowDispatcher(&press2); | |
| 2357 DispatchEventUsingWindowDispatcher(&move2); | |
| 2358 DispatchEventUsingWindowDispatcher(&release); | |
| 2359 DispatchEventUsingWindowDispatcher(&release2); | |
| 2360 | |
| 2361 // Ack the press and move events. | |
| 2362 delegate->Reset(); | |
| 2363 delegate->ReceivedAck(); | |
| 2364 EXPECT_2_EVENTS( | |
| 2365 delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); | |
| 2366 | |
| 2367 delegate->Reset(); | |
| 2368 delegate->ReceivedAck(); | |
| 2369 EXPECT_3_EVENTS(delegate->events(), | |
| 2370 ui::ET_GESTURE_TAP_CANCEL, | |
| 2371 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 2372 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 2373 | |
| 2374 delegate->Reset(); | |
| 2375 delegate->ReceivedAck(); | |
| 2376 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_BEGIN); | |
| 2377 | |
| 2378 delegate->Reset(); | |
| 2379 delegate->ReceivedAck(); | |
| 2380 EXPECT_2_EVENTS(delegate->events(), | |
| 2381 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 2382 ui::ET_GESTURE_PINCH_BEGIN); | |
| 2383 | |
| 2384 // Ack the first release. Although the release is processed, it should still | |
| 2385 // generate a pinch-end event. | |
| 2386 delegate->Reset(); | |
| 2387 delegate->ReceivedAckPreventDefaulted(); | |
| 2388 EXPECT_2_EVENTS( | |
| 2389 delegate->events(), ui::ET_GESTURE_PINCH_END, ui::ET_GESTURE_END); | |
| 2390 | |
| 2391 delegate->Reset(); | |
| 2392 delegate->ReceivedAckPreventDefaulted(); | |
| 2393 EXPECT_2_EVENTS( | |
| 2394 delegate->events(), ui::ET_GESTURE_SCROLL_END, ui::ET_GESTURE_END); | |
| 2395 } | |
| 2396 | |
| 2397 TEST_F(GestureRecognizerTest, GestureEndLocation) { | |
| 2398 GestureEventConsumeDelegate delegate; | |
| 2399 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2400 &delegate, -1234, gfx::Rect(10, 10, 300, 300), root_window())); | |
| 2401 ui::test::EventGenerator generator(root_window(), window.get()); | |
| 2402 const gfx::Point begin(20, 20); | |
| 2403 const gfx::Point end(150, 150); | |
| 2404 const gfx::Vector2d window_offset = | |
| 2405 window->bounds().origin().OffsetFromOrigin(); | |
| 2406 generator.GestureScrollSequence(begin, end, | |
| 2407 base::TimeDelta::FromMilliseconds(20), | |
| 2408 10); | |
| 2409 EXPECT_EQ((begin - window_offset).ToString(), | |
| 2410 delegate.scroll_begin_position().ToString()); | |
| 2411 EXPECT_EQ((end - window_offset).ToString(), | |
| 2412 delegate.gesture_end_location().ToString()); | |
| 2413 } | |
| 2414 | |
| 2415 TEST_F(GestureRecognizerTest, CaptureSendsGestureEnd) { | |
| 2416 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2417 new GestureEventConsumeDelegate()); | |
| 2418 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2419 delegate.get(), -1234, gfx::Rect(10, 10, 300, 300), root_window())); | |
| 2420 ui::test::EventGenerator generator(root_window()); | |
| 2421 | |
| 2422 generator.MoveMouseRelativeTo(window.get(), gfx::Point(10, 10)); | |
| 2423 generator.PressTouch(); | |
| 2424 RunAllPendingInMessageLoop(); | |
| 2425 | |
| 2426 EXPECT_TRUE(delegate->tap_down()); | |
| 2427 | |
| 2428 scoped_ptr<aura::Window> capture(CreateTestWindowWithBounds( | |
| 2429 gfx::Rect(10, 10, 200, 200), root_window())); | |
| 2430 capture->SetCapture(); | |
| 2431 RunAllPendingInMessageLoop(); | |
| 2432 | |
| 2433 EXPECT_TRUE(delegate->end()); | |
| 2434 EXPECT_TRUE(delegate->tap_cancel()); | |
| 2435 } | |
| 2436 | |
| 2437 // Check that previous touch actions that are completely finished (either | |
| 2438 // released or cancelled), do not receive extra synthetic cancels upon change of | |
| 2439 // capture. | |
| 2440 TEST_F(GestureRecognizerTest, CaptureDoesNotCancelFinishedTouches) { | |
| 2441 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2442 new GestureEventConsumeDelegate()); | |
| 2443 scoped_ptr<TestEventHandler> handler(new TestEventHandler); | |
| 2444 root_window()->AddPreTargetHandler(handler.get()); | |
| 2445 | |
| 2446 // Create a window and set it as the capture window. | |
| 2447 scoped_ptr<aura::Window> window1(CreateTestWindowWithDelegate(delegate.get(), | |
| 2448 -1234, gfx::Rect(10, 10, 300, 300), root_window())); | |
| 2449 window1->SetCapture(); | |
| 2450 | |
| 2451 ui::test::EventGenerator generator(root_window()); | |
| 2452 TimedEvents tes; | |
| 2453 | |
| 2454 // Generate two touch-press events on the window. | |
| 2455 scoped_ptr<ui::TouchEvent> touch0(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
| 2456 gfx::Point(20, 20), 0, | |
| 2457 tes.Now())); | |
| 2458 scoped_ptr<ui::TouchEvent> touch1(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | |
| 2459 gfx::Point(30, 30), 1, | |
| 2460 tes.Now())); | |
| 2461 generator.Dispatch(touch0.get()); | |
| 2462 generator.Dispatch(touch1.get()); | |
| 2463 RunAllPendingInMessageLoop(); | |
| 2464 EXPECT_EQ(2, handler->touch_pressed_count()); | |
| 2465 | |
| 2466 // Advance time. | |
| 2467 tes.LeapForward(1000); | |
| 2468 | |
| 2469 // End the two touches, one by a touch-release and one by a touch-cancel; to | |
| 2470 // cover both cases. | |
| 2471 touch0.reset(new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0, | |
| 2472 tes.Now())); | |
| 2473 touch1.reset(new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(30, 30), 1, | |
| 2474 tes.Now())); | |
| 2475 generator.Dispatch(touch0.get()); | |
| 2476 generator.Dispatch(touch1.get()); | |
| 2477 RunAllPendingInMessageLoop(); | |
| 2478 EXPECT_EQ(1, handler->touch_released_count()); | |
| 2479 EXPECT_EQ(1, handler->touch_cancelled_count()); | |
| 2480 | |
| 2481 // Create a new window and set it as the new capture window. | |
| 2482 scoped_ptr<aura::Window> window2(CreateTestWindowWithBounds( | |
| 2483 gfx::Rect(100, 100, 300, 300), root_window())); | |
| 2484 window2->SetCapture(); | |
| 2485 RunAllPendingInMessageLoop(); | |
| 2486 // Check that setting capture does not generate any synthetic touch-cancels | |
| 2487 // for the two previously finished touch actions. | |
| 2488 EXPECT_EQ(1, handler->touch_cancelled_count()); | |
| 2489 | |
| 2490 root_window()->RemovePreTargetHandler(handler.get()); | |
| 2491 } | |
| 2492 | |
| 2493 // Tests that a press with the same touch id as an existing touch is ignored. | |
| 2494 TEST_F(GestureRecognizerTest, PressDoesNotCrash) { | |
| 2495 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2496 new GestureEventConsumeDelegate()); | |
| 2497 TimedEvents tes; | |
| 2498 | |
| 2499 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2500 delegate.get(), -1234, gfx::Rect(10, 10, 300, 300), root_window())); | |
| 2501 | |
| 2502 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(45, 45), 7, tes.Now()); | |
| 2503 press.set_radius_x(40); | |
| 2504 DispatchEventUsingWindowDispatcher(&press); | |
| 2505 EXPECT_TRUE(delegate->tap_down()); | |
| 2506 EXPECT_EQ(gfx::Rect(5, 5, 80, 80).ToString(), | |
| 2507 delegate->bounding_box().ToString()); | |
| 2508 delegate->Reset(); | |
| 2509 | |
| 2510 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(55, 45), 7, tes.Now()); | |
| 2511 DispatchEventUsingWindowDispatcher(&press2); | |
| 2512 | |
| 2513 // This new press should not generate a tap-down. | |
| 2514 EXPECT_FALSE(delegate->begin()); | |
| 2515 EXPECT_FALSE(delegate->tap_down()); | |
| 2516 EXPECT_FALSE(delegate->tap_cancel()); | |
| 2517 EXPECT_FALSE(delegate->scroll_begin()); | |
| 2518 } | |
| 2519 | |
| 2520 TEST_F(GestureRecognizerTest, TwoFingerTap) { | |
| 2521 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2522 new GestureEventConsumeDelegate()); | |
| 2523 const int kWindowWidth = 123; | |
| 2524 const int kWindowHeight = 45; | |
| 2525 const int kTouchId1 = 2; | |
| 2526 const int kTouchId2 = 3; | |
| 2527 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2528 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2529 delegate.get(), -1234, bounds, root_window())); | |
| 2530 TimedEvents tes; | |
| 2531 | |
| 2532 delegate->Reset(); | |
| 2533 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2534 kTouchId1, tes.Now()); | |
| 2535 DispatchEventUsingWindowDispatcher(&press1); | |
| 2536 EXPECT_2_EVENTS( | |
| 2537 delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); | |
| 2538 | |
| 2539 delegate->Reset(); | |
| 2540 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 2541 kTouchId2, tes.Now()); | |
| 2542 DispatchEventUsingWindowDispatcher(&press2); | |
| 2543 EXPECT_2_EVENTS( | |
| 2544 delegate->events(), ui::ET_GESTURE_TAP_CANCEL, ui::ET_GESTURE_BEGIN); | |
| 2545 | |
| 2546 // Little bit of touch move should not affect our state. | |
| 2547 delegate->Reset(); | |
| 2548 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(102, 202), | |
| 2549 kTouchId1, tes.Now()); | |
| 2550 DispatchEventUsingWindowDispatcher(&move1); | |
| 2551 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(131, 202), | |
| 2552 kTouchId2, tes.Now()); | |
| 2553 DispatchEventUsingWindowDispatcher(&move2); | |
| 2554 EXPECT_2_EVENTS(delegate->events(), | |
| 2555 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 2556 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 2557 | |
| 2558 // Make sure there is enough delay before the touch is released so that it is | |
| 2559 // recognized as a tap. | |
| 2560 delegate->Reset(); | |
| 2561 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2562 kTouchId1, tes.LeapForward(50)); | |
| 2563 | |
| 2564 DispatchEventUsingWindowDispatcher(&release1); | |
| 2565 EXPECT_2_EVENTS( | |
| 2566 delegate->events(), ui::ET_GESTURE_TWO_FINGER_TAP, ui::ET_GESTURE_END); | |
| 2567 | |
| 2568 // Lift second finger. | |
| 2569 // Make sure there is enough delay before the touch is released so that it is | |
| 2570 // recognized as a tap. | |
| 2571 delegate->Reset(); | |
| 2572 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(130, 201), | |
| 2573 kTouchId2, tes.LeapForward(50)); | |
| 2574 | |
| 2575 DispatchEventUsingWindowDispatcher(&release2); | |
| 2576 EXPECT_2_EVENTS( | |
| 2577 delegate->events(), ui::ET_GESTURE_SCROLL_END, ui::ET_GESTURE_END); | |
| 2578 } | |
| 2579 | |
| 2580 TEST_F(GestureRecognizerTest, TwoFingerTapExpired) { | |
| 2581 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2582 new GestureEventConsumeDelegate()); | |
| 2583 const int kWindowWidth = 123; | |
| 2584 const int kWindowHeight = 45; | |
| 2585 const int kTouchId1 = 2; | |
| 2586 const int kTouchId2 = 3; | |
| 2587 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2588 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2589 delegate.get(), -1234, bounds, root_window())); | |
| 2590 TimedEvents tes; | |
| 2591 | |
| 2592 delegate->Reset(); | |
| 2593 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2594 kTouchId1, tes.Now()); | |
| 2595 DispatchEventUsingWindowDispatcher(&press1); | |
| 2596 | |
| 2597 delegate->Reset(); | |
| 2598 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 2599 kTouchId2, tes.Now()); | |
| 2600 DispatchEventUsingWindowDispatcher(&press2); | |
| 2601 | |
| 2602 // Send release event after sufficient delay so that two finger time expires. | |
| 2603 delegate->Reset(); | |
| 2604 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2605 kTouchId1, tes.LeapForward(1000)); | |
| 2606 | |
| 2607 DispatchEventUsingWindowDispatcher(&release1); | |
| 2608 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2609 | |
| 2610 // Lift second finger. | |
| 2611 // Make sure there is enough delay before the touch is released so that it is | |
| 2612 // recognized as a tap. | |
| 2613 delegate->Reset(); | |
| 2614 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(130, 201), | |
| 2615 kTouchId2, tes.LeapForward(50)); | |
| 2616 | |
| 2617 DispatchEventUsingWindowDispatcher(&release2); | |
| 2618 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2619 } | |
| 2620 | |
| 2621 TEST_F(GestureRecognizerTest, TwoFingerTapChangesToPinch) { | |
| 2622 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2623 new GestureEventConsumeDelegate()); | |
| 2624 const int kWindowWidth = 123; | |
| 2625 const int kWindowHeight = 45; | |
| 2626 const int kTouchId1 = 2; | |
| 2627 const int kTouchId2 = 3; | |
| 2628 TimedEvents tes; | |
| 2629 | |
| 2630 // Test moving first finger | |
| 2631 { | |
| 2632 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2633 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2634 delegate.get(), -1234, bounds, root_window())); | |
| 2635 | |
| 2636 delegate->Reset(); | |
| 2637 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2638 kTouchId1, tes.Now()); | |
| 2639 DispatchEventUsingWindowDispatcher(&press1); | |
| 2640 | |
| 2641 delegate->Reset(); | |
| 2642 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 2643 kTouchId2, tes.Now()); | |
| 2644 DispatchEventUsingWindowDispatcher(&press2); | |
| 2645 | |
| 2646 tes.SendScrollEvent(event_processor(), 230, 330, kTouchId1, delegate.get()); | |
| 2647 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2648 EXPECT_TRUE(delegate->pinch_begin()); | |
| 2649 | |
| 2650 // Make sure there is enough delay before the touch is released so that it | |
| 2651 // is recognized as a tap. | |
| 2652 delegate->Reset(); | |
| 2653 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2654 kTouchId2, tes.LeapForward(50)); | |
| 2655 | |
| 2656 DispatchEventUsingWindowDispatcher(&release); | |
| 2657 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2658 EXPECT_TRUE(delegate->pinch_end()); | |
| 2659 } | |
| 2660 | |
| 2661 // Test moving second finger | |
| 2662 { | |
| 2663 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2664 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2665 delegate.get(), -1234, bounds, root_window())); | |
| 2666 | |
| 2667 delegate->Reset(); | |
| 2668 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2669 kTouchId1, tes.Now()); | |
| 2670 DispatchEventUsingWindowDispatcher(&press1); | |
| 2671 | |
| 2672 delegate->Reset(); | |
| 2673 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 2674 kTouchId2, tes.Now()); | |
| 2675 DispatchEventUsingWindowDispatcher(&press2); | |
| 2676 | |
| 2677 tes.SendScrollEvent(event_processor(), 301, 230, kTouchId2, delegate.get()); | |
| 2678 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2679 EXPECT_TRUE(delegate->pinch_begin()); | |
| 2680 | |
| 2681 // Make sure there is enough delay before the touch is released so that it | |
| 2682 // is recognized as a tap. | |
| 2683 delegate->Reset(); | |
| 2684 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2685 kTouchId1, tes.LeapForward(50)); | |
| 2686 | |
| 2687 DispatchEventUsingWindowDispatcher(&release); | |
| 2688 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2689 EXPECT_TRUE(delegate->pinch_end()); | |
| 2690 } | |
| 2691 } | |
| 2692 | |
| 2693 TEST_F(GestureRecognizerTest, NoTwoFingerTapWhenFirstFingerHasScrolled) { | |
| 2694 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2695 new GestureEventConsumeDelegate()); | |
| 2696 const int kWindowWidth = 123; | |
| 2697 const int kWindowHeight = 45; | |
| 2698 const int kTouchId1 = 2; | |
| 2699 const int kTouchId2 = 3; | |
| 2700 TimedEvents tes; | |
| 2701 | |
| 2702 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2703 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2704 delegate.get(), -1234, bounds, root_window())); | |
| 2705 | |
| 2706 delegate->Reset(); | |
| 2707 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2708 kTouchId1, tes.Now()); | |
| 2709 DispatchEventUsingWindowDispatcher(&press1); | |
| 2710 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId1, delegate.get()); | |
| 2711 | |
| 2712 delegate->Reset(); | |
| 2713 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 2714 kTouchId2, tes.Now()); | |
| 2715 DispatchEventUsingWindowDispatcher(&press2); | |
| 2716 | |
| 2717 EXPECT_FALSE(delegate->pinch_begin()); | |
| 2718 | |
| 2719 // Make sure there is enough delay before the touch is released so that it | |
| 2720 // is recognized as a tap. | |
| 2721 delegate->Reset(); | |
| 2722 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2723 kTouchId2, tes.LeapForward(50)); | |
| 2724 | |
| 2725 DispatchEventUsingWindowDispatcher(&release); | |
| 2726 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2727 EXPECT_FALSE(delegate->pinch_end()); | |
| 2728 } | |
| 2729 | |
| 2730 TEST_F(GestureRecognizerTest, MultiFingerSwipe) { | |
| 2731 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2732 new GestureEventConsumeDelegate()); | |
| 2733 const int kWindowWidth = 123; | |
| 2734 const int kWindowHeight = 45; | |
| 2735 | |
| 2736 gfx::Rect bounds(5, 10, kWindowWidth, kWindowHeight); | |
| 2737 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2738 delegate.get(), -1234, bounds, root_window())); | |
| 2739 | |
| 2740 const int kSteps = 15; | |
| 2741 const int kTouchPoints = 4; | |
| 2742 gfx::Point points[kTouchPoints] = { | |
| 2743 gfx::Point(10, 30), | |
| 2744 gfx::Point(30, 20), | |
| 2745 gfx::Point(50, 30), | |
| 2746 gfx::Point(80, 50) | |
| 2747 }; | |
| 2748 | |
| 2749 ui::test::EventGenerator generator(root_window(), window.get()); | |
| 2750 | |
| 2751 // The unified gesture recognizer assumes a finger has stopped if it hasn't | |
| 2752 // moved for too long. See ui/events/gesture_detection/velocity_tracker.cc's | |
| 2753 // kAssumePointerStoppedTimeMs. | |
| 2754 for (int count = 2; count <= kTouchPoints; ++count) { | |
| 2755 generator.GestureMultiFingerScroll( | |
| 2756 count, points, 10, kSteps, 0, -11 * kSteps); | |
| 2757 EXPECT_TRUE(delegate->swipe_up()); | |
| 2758 delegate->Reset(); | |
| 2759 | |
| 2760 generator.GestureMultiFingerScroll( | |
| 2761 count, points, 10, kSteps, 0, 11 * kSteps); | |
| 2762 EXPECT_TRUE(delegate->swipe_down()); | |
| 2763 delegate->Reset(); | |
| 2764 | |
| 2765 generator.GestureMultiFingerScroll( | |
| 2766 count, points, 10, kSteps, -11 * kSteps, 0); | |
| 2767 EXPECT_TRUE(delegate->swipe_left()); | |
| 2768 delegate->Reset(); | |
| 2769 | |
| 2770 generator.GestureMultiFingerScroll( | |
| 2771 count, points, 10, kSteps, 11 * kSteps, 0); | |
| 2772 EXPECT_TRUE(delegate->swipe_right()); | |
| 2773 delegate->Reset(); | |
| 2774 | |
| 2775 generator.GestureMultiFingerScroll( | |
| 2776 count, points, 10, kSteps, 5 * kSteps, 12 * kSteps); | |
| 2777 EXPECT_FALSE(delegate->swipe_down()); | |
| 2778 delegate->Reset(); | |
| 2779 | |
| 2780 generator.GestureMultiFingerScroll( | |
| 2781 count, points, 10, kSteps, 4 * kSteps, 12 * kSteps); | |
| 2782 EXPECT_TRUE(delegate->swipe_down()); | |
| 2783 delegate->Reset(); | |
| 2784 | |
| 2785 generator.GestureMultiFingerScroll( | |
| 2786 count, points, 10, kSteps, 3 * kSteps, 12 * kSteps); | |
| 2787 EXPECT_TRUE(delegate->swipe_down()); | |
| 2788 delegate->Reset(); | |
| 2789 } | |
| 2790 } | |
| 2791 | |
| 2792 TEST_F(GestureRecognizerTest, TwoFingerTapCancelled) { | |
| 2793 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2794 new GestureEventConsumeDelegate()); | |
| 2795 const int kWindowWidth = 123; | |
| 2796 const int kWindowHeight = 45; | |
| 2797 const int kTouchId1 = 2; | |
| 2798 const int kTouchId2 = 3; | |
| 2799 TimedEvents tes; | |
| 2800 | |
| 2801 // Test canceling first finger. | |
| 2802 { | |
| 2803 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2804 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2805 delegate.get(), -1234, bounds, root_window())); | |
| 2806 | |
| 2807 delegate->Reset(); | |
| 2808 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2809 kTouchId1, tes.Now()); | |
| 2810 DispatchEventUsingWindowDispatcher(&press1); | |
| 2811 | |
| 2812 delegate->Reset(); | |
| 2813 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 2814 kTouchId2, tes.Now()); | |
| 2815 DispatchEventUsingWindowDispatcher(&press2); | |
| 2816 | |
| 2817 delegate->Reset(); | |
| 2818 ui::TouchEvent cancel(ui::ET_TOUCH_CANCELLED, gfx::Point(130, 201), | |
| 2819 kTouchId1, tes.Now()); | |
| 2820 DispatchEventUsingWindowDispatcher(&cancel); | |
| 2821 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2822 | |
| 2823 // Make sure there is enough delay before the touch is released so that it | |
| 2824 // is recognized as a tap. | |
| 2825 delegate->Reset(); | |
| 2826 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2827 kTouchId2, tes.LeapForward(50)); | |
| 2828 | |
| 2829 DispatchEventUsingWindowDispatcher(&release); | |
| 2830 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2831 } | |
| 2832 | |
| 2833 // Test canceling second finger | |
| 2834 { | |
| 2835 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2836 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2837 delegate.get(), -1234, bounds, root_window())); | |
| 2838 | |
| 2839 delegate->Reset(); | |
| 2840 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2841 kTouchId1, tes.Now()); | |
| 2842 DispatchEventUsingWindowDispatcher(&press1); | |
| 2843 | |
| 2844 delegate->Reset(); | |
| 2845 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 2846 kTouchId2, tes.Now()); | |
| 2847 DispatchEventUsingWindowDispatcher(&press2); | |
| 2848 | |
| 2849 delegate->Reset(); | |
| 2850 ui::TouchEvent cancel(ui::ET_TOUCH_CANCELLED, gfx::Point(130, 201), | |
| 2851 kTouchId2, tes.Now()); | |
| 2852 DispatchEventUsingWindowDispatcher(&cancel); | |
| 2853 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2854 | |
| 2855 // Make sure there is enough delay before the touch is released so that it | |
| 2856 // is recognized as a tap. | |
| 2857 delegate->Reset(); | |
| 2858 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 2859 kTouchId1, tes.LeapForward(50)); | |
| 2860 | |
| 2861 DispatchEventUsingWindowDispatcher(&release); | |
| 2862 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2863 } | |
| 2864 } | |
| 2865 | |
| 2866 TEST_F(GestureRecognizerTest, VeryWideTwoFingerTouchDownShouldBeAPinch) { | |
| 2867 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2868 new GestureEventConsumeDelegate()); | |
| 2869 const int kWindowWidth = 523; | |
| 2870 const int kWindowHeight = 45; | |
| 2871 const int kTouchId1 = 2; | |
| 2872 const int kTouchId2 = 3; | |
| 2873 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 2874 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2875 delegate.get(), -1234, bounds, root_window())); | |
| 2876 TimedEvents tes; | |
| 2877 | |
| 2878 delegate->Reset(); | |
| 2879 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2880 kTouchId1, tes.Now()); | |
| 2881 DispatchEventUsingWindowDispatcher(&press1); | |
| 2882 EXPECT_FALSE(delegate->tap()); | |
| 2883 EXPECT_TRUE(delegate->tap_down()); | |
| 2884 EXPECT_FALSE(delegate->tap_cancel()); | |
| 2885 EXPECT_FALSE(delegate->scroll_begin()); | |
| 2886 EXPECT_FALSE(delegate->scroll_update()); | |
| 2887 EXPECT_FALSE(delegate->scroll_end()); | |
| 2888 EXPECT_FALSE(delegate->long_press()); | |
| 2889 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2890 | |
| 2891 delegate->Reset(); | |
| 2892 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(430, 201), | |
| 2893 kTouchId2, tes.Now()); | |
| 2894 DispatchEventUsingWindowDispatcher(&press2); | |
| 2895 EXPECT_FALSE(delegate->tap()); | |
| 2896 EXPECT_FALSE(delegate->tap_down()); // no touch down for second tap. | |
| 2897 EXPECT_TRUE(delegate->tap_cancel()); | |
| 2898 EXPECT_FALSE(delegate->scroll_begin()); | |
| 2899 EXPECT_FALSE(delegate->scroll_update()); | |
| 2900 EXPECT_FALSE(delegate->scroll_end()); | |
| 2901 EXPECT_FALSE(delegate->long_press()); | |
| 2902 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2903 EXPECT_FALSE(delegate->pinch_begin()); | |
| 2904 | |
| 2905 delegate->Reset(); | |
| 2906 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(530, 301), | |
| 2907 kTouchId2, tes.Now()); | |
| 2908 DispatchEventUsingWindowDispatcher(&move2); | |
| 2909 EXPECT_FALSE(delegate->tap()); | |
| 2910 EXPECT_FALSE(delegate->tap_down()); | |
| 2911 EXPECT_FALSE(delegate->tap_cancel()); | |
| 2912 // Pinch & Scroll only when there is enough movement. | |
| 2913 EXPECT_TRUE(delegate->scroll_begin()); | |
| 2914 EXPECT_TRUE(delegate->scroll_update()); | |
| 2915 EXPECT_FALSE(delegate->scroll_end()); | |
| 2916 EXPECT_FALSE(delegate->long_press()); | |
| 2917 EXPECT_FALSE(delegate->two_finger_tap()); | |
| 2918 EXPECT_TRUE(delegate->pinch_begin()); | |
| 2919 } | |
| 2920 | |
| 2921 // Verifies if a window is the target of multiple touch-ids and we hide the | |
| 2922 // window everything is cleaned up correctly. | |
| 2923 TEST_F(GestureRecognizerTest, FlushAllOnHide) { | |
| 2924 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 2925 new GestureEventConsumeDelegate()); | |
| 2926 gfx::Rect bounds(0, 0, 200, 200); | |
| 2927 scoped_ptr<aura::Window> window( | |
| 2928 CreateTestWindowWithDelegate(delegate.get(), 0, bounds, root_window())); | |
| 2929 const int kTouchId1 = 8; | |
| 2930 const int kTouchId2 = 2; | |
| 2931 TimedEvents tes; | |
| 2932 | |
| 2933 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 2934 kTouchId1, tes.Now()); | |
| 2935 DispatchEventUsingWindowDispatcher(&press1); | |
| 2936 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), | |
| 2937 kTouchId2, tes.Now()); | |
| 2938 DispatchEventUsingWindowDispatcher(&press2); | |
| 2939 window->Hide(); | |
| 2940 EXPECT_EQ(NULL, | |
| 2941 ui::GestureRecognizer::Get()->GetTouchLockedTarget(press1)); | |
| 2942 EXPECT_EQ(NULL, | |
| 2943 ui::GestureRecognizer::Get()->GetTouchLockedTarget(press2)); | |
| 2944 } | |
| 2945 | |
| 2946 TEST_F(GestureRecognizerTest, LongPressTimerStopsOnPreventDefaultedTouchMoves) { | |
| 2947 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 2948 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 2949 const int kTouchId = 2; | |
| 2950 gfx::Rect bounds(100, 200, 100, 100); | |
| 2951 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 2952 delegate.get(), -1234, bounds, root_window())); | |
| 2953 delegate->set_window(window.get()); | |
| 2954 TimedEvents tes; | |
| 2955 | |
| 2956 delegate->Reset(); | |
| 2957 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 2958 kTouchId, tes.Now()); | |
| 2959 DispatchEventUsingWindowDispatcher(&press); | |
| 2960 // Scroll around, to cancel the long press | |
| 2961 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); | |
| 2962 | |
| 2963 delegate->Reset(); | |
| 2964 delegate->ReceivedAck(); | |
| 2965 EXPECT_TRUE(delegate->tap_down()); | |
| 2966 | |
| 2967 // Wait long enough that long press would have fired if the touchmove hadn't | |
| 2968 // prevented it. | |
| 2969 DelayByLongPressTimeout(); | |
| 2970 | |
| 2971 delegate->Reset(); | |
| 2972 delegate->ReceivedAckPreventDefaulted(); | |
| 2973 EXPECT_FALSE(delegate->long_press()); | |
| 2974 } | |
| 2975 | |
| 2976 // Same as GestureEventConsumeDelegate, but consumes all the touch-move events. | |
| 2977 class ConsumesTouchMovesDelegate : public GestureEventConsumeDelegate { | |
| 2978 public: | |
| 2979 ConsumesTouchMovesDelegate() : consume_touch_move_(true) {} | |
| 2980 virtual ~ConsumesTouchMovesDelegate() {} | |
| 2981 | |
| 2982 void set_consume_touch_move(bool consume) { consume_touch_move_ = consume; } | |
| 2983 | |
| 2984 private: | |
| 2985 virtual void OnTouchEvent(ui::TouchEvent* touch) override { | |
| 2986 if (consume_touch_move_ && touch->type() == ui::ET_TOUCH_MOVED) | |
| 2987 touch->SetHandled(); | |
| 2988 else | |
| 2989 GestureEventConsumeDelegate::OnTouchEvent(touch); | |
| 2990 } | |
| 2991 | |
| 2992 bool consume_touch_move_; | |
| 2993 | |
| 2994 DISALLOW_COPY_AND_ASSIGN(ConsumesTouchMovesDelegate); | |
| 2995 }; | |
| 2996 | |
| 2997 // Same as GestureEventScroll, but tests that the behavior is the same | |
| 2998 // even if all the touch-move events are consumed. | |
| 2999 TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { | |
| 3000 scoped_ptr<ConsumesTouchMovesDelegate> delegate( | |
| 3001 new ConsumesTouchMovesDelegate()); | |
| 3002 const int kWindowWidth = 123; | |
| 3003 const int kWindowHeight = 45; | |
| 3004 const int kTouchId = 5; | |
| 3005 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3006 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3007 delegate.get(), -1234, bounds, root_window())); | |
| 3008 TimedEvents tes; | |
| 3009 | |
| 3010 delegate->Reset(); | |
| 3011 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3012 kTouchId, tes.Now()); | |
| 3013 DispatchEventUsingWindowDispatcher(&press); | |
| 3014 EXPECT_FALSE(delegate->tap()); | |
| 3015 EXPECT_TRUE(delegate->tap_down()); | |
| 3016 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3017 EXPECT_TRUE(delegate->begin()); | |
| 3018 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3019 EXPECT_FALSE(delegate->scroll_update()); | |
| 3020 EXPECT_FALSE(delegate->scroll_end()); | |
| 3021 | |
| 3022 // Move the touch-point enough so that it would normally be considered a | |
| 3023 // scroll. But since the touch-moves will be consumed, the scroll should not | |
| 3024 // start. | |
| 3025 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); | |
| 3026 EXPECT_FALSE(delegate->tap()); | |
| 3027 EXPECT_FALSE(delegate->tap_down()); | |
| 3028 EXPECT_TRUE(delegate->tap_cancel()); | |
| 3029 EXPECT_FALSE(delegate->begin()); | |
| 3030 EXPECT_FALSE(delegate->scroll_update()); | |
| 3031 EXPECT_FALSE(delegate->scroll_end()); | |
| 3032 | |
| 3033 EXPECT_TRUE(delegate->scroll_begin()); | |
| 3034 | |
| 3035 // Release the touch back at the start point. This should end without causing | |
| 3036 // a tap. | |
| 3037 delegate->Reset(); | |
| 3038 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(130, 230), | |
| 3039 kTouchId, tes.LeapForward(50)); | |
| 3040 DispatchEventUsingWindowDispatcher(&release); | |
| 3041 EXPECT_FALSE(delegate->tap()); | |
| 3042 EXPECT_FALSE(delegate->tap_down()); | |
| 3043 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3044 EXPECT_FALSE(delegate->begin()); | |
| 3045 EXPECT_TRUE(delegate->end()); | |
| 3046 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3047 EXPECT_FALSE(delegate->scroll_update()); | |
| 3048 | |
| 3049 EXPECT_TRUE(delegate->scroll_end()); | |
| 3050 } | |
| 3051 | |
| 3052 // Tests the behavior of 2F scroll when some of the touch-move events are | |
| 3053 // consumed. | |
| 3054 TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { | |
| 3055 scoped_ptr<ConsumesTouchMovesDelegate> delegate( | |
| 3056 new ConsumesTouchMovesDelegate()); | |
| 3057 const int kWindowWidth = 123; | |
| 3058 const int kWindowHeight = 100; | |
| 3059 const int kTouchId1 = 2; | |
| 3060 const int kTouchId2 = 3; | |
| 3061 TimedEvents tes; | |
| 3062 | |
| 3063 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3064 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3065 delegate.get(), -1234, bounds, root_window())); | |
| 3066 | |
| 3067 delegate->Reset(); | |
| 3068 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3069 kTouchId1, tes.Now()); | |
| 3070 DispatchEventUsingWindowDispatcher(&press1); | |
| 3071 tes.SendScrollEvent(event_processor(), 131, 231, kTouchId1, delegate.get()); | |
| 3072 | |
| 3073 EXPECT_2_EVENTS(delegate->events(), | |
| 3074 ui::ET_GESTURE_TAP_CANCEL, | |
| 3075 ui::ET_GESTURE_SCROLL_BEGIN); | |
| 3076 | |
| 3077 delegate->Reset(); | |
| 3078 // Second finger touches down and moves. | |
| 3079 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), | |
| 3080 kTouchId2, tes.LeapForward(50)); | |
| 3081 DispatchEventUsingWindowDispatcher(&press2); | |
| 3082 tes.SendScrollEvent(event_processor(), 161, 231, kTouchId2, delegate.get()); | |
| 3083 EXPECT_0_EVENTS(delegate->events()); | |
| 3084 | |
| 3085 delegate->Reset(); | |
| 3086 // Move first finger again, no PinchUpdate & ScrollUpdate. | |
| 3087 tes.SendScrollEvent(event_processor(), 161, 261, kTouchId1, delegate.get()); | |
| 3088 EXPECT_0_EVENTS(delegate->events()); | |
| 3089 | |
| 3090 // Stops consuming touch-move. | |
| 3091 delegate->set_consume_touch_move(false); | |
| 3092 | |
| 3093 delegate->Reset(); | |
| 3094 // Making a pinch gesture. | |
| 3095 tes.SendScrollEvent(event_processor(), 161, 260, kTouchId1, delegate.get()); | |
| 3096 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 3097 | |
| 3098 delegate->Reset(); | |
| 3099 tes.SendScrollEvent(event_processor(), 161, 261, kTouchId2, delegate.get()); | |
| 3100 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 3101 | |
| 3102 delegate->Reset(); | |
| 3103 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3104 kTouchId1, tes.Now()); | |
| 3105 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(130, 201), | |
| 3106 kTouchId2, tes.Now()); | |
| 3107 DispatchEventUsingWindowDispatcher(&release1); | |
| 3108 DispatchEventUsingWindowDispatcher(&release2); | |
| 3109 | |
| 3110 EXPECT_3_EVENTS(delegate->events(), | |
| 3111 ui::ET_GESTURE_END, | |
| 3112 ui::ET_GESTURE_SCROLL_END, | |
| 3113 ui::ET_GESTURE_END); | |
| 3114 } | |
| 3115 | |
| 3116 // Like as GestureEventTouchMoveConsumed but tests the different behavior | |
| 3117 // depending on whether the events were consumed before or after the scroll | |
| 3118 // started. | |
| 3119 TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { | |
| 3120 scoped_ptr<ConsumesTouchMovesDelegate> delegate( | |
| 3121 new ConsumesTouchMovesDelegate()); | |
| 3122 const int kWindowWidth = 123; | |
| 3123 const int kWindowHeight = 45; | |
| 3124 const int kTouchId = 5; | |
| 3125 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3126 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3127 delegate.get(), -1234, bounds, root_window())); | |
| 3128 TimedEvents tes; | |
| 3129 | |
| 3130 delegate->Reset(); | |
| 3131 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3132 kTouchId, tes.Now()); | |
| 3133 DispatchEventUsingWindowDispatcher(&press); | |
| 3134 EXPECT_FALSE(delegate->tap()); | |
| 3135 EXPECT_TRUE(delegate->tap_down()); | |
| 3136 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3137 EXPECT_TRUE(delegate->begin()); | |
| 3138 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3139 EXPECT_FALSE(delegate->scroll_update()); | |
| 3140 EXPECT_FALSE(delegate->scroll_end()); | |
| 3141 | |
| 3142 // Move the touch-point enough so that it would normally be considered a | |
| 3143 // scroll. But since the touch-moves will be consumed, the scroll should not | |
| 3144 // start. | |
| 3145 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); | |
| 3146 EXPECT_FALSE(delegate->tap()); | |
| 3147 EXPECT_FALSE(delegate->tap_down()); | |
| 3148 EXPECT_TRUE(delegate->tap_cancel()); | |
| 3149 EXPECT_FALSE(delegate->begin()); | |
| 3150 EXPECT_FALSE(delegate->scroll_update()); | |
| 3151 EXPECT_FALSE(delegate->scroll_end()); | |
| 3152 | |
| 3153 // Consuming the first touch move event won't prevent all future scrolling. | |
| 3154 EXPECT_TRUE(delegate->scroll_begin()); | |
| 3155 | |
| 3156 // Now, stop consuming touch-move events, and move the touch-point again. | |
| 3157 delegate->set_consume_touch_move(false); | |
| 3158 tes.SendScrollEvent(event_processor(), 159, 259, kTouchId, delegate.get()); | |
| 3159 EXPECT_FALSE(delegate->tap()); | |
| 3160 EXPECT_FALSE(delegate->tap_down()); | |
| 3161 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3162 EXPECT_FALSE(delegate->begin()); | |
| 3163 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3164 EXPECT_FALSE(delegate->scroll_end()); | |
| 3165 | |
| 3166 // Scroll not prevented by consumed first touch move. | |
| 3167 EXPECT_TRUE(delegate->scroll_update()); | |
| 3168 EXPECT_EQ(29, delegate->scroll_x()); | |
| 3169 EXPECT_EQ(29, delegate->scroll_y()); | |
| 3170 EXPECT_EQ(gfx::Point(0, 0).ToString(), | |
| 3171 delegate->scroll_begin_position().ToString()); | |
| 3172 | |
| 3173 // Start consuming touch-move events again. | |
| 3174 delegate->set_consume_touch_move(true); | |
| 3175 | |
| 3176 // Move some more to generate a few more scroll updates. | |
| 3177 tes.SendScrollEvent(event_processor(), 110, 211, kTouchId, delegate.get()); | |
| 3178 EXPECT_FALSE(delegate->tap()); | |
| 3179 EXPECT_FALSE(delegate->tap_down()); | |
| 3180 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3181 EXPECT_FALSE(delegate->begin()); | |
| 3182 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3183 EXPECT_FALSE(delegate->scroll_update()); | |
| 3184 EXPECT_FALSE(delegate->scroll_end()); | |
| 3185 EXPECT_EQ(0, delegate->scroll_x()); | |
| 3186 EXPECT_EQ(0, delegate->scroll_y()); | |
| 3187 | |
| 3188 tes.SendScrollEvent(event_processor(), 140, 215, kTouchId, delegate.get()); | |
| 3189 EXPECT_FALSE(delegate->tap()); | |
| 3190 EXPECT_FALSE(delegate->tap_down()); | |
| 3191 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3192 EXPECT_FALSE(delegate->begin()); | |
| 3193 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3194 EXPECT_FALSE(delegate->scroll_update()); | |
| 3195 EXPECT_FALSE(delegate->scroll_end()); | |
| 3196 EXPECT_EQ(0, delegate->scroll_x()); | |
| 3197 EXPECT_EQ(0, delegate->scroll_y()); | |
| 3198 | |
| 3199 // Release the touch. | |
| 3200 delegate->Reset(); | |
| 3201 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3202 kTouchId, tes.LeapForward(50)); | |
| 3203 DispatchEventUsingWindowDispatcher(&release); | |
| 3204 EXPECT_FALSE(delegate->tap()); | |
| 3205 EXPECT_FALSE(delegate->tap_down()); | |
| 3206 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3207 EXPECT_FALSE(delegate->begin()); | |
| 3208 EXPECT_TRUE(delegate->end()); | |
| 3209 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3210 EXPECT_FALSE(delegate->scroll_update()); | |
| 3211 EXPECT_FALSE(delegate->fling()); | |
| 3212 | |
| 3213 EXPECT_TRUE(delegate->scroll_end()); | |
| 3214 } | |
| 3215 | |
| 3216 // Check that appropriate touch events generate double tap gesture events. | |
| 3217 TEST_F(GestureRecognizerTest, GestureEventDoubleTap) { | |
| 3218 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3219 new GestureEventConsumeDelegate()); | |
| 3220 const int kWindowWidth = 123; | |
| 3221 const int kWindowHeight = 45; | |
| 3222 const int kTouchId = 2; | |
| 3223 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3224 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3225 delegate.get(), -1234, bounds, root_window())); | |
| 3226 TimedEvents tes; | |
| 3227 | |
| 3228 // First tap (tested in GestureEventTap) | |
| 3229 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(104, 201), | |
| 3230 kTouchId, tes.Now()); | |
| 3231 DispatchEventUsingWindowDispatcher(&press1); | |
| 3232 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(104, 201), | |
| 3233 kTouchId, tes.LeapForward(50)); | |
| 3234 DispatchEventUsingWindowDispatcher(&release1); | |
| 3235 delegate->Reset(); | |
| 3236 | |
| 3237 // Second tap | |
| 3238 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 203), | |
| 3239 kTouchId, tes.LeapForward(200)); | |
| 3240 DispatchEventUsingWindowDispatcher(&press2); | |
| 3241 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(102, 206), | |
| 3242 kTouchId, tes.LeapForward(50)); | |
| 3243 DispatchEventUsingWindowDispatcher(&release2); | |
| 3244 | |
| 3245 EXPECT_TRUE(delegate->tap()); | |
| 3246 EXPECT_TRUE(delegate->tap_down()); | |
| 3247 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3248 EXPECT_TRUE(delegate->begin()); | |
| 3249 EXPECT_TRUE(delegate->end()); | |
| 3250 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3251 EXPECT_FALSE(delegate->scroll_update()); | |
| 3252 EXPECT_FALSE(delegate->scroll_end()); | |
| 3253 | |
| 3254 EXPECT_EQ(2, delegate->tap_count()); | |
| 3255 } | |
| 3256 | |
| 3257 // Check that appropriate touch events generate triple tap gesture events. | |
| 3258 TEST_F(GestureRecognizerTest, GestureEventTripleTap) { | |
| 3259 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3260 new GestureEventConsumeDelegate()); | |
| 3261 const int kWindowWidth = 123; | |
| 3262 const int kWindowHeight = 45; | |
| 3263 const int kTouchId = 2; | |
| 3264 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3265 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3266 delegate.get(), -1234, bounds, root_window())); | |
| 3267 TimedEvents tes; | |
| 3268 | |
| 3269 // First tap (tested in GestureEventTap) | |
| 3270 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(104, 201), | |
| 3271 kTouchId, tes.Now()); | |
| 3272 DispatchEventUsingWindowDispatcher(&press1); | |
| 3273 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(104, 201), | |
| 3274 kTouchId, tes.LeapForward(50)); | |
| 3275 DispatchEventUsingWindowDispatcher(&release1); | |
| 3276 | |
| 3277 EXPECT_EQ(1, delegate->tap_count()); | |
| 3278 delegate->Reset(); | |
| 3279 | |
| 3280 // Second tap (tested in GestureEventDoubleTap) | |
| 3281 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 203), | |
| 3282 kTouchId, tes.LeapForward(200)); | |
| 3283 DispatchEventUsingWindowDispatcher(&press2); | |
| 3284 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(102, 206), | |
| 3285 kTouchId, tes.LeapForward(50)); | |
| 3286 DispatchEventUsingWindowDispatcher(&release2); | |
| 3287 | |
| 3288 EXPECT_EQ(2, delegate->tap_count()); | |
| 3289 delegate->Reset(); | |
| 3290 | |
| 3291 // Third tap | |
| 3292 ui::TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(102, 206), | |
| 3293 kTouchId, tes.LeapForward(200)); | |
| 3294 DispatchEventUsingWindowDispatcher(&press3); | |
| 3295 ui::TouchEvent release3(ui::ET_TOUCH_RELEASED, gfx::Point(102, 206), | |
| 3296 kTouchId, tes.LeapForward(50)); | |
| 3297 DispatchEventUsingWindowDispatcher(&release3); | |
| 3298 | |
| 3299 // Third, Fourth and Fifth Taps. Taps after the third should have their | |
| 3300 // |tap_count| wrap around back to 1. | |
| 3301 for (int i = 3; i < 5; ++i) { | |
| 3302 ui::TouchEvent press3(ui::ET_TOUCH_PRESSED, | |
| 3303 gfx::Point(102, 206), | |
| 3304 kTouchId, | |
| 3305 tes.LeapForward(200)); | |
| 3306 DispatchEventUsingWindowDispatcher(&press3); | |
| 3307 ui::TouchEvent release3(ui::ET_TOUCH_RELEASED, | |
| 3308 gfx::Point(102, 206), | |
| 3309 kTouchId, | |
| 3310 tes.LeapForward(50)); | |
| 3311 DispatchEventUsingWindowDispatcher(&release3); | |
| 3312 | |
| 3313 EXPECT_TRUE(delegate->tap()); | |
| 3314 EXPECT_TRUE(delegate->tap_down()); | |
| 3315 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3316 EXPECT_TRUE(delegate->begin()); | |
| 3317 EXPECT_TRUE(delegate->end()); | |
| 3318 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3319 EXPECT_FALSE(delegate->scroll_update()); | |
| 3320 EXPECT_FALSE(delegate->scroll_end()); | |
| 3321 EXPECT_EQ(1 + (i % 3), delegate->tap_count()); | |
| 3322 } | |
| 3323 } | |
| 3324 | |
| 3325 // Check that we don't get a double tap when the two taps are far apart. | |
| 3326 TEST_F(GestureRecognizerTest, TwoTapsFarApart) { | |
| 3327 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3328 new GestureEventConsumeDelegate()); | |
| 3329 const int kWindowWidth = 123; | |
| 3330 const int kWindowHeight = 45; | |
| 3331 const int kTouchId = 2; | |
| 3332 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3333 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3334 delegate.get(), -1234, bounds, root_window())); | |
| 3335 TimedEvents tes; | |
| 3336 | |
| 3337 // First tap (tested in GestureEventTap) | |
| 3338 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3339 kTouchId, tes.Now()); | |
| 3340 DispatchEventUsingWindowDispatcher(&press1); | |
| 3341 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3342 kTouchId, tes.LeapForward(50)); | |
| 3343 DispatchEventUsingWindowDispatcher(&release1); | |
| 3344 delegate->Reset(); | |
| 3345 | |
| 3346 // Second tap, close in time but far in distance | |
| 3347 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(201, 201), | |
| 3348 kTouchId, tes.LeapForward(200)); | |
| 3349 DispatchEventUsingWindowDispatcher(&press2); | |
| 3350 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(201, 201), | |
| 3351 kTouchId, tes.LeapForward(50)); | |
| 3352 DispatchEventUsingWindowDispatcher(&release2); | |
| 3353 | |
| 3354 EXPECT_TRUE(delegate->tap()); | |
| 3355 EXPECT_TRUE(delegate->tap_down()); | |
| 3356 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3357 EXPECT_TRUE(delegate->begin()); | |
| 3358 EXPECT_TRUE(delegate->end()); | |
| 3359 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3360 EXPECT_FALSE(delegate->scroll_update()); | |
| 3361 EXPECT_FALSE(delegate->scroll_end()); | |
| 3362 | |
| 3363 EXPECT_EQ(1, delegate->tap_count()); | |
| 3364 } | |
| 3365 | |
| 3366 // Check that we don't get a double tap when the two taps have a long enough | |
| 3367 // delay in between. | |
| 3368 TEST_F(GestureRecognizerTest, TwoTapsWithDelayBetween) { | |
| 3369 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3370 new GestureEventConsumeDelegate()); | |
| 3371 const int kWindowWidth = 123; | |
| 3372 const int kWindowHeight = 45; | |
| 3373 const int kTouchId = 2; | |
| 3374 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3375 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3376 delegate.get(), -1234, bounds, root_window())); | |
| 3377 TimedEvents tes; | |
| 3378 | |
| 3379 // First tap (tested in GestureEventTap) | |
| 3380 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3381 kTouchId, tes.Now()); | |
| 3382 DispatchEventUsingWindowDispatcher(&press1); | |
| 3383 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3384 kTouchId, tes.LeapForward(50)); | |
| 3385 DispatchEventUsingWindowDispatcher(&release1); | |
| 3386 delegate->Reset(); | |
| 3387 | |
| 3388 // Second tap, close in distance but after some delay | |
| 3389 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3390 kTouchId, tes.LeapForward(2000)); | |
| 3391 DispatchEventUsingWindowDispatcher(&press2); | |
| 3392 ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3393 kTouchId, tes.LeapForward(50)); | |
| 3394 DispatchEventUsingWindowDispatcher(&release2); | |
| 3395 | |
| 3396 EXPECT_TRUE(delegate->tap()); | |
| 3397 EXPECT_TRUE(delegate->tap_down()); | |
| 3398 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3399 EXPECT_TRUE(delegate->begin()); | |
| 3400 EXPECT_TRUE(delegate->end()); | |
| 3401 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3402 EXPECT_FALSE(delegate->scroll_update()); | |
| 3403 EXPECT_FALSE(delegate->scroll_end()); | |
| 3404 | |
| 3405 EXPECT_EQ(1, delegate->tap_count()); | |
| 3406 } | |
| 3407 | |
| 3408 // Checks that if the bounding-box of a gesture changes because of change in | |
| 3409 // radius of a touch-point, and not because of change in position, then there | |
| 3410 // are not gesture events from that. | |
| 3411 TEST_F(GestureRecognizerTest, BoundingBoxRadiusChange) { | |
| 3412 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3413 new GestureEventConsumeDelegate()); | |
| 3414 const int kWindowWidth = 234; | |
| 3415 const int kWindowHeight = 345; | |
| 3416 const int kTouchId = 5, kTouchId2 = 7; | |
| 3417 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3418 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3419 delegate.get(), -1234, bounds, root_window())); | |
| 3420 TimedEvents tes; | |
| 3421 | |
| 3422 ui::TouchEvent press1( | |
| 3423 ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); | |
| 3424 DispatchEventUsingWindowDispatcher(&press1); | |
| 3425 EXPECT_TRUE(delegate->bounding_box().IsEmpty()); | |
| 3426 | |
| 3427 delegate->Reset(); | |
| 3428 | |
| 3429 ui::TouchEvent press2( | |
| 3430 ui::ET_TOUCH_PRESSED, gfx::Point(201, 201), kTouchId2, | |
| 3431 tes.LeapForward(400)); | |
| 3432 press2.set_radius_x(5); | |
| 3433 DispatchEventUsingWindowDispatcher(&press2); | |
| 3434 EXPECT_FALSE(delegate->pinch_begin()); | |
| 3435 EXPECT_EQ(gfx::Rect(101, 196, 105, 10).ToString(), | |
| 3436 delegate->bounding_box().ToString()); | |
| 3437 | |
| 3438 delegate->Reset(); | |
| 3439 | |
| 3440 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(50, 50), kTouchId, | |
| 3441 tes.LeapForward(40)); | |
| 3442 DispatchEventUsingWindowDispatcher(&move1); | |
| 3443 EXPECT_TRUE(delegate->pinch_begin()); | |
| 3444 EXPECT_EQ(gfx::Rect(50, 50, 156, 156).ToString(), | |
| 3445 delegate->bounding_box().ToString()); | |
| 3446 | |
| 3447 delegate->Reset(); | |
| 3448 | |
| 3449 // The position doesn't move, but the radius changes. | |
| 3450 ui::TouchEvent move2( | |
| 3451 ui::ET_TOUCH_MOVED, gfx::Point(50, 50), kTouchId, tes.LeapForward(40)); | |
| 3452 move2.set_radius_x(50); | |
| 3453 move2.set_radius_y(60); | |
| 3454 DispatchEventUsingWindowDispatcher(&move2); | |
| 3455 EXPECT_FALSE(delegate->tap()); | |
| 3456 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3457 EXPECT_FALSE(delegate->scroll_update()); | |
| 3458 EXPECT_FALSE(delegate->pinch_update()); | |
| 3459 | |
| 3460 delegate->Reset(); | |
| 3461 } | |
| 3462 | |
| 3463 // Checks that slow scrolls deliver the correct deltas. | |
| 3464 // In particular, fix for http;//crbug.com/150573. | |
| 3465 TEST_F(GestureRecognizerTest, NoDriftInScroll) { | |
| 3466 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(3); | |
| 3467 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3468 new GestureEventConsumeDelegate()); | |
| 3469 const int kWindowWidth = 234; | |
| 3470 const int kWindowHeight = 345; | |
| 3471 const int kTouchId = 5; | |
| 3472 TimedEvents tes; | |
| 3473 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3474 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3475 delegate.get(), -1234, bounds, root_window())); | |
| 3476 | |
| 3477 ui::TouchEvent press1( | |
| 3478 ui::ET_TOUCH_PRESSED, gfx::Point(101, 208), kTouchId, tes.Now()); | |
| 3479 DispatchEventUsingWindowDispatcher(&press1); | |
| 3480 EXPECT_TRUE(delegate->begin()); | |
| 3481 | |
| 3482 delegate->Reset(); | |
| 3483 | |
| 3484 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(101, 206), kTouchId, | |
| 3485 tes.LeapForward(40)); | |
| 3486 DispatchEventUsingWindowDispatcher(&move1); | |
| 3487 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3488 | |
| 3489 delegate->Reset(); | |
| 3490 | |
| 3491 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(101, 204), kTouchId, | |
| 3492 tes.LeapForward(40)); | |
| 3493 DispatchEventUsingWindowDispatcher(&move2); | |
| 3494 EXPECT_TRUE(delegate->tap_cancel()); | |
| 3495 EXPECT_TRUE(delegate->scroll_begin()); | |
| 3496 EXPECT_TRUE(delegate->scroll_update()); | |
| 3497 // 3 px consumed by touch slop region. | |
| 3498 EXPECT_EQ(-1, delegate->scroll_y()); | |
| 3499 EXPECT_EQ(-4, delegate->scroll_y_hint()); | |
| 3500 | |
| 3501 delegate->Reset(); | |
| 3502 | |
| 3503 ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(101, 204), kTouchId, | |
| 3504 tes.LeapForward(40)); | |
| 3505 DispatchEventUsingWindowDispatcher(&move3); | |
| 3506 EXPECT_FALSE(delegate->scroll_update()); | |
| 3507 | |
| 3508 delegate->Reset(); | |
| 3509 | |
| 3510 ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(101, 203), kTouchId, | |
| 3511 tes.LeapForward(40)); | |
| 3512 DispatchEventUsingWindowDispatcher(&move4); | |
| 3513 EXPECT_TRUE(delegate->scroll_update()); | |
| 3514 EXPECT_EQ(-1, delegate->scroll_y()); | |
| 3515 | |
| 3516 delegate->Reset(); | |
| 3517 } | |
| 3518 | |
| 3519 // Ensure that move events which are preventDefaulted will cause a tap | |
| 3520 // cancel gesture event to be fired if the move would normally cause a | |
| 3521 // scroll. See bug http://crbug.com/146397. | |
| 3522 TEST_F(GestureRecognizerTest, GestureEventConsumedTouchMoveCanFireTapCancel) { | |
| 3523 scoped_ptr<ConsumesTouchMovesDelegate> delegate( | |
| 3524 new ConsumesTouchMovesDelegate()); | |
| 3525 const int kTouchId = 5; | |
| 3526 gfx::Rect bounds(100, 200, 123, 45); | |
| 3527 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3528 delegate.get(), -1234, bounds, root_window())); | |
| 3529 TimedEvents tes; | |
| 3530 | |
| 3531 delegate->Reset(); | |
| 3532 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3533 kTouchId, tes.Now()); | |
| 3534 | |
| 3535 delegate->set_consume_touch_move(false); | |
| 3536 DispatchEventUsingWindowDispatcher(&press); | |
| 3537 delegate->set_consume_touch_move(true); | |
| 3538 delegate->Reset(); | |
| 3539 // Move the touch-point enough so that it would normally be considered a | |
| 3540 // scroll. But since the touch-moves will be consumed, no scrolling should | |
| 3541 // occur. | |
| 3542 // With the unified gesture detector, we will receive a scroll begin gesture, | |
| 3543 // whereas with the aura gesture recognizer we won't. | |
| 3544 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); | |
| 3545 EXPECT_FALSE(delegate->tap()); | |
| 3546 EXPECT_FALSE(delegate->tap_down()); | |
| 3547 EXPECT_TRUE(delegate->tap_cancel()); | |
| 3548 EXPECT_FALSE(delegate->begin()); | |
| 3549 EXPECT_FALSE(delegate->scroll_update()); | |
| 3550 EXPECT_FALSE(delegate->scroll_end()); | |
| 3551 } | |
| 3552 | |
| 3553 TEST_F(GestureRecognizerTest, | |
| 3554 TransferEventDispatchesTouchCancel) { | |
| 3555 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3556 new GestureEventConsumeDelegate()); | |
| 3557 TimedEvents tes; | |
| 3558 const int kWindowWidth = 800; | |
| 3559 const int kWindowHeight = 600; | |
| 3560 const int kTouchId1 = 1; | |
| 3561 const int kTouchId2 = 2; | |
| 3562 gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); | |
| 3563 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3564 delegate.get(), -1234, bounds, root_window())); | |
| 3565 scoped_ptr<TestEventHandler> handler(new TestEventHandler()); | |
| 3566 window->AddPreTargetHandler(handler.get()); | |
| 3567 | |
| 3568 // Start a gesture sequence on |window|. Then transfer the events to NULL. | |
| 3569 // Make sure |window| receives a touch-cancel event. | |
| 3570 delegate->Reset(); | |
| 3571 ui::TouchEvent press( | |
| 3572 ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); | |
| 3573 DispatchEventUsingWindowDispatcher(&press); | |
| 3574 EXPECT_2_EVENTS( | |
| 3575 delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); | |
| 3576 delegate->Reset(); | |
| 3577 ui::TouchEvent p2( | |
| 3578 ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), kTouchId2, tes.Now()); | |
| 3579 DispatchEventUsingWindowDispatcher(&p2); | |
| 3580 EXPECT_2_EVENTS( | |
| 3581 delegate->events(), ui::ET_GESTURE_TAP_CANCEL, ui::ET_GESTURE_BEGIN); | |
| 3582 delegate->Reset(); | |
| 3583 ui::TouchEvent move( | |
| 3584 ui::ET_TOUCH_MOVED, gfx::Point(350, 300), kTouchId2, tes.Now()); | |
| 3585 DispatchEventUsingWindowDispatcher(&move); | |
| 3586 EXPECT_3_EVENTS(delegate->events(), | |
| 3587 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 3588 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 3589 ui::ET_GESTURE_PINCH_BEGIN); | |
| 3590 EXPECT_EQ(2, handler->touch_pressed_count()); | |
| 3591 delegate->Reset(); | |
| 3592 handler->Reset(); | |
| 3593 | |
| 3594 ui::GestureRecognizer* gesture_recognizer = ui::GestureRecognizer::Get(); | |
| 3595 EXPECT_EQ(window.get(), | |
| 3596 gesture_recognizer->GetTouchLockedTarget(press)); | |
| 3597 gesture_recognizer->TransferEventsTo(window.get(), NULL); | |
| 3598 EXPECT_EQ(NULL, | |
| 3599 gesture_recognizer->GetTouchLockedTarget(press)); | |
| 3600 EXPECT_4_EVENTS(delegate->events(), | |
| 3601 ui::ET_GESTURE_PINCH_END, | |
| 3602 ui::ET_GESTURE_SCROLL_END, | |
| 3603 ui::ET_GESTURE_END, | |
| 3604 ui::ET_GESTURE_END); | |
| 3605 const std::vector<gfx::PointF>& points = handler->cancelled_touch_points(); | |
| 3606 EXPECT_EQ(2U, points.size()); | |
| 3607 EXPECT_EQ(gfx::Point(101, 201), points[0]); | |
| 3608 EXPECT_EQ(gfx::Point(350, 300), points[1]); | |
| 3609 } | |
| 3610 | |
| 3611 // Check that appropriate touch events generate show press events | |
| 3612 TEST_F(GestureRecognizerTest, GestureEventShowPress) { | |
| 3613 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3614 new GestureEventConsumeDelegate()); | |
| 3615 TimedEvents tes; | |
| 3616 const int kWindowWidth = 123; | |
| 3617 const int kWindowHeight = 45; | |
| 3618 const int kTouchId = 2; | |
| 3619 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3620 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3621 delegate.get(), -1234, bounds, root_window())); | |
| 3622 | |
| 3623 delegate->Reset(); | |
| 3624 | |
| 3625 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3626 kTouchId, tes.Now()); | |
| 3627 DispatchEventUsingWindowDispatcher(&press1); | |
| 3628 EXPECT_TRUE(delegate->tap_down()); | |
| 3629 EXPECT_TRUE(delegate->begin()); | |
| 3630 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3631 | |
| 3632 // We haven't pressed long enough for a show press to occur | |
| 3633 EXPECT_FALSE(delegate->show_press()); | |
| 3634 | |
| 3635 // Wait until the timer runs out | |
| 3636 delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_SHOW_PRESS); | |
| 3637 EXPECT_TRUE(delegate->show_press()); | |
| 3638 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3639 | |
| 3640 delegate->Reset(); | |
| 3641 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3642 kTouchId, tes.Now()); | |
| 3643 DispatchEventUsingWindowDispatcher(&release1); | |
| 3644 EXPECT_FALSE(delegate->long_press()); | |
| 3645 | |
| 3646 // Note the tap isn't dispatched until the release | |
| 3647 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3648 EXPECT_TRUE(delegate->tap()); | |
| 3649 } | |
| 3650 | |
| 3651 // Check that scrolling cancels a show press | |
| 3652 TEST_F(GestureRecognizerTest, GestureEventShowPressCancelledByScroll) { | |
| 3653 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3654 new GestureEventConsumeDelegate()); | |
| 3655 TimedEvents tes; | |
| 3656 const int kWindowWidth = 123; | |
| 3657 const int kWindowHeight = 45; | |
| 3658 const int kTouchId = 6; | |
| 3659 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3660 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3661 delegate.get(), -1234, bounds, root_window())); | |
| 3662 | |
| 3663 delegate->Reset(); | |
| 3664 | |
| 3665 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3666 kTouchId, tes.Now()); | |
| 3667 DispatchEventUsingWindowDispatcher(&press1); | |
| 3668 EXPECT_TRUE(delegate->tap_down()); | |
| 3669 | |
| 3670 // We haven't pressed long enough for a show press to occur | |
| 3671 EXPECT_FALSE(delegate->show_press()); | |
| 3672 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3673 | |
| 3674 // Scroll around, to cancel the show press | |
| 3675 tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); | |
| 3676 // Wait until the timer runs out | |
| 3677 DelayByShowPressTimeout(); | |
| 3678 EXPECT_FALSE(delegate->show_press()); | |
| 3679 EXPECT_TRUE(delegate->tap_cancel()); | |
| 3680 | |
| 3681 delegate->Reset(); | |
| 3682 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3683 kTouchId, tes.LeapForward(10)); | |
| 3684 DispatchEventUsingWindowDispatcher(&release1); | |
| 3685 EXPECT_FALSE(delegate->show_press()); | |
| 3686 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3687 } | |
| 3688 | |
| 3689 // Test that show press events are sent immediately on tap | |
| 3690 TEST_F(GestureRecognizerTest, GestureEventShowPressSentOnTap) { | |
| 3691 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3692 new GestureEventConsumeDelegate()); | |
| 3693 TimedEvents tes; | |
| 3694 const int kWindowWidth = 123; | |
| 3695 const int kWindowHeight = 45; | |
| 3696 const int kTouchId = 6; | |
| 3697 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3698 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3699 delegate.get(), -1234, bounds, root_window())); | |
| 3700 | |
| 3701 delegate->Reset(); | |
| 3702 | |
| 3703 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3704 kTouchId, tes.Now()); | |
| 3705 DispatchEventUsingWindowDispatcher(&press1); | |
| 3706 EXPECT_TRUE(delegate->tap_down()); | |
| 3707 | |
| 3708 // We haven't pressed long enough for a show press to occur | |
| 3709 EXPECT_FALSE(delegate->show_press()); | |
| 3710 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3711 | |
| 3712 delegate->Reset(); | |
| 3713 ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 3714 kTouchId, tes.LeapForward(50)); | |
| 3715 DispatchEventUsingWindowDispatcher(&release1); | |
| 3716 EXPECT_TRUE(delegate->show_press()); | |
| 3717 EXPECT_FALSE(delegate->tap_cancel()); | |
| 3718 EXPECT_TRUE(delegate->tap()); | |
| 3719 } | |
| 3720 | |
| 3721 // Test that consuming the first move touch event prevents a scroll. | |
| 3722 TEST_F(GestureRecognizerTest, GestureEventConsumedTouchMoveScrollTest) { | |
| 3723 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 3724 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 3725 TimedEvents tes; | |
| 3726 const int kTouchId = 7; | |
| 3727 gfx::Rect bounds(0, 0, 1000, 1000); | |
| 3728 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3729 delegate.get(), -1234, bounds, root_window())); | |
| 3730 delegate->set_window(window.get()); | |
| 3731 | |
| 3732 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 3733 kTouchId, tes.Now()); | |
| 3734 DispatchEventUsingWindowDispatcher(&press); | |
| 3735 delegate->ReceivedAck(); | |
| 3736 | |
| 3737 // A touch move within the slop region is never consumed in web contents. The | |
| 3738 // unified GR won't prevent scroll if a touch move within the slop region is | |
| 3739 // consumed, so make sure this touch move exceeds the slop region. | |
| 3740 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(10, 10), | |
| 3741 kTouchId, tes.Now()); | |
| 3742 DispatchEventUsingWindowDispatcher(&move1); | |
| 3743 delegate->ReceivedAckPreventDefaulted(); | |
| 3744 | |
| 3745 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), | |
| 3746 kTouchId, tes.Now()); | |
| 3747 DispatchEventUsingWindowDispatcher(&move2); | |
| 3748 delegate->ReceivedAck(); | |
| 3749 | |
| 3750 // With the unified gesture detector, consuming the first touch move event | |
| 3751 // won't prevent all future scrolling. | |
| 3752 EXPECT_TRUE(delegate->scroll_begin()); | |
| 3753 EXPECT_TRUE(delegate->scroll_update()); | |
| 3754 } | |
| 3755 | |
| 3756 // Test that consuming the first move touch doesn't prevent a tap. | |
| 3757 TEST_F(GestureRecognizerTest, GestureEventConsumedTouchMoveTapTest) { | |
| 3758 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 3759 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 3760 TimedEvents tes; | |
| 3761 const int kTouchId = 7; | |
| 3762 gfx::Rect bounds(0, 0, 1000, 1000); | |
| 3763 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3764 delegate.get(), -1234, bounds, root_window())); | |
| 3765 delegate->set_window(window.get()); | |
| 3766 | |
| 3767 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 3768 kTouchId, tes.Now()); | |
| 3769 DispatchEventUsingWindowDispatcher(&press); | |
| 3770 delegate->ReceivedAck(); | |
| 3771 | |
| 3772 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(2, 2), | |
| 3773 kTouchId, tes.Now()); | |
| 3774 DispatchEventUsingWindowDispatcher(&move); | |
| 3775 delegate->ReceivedAckPreventDefaulted(); | |
| 3776 | |
| 3777 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(2, 2), | |
| 3778 kTouchId, tes.LeapForward(50)); | |
| 3779 DispatchEventUsingWindowDispatcher(&release); | |
| 3780 delegate->ReceivedAck(); | |
| 3781 | |
| 3782 EXPECT_TRUE(delegate->tap()); | |
| 3783 } | |
| 3784 | |
| 3785 // Test that consuming the first move touch doesn't prevent a long press. | |
| 3786 TEST_F(GestureRecognizerTest, GestureEventConsumedTouchMoveLongPressTest) { | |
| 3787 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 3788 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 3789 TimedEvents tes; | |
| 3790 const int kWindowWidth = 123; | |
| 3791 const int kWindowHeight = 45; | |
| 3792 const int kTouchId = 2; | |
| 3793 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 3794 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3795 delegate.get(), -1234, bounds, root_window())); | |
| 3796 delegate->set_window(window.get()); | |
| 3797 | |
| 3798 delegate->Reset(); | |
| 3799 | |
| 3800 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 3801 kTouchId, tes.Now()); | |
| 3802 DispatchEventUsingWindowDispatcher(&press1); | |
| 3803 delegate->ReceivedAck(); | |
| 3804 | |
| 3805 ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(103, 203), | |
| 3806 kTouchId, tes.Now()); | |
| 3807 DispatchEventUsingWindowDispatcher(&move); | |
| 3808 delegate->ReceivedAckPreventDefaulted(); | |
| 3809 | |
| 3810 // Wait until the timer runs out | |
| 3811 delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); | |
| 3812 EXPECT_TRUE(delegate->long_press()); | |
| 3813 } | |
| 3814 | |
| 3815 // Tests that the deltas are correct when leaving the slop region very slowly. | |
| 3816 TEST_F(GestureRecognizerTest, TestExceedingSlopSlowly) { | |
| 3817 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(3); | |
| 3818 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 3819 new GestureEventConsumeDelegate()); | |
| 3820 const int kWindowWidth = 234; | |
| 3821 const int kWindowHeight = 345; | |
| 3822 const int kTouchId = 5; | |
| 3823 TimedEvents tes; | |
| 3824 gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); | |
| 3825 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3826 delegate.get(), -1234, bounds, root_window())); | |
| 3827 | |
| 3828 ui::TouchEvent press( | |
| 3829 ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId, tes.Now()); | |
| 3830 DispatchEventUsingWindowDispatcher(&press); | |
| 3831 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3832 EXPECT_FALSE(delegate->scroll_update()); | |
| 3833 delegate->Reset(); | |
| 3834 | |
| 3835 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(11, 10), kTouchId, | |
| 3836 tes.LeapForward(40)); | |
| 3837 DispatchEventUsingWindowDispatcher(&move1); | |
| 3838 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3839 EXPECT_FALSE(delegate->scroll_update()); | |
| 3840 EXPECT_EQ(0, delegate->scroll_x()); | |
| 3841 EXPECT_EQ(0, delegate->scroll_x_hint()); | |
| 3842 delegate->Reset(); | |
| 3843 | |
| 3844 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(12, 10), kTouchId, | |
| 3845 tes.LeapForward(40)); | |
| 3846 DispatchEventUsingWindowDispatcher(&move2); | |
| 3847 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3848 EXPECT_FALSE(delegate->scroll_update()); | |
| 3849 EXPECT_EQ(0, delegate->scroll_x()); | |
| 3850 EXPECT_EQ(0, delegate->scroll_x_hint()); | |
| 3851 delegate->Reset(); | |
| 3852 | |
| 3853 | |
| 3854 ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::PointF(13.1f, 10.f), kTouchId, | |
| 3855 tes.LeapForward(40)); | |
| 3856 DispatchEventUsingWindowDispatcher(&move3); | |
| 3857 EXPECT_TRUE(delegate->scroll_begin()); | |
| 3858 EXPECT_TRUE(delegate->scroll_update()); | |
| 3859 EXPECT_NEAR(0.1, delegate->scroll_x(), 0.0001); | |
| 3860 EXPECT_FLOAT_EQ(3.1f, delegate->scroll_x_hint()); | |
| 3861 delegate->Reset(); | |
| 3862 | |
| 3863 ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(14, 10), kTouchId, | |
| 3864 tes.LeapForward(40)); | |
| 3865 DispatchEventUsingWindowDispatcher(&move4); | |
| 3866 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3867 EXPECT_TRUE(delegate->scroll_update()); | |
| 3868 EXPECT_NEAR(0.9, delegate->scroll_x(), 0.0001); | |
| 3869 EXPECT_EQ(0.f, delegate->scroll_x_hint()); | |
| 3870 delegate->Reset(); | |
| 3871 } | |
| 3872 | |
| 3873 TEST_F(GestureRecognizerTest, ScrollAlternatelyConsumedTest) { | |
| 3874 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 3875 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 3876 TimedEvents tes; | |
| 3877 const int kWindowWidth = 3000; | |
| 3878 const int kWindowHeight = 3000; | |
| 3879 const int kTouchId = 2; | |
| 3880 gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); | |
| 3881 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3882 delegate.get(), -1234, bounds, root_window())); | |
| 3883 delegate->set_window(window.get()); | |
| 3884 | |
| 3885 delegate->Reset(); | |
| 3886 | |
| 3887 int x = 0; | |
| 3888 int y = 0; | |
| 3889 | |
| 3890 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(x, y), | |
| 3891 kTouchId, tes.Now()); | |
| 3892 DispatchEventUsingWindowDispatcher(&press1); | |
| 3893 delegate->ReceivedAck(); | |
| 3894 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3895 EXPECT_FALSE(delegate->scroll_update()); | |
| 3896 delegate->Reset(); | |
| 3897 | |
| 3898 x += 100; | |
| 3899 y += 100; | |
| 3900 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(x, y), | |
| 3901 kTouchId, tes.Now()); | |
| 3902 DispatchEventUsingWindowDispatcher(&move1); | |
| 3903 delegate->ReceivedAck(); | |
| 3904 EXPECT_TRUE(delegate->scroll_begin()); | |
| 3905 EXPECT_TRUE(delegate->scroll_update()); | |
| 3906 delegate->Reset(); | |
| 3907 | |
| 3908 for (int i = 0; i < 3; ++i) { | |
| 3909 x += 10; | |
| 3910 y += 10; | |
| 3911 ui::TouchEvent move2( | |
| 3912 ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId, tes.Now()); | |
| 3913 DispatchEventUsingWindowDispatcher(&move2); | |
| 3914 delegate->ReceivedAck(); | |
| 3915 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3916 EXPECT_TRUE(delegate->scroll_update()); | |
| 3917 EXPECT_EQ(10, delegate->scroll_x()); | |
| 3918 EXPECT_EQ(10, delegate->scroll_y()); | |
| 3919 delegate->Reset(); | |
| 3920 | |
| 3921 x += 20; | |
| 3922 y += 20; | |
| 3923 ui::TouchEvent move3( | |
| 3924 ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId, tes.Now()); | |
| 3925 DispatchEventUsingWindowDispatcher(&move3); | |
| 3926 delegate->ReceivedAckPreventDefaulted(); | |
| 3927 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3928 EXPECT_FALSE(delegate->scroll_update()); | |
| 3929 delegate->Reset(); | |
| 3930 } | |
| 3931 } | |
| 3932 | |
| 3933 TEST_F(GestureRecognizerTest, PinchAlternatelyConsumedTest) { | |
| 3934 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 3935 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 3936 TimedEvents tes; | |
| 3937 const int kWindowWidth = 3000; | |
| 3938 const int kWindowHeight = 3000; | |
| 3939 const int kTouchId1 = 5; | |
| 3940 const int kTouchId2 = 7; | |
| 3941 gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); | |
| 3942 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 3943 delegate.get(), -1234, bounds, root_window())); | |
| 3944 delegate->set_window(window.get()); | |
| 3945 delegate->Reset(); | |
| 3946 | |
| 3947 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), | |
| 3948 kTouchId1, tes.Now()); | |
| 3949 DispatchEventUsingWindowDispatcher(&press1); | |
| 3950 delegate->ReceivedAck(); | |
| 3951 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3952 EXPECT_FALSE(delegate->scroll_update()); | |
| 3953 delegate->Reset(); | |
| 3954 | |
| 3955 int x = 0; | |
| 3956 int y = 0; | |
| 3957 | |
| 3958 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(x, y), | |
| 3959 kTouchId2, tes.Now()); | |
| 3960 DispatchEventUsingWindowDispatcher(&press2); | |
| 3961 delegate->ReceivedAck(); | |
| 3962 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3963 EXPECT_FALSE(delegate->scroll_update()); | |
| 3964 EXPECT_FALSE(delegate->pinch_begin()); | |
| 3965 EXPECT_FALSE(delegate->pinch_update()); | |
| 3966 | |
| 3967 delegate->Reset(); | |
| 3968 | |
| 3969 x += 100; | |
| 3970 y += 100; | |
| 3971 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(x, y), | |
| 3972 kTouchId2, tes.Now()); | |
| 3973 DispatchEventUsingWindowDispatcher(&move1); | |
| 3974 delegate->ReceivedAck(); | |
| 3975 EXPECT_TRUE(delegate->scroll_begin()); | |
| 3976 EXPECT_TRUE(delegate->scroll_update()); | |
| 3977 EXPECT_TRUE(delegate->pinch_begin()); | |
| 3978 EXPECT_FALSE(delegate->pinch_update()); | |
| 3979 delegate->Reset(); | |
| 3980 | |
| 3981 const float expected_scales[] = {1.5f, 1.2f, 1.125f}; | |
| 3982 | |
| 3983 for (int i = 0; i < 3; ++i) { | |
| 3984 x += 50; | |
| 3985 y += 50; | |
| 3986 ui::TouchEvent move2( | |
| 3987 ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId2, tes.Now()); | |
| 3988 DispatchEventUsingWindowDispatcher(&move2); | |
| 3989 delegate->ReceivedAck(); | |
| 3990 EXPECT_FALSE(delegate->scroll_begin()); | |
| 3991 EXPECT_TRUE(delegate->scroll_update()); | |
| 3992 EXPECT_FALSE(delegate->scroll_end()); | |
| 3993 EXPECT_FALSE(delegate->pinch_begin()); | |
| 3994 EXPECT_TRUE(delegate->pinch_update()); | |
| 3995 EXPECT_FALSE(delegate->pinch_end()); | |
| 3996 EXPECT_EQ(25, delegate->scroll_x()); | |
| 3997 EXPECT_EQ(25, delegate->scroll_y()); | |
| 3998 EXPECT_FLOAT_EQ(expected_scales[i], delegate->scale()); | |
| 3999 delegate->Reset(); | |
| 4000 | |
| 4001 x += 100; | |
| 4002 y += 100; | |
| 4003 ui::TouchEvent move3( | |
| 4004 ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId2, tes.Now()); | |
| 4005 DispatchEventUsingWindowDispatcher(&move3); | |
| 4006 delegate->ReceivedAckPreventDefaulted(); | |
| 4007 EXPECT_FALSE(delegate->scroll_begin()); | |
| 4008 EXPECT_FALSE(delegate->scroll_update()); | |
| 4009 EXPECT_FALSE(delegate->scroll_end()); | |
| 4010 EXPECT_FALSE(delegate->pinch_begin()); | |
| 4011 EXPECT_FALSE(delegate->pinch_update()); | |
| 4012 EXPECT_FALSE(delegate->pinch_end()); | |
| 4013 delegate->Reset(); | |
| 4014 } | |
| 4015 } | |
| 4016 | |
| 4017 // Test that touch event flags are passed through to the gesture event. | |
| 4018 TEST_F(GestureRecognizerTest, GestureEventFlagsPassedFromTouchEvent) { | |
| 4019 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 4020 new GestureEventConsumeDelegate()); | |
| 4021 TimedEvents tes; | |
| 4022 const int kWindowWidth = 123; | |
| 4023 const int kWindowHeight = 45; | |
| 4024 const int kTouchId = 6; | |
| 4025 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 4026 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 4027 delegate.get(), -1234, bounds, root_window())); | |
| 4028 | |
| 4029 delegate->Reset(); | |
| 4030 | |
| 4031 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 4032 kTouchId, tes.Now()); | |
| 4033 DispatchEventUsingWindowDispatcher(&press1); | |
| 4034 EXPECT_TRUE(delegate->tap_down()); | |
| 4035 | |
| 4036 int default_flags = delegate->flags(); | |
| 4037 | |
| 4038 ui::TouchEvent move1( | |
| 4039 ui::ET_TOUCH_MOVED, gfx::Point(397, 149), kTouchId, tes.LeapForward(50)); | |
| 4040 move1.set_flags(992); | |
| 4041 | |
| 4042 DispatchEventUsingWindowDispatcher(&move1); | |
| 4043 EXPECT_NE(default_flags, delegate->flags()); | |
| 4044 } | |
| 4045 | |
| 4046 // Test that latency info is passed through to the gesture event. | |
| 4047 TEST_F(GestureRecognizerTest, LatencyPassedFromTouchEvent) { | |
| 4048 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 4049 new GestureEventConsumeDelegate()); | |
| 4050 TimedEvents tes; | |
| 4051 const int kWindowWidth = 123; | |
| 4052 const int kWindowHeight = 45; | |
| 4053 const int kTouchId = 6; | |
| 4054 | |
| 4055 const base::TimeTicks time_original = base::TimeTicks::FromInternalValue(100); | |
| 4056 const base::TimeTicks time_ui = base::TimeTicks::FromInternalValue(200); | |
| 4057 const base::TimeTicks time_acked = base::TimeTicks::FromInternalValue(300); | |
| 4058 | |
| 4059 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 4060 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 4061 delegate.get(), -1234, bounds, root_window())); | |
| 4062 | |
| 4063 delegate->Reset(); | |
| 4064 | |
| 4065 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 4066 kTouchId, tes.Now()); | |
| 4067 | |
| 4068 // Ensure the only components around are the ones we add. | |
| 4069 press1.latency()->Clear(); | |
| 4070 | |
| 4071 press1.latency()->AddLatencyNumberWithTimestamp( | |
| 4072 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, time_original, 1); | |
| 4073 | |
| 4074 press1.latency()->AddLatencyNumberWithTimestamp( | |
| 4075 ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0, time_ui, 1); | |
| 4076 | |
| 4077 press1.latency()->AddLatencyNumberWithTimestamp( | |
| 4078 ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT, 0, 0, time_acked, 1); | |
| 4079 | |
| 4080 DispatchEventUsingWindowDispatcher(&press1); | |
| 4081 EXPECT_TRUE(delegate->tap_down()); | |
| 4082 | |
| 4083 ui::LatencyInfo::LatencyComponent component; | |
| 4084 | |
| 4085 EXPECT_EQ(3U, delegate->latency_info().latency_components.size()); | |
| 4086 ASSERT_TRUE(delegate->latency_info().FindLatency( | |
| 4087 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component)); | |
| 4088 EXPECT_EQ(time_original, component.event_time); | |
| 4089 | |
| 4090 ASSERT_TRUE(delegate->latency_info().FindLatency( | |
| 4091 ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, &component)); | |
| 4092 EXPECT_EQ(time_ui, component.event_time); | |
| 4093 | |
| 4094 ASSERT_TRUE(delegate->latency_info().FindLatency( | |
| 4095 ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT, 0, &component)); | |
| 4096 EXPECT_EQ(time_acked, component.event_time); | |
| 4097 | |
| 4098 delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_SHOW_PRESS); | |
| 4099 EXPECT_TRUE(delegate->show_press()); | |
| 4100 EXPECT_EQ(0U, delegate->latency_info().latency_components.size()); | |
| 4101 } | |
| 4102 | |
| 4103 // A delegate that deletes a window on long press. | |
| 4104 class GestureEventDeleteWindowOnLongPress : public GestureEventConsumeDelegate { | |
| 4105 public: | |
| 4106 GestureEventDeleteWindowOnLongPress() | |
| 4107 : window_(NULL) {} | |
| 4108 | |
| 4109 void set_window(aura::Window** window) { window_ = window; } | |
| 4110 | |
| 4111 virtual void OnGestureEvent(ui::GestureEvent* gesture) override { | |
| 4112 GestureEventConsumeDelegate::OnGestureEvent(gesture); | |
| 4113 if (gesture->type() != ui::ET_GESTURE_LONG_PRESS) | |
| 4114 return; | |
| 4115 ui::GestureRecognizer::Get()->CleanupStateForConsumer(*window_); | |
| 4116 delete *window_; | |
| 4117 *window_ = NULL; | |
| 4118 } | |
| 4119 | |
| 4120 private: | |
| 4121 aura::Window** window_; | |
| 4122 DISALLOW_COPY_AND_ASSIGN(GestureEventDeleteWindowOnLongPress); | |
| 4123 }; | |
| 4124 | |
| 4125 // Check that deleting the window in response to a long press gesture doesn't | |
| 4126 // crash. | |
| 4127 TEST_F(GestureRecognizerTest, GestureEventLongPressDeletingWindow) { | |
| 4128 GestureEventDeleteWindowOnLongPress delegate; | |
| 4129 const int kWindowWidth = 123; | |
| 4130 const int kWindowHeight = 45; | |
| 4131 const int kTouchId = 2; | |
| 4132 gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); | |
| 4133 aura::Window* window(CreateTestWindowWithDelegate( | |
| 4134 &delegate, -1234, bounds, root_window())); | |
| 4135 delegate.set_window(&window); | |
| 4136 | |
| 4137 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, | |
| 4138 gfx::Point(101, 201), | |
| 4139 kTouchId, | |
| 4140 ui::EventTimeForNow()); | |
| 4141 DispatchEventUsingWindowDispatcher(&press1); | |
| 4142 EXPECT_TRUE(window != NULL); | |
| 4143 | |
| 4144 // Wait until the timer runs out. | |
| 4145 delegate.WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); | |
| 4146 EXPECT_EQ(NULL, window); | |
| 4147 } | |
| 4148 | |
| 4149 TEST_F(GestureRecognizerTest, GestureEventSmallPinchDisabled) { | |
| 4150 CommandLine::ForCurrentProcess()->AppendSwitch( | |
| 4151 switches::kCompensateForUnstablePinchZoom); | |
| 4152 | |
| 4153 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 4154 new GestureEventConsumeDelegate()); | |
| 4155 TimedEvents tes; | |
| 4156 const int kWindowWidth = 300; | |
| 4157 const int kWindowHeight = 400; | |
| 4158 const int kTouchId1 = 3; | |
| 4159 const int kTouchId2 = 5; | |
| 4160 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | |
| 4161 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 4162 delegate.get(), -1234, bounds, root_window())); | |
| 4163 | |
| 4164 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 301), | |
| 4165 kTouchId1, tes.Now()); | |
| 4166 DispatchEventUsingWindowDispatcher(&press1); | |
| 4167 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 4168 kTouchId2, tes.Now()); | |
| 4169 DispatchEventUsingWindowDispatcher(&press2); | |
| 4170 | |
| 4171 // Move the first finger. | |
| 4172 delegate->Reset(); | |
| 4173 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(65, 201), | |
| 4174 kTouchId1, tes.Now()); | |
| 4175 DispatchEventUsingWindowDispatcher(&move1); | |
| 4176 | |
| 4177 EXPECT_3_EVENTS(delegate->events(), | |
| 4178 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 4179 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 4180 ui::ET_GESTURE_PINCH_BEGIN); | |
| 4181 | |
| 4182 // No pinch update occurs, as kCompensateForUnstablePinchZoom is on, and this | |
| 4183 // is a very small pinch. | |
| 4184 delegate->Reset(); | |
| 4185 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(65, 202), | |
| 4186 kTouchId1, tes.Now()); | |
| 4187 DispatchEventUsingWindowDispatcher(&move2); | |
| 4188 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 4189 } | |
| 4190 | |
| 4191 TEST_F(GestureRecognizerTest, GestureEventSmallPinchEnabled) { | |
| 4192 scoped_ptr<GestureEventConsumeDelegate> delegate( | |
| 4193 new GestureEventConsumeDelegate()); | |
| 4194 TimedEvents tes; | |
| 4195 const int kWindowWidth = 300; | |
| 4196 const int kWindowHeight = 400; | |
| 4197 const int kTouchId1 = 3; | |
| 4198 const int kTouchId2 = 5; | |
| 4199 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | |
| 4200 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 4201 delegate.get(), -1234, bounds, root_window())); | |
| 4202 | |
| 4203 ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 301), | |
| 4204 kTouchId1, tes.Now()); | |
| 4205 DispatchEventUsingWindowDispatcher(&press1); | |
| 4206 ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), | |
| 4207 kTouchId2, tes.Now()); | |
| 4208 DispatchEventUsingWindowDispatcher(&press2); | |
| 4209 | |
| 4210 // Move the first finger. | |
| 4211 delegate->Reset(); | |
| 4212 ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(65, 201), | |
| 4213 kTouchId1, tes.Now()); | |
| 4214 DispatchEventUsingWindowDispatcher(&move1); | |
| 4215 | |
| 4216 EXPECT_3_EVENTS(delegate->events(), | |
| 4217 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 4218 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 4219 ui::ET_GESTURE_PINCH_BEGIN); | |
| 4220 | |
| 4221 delegate->Reset(); | |
| 4222 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(65, 202), | |
| 4223 kTouchId1, tes.Now()); | |
| 4224 DispatchEventUsingWindowDispatcher(&move2); | |
| 4225 EXPECT_2_EVENTS(delegate->events(), | |
| 4226 ui::ET_GESTURE_SCROLL_UPDATE, | |
| 4227 ui::ET_GESTURE_PINCH_UPDATE); | |
| 4228 } | |
| 4229 | |
| 4230 // Tests that delaying the ack of a touch release doesn't trigger a long press | |
| 4231 // gesture. | |
| 4232 TEST_F(GestureRecognizerTest, DISABLED_EagerGestureDetection) { | |
| 4233 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 4234 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 4235 TimedEvents tes; | |
| 4236 const int kTouchId = 2; | |
| 4237 gfx::Rect bounds(100, 200, 100, 100); | |
| 4238 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 4239 delegate.get(), -1234, bounds, root_window())); | |
| 4240 delegate->set_window(window.get()); | |
| 4241 | |
| 4242 delegate->Reset(); | |
| 4243 ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), | |
| 4244 kTouchId, tes.Now()); | |
| 4245 DispatchEventUsingWindowDispatcher(&press); | |
| 4246 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), | |
| 4247 kTouchId, tes.LeapForward(50)); | |
| 4248 DispatchEventUsingWindowDispatcher(&release); | |
| 4249 | |
| 4250 delegate->Reset(); | |
| 4251 // Ack the touch press. | |
| 4252 delegate->ReceivedAck(); | |
| 4253 EXPECT_TRUE(delegate->tap_down()); | |
| 4254 | |
| 4255 delegate->Reset(); | |
| 4256 // Wait until the long press event would fire (if we weren't eager). | |
| 4257 DelayByLongPressTimeout(); | |
| 4258 | |
| 4259 // Ack the touch release. | |
| 4260 delegate->ReceivedAck(); | |
| 4261 EXPECT_TRUE(delegate->tap()); | |
| 4262 EXPECT_FALSE(delegate->long_press()); | |
| 4263 } | |
| 4264 | |
| 4265 // This tests crbug.com/405519, in which events which the gesture detector | |
| 4266 // ignores cause future events to also be thrown away. | |
| 4267 TEST_F(GestureRecognizerTest, IgnoredEventsDontPreventFutureEvents) { | |
| 4268 scoped_ptr<QueueTouchEventDelegate> delegate( | |
| 4269 new QueueTouchEventDelegate(host()->dispatcher())); | |
| 4270 TimedEvents tes; | |
| 4271 const int kWindowWidth = 300; | |
| 4272 const int kWindowHeight = 400; | |
| 4273 const int kTouchId1 = 3; | |
| 4274 gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); | |
| 4275 scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( | |
| 4276 delegate.get(), -1234, bounds, root_window())); | |
| 4277 delegate->set_window(window.get()); | |
| 4278 | |
| 4279 ui::TouchEvent press1( | |
| 4280 ui::ET_TOUCH_PRESSED, gfx::Point(101, 301), kTouchId1, tes.Now()); | |
| 4281 DispatchEventUsingWindowDispatcher(&press1); | |
| 4282 delegate->ReceivedAck(); | |
| 4283 | |
| 4284 EXPECT_2_EVENTS( | |
| 4285 delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); | |
| 4286 | |
| 4287 // Move the first finger. | |
| 4288 delegate->Reset(); | |
| 4289 ui::TouchEvent move1( | |
| 4290 ui::ET_TOUCH_MOVED, gfx::Point(65, 201), kTouchId1, tes.Now()); | |
| 4291 DispatchEventUsingWindowDispatcher(&move1); | |
| 4292 delegate->ReceivedAck(); | |
| 4293 | |
| 4294 EXPECT_3_EVENTS(delegate->events(), | |
| 4295 ui::ET_GESTURE_TAP_CANCEL, | |
| 4296 ui::ET_GESTURE_SCROLL_BEGIN, | |
| 4297 ui::ET_GESTURE_SCROLL_UPDATE); | |
| 4298 | |
| 4299 delegate->Reset(); | |
| 4300 ui::TouchEvent move2( | |
| 4301 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); | |
| 4302 DispatchEventUsingWindowDispatcher(&move2); | |
| 4303 | |
| 4304 // Send a touchmove event at the same location as the previous touchmove | |
| 4305 // event. This shouldn't do anything. | |
| 4306 ui::TouchEvent move3( | |
| 4307 ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); | |
| 4308 DispatchEventUsingWindowDispatcher(&move3); | |
| 4309 | |
| 4310 delegate->ReceivedAck(); | |
| 4311 EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); | |
| 4312 } | |
| 4313 | |
| 4314 } // namespace test | |
| 4315 } // namespace aura | |
| OLD | NEW |