event_dispatcher_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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 "ui/events/event_dispatcher.h" 6 7#include "testing/gtest/include/gtest/gtest.h" 8#include "ui/events/event.h" 9#include "ui/events/event_dispatcher.h" 10#include "ui/events/event_target.h" 11#include "ui/events/event_target_iterator.h" 12#include "ui/events/event_utils.h" 13 14namespace ui { 15 16namespace { 17 18class TestTarget : public EventTarget { 19 public: 20 TestTarget() : parent_(NULL), valid_(true) {} 21 virtual ~TestTarget() {} 22 23 void set_parent(TestTarget* parent) { parent_ = parent; } 24 25 bool valid() const { return valid_; } 26 void set_valid(bool valid) { valid_ = valid; } 27 28 void AddHandlerId(int id) { 29 handler_list_.push_back(id); 30 } 31 32 const std::vector<int>& handler_list() const { return handler_list_; } 33 34 void Reset() { 35 handler_list_.clear(); 36 valid_ = true; 37 } 38 39 private: 40 // Overridden from EventTarget: 41 virtual bool CanAcceptEvent(const ui::Event& event) OVERRIDE { 42 return true; 43 } 44 45 virtual EventTarget* GetParentTarget() OVERRIDE { 46 return parent_; 47 } 48 49 virtual scoped_ptr<EventTargetIterator> GetChildIterator() const OVERRIDE { 50 return scoped_ptr<EventTargetIterator>(); 51 } 52 53 virtual EventTargeter* GetEventTargeter() OVERRIDE { 54 return NULL; 55 } 56 57 TestTarget* parent_; 58 std::vector<int> handler_list_; 59 bool valid_; 60 61 DISALLOW_COPY_AND_ASSIGN(TestTarget); 62}; 63 64class TestEventHandler : public EventHandler { 65 public: 66 TestEventHandler(int id) 67 : id_(id), 68 event_result_(ER_UNHANDLED), 69 expect_pre_target_(false), 70 expect_post_target_(false), 71 received_pre_target_(false) { 72 } 73 74 virtual ~TestEventHandler() {} 75 76 virtual void ReceivedEvent(Event* event) { 77 static_cast<TestTarget*>(event->target())->AddHandlerId(id_); 78 if (event->phase() == ui::EP_POSTTARGET) { 79 EXPECT_TRUE(expect_post_target_); 80 if (expect_pre_target_) 81 EXPECT_TRUE(received_pre_target_); 82 } else if (event->phase() == ui::EP_PRETARGET) { 83 EXPECT_TRUE(expect_pre_target_); 84 received_pre_target_ = true; 85 } else { 86 NOTREACHED(); 87 } 88 } 89 90 void set_event_result(EventResult result) { event_result_ = result; } 91 92 void set_expect_pre_target(bool expect) { expect_pre_target_ = expect; } 93 void set_expect_post_target(bool expect) { expect_post_target_ = expect; } 94 95 private: 96 // Overridden from EventHandler: 97 virtual void OnEvent(Event* event) OVERRIDE { 98 ui::EventHandler::OnEvent(event); 99 ReceivedEvent(event); 100 SetStatusOnEvent(event); 101 } 102 103 void SetStatusOnEvent(Event* event) { 104 if (event_result_ & ui::ER_CONSUMED) 105 event->StopPropagation(); 106 if (event_result_ & ui::ER_HANDLED) 107 event->SetHandled(); 108 } 109 110 int id_; 111 EventResult event_result_; 112 bool expect_pre_target_; 113 bool expect_post_target_; 114 bool received_pre_target_; 115 116 DISALLOW_COPY_AND_ASSIGN(TestEventHandler); 117}; 118 119class NonCancelableEvent : public Event { 120 public: 121 NonCancelableEvent() 122 : Event(ui::ET_CANCEL_MODE, ui::EventTimeForNow(), 0) { 123 set_cancelable(false); 124 } 125 126 virtual ~NonCancelableEvent() {} 127 128 private: 129 DISALLOW_COPY_AND_ASSIGN(NonCancelableEvent); 130}; 131 132// Destroys the dispatcher-delegate when it receives any event. 133class EventHandlerDestroyDispatcherDelegate : public TestEventHandler { 134 public: 135 EventHandlerDestroyDispatcherDelegate(EventDispatcherDelegate* delegate, 136 int id) 137 : TestEventHandler(id), 138 dispatcher_delegate_(delegate) { 139 } 140 141 virtual ~EventHandlerDestroyDispatcherDelegate() {} 142 143 private: 144 virtual void ReceivedEvent(Event* event) OVERRIDE { 145 TestEventHandler::ReceivedEvent(event); 146 delete dispatcher_delegate_; 147 } 148 149 EventDispatcherDelegate* dispatcher_delegate_; 150 151 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyDispatcherDelegate); 152}; 153 154// Invalidates the target when it receives any event. 155class InvalidateTargetEventHandler : public TestEventHandler { 156 public: 157 explicit InvalidateTargetEventHandler(int id) : TestEventHandler(id) {} 158 virtual ~InvalidateTargetEventHandler() {} 159 160 private: 161 virtual void ReceivedEvent(Event* event) OVERRIDE { 162 TestEventHandler::ReceivedEvent(event); 163 TestTarget* target = static_cast<TestTarget*>(event->target()); 164 target->set_valid(false); 165 } 166 167 DISALLOW_COPY_AND_ASSIGN(InvalidateTargetEventHandler); 168}; 169 170// Destroys a second event handler when this handler gets an event. 171// Optionally also destroys the dispatcher. 172class EventHandlerDestroyer : public TestEventHandler { 173 public: 174 EventHandlerDestroyer(int id, EventHandler* destroy) 175 : TestEventHandler(id), 176 to_destroy_(destroy), 177 dispatcher_delegate_(NULL) { 178 } 179 180 virtual ~EventHandlerDestroyer() { 181 CHECK(!to_destroy_); 182 } 183 184 void set_dispatcher_delegate(EventDispatcherDelegate* dispatcher_delegate) { 185 dispatcher_delegate_ = dispatcher_delegate; 186 } 187 188 private: 189 virtual void ReceivedEvent(Event* event) OVERRIDE { 190 TestEventHandler::ReceivedEvent(event); 191 delete to_destroy_; 192 to_destroy_ = NULL; 193 194 if (dispatcher_delegate_) { 195 delete dispatcher_delegate_; 196 dispatcher_delegate_ = NULL; 197 } 198 } 199 200 EventHandler* to_destroy_; 201 EventDispatcherDelegate* dispatcher_delegate_; 202 203 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyer); 204}; 205 206class TestEventDispatcher : public EventDispatcherDelegate { 207 public: 208 TestEventDispatcher() {} 209 210 virtual ~TestEventDispatcher() {} 211 212 void ProcessEvent(EventTarget* target, Event* event) { 213 EventDispatchDetails details = DispatchEvent(target, event); 214 if (details.dispatcher_destroyed) 215 return; 216 } 217 218 private: 219 // Overridden from EventDispatcherDelegate: 220 virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE { 221 TestTarget* test_target = static_cast<TestTarget*>(target); 222 return test_target->valid(); 223 } 224 225 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher); 226}; 227 228} // namespace 229 230TEST(EventDispatcherTest, EventDispatchOrder) { 231 TestEventDispatcher dispatcher; 232 TestTarget parent, child; 233 TestEventHandler h1(1), h2(2), h3(3), h4(4); 234 TestEventHandler h5(5), h6(6), h7(7), h8(8); 235 236 child.set_parent(&parent); 237 238 parent.AddPreTargetHandler(&h1); 239 parent.AddPreTargetHandler(&h2); 240 241 child.AddPreTargetHandler(&h3); 242 child.AddPreTargetHandler(&h4); 243 244 h1.set_expect_pre_target(true); 245 h2.set_expect_pre_target(true); 246 h3.set_expect_pre_target(true); 247 h4.set_expect_pre_target(true); 248 249 child.AddPostTargetHandler(&h5); 250 child.AddPostTargetHandler(&h6); 251 252 parent.AddPostTargetHandler(&h7); 253 parent.AddPostTargetHandler(&h8); 254 255 h5.set_expect_post_target(true); 256 h6.set_expect_post_target(true); 257 h7.set_expect_post_target(true); 258 h8.set_expect_post_target(true); 259 260 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), 261 gfx::Point(3, 4), 0); 262 Event::DispatcherApi event_mod(&mouse); 263 dispatcher.ProcessEvent(&child, &mouse); 264 EXPECT_FALSE(mouse.stopped_propagation()); 265 EXPECT_FALSE(mouse.handled()); 266 267 { 268 int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 269 EXPECT_EQ( 270 std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)), 271 child.handler_list()); 272 } 273 274 child.Reset(); 275 event_mod.set_phase(EP_PREDISPATCH); 276 event_mod.set_result(ER_UNHANDLED); 277 278 h1.set_event_result(ER_HANDLED); 279 dispatcher.ProcessEvent(&child, &mouse); 280 EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); 281 EXPECT_FALSE(mouse.stopped_propagation()); 282 EXPECT_TRUE(mouse.handled()); 283 { 284 // |h1| marks the event as handled. So only the pre-target handlers should 285 // receive the event. 286 int expected[] = { 1, 2, 3, 4 }; 287 EXPECT_EQ( 288 std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)), 289 child.handler_list()); 290 } 291 292 child.Reset(); 293 event_mod.set_phase(EP_PREDISPATCH); 294 event_mod.set_result(ER_UNHANDLED); 295 296 int nexpected[] = { 1, 2, 3, 4, 5 }; 297 h1.set_event_result(ER_UNHANDLED); 298 h5.set_event_result(ER_CONSUMED); 299 dispatcher.ProcessEvent(&child, &mouse); 300 EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); 301 EXPECT_TRUE(mouse.stopped_propagation()); 302 EXPECT_TRUE(mouse.handled()); 303 EXPECT_EQ( 304 std::vector<int>(nexpected, nexpected + sizeof(nexpected) / sizeof(int)), 305 child.handler_list()); 306 307 child.Reset(); 308 event_mod.set_phase(EP_PREDISPATCH); 309 event_mod.set_result(ER_UNHANDLED); 310 311 int exp[] = { 1 }; 312 h1.set_event_result(ER_CONSUMED); 313 dispatcher.ProcessEvent(&child, &mouse); 314 EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); 315 EXPECT_TRUE(mouse.stopped_propagation()); 316 EXPECT_TRUE(mouse.handled()); 317 EXPECT_EQ( 318 std::vector<int>(exp, exp + sizeof(exp) / sizeof(int)), 319 child.handler_list()); 320} 321 322// Tests that the event-phases are correct. 323TEST(EventDispatcherTest, EventDispatchPhase) { 324 TestEventDispatcher dispatcher; 325 TestTarget target; 326 327 TestEventHandler handler(11); 328 329 target.AddPreTargetHandler(&handler); 330 target.AddPostTargetHandler(&handler); 331 handler.set_expect_pre_target(true); 332 handler.set_expect_post_target(true); 333 334 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), 335 gfx::Point(3, 4), 0); 336 Event::DispatcherApi event_mod(&mouse); 337 dispatcher.ProcessEvent(&target, &mouse); 338 EXPECT_EQ(ER_UNHANDLED, mouse.result()); 339 340 int handlers[] = { 11, 11 }; 341 EXPECT_EQ( 342 std::vector<int>(handlers, handlers + sizeof(handlers) / sizeof(int)), 343 target.handler_list()); 344} 345 346// Tests that if the dispatcher is destroyed in the middle of pre or post-target 347// dispatching events, it doesn't cause a crash. 348TEST(EventDispatcherTest, EventDispatcherDestroyedDuringDispatch) { 349 // Test for pre-target first. 350 { 351 TestEventDispatcher* dispatcher = new TestEventDispatcher(); 352 TestTarget target; 353 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5); 354 TestEventHandler h1(1), h2(2); 355 356 target.AddPreTargetHandler(&h1); 357 target.AddPreTargetHandler(&handler); 358 target.AddPreTargetHandler(&h2); 359 360 h1.set_expect_pre_target(true); 361 handler.set_expect_pre_target(true); 362 // |h2| should not receive any events at all since |handler| will have 363 // destroyed the dispatcher. 364 h2.set_expect_pre_target(false); 365 366 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), 367 gfx::Point(3, 4), 0); 368 Event::DispatcherApi event_mod(&mouse); 369 dispatcher->ProcessEvent(&target, &mouse); 370 EXPECT_EQ(ER_CONSUMED, mouse.result()); 371 EXPECT_EQ(2U, target.handler_list().size()); 372 EXPECT_EQ(1, target.handler_list()[0]); 373 EXPECT_EQ(5, target.handler_list()[1]); 374 } 375 376 // Test for non-cancelable event. 377 { 378 TestEventDispatcher* dispatcher = new TestEventDispatcher(); 379 TestTarget target; 380 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5); 381 TestEventHandler h1(1), h2(2); 382 383 target.AddPreTargetHandler(&h1); 384 target.AddPreTargetHandler(&handler); 385 target.AddPreTargetHandler(&h2); 386 387 h1.set_expect_pre_target(true); 388 handler.set_expect_pre_target(true); 389 // |h2| should not receive any events at all since |handler| will have 390 // destroyed the dispatcher. 391 h2.set_expect_pre_target(false); 392 393 NonCancelableEvent event; 394 Event::DispatcherApi event_mod(&event); 395 dispatcher->ProcessEvent(&target, &event); 396 EXPECT_EQ(2U, target.handler_list().size()); 397 EXPECT_EQ(1, target.handler_list()[0]); 398 EXPECT_EQ(5, target.handler_list()[1]); 399 } 400 401 // Now test for post-target. 402 { 403 TestEventDispatcher* dispatcher = new TestEventDispatcher(); 404 TestTarget target; 405 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5); 406 TestEventHandler h1(1), h2(2); 407 408 target.AddPostTargetHandler(&h1); 409 target.AddPostTargetHandler(&handler); 410 target.AddPostTargetHandler(&h2); 411 412 h1.set_expect_post_target(true); 413 handler.set_expect_post_target(true); 414 // |h2| should not receive any events at all since |handler| will have 415 // destroyed the dispatcher. 416 h2.set_expect_post_target(false); 417 418 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), 419 gfx::Point(3, 4), 0); 420 Event::DispatcherApi event_mod(&mouse); 421 dispatcher->ProcessEvent(&target, &mouse); 422 EXPECT_EQ(ER_CONSUMED, mouse.result()); 423 EXPECT_EQ(2U, target.handler_list().size()); 424 EXPECT_EQ(1, target.handler_list()[0]); 425 EXPECT_EQ(5, target.handler_list()[1]); 426 } 427 428 // Test for non-cancelable event. 429 { 430 TestEventDispatcher* dispatcher = new TestEventDispatcher(); 431 TestTarget target; 432 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5); 433 TestEventHandler h1(1), h2(2); 434 435 target.AddPostTargetHandler(&h1); 436 target.AddPostTargetHandler(&handler); 437 target.AddPostTargetHandler(&h2); 438 439 h1.set_expect_post_target(true); 440 handler.set_expect_post_target(true); 441 // |h2| should not receive any events at all since |handler| will have 442 // destroyed the dispatcher. 443 h2.set_expect_post_target(false); 444 445 NonCancelableEvent event; 446 Event::DispatcherApi event_mod(&event); 447 dispatcher->ProcessEvent(&target, &event); 448 EXPECT_EQ(2U, target.handler_list().size()); 449 EXPECT_EQ(1, target.handler_list()[0]); 450 EXPECT_EQ(5, target.handler_list()[1]); 451 } 452} 453 454// Tests that a target becoming invalid in the middle of pre- or post-target 455// event processing aborts processing. 456TEST(EventDispatcherTest, EventDispatcherInvalidateTarget) { 457 TestEventDispatcher dispatcher; 458 TestTarget target; 459 TestEventHandler h1(1); 460 InvalidateTargetEventHandler invalidate_handler(2); 461 TestEventHandler h3(3); 462 463 target.AddPreTargetHandler(&h1); 464 target.AddPreTargetHandler(&invalidate_handler); 465 target.AddPreTargetHandler(&h3); 466 467 h1.set_expect_pre_target(true); 468 invalidate_handler.set_expect_pre_target(true); 469 // |h3| should not receive events as the target will be invalidated. 470 h3.set_expect_pre_target(false); 471 472 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0); 473 dispatcher.ProcessEvent(&target, &mouse); 474 EXPECT_FALSE(target.valid()); 475 EXPECT_TRUE(mouse.stopped_propagation()); 476 EXPECT_EQ(2U, target.handler_list().size()); 477 EXPECT_EQ(1, target.handler_list()[0]); 478 EXPECT_EQ(2, target.handler_list()[1]); 479 480 // Test for non-cancelable event. 481 target.Reset(); 482 NonCancelableEvent event; 483 dispatcher.ProcessEvent(&target, &event); 484 EXPECT_FALSE(target.valid()); 485 EXPECT_TRUE(mouse.stopped_propagation()); 486 EXPECT_EQ(2U, target.handler_list().size()); 487 EXPECT_EQ(1, target.handler_list()[0]); 488 EXPECT_EQ(2, target.handler_list()[1]); 489} 490 491// Tests that if an event-handler gets destroyed during event-dispatch, it does 492// not cause a crash. 493TEST(EventDispatcherTest, EventHandlerDestroyedDuringDispatch) { 494 { 495 TestEventDispatcher dispatcher; 496 TestTarget target; 497 TestEventHandler h1(1); 498 TestEventHandler* h3 = new TestEventHandler(3); 499 EventHandlerDestroyer handle_destroyer(2, h3); 500 501 target.AddPreTargetHandler(&h1); 502 target.AddPreTargetHandler(&handle_destroyer); 503 target.AddPreTargetHandler(h3); 504 505 h1.set_expect_pre_target(true); 506 handle_destroyer.set_expect_pre_target(true); 507 // |h3| should not receive events since |handle_destroyer| will have 508 // destroyed it. 509 h3->set_expect_pre_target(false); 510 511 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0); 512 dispatcher.ProcessEvent(&target, &mouse); 513 EXPECT_FALSE(mouse.stopped_propagation()); 514 EXPECT_EQ(2U, target.handler_list().size()); 515 EXPECT_EQ(1, target.handler_list()[0]); 516 EXPECT_EQ(2, target.handler_list()[1]); 517 } 518 519 // Test for non-cancelable events. 520 { 521 TestEventDispatcher dispatcher; 522 TestTarget target; 523 TestEventHandler h1(1); 524 TestEventHandler* h3 = new TestEventHandler(3); 525 EventHandlerDestroyer handle_destroyer(2, h3); 526 527 target.AddPreTargetHandler(&h1); 528 target.AddPreTargetHandler(&handle_destroyer); 529 target.AddPreTargetHandler(h3); 530 531 h1.set_expect_pre_target(true); 532 handle_destroyer.set_expect_pre_target(true); 533 h3->set_expect_pre_target(false); 534 535 NonCancelableEvent event; 536 dispatcher.ProcessEvent(&target, &event); 537 EXPECT_EQ(2U, target.handler_list().size()); 538 EXPECT_EQ(1, target.handler_list()[0]); 539 EXPECT_EQ(2, target.handler_list()[1]); 540 } 541} 542 543// Tests that things work correctly if an event-handler destroys both the 544// dispatcher and a handler. 545TEST(EventDispatcherTest, EventHandlerAndDispatcherDestroyedDuringDispatch) { 546 { 547 TestEventDispatcher* dispatcher = new TestEventDispatcher(); 548 TestTarget target; 549 TestEventHandler h1(1); 550 TestEventHandler* h3 = new TestEventHandler(3); 551 EventHandlerDestroyer destroyer(2, h3); 552 553 target.AddPreTargetHandler(&h1); 554 target.AddPreTargetHandler(&destroyer); 555 target.AddPreTargetHandler(h3); 556 557 h1.set_expect_pre_target(true); 558 destroyer.set_expect_pre_target(true); 559 destroyer.set_dispatcher_delegate(dispatcher); 560 // |h3| should not receive events since |destroyer| will have destroyed 561 // it. 562 h3->set_expect_pre_target(false); 563 564 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0); 565 dispatcher->ProcessEvent(&target, &mouse); 566 EXPECT_TRUE(mouse.stopped_propagation()); 567 EXPECT_EQ(2U, target.handler_list().size()); 568 EXPECT_EQ(1, target.handler_list()[0]); 569 EXPECT_EQ(2, target.handler_list()[1]); 570 } 571 572 // Test for non-cancelable events. 573 { 574 TestEventDispatcher* dispatcher = new TestEventDispatcher(); 575 TestTarget target; 576 TestEventHandler h1(1); 577 TestEventHandler* h3 = new TestEventHandler(3); 578 EventHandlerDestroyer destroyer(2, h3); 579 580 target.AddPreTargetHandler(&h1); 581 target.AddPreTargetHandler(&destroyer); 582 target.AddPreTargetHandler(h3); 583 584 h1.set_expect_pre_target(true); 585 destroyer.set_expect_pre_target(true); 586 destroyer.set_dispatcher_delegate(dispatcher); 587 // |h3| should not receive events since |destroyer| will have destroyed 588 // it. 589 h3->set_expect_pre_target(false); 590 591 NonCancelableEvent event; 592 dispatcher->ProcessEvent(&target, &event); 593 EXPECT_EQ(2U, target.handler_list().size()); 594 EXPECT_EQ(1, target.handler_list()[0]); 595 EXPECT_EQ(2, target.handler_list()[1]); 596 } 597} 598 599} // namespace ui 600