event_dispatcher_unittest.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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_utils.h"
10
11namespace ui {
12
13namespace {
14
15class 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
53class 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
108class 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.
122class 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.
144class 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.
161class 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
195class 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
217TEST(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.
310TEST(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.
335TEST(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.
443TEST(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.
480TEST(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.
532TEST(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