1e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher// Use of this source code is governed by a BSD-style license that can be
3e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher// found in the LICENSE file.
4ef18e8147903885708d1c264904129af4fb636d6Jan Engelhardt
5ef18e8147903885708d1c264904129af4fb636d6Jan Engelhardt#include "ui/events/event_dispatcher.h"
6ef18e8147903885708d1c264904129af4fb636d6Jan Engelhardt
7c02e80878979d2205f3d89d05548397871e598e9Jan Engelhardt#include "testing/gtest/include/gtest/gtest.h"
8e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include "ui/events/event.h"
93aef54dce4f9bbe0b466478fd33a1d3131efbbb8Rusty Russell#include "ui/events/event_dispatcher.h"
103aef54dce4f9bbe0b466478fd33a1d3131efbbb8Rusty Russell#include "ui/events/event_target.h"
113aef54dce4f9bbe0b466478fd33a1d3131efbbb8Rusty Russell#include "ui/events/event_target_iterator.h"
123aef54dce4f9bbe0b466478fd33a1d3131efbbb8Rusty Russell#include "ui/events/event_utils.h"
133aef54dce4f9bbe0b466478fd33a1d3131efbbb8Rusty Russell
140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAInamespace ui {
150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI
16e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchernamespace {
1763e9063a660809385fd17edb94da044c7c884e02Illes Marci
1863e9063a660809385fd17edb94da044c7c884e02Illes Marciclass TestTarget : public EventTarget {
19e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher public:
20e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher  TestTarget() : parent_(NULL), valid_(true) {}
21fd1873110f8e57be578df17fc9d03536b10f4f73Jan Engelhardt  virtual ~TestTarget() {}
22a114e9e8be802ab744d442449b3ec7de03c58621Harald Welte
231c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt  void set_parent(TestTarget* parent) { parent_ = parent; }
24a114e9e8be802ab744d442449b3ec7de03c58621Harald Welte
251c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt  bool valid() const { return valid_; }
261c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt  void set_valid(bool valid) { valid_ = valid; }
271c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt
2896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom  void AddHandlerId(int id) {
291c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt    handler_list_.push_back(id);
308cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester  }
318cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester
328cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester  const std::vector<int>& handler_list() const { return handler_list_; }
338cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester
348cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester  void Reset() {
358cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester    handler_list_.clear();
368cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester    valid_ = true;
378cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester  }
388cf65913bb6353bf0e92eab0669d1c4c53b43623Phil Oester
39e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 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  EventDispatchDetails ProcessEvent(EventTarget* target, Event* event) {
213    return DispatchEvent(target, event);
214  }
215
216 private:
217  // Overridden from EventDispatcherDelegate:
218  virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE {
219    TestTarget* test_target = static_cast<TestTarget*>(target);
220    return test_target->valid();
221  }
222
223  DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher);
224};
225
226}  // namespace
227
228TEST(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);
233
234  child.set_parent(&parent);
235
236  parent.AddPreTargetHandler(&h1);
237  parent.AddPreTargetHandler(&h2);
238
239  child.AddPreTargetHandler(&h3);
240  child.AddPreTargetHandler(&h4);
241
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);
246
247  child.AddPostTargetHandler(&h5);
248  child.AddPostTargetHandler(&h6);
249
250  parent.AddPostTargetHandler(&h7);
251  parent.AddPostTargetHandler(&h8);
252
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);
257
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());
264
265  {
266    int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
267    EXPECT_EQ(
268        std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
269        child.handler_list());
270  }
271
272  child.Reset();
273  event_mod.set_phase(EP_PREDISPATCH);
274  event_mod.set_result(ER_UNHANDLED);
275
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());
281  {
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 };
285    EXPECT_EQ(
286        std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
287        child.handler_list());
288  }
289
290  child.Reset();
291  event_mod.set_phase(EP_PREDISPATCH);
292  event_mod.set_result(ER_UNHANDLED);
293
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());
301  EXPECT_EQ(
302      std::vector<int>(nexpected, nexpected + sizeof(nexpected) / sizeof(int)),
303      child.handler_list());
304
305  child.Reset();
306  event_mod.set_phase(EP_PREDISPATCH);
307  event_mod.set_result(ER_UNHANDLED);
308
309  int exp[] = { 1 };
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());
315  EXPECT_EQ(
316      std::vector<int>(exp, exp + sizeof(exp) / sizeof(int)),
317      child.handler_list());
318}
319
320// Tests that the event-phases are correct.
321TEST(EventDispatcherTest, EventDispatchPhase) {
322  TestEventDispatcher dispatcher;
323  TestTarget target;
324
325  TestEventHandler handler(11);
326
327  target.AddPreTargetHandler(&handler);
328  target.AddPostTargetHandler(&handler);
329  handler.set_expect_pre_target(true);
330  handler.set_expect_post_target(true);
331
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());
337
338  int handlers[] = { 11, 11 };
339  EXPECT_EQ(
340      std::vector<int>(handlers, handlers + sizeof(handlers) / sizeof(int)),
341      target.handler_list());
342}
343
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.
346TEST(EventDispatcherTest, EventDispatcherDestroyedDuringDispatch) {
347  // Test for pre-target first.
348  {
349    TestEventDispatcher* dispatcher = new TestEventDispatcher();
350    TestTarget target;
351    EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
352    TestEventHandler h1(1), h2(2);
353
354    target.AddPreTargetHandler(&h1);
355    target.AddPreTargetHandler(&handler);
356    target.AddPreTargetHandler(&h2);
357
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);
363
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]);
372  }
373
374  // Test for non-cancelable event.
375  {
376    TestEventDispatcher* dispatcher = new TestEventDispatcher();
377    TestTarget target;
378    EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
379    TestEventHandler h1(1), h2(2);
380
381    target.AddPreTargetHandler(&h1);
382    target.AddPreTargetHandler(&handler);
383    target.AddPreTargetHandler(&h2);
384
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);
390
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]);
397  }
398
399  // Now test for post-target.
400  {
401    TestEventDispatcher* dispatcher = new TestEventDispatcher();
402    TestTarget target;
403    EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
404    TestEventHandler h1(1), h2(2);
405
406    target.AddPostTargetHandler(&h1);
407    target.AddPostTargetHandler(&handler);
408    target.AddPostTargetHandler(&h2);
409
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);
415
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]);
424  }
425
426  // Test for non-cancelable event.
427  {
428    TestEventDispatcher* dispatcher = new TestEventDispatcher();
429    TestTarget target;
430    EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
431    TestEventHandler h1(1), h2(2);
432
433    target.AddPostTargetHandler(&h1);
434    target.AddPostTargetHandler(&handler);
435    target.AddPostTargetHandler(&h2);
436
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);
442
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]);
449  }
450}
451
452// Tests that a target becoming invalid in the middle of pre- or post-target
453// event processing aborts processing.
454TEST(EventDispatcherTest, EventDispatcherInvalidateTarget) {
455  TestEventDispatcher dispatcher;
456  TestTarget target;
457  TestEventHandler h1(1);
458  InvalidateTargetEventHandler invalidate_handler(2);
459  TestEventHandler h3(3);
460
461  target.AddPreTargetHandler(&h1);
462  target.AddPreTargetHandler(&invalidate_handler);
463  target.AddPreTargetHandler(&h3);
464
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);
469
470  MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0,
471                   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]);
480
481  // Test for non-cancelable event.
482  target.Reset();
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]);
491}
492
493// Tests that if an event-handler gets destroyed during event-dispatch, it does
494// not cause a crash.
495TEST(EventDispatcherTest, EventHandlerDestroyedDuringDispatch) {
496  {
497    TestEventDispatcher dispatcher;
498    TestTarget target;
499    TestEventHandler h1(1);
500    TestEventHandler* h3 = new TestEventHandler(3);
501    EventHandlerDestroyer handle_destroyer(2, h3);
502
503    target.AddPreTargetHandler(&h1);
504    target.AddPreTargetHandler(&handle_destroyer);
505    target.AddPreTargetHandler(h3);
506
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
510    // destroyed it.
511    h3->set_expect_pre_target(false);
512
513    MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0,
514                     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]);
522  }
523
524  // Test for non-cancelable events.
525  {
526    TestEventDispatcher dispatcher;
527    TestTarget target;
528    TestEventHandler h1(1);
529    TestEventHandler* h3 = new TestEventHandler(3);
530    EventHandlerDestroyer handle_destroyer(2, h3);
531
532    target.AddPreTargetHandler(&h1);
533    target.AddPreTargetHandler(&handle_destroyer);
534    target.AddPreTargetHandler(h3);
535
536    h1.set_expect_pre_target(true);
537    handle_destroyer.set_expect_pre_target(true);
538    h3->set_expect_pre_target(false);
539
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]);
547  }
548}
549
550// Tests that things work correctly if an event-handler destroys both the
551// dispatcher and a handler.
552TEST(EventDispatcherTest, EventHandlerAndDispatcherDestroyedDuringDispatch) {
553  {
554    TestEventDispatcher* dispatcher = new TestEventDispatcher();
555    TestTarget target;
556    TestEventHandler h1(1);
557    TestEventHandler* h3 = new TestEventHandler(3);
558    EventHandlerDestroyer destroyer(2, h3);
559
560    target.AddPreTargetHandler(&h1);
561    target.AddPreTargetHandler(&destroyer);
562    target.AddPreTargetHandler(h3);
563
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
568    // it.
569    h3->set_expect_pre_target(false);
570
571    MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0,
572                     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]);
579  }
580
581  // Test for non-cancelable events.
582  {
583    TestEventDispatcher* dispatcher = new TestEventDispatcher();
584    TestTarget target;
585    TestEventHandler h1(1);
586    TestEventHandler* h3 = new TestEventHandler(3);
587    EventHandlerDestroyer destroyer(2, h3);
588
589    target.AddPreTargetHandler(&h1);
590    target.AddPreTargetHandler(&destroyer);
591    target.AddPreTargetHandler(h3);
592
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
597    // it.
598    h3->set_expect_pre_target(false);
599
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]);
606  }
607}
608
609}  // namespace ui
610