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/base/events/event_dispatcher.h"
7 #include "testing/gtest/include/gtest/gtest.h"
13 class TestTarget
: public EventTarget
{
15 TestTarget() : parent_(NULL
), valid_(true) {}
16 virtual ~TestTarget() {}
18 void set_parent(TestTarget
* parent
) { parent_
= parent
; }
20 bool valid() const { return valid_
; }
21 void set_valid(bool valid
) { valid_
= valid
; }
23 void AddHandlerId(int id
) {
24 handler_list_
.push_back(id
);
27 const std::vector
<int>& handler_list() const { return handler_list_
; }
30 handler_list_
.clear();
34 // Overridden from EventTarget:
35 virtual bool CanAcceptEvent(const ui::Event
& event
) OVERRIDE
{
39 virtual EventTarget
* GetParentTarget() OVERRIDE
{
44 std::vector
<int> handler_list_
;
47 DISALLOW_COPY_AND_ASSIGN(TestTarget
);
50 class TestEventHandler
: public EventHandler
{
52 TestEventHandler(int id
)
54 event_result_(ER_UNHANDLED
),
55 expect_pre_target_(false),
56 expect_post_target_(false),
57 received_pre_target_(false) {
60 virtual ~TestEventHandler() {}
62 virtual void ReceivedEvent(Event
* event
) {
63 static_cast<TestTarget
*>(event
->target())->AddHandlerId(id_
);
64 if (event
->phase() == ui::EP_POSTTARGET
) {
65 EXPECT_TRUE(expect_post_target_
);
66 if (expect_pre_target_
)
67 EXPECT_TRUE(received_pre_target_
);
68 } else if (event
->phase() == ui::EP_PRETARGET
) {
69 EXPECT_TRUE(expect_pre_target_
);
70 received_pre_target_
= true;
76 void set_event_result(EventResult result
) { event_result_
= result
; }
78 void set_expect_pre_target(bool expect
) { expect_pre_target_
= expect
; }
79 void set_expect_post_target(bool expect
) { expect_post_target_
= expect
; }
82 // Overridden from EventHandler:
83 virtual void OnKeyEvent(KeyEvent
* event
) OVERRIDE
{
85 SetStatusOnEvent(event
);
88 virtual void OnMouseEvent(MouseEvent
* event
) OVERRIDE
{
90 SetStatusOnEvent(event
);
93 virtual void OnScrollEvent(ScrollEvent
* event
) OVERRIDE
{
95 SetStatusOnEvent(event
);
98 virtual void OnTouchEvent(TouchEvent
* event
) OVERRIDE
{
100 SetStatusOnEvent(event
);
103 virtual void OnGestureEvent(GestureEvent
* event
) OVERRIDE
{
104 ReceivedEvent(event
);
105 SetStatusOnEvent(event
);
108 void SetStatusOnEvent(Event
* event
) {
109 if (event_result_
& ui::ER_CONSUMED
)
110 event
->StopPropagation();
111 if (event_result_
& ui::ER_HANDLED
)
116 EventResult event_result_
;
117 bool expect_pre_target_
;
118 bool expect_post_target_
;
119 bool received_pre_target_
;
121 DISALLOW_COPY_AND_ASSIGN(TestEventHandler
);
124 // Destroys the dispatcher-delegate when it receives any event.
125 class EventHandlerDestroyDispatcherDelegate
: public TestEventHandler
{
127 EventHandlerDestroyDispatcherDelegate(EventDispatcherDelegate
* delegate
,
129 : TestEventHandler(id
),
130 dispatcher_delegate_(delegate
) {
133 virtual ~EventHandlerDestroyDispatcherDelegate() {}
136 virtual void ReceivedEvent(Event
* event
) OVERRIDE
{
137 TestEventHandler::ReceivedEvent(event
);
138 delete dispatcher_delegate_
;
141 EventDispatcherDelegate
* dispatcher_delegate_
;
143 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyDispatcherDelegate
);
146 // Invalidates the target when it receives any event.
147 class InvalidateTargetEventHandler
: public TestEventHandler
{
149 explicit InvalidateTargetEventHandler(int id
) : TestEventHandler(id
) {}
150 virtual ~InvalidateTargetEventHandler() {}
153 virtual void ReceivedEvent(Event
* event
) {
154 TestEventHandler::ReceivedEvent(event
);
155 TestTarget
* target
= static_cast<TestTarget
*>(event
->target());
156 target
->set_valid(false);
159 DISALLOW_COPY_AND_ASSIGN(InvalidateTargetEventHandler
);
162 // Destroys a second event handler when this handler gets an event.
163 // Optionally also destroys the dispatcher.
164 class EventHandlerDestroyer
: public TestEventHandler
{
166 EventHandlerDestroyer(int id
, EventHandler
* destroy
)
167 : TestEventHandler(id
),
168 to_destroy_(destroy
),
169 dispatcher_delegate_(NULL
) {
172 virtual ~EventHandlerDestroyer() {
176 void set_dispatcher_delegate(EventDispatcherDelegate
* dispatcher_delegate
) {
177 dispatcher_delegate_
= dispatcher_delegate
;
181 virtual void ReceivedEvent(Event
* event
) {
182 TestEventHandler::ReceivedEvent(event
);
186 if (dispatcher_delegate_
) {
187 delete dispatcher_delegate_
;
188 dispatcher_delegate_
= NULL
;
192 EventHandler
* to_destroy_
;
193 EventDispatcherDelegate
* dispatcher_delegate_
;
195 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyer
);
198 class TestEventDispatcher
: public EventDispatcherDelegate
{
200 TestEventDispatcher() {}
202 virtual ~TestEventDispatcher() {}
204 void ProcessEvent(EventTarget
* target
, Event
* event
) {
205 DispatchEvent(target
, event
);
209 // Overridden from EventDispatcherDelegate:
210 virtual bool CanDispatchToTarget(EventTarget
* target
) OVERRIDE
{
211 TestTarget
* test_target
= static_cast<TestTarget
*>(target
);
212 return test_target
->valid();
215 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher
);
220 TEST(EventDispatcherTest
, EventDispatchOrder
) {
221 TestEventDispatcher dispatcher
;
222 TestTarget parent
, child
;
223 TestEventHandler
h1(1), h2(2), h3(3), h4(4);
224 TestEventHandler
h5(5), h6(6), h7(7), h8(8);
226 child
.set_parent(&parent
);
228 parent
.AddPreTargetHandler(&h1
);
229 parent
.AddPreTargetHandler(&h2
);
231 child
.AddPreTargetHandler(&h3
);
232 child
.AddPreTargetHandler(&h4
);
234 h1
.set_expect_pre_target(true);
235 h2
.set_expect_pre_target(true);
236 h3
.set_expect_pre_target(true);
237 h4
.set_expect_pre_target(true);
239 child
.AddPostTargetHandler(&h5
);
240 child
.AddPostTargetHandler(&h6
);
242 parent
.AddPostTargetHandler(&h7
);
243 parent
.AddPostTargetHandler(&h8
);
245 h5
.set_expect_post_target(true);
246 h6
.set_expect_post_target(true);
247 h7
.set_expect_post_target(true);
248 h8
.set_expect_post_target(true);
250 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
251 gfx::Point(3, 4), 0);
252 Event::DispatcherApi
event_mod(&mouse
);
253 dispatcher
.ProcessEvent(&child
, &mouse
);
254 EXPECT_FALSE(mouse
.stopped_propagation());
255 EXPECT_FALSE(mouse
.handled());
258 int expected
[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
260 std::vector
<int>(expected
, expected
+ sizeof(expected
) / sizeof(int)),
261 child
.handler_list());
265 event_mod
.set_phase(EP_PREDISPATCH
);
266 event_mod
.set_result(ER_UNHANDLED
);
268 h1
.set_event_result(ER_HANDLED
);
269 dispatcher
.ProcessEvent(&child
, &mouse
);
270 EXPECT_EQ(EP_POSTDISPATCH
, mouse
.phase());
271 EXPECT_FALSE(mouse
.stopped_propagation());
272 EXPECT_TRUE(mouse
.handled());
274 // |h1| marks the event as handled. So only the pre-target handlers should
275 // receive the event.
276 int expected
[] = { 1, 2, 3, 4 };
278 std::vector
<int>(expected
, expected
+ sizeof(expected
) / sizeof(int)),
279 child
.handler_list());
283 event_mod
.set_phase(EP_PREDISPATCH
);
284 event_mod
.set_result(ER_UNHANDLED
);
286 int nexpected
[] = { 1, 2, 3, 4, 5 };
287 h1
.set_event_result(ER_UNHANDLED
);
288 h5
.set_event_result(ER_CONSUMED
);
289 dispatcher
.ProcessEvent(&child
, &mouse
);
290 EXPECT_EQ(EP_POSTDISPATCH
, mouse
.phase());
291 EXPECT_TRUE(mouse
.stopped_propagation());
292 EXPECT_TRUE(mouse
.handled());
294 std::vector
<int>(nexpected
, nexpected
+ sizeof(nexpected
) / sizeof(int)),
295 child
.handler_list());
298 event_mod
.set_phase(EP_PREDISPATCH
);
299 event_mod
.set_result(ER_UNHANDLED
);
302 h1
.set_event_result(ER_CONSUMED
);
303 dispatcher
.ProcessEvent(&child
, &mouse
);
304 EXPECT_EQ(EP_POSTDISPATCH
, mouse
.phase());
305 EXPECT_TRUE(mouse
.stopped_propagation());
306 EXPECT_TRUE(mouse
.handled());
308 std::vector
<int>(exp
, exp
+ sizeof(exp
) / sizeof(int)),
309 child
.handler_list());
312 // Tests that the event-phases are correct.
313 TEST(EventDispatcherTest
, EventDispatchPhase
) {
314 TestEventDispatcher dispatcher
;
317 TestEventHandler
handler(11);
319 target
.AddPreTargetHandler(&handler
);
320 target
.AddPostTargetHandler(&handler
);
321 handler
.set_expect_pre_target(true);
322 handler
.set_expect_post_target(true);
324 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
325 gfx::Point(3, 4), 0);
326 Event::DispatcherApi
event_mod(&mouse
);
327 dispatcher
.ProcessEvent(&target
, &mouse
);
328 EXPECT_EQ(ER_UNHANDLED
, mouse
.result());
330 int handlers
[] = { 11, 11 };
332 std::vector
<int>(handlers
, handlers
+ sizeof(handlers
) / sizeof(int)),
333 target
.handler_list());
336 // Tests that if the dispatcher is destroyed in the middle of pre or post-target
337 // dispatching events, it doesn't cause a crash.
338 TEST(EventDispatcherTest
, EventDispatcherDestroyedDuringDispatch
) {
339 // Test for pre-target first.
341 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
343 EventHandlerDestroyDispatcherDelegate
handler(dispatcher
, 5);
344 TestEventHandler
h1(1), h2(2);
346 target
.AddPreTargetHandler(&h1
);
347 target
.AddPreTargetHandler(&handler
);
348 target
.AddPreTargetHandler(&h2
);
350 h1
.set_expect_pre_target(true);
351 handler
.set_expect_pre_target(true);
352 // |h2| should not receive any events at all since |handler| will have
353 // destroyed the dispatcher.
354 h2
.set_expect_pre_target(false);
356 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
357 gfx::Point(3, 4), 0);
358 Event::DispatcherApi
event_mod(&mouse
);
359 dispatcher
->ProcessEvent(&target
, &mouse
);
360 EXPECT_EQ(ER_CONSUMED
, mouse
.result());
361 EXPECT_EQ(2U, target
.handler_list().size());
362 EXPECT_EQ(1, target
.handler_list()[0]);
363 EXPECT_EQ(5, target
.handler_list()[1]);
366 // Now test for post-target.
368 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
370 EventHandlerDestroyDispatcherDelegate
handler(dispatcher
, 5);
371 TestEventHandler
h1(1), h2(2);
373 target
.AddPostTargetHandler(&h1
);
374 target
.AddPostTargetHandler(&handler
);
375 target
.AddPostTargetHandler(&h2
);
377 h1
.set_expect_post_target(true);
378 handler
.set_expect_post_target(true);
379 // |h2| should not receive any events at all since |handler| will have
380 // destroyed the dispatcher.
381 h2
.set_expect_post_target(false);
383 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4),
384 gfx::Point(3, 4), 0);
385 Event::DispatcherApi
event_mod(&mouse
);
386 dispatcher
->ProcessEvent(&target
, &mouse
);
387 EXPECT_EQ(ER_CONSUMED
, mouse
.result());
388 EXPECT_EQ(2U, target
.handler_list().size());
389 EXPECT_EQ(1, target
.handler_list()[0]);
390 EXPECT_EQ(5, target
.handler_list()[1]);
394 // Tests that a target becoming invalid in the middle of pre- or post-target
395 // event processing aborts processing.
396 TEST(EventDispatcherTest
, EventDispatcherInvalidateTarget
) {
397 TestEventDispatcher dispatcher
;
399 TestEventHandler
h1(1);
400 InvalidateTargetEventHandler
invalidate_handler(2);
401 TestEventHandler
h3(3);
403 target
.AddPreTargetHandler(&h1
);
404 target
.AddPreTargetHandler(&invalidate_handler
);
405 target
.AddPreTargetHandler(&h3
);
407 h1
.set_expect_pre_target(true);
408 invalidate_handler
.set_expect_pre_target(true);
409 // |h3| should not receive events as the target will be invalidated.
410 h3
.set_expect_pre_target(false);
412 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4), gfx::Point(3, 4), 0);
413 dispatcher
.ProcessEvent(&target
, &mouse
);
414 EXPECT_FALSE(target
.valid());
415 EXPECT_TRUE(mouse
.stopped_propagation());
416 EXPECT_EQ(2U, target
.handler_list().size());
417 EXPECT_EQ(1, target
.handler_list()[0]);
418 EXPECT_EQ(2, target
.handler_list()[1]);
421 // Tests that if an event-handler gets destroyed during event-dispatch, it does
422 // not cause a crash.
423 TEST(EventDispatcherTest
, EventHandlerDestroyedDuringDispatch
) {
424 TestEventDispatcher dispatcher
;
426 TestEventHandler
h1(1);
427 TestEventHandler
* h3
= new TestEventHandler(3);
428 EventHandlerDestroyer
handle_destroyer(2, h3
);
430 target
.AddPreTargetHandler(&h1
);
431 target
.AddPreTargetHandler(&handle_destroyer
);
432 target
.AddPreTargetHandler(h3
);
434 h1
.set_expect_pre_target(true);
435 handle_destroyer
.set_expect_pre_target(true);
436 // |h3| should not receive events since |handle_destroyer| will have destroyed
438 h3
->set_expect_pre_target(false);
440 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4), gfx::Point(3, 4), 0);
441 dispatcher
.ProcessEvent(&target
, &mouse
);
442 EXPECT_FALSE(mouse
.stopped_propagation());
443 EXPECT_EQ(2U, target
.handler_list().size());
444 EXPECT_EQ(1, target
.handler_list()[0]);
445 EXPECT_EQ(2, target
.handler_list()[1]);
448 // Tests that things work correctly if an event-handler destroys both the
449 // dispatcher and a handler.
450 TEST(EventDispatcherTest
, EventHandlerAndDispatcherDestroyedDuringDispatch
) {
451 TestEventDispatcher
* dispatcher
= new TestEventDispatcher();
453 TestEventHandler
h1(1);
454 TestEventHandler
* h3
= new TestEventHandler(3);
455 EventHandlerDestroyer
destroyer(2, h3
);
457 target
.AddPreTargetHandler(&h1
);
458 target
.AddPreTargetHandler(&destroyer
);
459 target
.AddPreTargetHandler(h3
);
461 h1
.set_expect_pre_target(true);
462 destroyer
.set_expect_pre_target(true);
463 destroyer
.set_dispatcher_delegate(dispatcher
);
464 // |h3| should not receive events since |destroyer| will have destroyed
466 h3
->set_expect_pre_target(false);
468 MouseEvent
mouse(ui::ET_MOUSE_MOVED
, gfx::Point(3, 4), gfx::Point(3, 4), 0);
469 dispatcher
->ProcessEvent(&target
, &mouse
);
470 EXPECT_TRUE(mouse
.stopped_propagation());
471 EXPECT_EQ(2U, target
.handler_list().size());
472 EXPECT_EQ(1, target
.handler_list()[0]);
473 EXPECT_EQ(2, target
.handler_list()[1]);