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