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