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