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