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.
5 #include "ui/events/event_dispatcher.h"
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"
18 class TestTarget
: public EventTarget
{
20 TestTarget() : parent_(NULL
), valid_(true) {}
21 virtual ~TestTarget() {}
23 void set_parent(TestTarget
* parent
) { parent_
= parent
; }
25 bool valid() const { return valid_
; }
26 void set_valid(bool valid
) { valid_
= valid
; }
28 void AddHandlerId(int id
) {
29 handler_list_
.push_back(id
);
32 const std::vector
<int>& handler_list() const { return handler_list_
; }
35 handler_list_
.clear();
40 // Overridden from EventTarget:
41 virtual bool CanAcceptEvent(const ui::Event
& event
) OVERRIDE
{
45 virtual EventTarget
* GetParentTarget() OVERRIDE
{
49 virtual scoped_ptr
<EventTargetIterator
> GetChildIterator() const OVERRIDE
{
50 return scoped_ptr
<EventTargetIterator
>();
53 virtual EventTargeter
* GetEventTargeter() OVERRIDE
{
58 std::vector
<int> handler_list_
;
61 DISALLOW_COPY_AND_ASSIGN(TestTarget
);
64 class TestEventHandler
: public EventHandler
{
66 TestEventHandler(int id
)
68 event_result_(ER_UNHANDLED
),
69 expect_pre_target_(false),
70 expect_post_target_(false),
71 received_pre_target_(false) {
74 virtual ~TestEventHandler() {}
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;
90 void set_event_result(EventResult result
) { event_result_
= result
; }
92 void set_expect_pre_target(bool expect
) { expect_pre_target_
= expect
; }
93 void set_expect_post_target(bool expect
) { expect_post_target_
= expect
; }
96 // Overridden from EventHandler:
97 virtual void OnEvent(Event
* event
) OVERRIDE
{
98 ui::EventHandler::OnEvent(event
);
100 SetStatusOnEvent(event
);
103 void SetStatusOnEvent(Event
* event
) {
104 if (event_result_
& ui::ER_CONSUMED
)
105 event
->StopPropagation();
106 if (event_result_
& ui::ER_HANDLED
)
111 EventResult event_result_
;
112 bool expect_pre_target_
;
113 bool expect_post_target_
;
114 bool received_pre_target_
;
116 DISALLOW_COPY_AND_ASSIGN(TestEventHandler
);
119 class NonCancelableEvent
: public Event
{
122 : Event(ui::ET_CANCEL_MODE
, ui::EventTimeForNow(), 0) {
123 set_cancelable(false);
126 virtual ~NonCancelableEvent() {}
129 DISALLOW_COPY_AND_ASSIGN(NonCancelableEvent
);
132 // Destroys the dispatcher-delegate when it receives any event.
133 class EventHandlerDestroyDispatcherDelegate
: public TestEventHandler
{
135 EventHandlerDestroyDispatcherDelegate(EventDispatcherDelegate
* delegate
,
137 : TestEventHandler(id
),
138 dispatcher_delegate_(delegate
) {
141 virtual ~EventHandlerDestroyDispatcherDelegate() {}
144 virtual void ReceivedEvent(Event
* event
) OVERRIDE
{
145 TestEventHandler::ReceivedEvent(event
);
146 delete dispatcher_delegate_
;
149 EventDispatcherDelegate
* dispatcher_delegate_
;
151 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyDispatcherDelegate
);
154 // Invalidates the target when it receives any event.
155 class InvalidateTargetEventHandler
: public TestEventHandler
{
157 explicit InvalidateTargetEventHandler(int id
) : TestEventHandler(id
) {}
158 virtual ~InvalidateTargetEventHandler() {}
161 virtual void ReceivedEvent(Event
* event
) OVERRIDE
{
162 TestEventHandler::ReceivedEvent(event
);
163 TestTarget
* target
= static_cast<TestTarget
*>(event
->target());
164 target
->set_valid(false);
167 DISALLOW_COPY_AND_ASSIGN(InvalidateTargetEventHandler
);
170 // Destroys a second event handler when this handler gets an event.
171 // Optionally also destroys the dispatcher.
172 class EventHandlerDestroyer
: public TestEventHandler
{
174 EventHandlerDestroyer(int id
, EventHandler
* destroy
)
175 : TestEventHandler(id
),
176 to_destroy_(destroy
),
177 dispatcher_delegate_(NULL
) {
180 virtual ~EventHandlerDestroyer() {
184 void set_dispatcher_delegate(EventDispatcherDelegate
* dispatcher_delegate
) {
185 dispatcher_delegate_
= dispatcher_delegate
;
189 virtual void ReceivedEvent(Event
* event
) OVERRIDE
{
190 TestEventHandler::ReceivedEvent(event
);
194 if (dispatcher_delegate_
) {
195 delete dispatcher_delegate_
;
196 dispatcher_delegate_
= NULL
;
200 EventHandler
* to_destroy_
;
201 EventDispatcherDelegate
* dispatcher_delegate_
;
203 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyer
);
206 class TestEventDispatcher
: public EventDispatcherDelegate
{
208 TestEventDispatcher() {}
210 virtual ~TestEventDispatcher() {}
212 EventDispatchDetails
ProcessEvent(EventTarget
* target
, Event
* event
) {
213 return DispatchEvent(target
, event
);
217 // Overridden from EventDispatcherDelegate:
218 virtual bool CanDispatchToTarget(EventTarget
* target
) OVERRIDE
{
219 TestTarget
* test_target
= static_cast<TestTarget
*>(target
);
220 return test_target
->valid();
223 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher
);
228 TEST(EventDispatcherTest
, EventDispatchOrder
) {
229 TestEventDispatcher dispatcher
;
230 TestTarget parent
, child
;
231 TestEventHandler
h1(1), h2(2), h3(3), h4(4);
232 TestEventHandler
h5(5), h6(6), h7(7), h8(8);
234 child
.set_parent(&parent
);
236 parent
.AddPreTargetHandler(&h1
);
237 parent
.AddPreTargetHandler(&h2
);
239 child
.AddPreTargetHandler(&h3
);
240 child
.AddPreTargetHandler(&h4
);
242 h1
.set_expect_pre_target(true);
243 h2
.set_expect_pre_target(true);
244 h3
.set_expect_pre_target(true);
245 h4
.set_expect_pre_target(true);
247 child
.AddPostTargetHandler(&h5
);
248 child
.AddPostTargetHandler(&h6
);
250 parent
.AddPostTargetHandler(&h7
);
251 parent
.AddPostTargetHandler(&h8
);
253 h5
.set_expect_post_target(true);
254 h6
.set_expect_post_target(true);
255 h7
.set_expect_post_target(true);
256 h8
.set_expect_post_target(true);
258 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
259 gfx::Point(3, 4), 0, 0);
260 Event::DispatcherApi
event_mod(&mouse
);
261 dispatcher
.ProcessEvent(&child
, &mouse
);
262 EXPECT_FALSE(mouse
.stopped_propagation());
263 EXPECT_FALSE(mouse
.handled());
266 int expected
[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
268 std::vector
<int>(expected
, expected
+ sizeof(expected
) / sizeof(int)),
269 child
.handler_list());
273 event_mod
.set_phase(EP_PREDISPATCH
);
274 event_mod
.set_result(ER_UNHANDLED
);
276 h1
.set_event_result(ER_HANDLED
);
277 dispatcher
.ProcessEvent(&child
, &mouse
);
278 EXPECT_EQ(EP_POSTDISPATCH
, mouse
.phase());
279 EXPECT_FALSE(mouse
.stopped_propagation());
280 EXPECT_TRUE(mouse
.handled());
282 // |h1| marks the event as handled. So only the pre-target handlers should
283 // receive the event.
284 int expected
[] = { 1, 2, 3, 4 };
286 std::vector
<int>(expected
, expected
+ sizeof(expected
) / sizeof(int)),
287 child
.handler_list());
291 event_mod
.set_phase(EP_PREDISPATCH
);
292 event_mod
.set_result(ER_UNHANDLED
);
294 int nexpected
[] = { 1, 2, 3, 4, 5 };
295 h1
.set_event_result(ER_UNHANDLED
);
296 h5
.set_event_result(ER_CONSUMED
);
297 dispatcher
.ProcessEvent(&child
, &mouse
);
298 EXPECT_EQ(EP_POSTDISPATCH
, mouse
.phase());
299 EXPECT_TRUE(mouse
.stopped_propagation());
300 EXPECT_TRUE(mouse
.handled());
302 std::vector
<int>(nexpected
, nexpected
+ sizeof(nexpected
) / sizeof(int)),
303 child
.handler_list());
306 event_mod
.set_phase(EP_PREDISPATCH
);
307 event_mod
.set_result(ER_UNHANDLED
);
310 h1
.set_event_result(ER_CONSUMED
);
311 dispatcher
.ProcessEvent(&child
, &mouse
);
312 EXPECT_EQ(EP_POSTDISPATCH
, mouse
.phase());
313 EXPECT_TRUE(mouse
.stopped_propagation());
314 EXPECT_TRUE(mouse
.handled());
316 std::vector
<int>(exp
, exp
+ sizeof(exp
) / sizeof(int)),
317 child
.handler_list());
320 // Tests that the event-phases are correct.
321 TEST(EventDispatcherTest
, EventDispatchPhase
) {
322 TestEventDispatcher dispatcher
;
325 TestEventHandler
handler(11);
327 target
.AddPreTargetHandler(&handler
);
328 target
.AddPostTargetHandler(&handler
);
329 handler
.set_expect_pre_target(true);
330 handler
.set_expect_post_target(true);
332 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
333 gfx::Point(3, 4), 0, 0);
334 Event::DispatcherApi
event_mod(&mouse
);
335 dispatcher
.ProcessEvent(&target
, &mouse
);
336 EXPECT_EQ(ER_UNHANDLED
, mouse
.result());
338 int handlers
[] = { 11, 11 };
340 std::vector
<int>(handlers
, handlers
+ sizeof(handlers
) / sizeof(int)),
341 target
.handler_list());
344 // Tests that if the dispatcher is destroyed in the middle of pre or post-target
345 // dispatching events, it doesn't cause a crash.
346 TEST(EventDispatcherTest
, EventDispatcherDestroyedDuringDispatch
) {
347 // Test for pre-target first.
349 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
351 EventHandlerDestroyDispatcherDelegate
handler(dispatcher
, 5);
352 TestEventHandler
h1(1), h2(2);
354 target
.AddPreTargetHandler(&h1
);
355 target
.AddPreTargetHandler(&handler
);
356 target
.AddPreTargetHandler(&h2
);
358 h1
.set_expect_pre_target(true);
359 handler
.set_expect_pre_target(true);
360 // |h2| should not receive any events at all since |handler| will have
361 // destroyed the dispatcher.
362 h2
.set_expect_pre_target(false);
364 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
365 gfx::Point(3, 4), 0, 0);
366 EventDispatchDetails details
= dispatcher
->ProcessEvent(&target
, &mouse
);
367 EXPECT_TRUE(details
.dispatcher_destroyed
);
368 EXPECT_EQ(ER_CONSUMED
, mouse
.result());
369 EXPECT_EQ(2U, target
.handler_list().size());
370 EXPECT_EQ(1, target
.handler_list()[0]);
371 EXPECT_EQ(5, target
.handler_list()[1]);
374 // Test for non-cancelable event.
376 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
378 EventHandlerDestroyDispatcherDelegate
handler(dispatcher
, 5);
379 TestEventHandler
h1(1), h2(2);
381 target
.AddPreTargetHandler(&h1
);
382 target
.AddPreTargetHandler(&handler
);
383 target
.AddPreTargetHandler(&h2
);
385 h1
.set_expect_pre_target(true);
386 handler
.set_expect_pre_target(true);
387 // |h2| should not receive any events at all since |handler| will have
388 // destroyed the dispatcher.
389 h2
.set_expect_pre_target(false);
391 NonCancelableEvent event
;
392 EventDispatchDetails details
= dispatcher
->ProcessEvent(&target
, &event
);
393 EXPECT_TRUE(details
.dispatcher_destroyed
);
394 EXPECT_EQ(2U, target
.handler_list().size());
395 EXPECT_EQ(1, target
.handler_list()[0]);
396 EXPECT_EQ(5, target
.handler_list()[1]);
399 // Now test for post-target.
401 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
403 EventHandlerDestroyDispatcherDelegate
handler(dispatcher
, 5);
404 TestEventHandler
h1(1), h2(2);
406 target
.AddPostTargetHandler(&h1
);
407 target
.AddPostTargetHandler(&handler
);
408 target
.AddPostTargetHandler(&h2
);
410 h1
.set_expect_post_target(true);
411 handler
.set_expect_post_target(true);
412 // |h2| should not receive any events at all since |handler| will have
413 // destroyed the dispatcher.
414 h2
.set_expect_post_target(false);
416 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
417 gfx::Point(3, 4), 0, 0);
418 EventDispatchDetails details
= dispatcher
->ProcessEvent(&target
, &mouse
);
419 EXPECT_TRUE(details
.dispatcher_destroyed
);
420 EXPECT_EQ(ER_CONSUMED
, mouse
.result());
421 EXPECT_EQ(2U, target
.handler_list().size());
422 EXPECT_EQ(1, target
.handler_list()[0]);
423 EXPECT_EQ(5, target
.handler_list()[1]);
426 // Test for non-cancelable event.
428 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
430 EventHandlerDestroyDispatcherDelegate
handler(dispatcher
, 5);
431 TestEventHandler
h1(1), h2(2);
433 target
.AddPostTargetHandler(&h1
);
434 target
.AddPostTargetHandler(&handler
);
435 target
.AddPostTargetHandler(&h2
);
437 h1
.set_expect_post_target(true);
438 handler
.set_expect_post_target(true);
439 // |h2| should not receive any events at all since |handler| will have
440 // destroyed the dispatcher.
441 h2
.set_expect_post_target(false);
443 NonCancelableEvent event
;
444 EventDispatchDetails details
= dispatcher
->ProcessEvent(&target
, &event
);
445 EXPECT_TRUE(details
.dispatcher_destroyed
);
446 EXPECT_EQ(2U, target
.handler_list().size());
447 EXPECT_EQ(1, target
.handler_list()[0]);
448 EXPECT_EQ(5, target
.handler_list()[1]);
452 // Tests that a target becoming invalid in the middle of pre- or post-target
453 // event processing aborts processing.
454 TEST(EventDispatcherTest
, EventDispatcherInvalidateTarget
) {
455 TestEventDispatcher dispatcher
;
457 TestEventHandler
h1(1);
458 InvalidateTargetEventHandler
invalidate_handler(2);
459 TestEventHandler
h3(3);
461 target
.AddPreTargetHandler(&h1
);
462 target
.AddPreTargetHandler(&invalidate_handler
);
463 target
.AddPreTargetHandler(&h3
);
465 h1
.set_expect_pre_target(true);
466 invalidate_handler
.set_expect_pre_target(true);
467 // |h3| should not receive events as the target will be invalidated.
468 h3
.set_expect_pre_target(false);
470 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4), gfx::Point(3, 4), 0,
472 EventDispatchDetails details
= dispatcher
.ProcessEvent(&target
, &mouse
);
473 EXPECT_FALSE(details
.dispatcher_destroyed
);
474 EXPECT_TRUE(details
.target_destroyed
);
475 EXPECT_FALSE(target
.valid());
476 EXPECT_TRUE(mouse
.stopped_propagation());
477 EXPECT_EQ(2U, target
.handler_list().size());
478 EXPECT_EQ(1, target
.handler_list()[0]);
479 EXPECT_EQ(2, target
.handler_list()[1]);
481 // Test for non-cancelable event.
483 NonCancelableEvent event
;
484 details
= dispatcher
.ProcessEvent(&target
, &event
);
485 EXPECT_FALSE(details
.dispatcher_destroyed
);
486 EXPECT_TRUE(details
.target_destroyed
);
487 EXPECT_FALSE(target
.valid());
488 EXPECT_EQ(2U, target
.handler_list().size());
489 EXPECT_EQ(1, target
.handler_list()[0]);
490 EXPECT_EQ(2, target
.handler_list()[1]);
493 // Tests that if an event-handler gets destroyed during event-dispatch, it does
494 // not cause a crash.
495 TEST(EventDispatcherTest
, EventHandlerDestroyedDuringDispatch
) {
497 TestEventDispatcher dispatcher
;
499 TestEventHandler
h1(1);
500 TestEventHandler
* h3
= new TestEventHandler(3);
501 EventHandlerDestroyer
handle_destroyer(2, h3
);
503 target
.AddPreTargetHandler(&h1
);
504 target
.AddPreTargetHandler(&handle_destroyer
);
505 target
.AddPreTargetHandler(h3
);
507 h1
.set_expect_pre_target(true);
508 handle_destroyer
.set_expect_pre_target(true);
509 // |h3| should not receive events since |handle_destroyer| will have
511 h3
->set_expect_pre_target(false);
513 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4), gfx::Point(3, 4), 0,
515 EventDispatchDetails details
= dispatcher
.ProcessEvent(&target
, &mouse
);
516 EXPECT_FALSE(details
.dispatcher_destroyed
);
517 EXPECT_FALSE(details
.target_destroyed
);
518 EXPECT_FALSE(mouse
.stopped_propagation());
519 EXPECT_EQ(2U, target
.handler_list().size());
520 EXPECT_EQ(1, target
.handler_list()[0]);
521 EXPECT_EQ(2, target
.handler_list()[1]);
524 // Test for non-cancelable events.
526 TestEventDispatcher dispatcher
;
528 TestEventHandler
h1(1);
529 TestEventHandler
* h3
= new TestEventHandler(3);
530 EventHandlerDestroyer
handle_destroyer(2, h3
);
532 target
.AddPreTargetHandler(&h1
);
533 target
.AddPreTargetHandler(&handle_destroyer
);
534 target
.AddPreTargetHandler(h3
);
536 h1
.set_expect_pre_target(true);
537 handle_destroyer
.set_expect_pre_target(true);
538 h3
->set_expect_pre_target(false);
540 NonCancelableEvent event
;
541 EventDispatchDetails details
= dispatcher
.ProcessEvent(&target
, &event
);
542 EXPECT_FALSE(details
.dispatcher_destroyed
);
543 EXPECT_FALSE(details
.target_destroyed
);
544 EXPECT_EQ(2U, target
.handler_list().size());
545 EXPECT_EQ(1, target
.handler_list()[0]);
546 EXPECT_EQ(2, target
.handler_list()[1]);
550 // Tests that things work correctly if an event-handler destroys both the
551 // dispatcher and a handler.
552 TEST(EventDispatcherTest
, EventHandlerAndDispatcherDestroyedDuringDispatch
) {
554 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
556 TestEventHandler
h1(1);
557 TestEventHandler
* h3
= new TestEventHandler(3);
558 EventHandlerDestroyer
destroyer(2, h3
);
560 target
.AddPreTargetHandler(&h1
);
561 target
.AddPreTargetHandler(&destroyer
);
562 target
.AddPreTargetHandler(h3
);
564 h1
.set_expect_pre_target(true);
565 destroyer
.set_expect_pre_target(true);
566 destroyer
.set_dispatcher_delegate(dispatcher
);
567 // |h3| should not receive events since |destroyer| will have destroyed
569 h3
->set_expect_pre_target(false);
571 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4), gfx::Point(3, 4), 0,
573 EventDispatchDetails details
= dispatcher
->ProcessEvent(&target
, &mouse
);
574 EXPECT_TRUE(details
.dispatcher_destroyed
);
575 EXPECT_TRUE(mouse
.stopped_propagation());
576 EXPECT_EQ(2U, target
.handler_list().size());
577 EXPECT_EQ(1, target
.handler_list()[0]);
578 EXPECT_EQ(2, target
.handler_list()[1]);
581 // Test for non-cancelable events.
583 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
585 TestEventHandler
h1(1);
586 TestEventHandler
* h3
= new TestEventHandler(3);
587 EventHandlerDestroyer
destroyer(2, h3
);
589 target
.AddPreTargetHandler(&h1
);
590 target
.AddPreTargetHandler(&destroyer
);
591 target
.AddPreTargetHandler(h3
);
593 h1
.set_expect_pre_target(true);
594 destroyer
.set_expect_pre_target(true);
595 destroyer
.set_dispatcher_delegate(dispatcher
);
596 // |h3| should not receive events since |destroyer| will have destroyed
598 h3
->set_expect_pre_target(false);
600 NonCancelableEvent event
;
601 EventDispatchDetails details
= dispatcher
->ProcessEvent(&target
, &event
);
602 EXPECT_TRUE(details
.dispatcher_destroyed
);
603 EXPECT_EQ(2U, target
.handler_list().size());
604 EXPECT_EQ(1, target
.handler_list()[0]);
605 EXPECT_EQ(2, target
.handler_list()[1]);