Mailbox support for texture layers.
[chromium-blink-merge.git] / ui / base / events / event_dispatcher_unittest.cc
blob4b61cb4bd16bfd9e6dbb4a56babb4ccf7232b734
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"
9 namespace ui {
11 namespace {
13 class TestTarget : public EventTarget {
14 public:
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_; }
29 void Reset() {
30 handler_list_.clear();
33 private:
34 // Overridden from EventTarget:
35 virtual bool CanAcceptEvent(const ui::Event& event) OVERRIDE {
36 return true;
39 virtual EventTarget* GetParentTarget() OVERRIDE {
40 return parent_;
43 TestTarget* parent_;
44 std::vector<int> handler_list_;
45 bool valid_;
47 DISALLOW_COPY_AND_ASSIGN(TestTarget);
50 class TestEventHandler : public EventHandler {
51 public:
52 TestEventHandler(int id)
53 : id_(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;
71 } else {
72 NOTREACHED();
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; }
81 private:
82 // Overridden from EventHandler:
83 virtual void OnKeyEvent(KeyEvent* event) OVERRIDE {
84 ReceivedEvent(event);
85 SetStatusOnEvent(event);
88 virtual void OnMouseEvent(MouseEvent* event) OVERRIDE {
89 ReceivedEvent(event);
90 SetStatusOnEvent(event);
93 virtual void OnScrollEvent(ScrollEvent* event) OVERRIDE {
94 ReceivedEvent(event);
95 SetStatusOnEvent(event);
98 virtual void OnTouchEvent(TouchEvent* event) OVERRIDE {
99 ReceivedEvent(event);
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)
112 event->SetHandled();
115 int id_;
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 {
126 public:
127 EventHandlerDestroyDispatcherDelegate(EventDispatcherDelegate* delegate,
128 int id)
129 : TestEventHandler(id),
130 dispatcher_delegate_(delegate) {
133 virtual ~EventHandlerDestroyDispatcherDelegate() {}
135 private:
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 {
148 public:
149 explicit InvalidateTargetEventHandler(int id) : TestEventHandler(id) {}
150 virtual ~InvalidateTargetEventHandler() {}
152 private:
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 {
165 public:
166 EventHandlerDestroyer(int id, EventHandler* destroy)
167 : TestEventHandler(id),
168 to_destroy_(destroy),
169 dispatcher_delegate_(NULL) {
172 virtual ~EventHandlerDestroyer() {
173 CHECK(!to_destroy_);
176 void set_dispatcher_delegate(EventDispatcherDelegate* dispatcher_delegate) {
177 dispatcher_delegate_ = dispatcher_delegate;
180 private:
181 virtual void ReceivedEvent(Event* event) {
182 TestEventHandler::ReceivedEvent(event);
183 delete to_destroy_;
184 to_destroy_ = NULL;
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 {
199 public:
200 TestEventDispatcher() {}
202 virtual ~TestEventDispatcher() {}
204 void ProcessEvent(EventTarget* target, Event* event) {
205 DispatchEvent(target, event);
208 private:
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);
218 } // namespace
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 };
259 EXPECT_EQ(
260 std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
261 child.handler_list());
264 child.Reset();
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 };
277 EXPECT_EQ(
278 std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
279 child.handler_list());
282 child.Reset();
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());
293 EXPECT_EQ(
294 std::vector<int>(nexpected, nexpected + sizeof(nexpected) / sizeof(int)),
295 child.handler_list());
297 child.Reset();
298 event_mod.set_phase(EP_PREDISPATCH);
299 event_mod.set_result(ER_UNHANDLED);
301 int exp[] = { 1 };
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());
307 EXPECT_EQ(
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;
315 TestTarget target;
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 };
331 EXPECT_EQ(
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();
342 TestTarget target;
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();
369 TestTarget target;
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;
398 TestTarget target;
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;
425 TestTarget target;
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
437 // it.
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();
452 TestTarget target;
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
465 // it.
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]);
475 } // namespace ui