1// Copyright 2014 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/platform/platform_event_source.h"
6
7#include "base/bind.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/memory/scoped_vector.h"
10#include "base/message_loop/message_loop.h"
11#include "base/run_loop.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "ui/events/platform/platform_event_dispatcher.h"
14#include "ui/events/platform/platform_event_observer.h"
15#include "ui/events/platform/scoped_event_dispatcher.h"
16
17namespace ui {
18
19namespace {
20
21scoped_ptr<PlatformEvent> CreatePlatformEvent() {
22  scoped_ptr<PlatformEvent> event(new PlatformEvent());
23  memset(event.get(), 0, sizeof(PlatformEvent));
24  return event.Pass();
25}
26
27template <typename T>
28void DestroyScopedPtr(scoped_ptr<T> object) {}
29
30void RemoveDispatcher(PlatformEventDispatcher* dispatcher) {
31  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(dispatcher);
32}
33
34void RemoveDispatchers(PlatformEventDispatcher* first,
35                       PlatformEventDispatcher* second) {
36  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(first);
37  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(second);
38}
39
40void AddDispatcher(PlatformEventDispatcher* dispatcher) {
41  PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(dispatcher);
42}
43
44}  // namespace
45
46class TestPlatformEventSource : public PlatformEventSource {
47 public:
48  TestPlatformEventSource()
49      : stop_stream_(false) {
50  }
51  virtual ~TestPlatformEventSource() {}
52
53  uint32_t Dispatch(const PlatformEvent& event) { return DispatchEvent(event); }
54
55  // Dispatches the stream of events, and returns the number of events that are
56  // dispatched before it is requested to stop.
57  size_t DispatchEventStream(const ScopedVector<PlatformEvent>& events) {
58    stop_stream_ = false;
59    for (size_t count = 0; count < events.size(); ++count) {
60      DispatchEvent(*events[count]);
61      if (stop_stream_)
62        return count + 1;
63    }
64    return events.size();
65  }
66
67  // PlatformEventSource:
68  virtual void StopCurrentEventStream() OVERRIDE {
69    stop_stream_ = true;
70  }
71
72 private:
73  bool stop_stream_;
74  DISALLOW_COPY_AND_ASSIGN(TestPlatformEventSource);
75};
76
77class TestPlatformEventDispatcher : public PlatformEventDispatcher {
78 public:
79  TestPlatformEventDispatcher(int id, std::vector<int>* list)
80      : id_(id),
81        list_(list),
82        post_dispatch_action_(POST_DISPATCH_NONE),
83        stop_stream_(false) {
84    PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
85  }
86  virtual ~TestPlatformEventDispatcher() {
87    PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
88  }
89
90  void set_post_dispatch_action(uint32_t action) {
91    post_dispatch_action_ = action;
92  }
93
94 protected:
95  // PlatformEventDispatcher:
96  virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE {
97    return true;
98  }
99
100  virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
101    list_->push_back(id_);
102    return post_dispatch_action_;
103  }
104
105 private:
106  int id_;
107  std::vector<int>* list_;
108  uint32_t post_dispatch_action_;
109  bool stop_stream_;
110
111  DISALLOW_COPY_AND_ASSIGN(TestPlatformEventDispatcher);
112};
113
114class TestPlatformEventObserver : public PlatformEventObserver {
115 public:
116  TestPlatformEventObserver(int id, std::vector<int>* list)
117      : id_(id), list_(list) {
118    PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
119  }
120  virtual ~TestPlatformEventObserver() {
121    PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
122  }
123
124 protected:
125  // PlatformEventObserver:
126  virtual void WillProcessEvent(const PlatformEvent& event) OVERRIDE {
127    list_->push_back(id_);
128  }
129
130  virtual void DidProcessEvent(const PlatformEvent& event) OVERRIDE {}
131
132 private:
133  int id_;
134  std::vector<int>* list_;
135
136  DISALLOW_COPY_AND_ASSIGN(TestPlatformEventObserver);
137};
138
139class PlatformEventTest : public testing::Test {
140 public:
141  PlatformEventTest() {}
142  virtual ~PlatformEventTest() {}
143
144  TestPlatformEventSource* source() { return source_.get(); }
145
146 protected:
147  // testing::Test:
148  virtual void SetUp() OVERRIDE {
149    source_.reset(new TestPlatformEventSource());
150  }
151
152 private:
153  scoped_ptr<TestPlatformEventSource> source_;
154
155  DISALLOW_COPY_AND_ASSIGN(PlatformEventTest);
156};
157
158// Tests that a dispatcher receives an event.
159TEST_F(PlatformEventTest, DispatcherBasic) {
160  std::vector<int> list_dispatcher;
161  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
162  source()->Dispatch(*event);
163  EXPECT_EQ(0u, list_dispatcher.size());
164  {
165    TestPlatformEventDispatcher dispatcher(1, &list_dispatcher);
166
167    scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
168    source()->Dispatch(*event);
169    ASSERT_EQ(1u, list_dispatcher.size());
170    EXPECT_EQ(1, list_dispatcher[0]);
171  }
172
173  list_dispatcher.clear();
174  event = CreatePlatformEvent();
175  source()->Dispatch(*event);
176  EXPECT_EQ(0u, list_dispatcher.size());
177}
178
179// Tests that dispatchers receive events in the correct order.
180TEST_F(PlatformEventTest, DispatcherOrder) {
181  std::vector<int> list_dispatcher;
182  int sequence[] = {21, 3, 6, 45};
183  ScopedVector<TestPlatformEventDispatcher> dispatchers;
184  for (size_t i = 0; i < arraysize(sequence); ++i) {
185    dispatchers.push_back(
186        new TestPlatformEventDispatcher(sequence[i], &list_dispatcher));
187  }
188  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
189  source()->Dispatch(*event);
190  ASSERT_EQ(arraysize(sequence), list_dispatcher.size());
191  EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)),
192            list_dispatcher);
193}
194
195// Tests that if a dispatcher consumes the event, the subsequent dispatchers do
196// not receive the event.
197TEST_F(PlatformEventTest, DispatcherConsumesEventToStopDispatch) {
198  std::vector<int> list_dispatcher;
199  TestPlatformEventDispatcher first(12, &list_dispatcher);
200  TestPlatformEventDispatcher second(23, &list_dispatcher);
201
202  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
203  source()->Dispatch(*event);
204  ASSERT_EQ(2u, list_dispatcher.size());
205  EXPECT_EQ(12, list_dispatcher[0]);
206  EXPECT_EQ(23, list_dispatcher[1]);
207  list_dispatcher.clear();
208
209  first.set_post_dispatch_action(POST_DISPATCH_STOP_PROPAGATION);
210  event = CreatePlatformEvent();
211  source()->Dispatch(*event);
212  ASSERT_EQ(1u, list_dispatcher.size());
213  EXPECT_EQ(12, list_dispatcher[0]);
214}
215
216// Tests that observers receive events.
217TEST_F(PlatformEventTest, ObserverBasic) {
218  std::vector<int> list_observer;
219  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
220  source()->Dispatch(*event);
221  EXPECT_EQ(0u, list_observer.size());
222  {
223    TestPlatformEventObserver observer(31, &list_observer);
224
225    scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
226    source()->Dispatch(*event);
227    ASSERT_EQ(1u, list_observer.size());
228    EXPECT_EQ(31, list_observer[0]);
229  }
230
231  list_observer.clear();
232  event = CreatePlatformEvent();
233  source()->Dispatch(*event);
234  EXPECT_EQ(0u, list_observer.size());
235}
236
237// Tests that observers receive events in the correct order.
238TEST_F(PlatformEventTest, ObserverOrder) {
239  std::vector<int> list_observer;
240  const int sequence[] = {21, 3, 6, 45};
241  ScopedVector<TestPlatformEventObserver> observers;
242  for (size_t i = 0; i < arraysize(sequence); ++i) {
243    observers.push_back(
244        new TestPlatformEventObserver(sequence[i], &list_observer));
245  }
246  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
247  source()->Dispatch(*event);
248  ASSERT_EQ(arraysize(sequence), list_observer.size());
249  EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)),
250            list_observer);
251}
252
253// Tests that observers and dispatchers receive events in the correct order.
254TEST_F(PlatformEventTest, DispatcherAndObserverOrder) {
255  std::vector<int> list;
256  TestPlatformEventDispatcher first_d(12, &list);
257  TestPlatformEventObserver first_o(10, &list);
258  TestPlatformEventDispatcher second_d(23, &list);
259  TestPlatformEventObserver second_o(20, &list);
260  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
261  source()->Dispatch(*event);
262  const int expected[] = {10, 20, 12, 23};
263  EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list);
264}
265
266// Tests that an overridden dispatcher receives events before the default
267// dispatchers.
268TEST_F(PlatformEventTest, OverriddenDispatcherBasic) {
269  std::vector<int> list;
270  TestPlatformEventDispatcher dispatcher(10, &list);
271  TestPlatformEventObserver observer(15, &list);
272  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
273  source()->Dispatch(*event);
274  ASSERT_EQ(2u, list.size());
275  EXPECT_EQ(15, list[0]);
276  EXPECT_EQ(10, list[1]);
277  list.clear();
278
279  TestPlatformEventDispatcher overriding_dispatcher(20, &list);
280  source()->RemovePlatformEventDispatcher(&overriding_dispatcher);
281  scoped_ptr<ScopedEventDispatcher> handle =
282      source()->OverrideDispatcher(&overriding_dispatcher);
283  source()->Dispatch(*event);
284  ASSERT_EQ(2u, list.size());
285  EXPECT_EQ(15, list[0]);
286  EXPECT_EQ(20, list[1]);
287}
288
289// Tests that an overridden dispatcher can request that the default dispatchers
290// can dispatch the events.
291TEST_F(PlatformEventTest, OverriddenDispatcherInvokeDefaultDispatcher) {
292  std::vector<int> list;
293  TestPlatformEventDispatcher dispatcher(10, &list);
294  TestPlatformEventObserver observer(15, &list);
295  TestPlatformEventDispatcher overriding_dispatcher(20, &list);
296  source()->RemovePlatformEventDispatcher(&overriding_dispatcher);
297  scoped_ptr<ScopedEventDispatcher> handle =
298      source()->OverrideDispatcher(&overriding_dispatcher);
299  overriding_dispatcher.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT);
300
301  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
302  source()->Dispatch(*event);
303  // First the observer, then the overriding dispatcher, then the default
304  // dispatcher.
305  ASSERT_EQ(3u, list.size());
306  EXPECT_EQ(15, list[0]);
307  EXPECT_EQ(20, list[1]);
308  EXPECT_EQ(10, list[2]);
309  list.clear();
310
311  // Install a second overriding dispatcher.
312  TestPlatformEventDispatcher second_overriding(50, &list);
313  source()->RemovePlatformEventDispatcher(&second_overriding);
314  scoped_ptr<ScopedEventDispatcher> second_override_handle =
315      source()->OverrideDispatcher(&second_overriding);
316  source()->Dispatch(*event);
317  ASSERT_EQ(2u, list.size());
318  EXPECT_EQ(15, list[0]);
319  EXPECT_EQ(50, list[1]);
320  list.clear();
321
322  second_overriding.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT);
323  source()->Dispatch(*event);
324  // First the observer, then the second overriding dispatcher, then the default
325  // dispatcher.
326  ASSERT_EQ(3u, list.size());
327  EXPECT_EQ(15, list[0]);
328  EXPECT_EQ(50, list[1]);
329  EXPECT_EQ(10, list[2]);
330}
331
332// Runs a callback during an event dispatch.
333class RunCallbackDuringDispatch : public TestPlatformEventDispatcher {
334 public:
335  RunCallbackDuringDispatch(int id, std::vector<int>* list)
336      : TestPlatformEventDispatcher(id, list) {}
337  virtual ~RunCallbackDuringDispatch() {}
338
339  void set_callback(const base::Closure& callback) {
340    callback_ = callback;
341  }
342
343 protected:
344  // PlatformEventDispatcher:
345  virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
346    if (!callback_.is_null())
347      callback_.Run();
348    return TestPlatformEventDispatcher::DispatchEvent(event);
349  }
350
351 private:
352  base::Closure callback_;
353
354  DISALLOW_COPY_AND_ASSIGN(RunCallbackDuringDispatch);
355};
356
357// Test that if a dispatcher removes another dispatcher that is later in the
358// dispatcher list during dispatching an event, then event dispatching still
359// continues correctly.
360TEST_F(PlatformEventTest, DispatcherRemovesNextDispatcherDuringDispatch) {
361  std::vector<int> list;
362  TestPlatformEventDispatcher first(10, &list);
363  RunCallbackDuringDispatch second(15, &list);
364  TestPlatformEventDispatcher third(20, &list);
365  TestPlatformEventDispatcher fourth(30, &list);
366
367  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&third)));
368
369  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
370  source()->Dispatch(*event);
371  // |second| removes |third| from the dispatcher list during dispatch. So the
372  // event should only reach |first|, |second|, and |fourth|.
373  ASSERT_EQ(3u, list.size());
374  EXPECT_EQ(10, list[0]);
375  EXPECT_EQ(15, list[1]);
376  EXPECT_EQ(30, list[2]);
377}
378
379// Tests that if a dispatcher removes itself from the dispatcher list during
380// dispatching an event, then event dispatching continues correctly.
381TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatch) {
382  std::vector<int> list;
383  TestPlatformEventDispatcher first(10, &list);
384  RunCallbackDuringDispatch second(15, &list);
385  TestPlatformEventDispatcher third(20, &list);
386
387  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&second)));
388
389  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
390  source()->Dispatch(*event);
391  // |second| removes itself from the dispatcher list during dispatch. So the
392  // event should reach all three dispatchers in the list.
393  ASSERT_EQ(3u, list.size());
394  EXPECT_EQ(10, list[0]);
395  EXPECT_EQ(15, list[1]);
396  EXPECT_EQ(20, list[2]);
397}
398
399// Tests that if a dispatcher removes itself from the dispatcher list during
400// dispatching an event, and this dispatcher is last in the dispatcher-list,
401// then event dispatching ends correctly.
402TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatchLast) {
403  std::vector<int> list;
404  TestPlatformEventDispatcher first(10, &list);
405  RunCallbackDuringDispatch second(15, &list);
406
407  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&second)));
408
409  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
410  source()->Dispatch(*event);
411  // |second| removes itself during dispatch. So both dispatchers will have
412  // received the event.
413  ASSERT_EQ(2u, list.size());
414  EXPECT_EQ(10, list[0]);
415  EXPECT_EQ(15, list[1]);
416}
417
418// Tests that if a dispatcher removes a single dispatcher that comes before it
419// in the dispatcher list, then dispatch continues correctly.
420TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatcherDuringDispatch) {
421  std::vector<int> list;
422  TestPlatformEventDispatcher first(10, &list);
423  RunCallbackDuringDispatch second(15, &list);
424  TestPlatformEventDispatcher third(20, &list);
425
426  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&first)));
427
428  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
429  source()->Dispatch(*event);
430  // |second| removes |first| from the dispatcher list during dispatch. The
431  // event should reach all three dispatchers.
432  ASSERT_EQ(3u, list.size());
433  EXPECT_EQ(10, list[0]);
434  EXPECT_EQ(15, list[1]);
435  EXPECT_EQ(20, list[2]);
436}
437
438// Tests that if a dispatcher removes multiple dispatchers that comes before it
439// in the dispatcher list, then dispatch continues correctly.
440TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatchersDuringDispatch) {
441  std::vector<int> list;
442  TestPlatformEventDispatcher first(10, &list);
443  TestPlatformEventDispatcher second(12, &list);
444  RunCallbackDuringDispatch third(15, &list);
445  TestPlatformEventDispatcher fourth(20, &list);
446
447  third.set_callback(base::Bind(&RemoveDispatchers,
448                                base::Unretained(&first),
449                                base::Unretained(&second)));
450
451  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
452  source()->Dispatch(*event);
453  // |third| removes |first| and |second| from the dispatcher list during
454  // dispatch. The event should reach all three dispatchers.
455  ASSERT_EQ(4u, list.size());
456  EXPECT_EQ(10, list[0]);
457  EXPECT_EQ(12, list[1]);
458  EXPECT_EQ(15, list[2]);
459  EXPECT_EQ(20, list[3]);
460}
461
462// Tests that adding a dispatcher during dispatching an event receives that
463// event.
464TEST_F(PlatformEventTest, DispatcherAddedDuringDispatchReceivesEvent) {
465  std::vector<int> list;
466  TestPlatformEventDispatcher first(10, &list);
467  RunCallbackDuringDispatch second(15, &list);
468  TestPlatformEventDispatcher third(20, &list);
469  TestPlatformEventDispatcher fourth(30, &list);
470  RemoveDispatchers(&third, &fourth);
471
472  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
473  source()->Dispatch(*event);
474  ASSERT_EQ(2u, list.size());
475  EXPECT_EQ(10, list[0]);
476  EXPECT_EQ(15, list[1]);
477
478  second.set_callback(base::Bind(&AddDispatcher, base::Unretained(&third)));
479  list.clear();
480  source()->Dispatch(*event);
481  ASSERT_EQ(3u, list.size());
482  EXPECT_EQ(10, list[0]);
483  EXPECT_EQ(15, list[1]);
484  EXPECT_EQ(20, list[2]);
485
486  second.set_callback(base::Bind(&AddDispatcher, base::Unretained(&fourth)));
487  list.clear();
488  source()->Dispatch(*event);
489  ASSERT_EQ(4u, list.size());
490  EXPECT_EQ(10, list[0]);
491  EXPECT_EQ(15, list[1]);
492  EXPECT_EQ(20, list[2]);
493  EXPECT_EQ(30, list[3]);
494}
495
496// Provides mechanism for running tests from inside an active message-loop.
497class PlatformEventTestWithMessageLoop : public PlatformEventTest {
498 public:
499  PlatformEventTestWithMessageLoop() {}
500  virtual ~PlatformEventTestWithMessageLoop() {}
501
502  void Run() {
503    message_loop_.PostTask(
504        FROM_HERE,
505        base::Bind(&PlatformEventTestWithMessageLoop::RunTest,
506                   base::Unretained(this)));
507    message_loop_.Run();
508  }
509
510 protected:
511  void RunTest() {
512    RunTestImpl();
513    message_loop_.Quit();
514  }
515
516  virtual void RunTestImpl() = 0;
517
518 private:
519  base::MessageLoopForUI message_loop_;
520
521  DISALLOW_COPY_AND_ASSIGN(PlatformEventTestWithMessageLoop);
522};
523
524#define RUN_TEST_IN_MESSAGE_LOOP(name) \
525  TEST_F(name, Run) { Run(); }
526
527// Tests that a ScopedEventDispatcher restores the previous dispatcher when
528// destroyed.
529class ScopedDispatcherRestoresAfterDestroy
530    : public PlatformEventTestWithMessageLoop {
531 public:
532  // PlatformEventTestWithMessageLoop:
533  virtual void RunTestImpl() OVERRIDE {
534    std::vector<int> list;
535    TestPlatformEventDispatcher dispatcher(10, &list);
536    TestPlatformEventObserver observer(15, &list);
537
538    TestPlatformEventDispatcher first_overriding(20, &list);
539    source()->RemovePlatformEventDispatcher(&first_overriding);
540    scoped_ptr<ScopedEventDispatcher> first_override_handle =
541        source()->OverrideDispatcher(&first_overriding);
542
543    // Install a second overriding dispatcher.
544    TestPlatformEventDispatcher second_overriding(50, &list);
545    source()->RemovePlatformEventDispatcher(&second_overriding);
546    scoped_ptr<ScopedEventDispatcher> second_override_handle =
547        source()->OverrideDispatcher(&second_overriding);
548
549    scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
550    source()->Dispatch(*event);
551    ASSERT_EQ(2u, list.size());
552    EXPECT_EQ(15, list[0]);
553    EXPECT_EQ(50, list[1]);
554    list.clear();
555
556    second_override_handle.reset();
557    source()->Dispatch(*event);
558    ASSERT_EQ(2u, list.size());
559    EXPECT_EQ(15, list[0]);
560    EXPECT_EQ(20, list[1]);
561  }
562};
563
564RUN_TEST_IN_MESSAGE_LOOP(ScopedDispatcherRestoresAfterDestroy)
565
566// This dispatcher destroys the handle to the ScopedEventDispatcher when
567// dispatching an event.
568class DestroyScopedHandleDispatcher : public TestPlatformEventDispatcher {
569 public:
570  DestroyScopedHandleDispatcher(int id, std::vector<int>* list)
571      : TestPlatformEventDispatcher(id, list) {}
572  virtual ~DestroyScopedHandleDispatcher() {}
573
574  void SetScopedHandle(scoped_ptr<ScopedEventDispatcher> handler) {
575    handler_ = handler.Pass();
576  }
577
578  void set_callback(const base::Closure& callback) {
579    callback_ = callback;
580  }
581
582 private:
583  // PlatformEventDispatcher:
584  virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE {
585    return true;
586  }
587
588  virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
589    handler_.reset();
590    uint32_t action = TestPlatformEventDispatcher::DispatchEvent(event);
591    if (!callback_.is_null()) {
592      callback_.Run();
593      callback_ = base::Closure();
594    }
595    return action;
596  }
597
598  scoped_ptr<ScopedEventDispatcher> handler_;
599  base::Closure callback_;
600
601  DISALLOW_COPY_AND_ASSIGN(DestroyScopedHandleDispatcher);
602};
603
604// Tests that resetting an overridden dispatcher causes the nested message-loop
605// iteration to stop and the rest of the events are dispatched in the next
606// iteration.
607class DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration
608    : public PlatformEventTestWithMessageLoop {
609 public:
610  void NestedTask(std::vector<int>* list,
611                  TestPlatformEventDispatcher* dispatcher) {
612    ScopedVector<PlatformEvent> events;
613    scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
614    events.push_back(event.release());
615    event = CreatePlatformEvent();
616    events.push_back(event.release());
617
618    // Attempt to dispatch a couple of events. Dispatching the first event will
619    // have terminated the ScopedEventDispatcher object, which will terminate
620    // the current iteration of the message-loop.
621    size_t count = source()->DispatchEventStream(events);
622    EXPECT_EQ(1u, count);
623    ASSERT_EQ(2u, list->size());
624    EXPECT_EQ(15, (*list)[0]);
625    EXPECT_EQ(20, (*list)[1]);
626    list->clear();
627
628    ASSERT_LT(count, events.size());
629    events.erase(events.begin(), events.begin() + count);
630
631    count = source()->DispatchEventStream(events);
632    EXPECT_EQ(1u, count);
633    ASSERT_EQ(2u, list->size());
634    EXPECT_EQ(15, (*list)[0]);
635    EXPECT_EQ(10, (*list)[1]);
636    list->clear();
637
638    // Terminate the message-loop.
639    base::MessageLoopForUI::current()->QuitNow();
640  }
641
642  // PlatformEventTestWithMessageLoop:
643  virtual void RunTestImpl() OVERRIDE {
644    std::vector<int> list;
645    TestPlatformEventDispatcher dispatcher(10, &list);
646    TestPlatformEventObserver observer(15, &list);
647
648    DestroyScopedHandleDispatcher overriding(20, &list);
649    source()->RemovePlatformEventDispatcher(&overriding);
650    scoped_ptr<ScopedEventDispatcher> override_handle =
651        source()->OverrideDispatcher(&overriding);
652
653    scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
654    source()->Dispatch(*event);
655    ASSERT_EQ(2u, list.size());
656    EXPECT_EQ(15, list[0]);
657    EXPECT_EQ(20, list[1]);
658    list.clear();
659
660    overriding.SetScopedHandle(override_handle.Pass());
661    base::RunLoop run_loop;
662    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
663    base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
664    loop->PostTask(
665        FROM_HERE,
666        base::Bind(
667            &DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration::
668                NestedTask,
669            base::Unretained(this),
670            base::Unretained(&list),
671            base::Unretained(&overriding)));
672    run_loop.Run();
673
674    // Dispatching the event should now reach the default dispatcher.
675    source()->Dispatch(*event);
676    ASSERT_EQ(2u, list.size());
677    EXPECT_EQ(15, list[0]);
678    EXPECT_EQ(10, list[1]);
679  }
680};
681
682RUN_TEST_IN_MESSAGE_LOOP(
683    DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration)
684
685// Tests that resetting an overridden dispatcher, and installing another
686// overridden dispatcher before the nested message-loop completely unwinds
687// function correctly.
688class ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration
689    : public PlatformEventTestWithMessageLoop {
690 public:
691  void NestedTask(scoped_ptr<ScopedEventDispatcher> dispatch_handle,
692                  std::vector<int>* list) {
693    scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
694    source()->Dispatch(*event);
695    ASSERT_EQ(2u, list->size());
696    EXPECT_EQ(15, (*list)[0]);
697    EXPECT_EQ(20, (*list)[1]);
698    list->clear();
699
700    // Reset the override dispatcher. This should restore the default
701    // dispatcher.
702    dispatch_handle.reset();
703    source()->Dispatch(*event);
704    ASSERT_EQ(2u, list->size());
705    EXPECT_EQ(15, (*list)[0]);
706    EXPECT_EQ(10, (*list)[1]);
707    list->clear();
708
709    // Install another override-dispatcher.
710    DestroyScopedHandleDispatcher second_overriding(70, list);
711    source()->RemovePlatformEventDispatcher(&second_overriding);
712    scoped_ptr<ScopedEventDispatcher> second_override_handle =
713        source()->OverrideDispatcher(&second_overriding);
714
715    source()->Dispatch(*event);
716    ASSERT_EQ(2u, list->size());
717    EXPECT_EQ(15, (*list)[0]);
718    EXPECT_EQ(70, (*list)[1]);
719    list->clear();
720
721    second_overriding.SetScopedHandle(second_override_handle.Pass());
722    second_overriding.set_post_dispatch_action(POST_DISPATCH_NONE);
723    base::RunLoop run_loop;
724    second_overriding.set_callback(run_loop.QuitClosure());
725    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
726    base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
727    loop->PostTask(
728        FROM_HERE,
729        base::Bind(base::IgnoreResult(&TestPlatformEventSource::Dispatch),
730                   base::Unretained(source()),
731                   *event));
732    run_loop.Run();
733    ASSERT_EQ(2u, list->size());
734    EXPECT_EQ(15, (*list)[0]);
735    EXPECT_EQ(70, (*list)[1]);
736    list->clear();
737
738    // Terminate the message-loop.
739    base::MessageLoopForUI::current()->QuitNow();
740  }
741
742  // PlatformEventTestWithMessageLoop:
743  virtual void RunTestImpl() OVERRIDE {
744    std::vector<int> list;
745    TestPlatformEventDispatcher dispatcher(10, &list);
746    TestPlatformEventObserver observer(15, &list);
747
748    TestPlatformEventDispatcher overriding(20, &list);
749    source()->RemovePlatformEventDispatcher(&overriding);
750    scoped_ptr<ScopedEventDispatcher> override_handle =
751        source()->OverrideDispatcher(&overriding);
752
753    scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
754    source()->Dispatch(*event);
755    ASSERT_EQ(2u, list.size());
756    EXPECT_EQ(15, list[0]);
757    EXPECT_EQ(20, list[1]);
758    list.clear();
759
760    // Start a nested message-loop, and destroy |override_handle| in the nested
761    // loop. That should terminate the nested loop, restore the previous
762    // dispatchers, and return control to this function.
763    base::RunLoop run_loop;
764    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
765    base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
766    loop->PostTask(
767        FROM_HERE,
768        base::Bind(
769            &ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration::
770                NestedTask,
771            base::Unretained(this),
772            base::Passed(&override_handle),
773            base::Unretained(&list)));
774    run_loop.Run();
775
776    // Dispatching the event should now reach the default dispatcher.
777    source()->Dispatch(*event);
778    ASSERT_EQ(2u, list.size());
779    EXPECT_EQ(15, list[0]);
780    EXPECT_EQ(10, list[1]);
781  }
782};
783
784RUN_TEST_IN_MESSAGE_LOOP(
785    ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration)
786
787}  // namespace ui
788