123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ui/events/platform/platform_event_source.h"
- #include <stddef.h>
- #include <stdint.h>
- #include <memory>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/memory/raw_ptr.h"
- #include "base/run_loop.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "ui/events/platform/platform_event_dispatcher.h"
- #include "ui/events/platform/platform_event_observer.h"
- #include "ui/events/platform/scoped_event_dispatcher.h"
- namespace ui {
- namespace {
- std::unique_ptr<PlatformEvent> CreatePlatformEvent() {
- std::unique_ptr<PlatformEvent> event = std::make_unique<PlatformEvent>();
- memset(event.get(), 0, sizeof(PlatformEvent));
- return event;
- }
- void RemoveDispatcher(PlatformEventDispatcher* dispatcher) {
- PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(dispatcher);
- }
- void RemoveDispatchers(PlatformEventDispatcher* first,
- PlatformEventDispatcher* second) {
- PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(first);
- PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(second);
- }
- void AddDispatcher(PlatformEventDispatcher* dispatcher) {
- PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(dispatcher);
- }
- } // namespace
- class TestPlatformEventSource : public PlatformEventSource {
- public:
- TestPlatformEventSource() = default;
- TestPlatformEventSource(const TestPlatformEventSource&) = delete;
- TestPlatformEventSource& operator=(const TestPlatformEventSource&) = delete;
- ~TestPlatformEventSource() override = default;
- uint32_t Dispatch(const PlatformEvent& event) { return DispatchEvent(event); }
- };
- class TestPlatformEventDispatcher : public PlatformEventDispatcher {
- public:
- TestPlatformEventDispatcher(int id, std::vector<int>* list)
- : id_(id),
- list_(list),
- post_dispatch_action_(POST_DISPATCH_NONE) {
- PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
- }
- TestPlatformEventDispatcher(const TestPlatformEventDispatcher&) = delete;
- TestPlatformEventDispatcher& operator=(const TestPlatformEventDispatcher&) =
- delete;
- ~TestPlatformEventDispatcher() override {
- PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
- }
- void set_post_dispatch_action(uint32_t action) {
- post_dispatch_action_ = action;
- }
- protected:
- // PlatformEventDispatcher:
- bool CanDispatchEvent(const PlatformEvent& event) override { return true; }
- uint32_t DispatchEvent(const PlatformEvent& event) override {
- list_->push_back(id_);
- return post_dispatch_action_;
- }
- private:
- int id_;
- raw_ptr<std::vector<int>> list_;
- uint32_t post_dispatch_action_;
- };
- class TestPlatformEventObserver : public PlatformEventObserver {
- public:
- TestPlatformEventObserver(int id, std::vector<int>* list)
- : id_(id), list_(list) {
- PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
- }
- TestPlatformEventObserver(const TestPlatformEventObserver&) = delete;
- TestPlatformEventObserver& operator=(const TestPlatformEventObserver&) =
- delete;
- ~TestPlatformEventObserver() override {
- PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
- }
- protected:
- // PlatformEventObserver:
- void WillProcessEvent(const PlatformEvent& event) override {
- list_->push_back(id_);
- }
- void DidProcessEvent(const PlatformEvent& event) override {}
- private:
- int id_;
- raw_ptr<std::vector<int>> list_;
- };
- class PlatformEventTest : public testing::Test {
- public:
- PlatformEventTest() {}
- PlatformEventTest(const PlatformEventTest&) = delete;
- PlatformEventTest& operator=(const PlatformEventTest&) = delete;
- ~PlatformEventTest() override {}
- TestPlatformEventSource* source() { return source_.get(); }
- protected:
- // testing::Test:
- void SetUp() override {
- source_ = std::make_unique<TestPlatformEventSource>();
- }
- private:
- std::unique_ptr<TestPlatformEventSource> source_;
- };
- // Tests that a dispatcher receives an event.
- TEST_F(PlatformEventTest, DispatcherBasic) {
- std::vector<int> list_dispatcher;
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- EXPECT_EQ(0u, list_dispatcher.size());
- {
- TestPlatformEventDispatcher dispatcher(1, &list_dispatcher);
- event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(1u, list_dispatcher.size());
- EXPECT_EQ(1, list_dispatcher[0]);
- }
- list_dispatcher.clear();
- event = CreatePlatformEvent();
- source()->Dispatch(*event);
- EXPECT_EQ(0u, list_dispatcher.size());
- }
- // Tests that dispatchers receive events in the correct order.
- TEST_F(PlatformEventTest, DispatcherOrder) {
- std::vector<int> list_dispatcher;
- int sequence[] = {21, 3, 6, 45};
- std::vector<std::unique_ptr<TestPlatformEventDispatcher>> dispatchers;
- for (auto id : sequence) {
- dispatchers.push_back(
- std::make_unique<TestPlatformEventDispatcher>(id, &list_dispatcher));
- }
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(std::size(sequence), list_dispatcher.size());
- EXPECT_EQ(std::vector<int>(sequence, sequence + std::size(sequence)),
- list_dispatcher);
- }
- // Tests that if a dispatcher consumes the event, the subsequent dispatchers do
- // not receive the event.
- TEST_F(PlatformEventTest, DispatcherConsumesEventToStopDispatch) {
- std::vector<int> list_dispatcher;
- TestPlatformEventDispatcher first(12, &list_dispatcher);
- TestPlatformEventDispatcher second(23, &list_dispatcher);
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list_dispatcher.size());
- EXPECT_EQ(12, list_dispatcher[0]);
- EXPECT_EQ(23, list_dispatcher[1]);
- list_dispatcher.clear();
- first.set_post_dispatch_action(POST_DISPATCH_STOP_PROPAGATION);
- event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(1u, list_dispatcher.size());
- EXPECT_EQ(12, list_dispatcher[0]);
- }
- // Tests that observers receive events.
- TEST_F(PlatformEventTest, ObserverBasic) {
- std::vector<int> list_observer;
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- EXPECT_EQ(0u, list_observer.size());
- {
- TestPlatformEventObserver observer(31, &list_observer);
- event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(1u, list_observer.size());
- EXPECT_EQ(31, list_observer[0]);
- }
- list_observer.clear();
- event = CreatePlatformEvent();
- source()->Dispatch(*event);
- EXPECT_EQ(0u, list_observer.size());
- }
- // Tests that observers receive events in the correct order.
- TEST_F(PlatformEventTest, ObserverOrder) {
- std::vector<int> list_observer;
- const int sequence[] = {21, 3, 6, 45};
- std::vector<std::unique_ptr<TestPlatformEventObserver>> observers;
- for (auto id : sequence) {
- observers.push_back(
- std::make_unique<TestPlatformEventObserver>(id, &list_observer));
- }
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(std::size(sequence), list_observer.size());
- EXPECT_EQ(std::vector<int>(sequence, sequence + std::size(sequence)),
- list_observer);
- }
- // Tests that observers and dispatchers receive events in the correct order.
- TEST_F(PlatformEventTest, DispatcherAndObserverOrder) {
- std::vector<int> list;
- TestPlatformEventDispatcher first_d(12, &list);
- TestPlatformEventObserver first_o(10, &list);
- TestPlatformEventDispatcher second_d(23, &list);
- TestPlatformEventObserver second_o(20, &list);
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- const int expected[] = {10, 20, 12, 23};
- EXPECT_EQ(std::vector<int>(expected, expected + std::size(expected)), list);
- }
- // Tests that an overridden dispatcher receives events before the default
- // dispatchers.
- TEST_F(PlatformEventTest, OverriddenDispatcherBasic) {
- std::vector<int> list;
- TestPlatformEventDispatcher dispatcher(10, &list);
- TestPlatformEventObserver observer(15, &list);
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(10, list[1]);
- list.clear();
- TestPlatformEventDispatcher overriding_dispatcher(20, &list);
- source()->RemovePlatformEventDispatcher(&overriding_dispatcher);
- std::unique_ptr<ScopedEventDispatcher> handle =
- source()->OverrideDispatcher(&overriding_dispatcher);
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(20, list[1]);
- }
- // Tests that an overridden dispatcher can request that the default dispatchers
- // can dispatch the events.
- TEST_F(PlatformEventTest, OverriddenDispatcherInvokeDefaultDispatcher) {
- std::vector<int> list;
- TestPlatformEventDispatcher dispatcher(10, &list);
- TestPlatformEventObserver observer(15, &list);
- TestPlatformEventDispatcher overriding_dispatcher(20, &list);
- source()->RemovePlatformEventDispatcher(&overriding_dispatcher);
- std::unique_ptr<ScopedEventDispatcher> handle =
- source()->OverrideDispatcher(&overriding_dispatcher);
- overriding_dispatcher.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT);
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- // First the observer, then the overriding dispatcher, then the default
- // dispatcher.
- ASSERT_EQ(3u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(20, list[1]);
- EXPECT_EQ(10, list[2]);
- list.clear();
- // Install a second overriding dispatcher.
- TestPlatformEventDispatcher second_overriding(50, &list);
- source()->RemovePlatformEventDispatcher(&second_overriding);
- std::unique_ptr<ScopedEventDispatcher> second_override_handle =
- source()->OverrideDispatcher(&second_overriding);
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(50, list[1]);
- list.clear();
- second_overriding.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT);
- source()->Dispatch(*event);
- // First the observer, then the second overriding dispatcher, then the default
- // dispatcher.
- ASSERT_EQ(3u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(50, list[1]);
- EXPECT_EQ(10, list[2]);
- }
- // Runs a callback during an event dispatch.
- class RunCallbackDuringDispatch : public TestPlatformEventDispatcher {
- public:
- RunCallbackDuringDispatch(int id, std::vector<int>* list)
- : TestPlatformEventDispatcher(id, list) {}
- RunCallbackDuringDispatch(const RunCallbackDuringDispatch&) = delete;
- RunCallbackDuringDispatch& operator=(const RunCallbackDuringDispatch&) =
- delete;
- ~RunCallbackDuringDispatch() override {}
- void set_callback(base::OnceClosure callback) {
- callback_ = std::move(callback);
- }
- protected:
- // PlatformEventDispatcher:
- uint32_t DispatchEvent(const PlatformEvent& event) override {
- if (!callback_.is_null())
- std::move(callback_).Run();
- return TestPlatformEventDispatcher::DispatchEvent(event);
- }
- private:
- base::OnceClosure callback_;
- };
- // Test that if a dispatcher removes another dispatcher that is later in the
- // dispatcher list during dispatching an event, then event dispatching still
- // continues correctly.
- TEST_F(PlatformEventTest, DispatcherRemovesNextDispatcherDuringDispatch) {
- std::vector<int> list;
- TestPlatformEventDispatcher first(10, &list);
- RunCallbackDuringDispatch second(15, &list);
- TestPlatformEventDispatcher third(20, &list);
- TestPlatformEventDispatcher fourth(30, &list);
- second.set_callback(
- base::BindOnce(&RemoveDispatcher, base::Unretained(&third)));
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- // |second| removes |third| from the dispatcher list during dispatch. So the
- // event should only reach |first|, |second|, and |fourth|.
- ASSERT_EQ(3u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(15, list[1]);
- EXPECT_EQ(30, list[2]);
- }
- // Tests that if a dispatcher removes itself from the dispatcher list during
- // dispatching an event, then event dispatching continues correctly.
- TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatch) {
- std::vector<int> list;
- TestPlatformEventDispatcher first(10, &list);
- RunCallbackDuringDispatch second(15, &list);
- TestPlatformEventDispatcher third(20, &list);
- second.set_callback(
- base::BindOnce(&RemoveDispatcher, base::Unretained(&second)));
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- // |second| removes itself from the dispatcher list during dispatch. So the
- // event should reach all three dispatchers in the list.
- ASSERT_EQ(3u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(15, list[1]);
- EXPECT_EQ(20, list[2]);
- }
- // Tests that if a dispatcher removes itself from the dispatcher list during
- // dispatching an event, and this dispatcher is last in the dispatcher-list,
- // then event dispatching ends correctly.
- TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatchLast) {
- std::vector<int> list;
- TestPlatformEventDispatcher first(10, &list);
- RunCallbackDuringDispatch second(15, &list);
- second.set_callback(
- base::BindOnce(&RemoveDispatcher, base::Unretained(&second)));
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- // |second| removes itself during dispatch. So both dispatchers will have
- // received the event.
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(15, list[1]);
- }
- // Tests that if a dispatcher removes a single dispatcher that comes before it
- // in the dispatcher list, then dispatch continues correctly.
- TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatcherDuringDispatch) {
- std::vector<int> list;
- TestPlatformEventDispatcher first(10, &list);
- RunCallbackDuringDispatch second(15, &list);
- TestPlatformEventDispatcher third(20, &list);
- second.set_callback(
- base::BindOnce(&RemoveDispatcher, base::Unretained(&first)));
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- // |second| removes |first| from the dispatcher list during dispatch. The
- // event should reach all three dispatchers.
- ASSERT_EQ(3u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(15, list[1]);
- EXPECT_EQ(20, list[2]);
- }
- // Tests that if a dispatcher removes multiple dispatchers that comes before it
- // in the dispatcher list, then dispatch continues correctly.
- TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatchersDuringDispatch) {
- std::vector<int> list;
- TestPlatformEventDispatcher first(10, &list);
- TestPlatformEventDispatcher second(12, &list);
- RunCallbackDuringDispatch third(15, &list);
- TestPlatformEventDispatcher fourth(20, &list);
- third.set_callback(base::BindOnce(
- &RemoveDispatchers, base::Unretained(&first), base::Unretained(&second)));
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- // |third| removes |first| and |second| from the dispatcher list during
- // dispatch. The event should reach all three dispatchers.
- ASSERT_EQ(4u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(12, list[1]);
- EXPECT_EQ(15, list[2]);
- EXPECT_EQ(20, list[3]);
- }
- // Tests that adding a dispatcher during dispatching an event receives that
- // event.
- TEST_F(PlatformEventTest, DispatcherAddedDuringDispatchReceivesEvent) {
- std::vector<int> list;
- TestPlatformEventDispatcher first(10, &list);
- RunCallbackDuringDispatch second(15, &list);
- TestPlatformEventDispatcher third(20, &list);
- TestPlatformEventDispatcher fourth(30, &list);
- RemoveDispatchers(&third, &fourth);
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(15, list[1]);
- second.set_callback(base::BindOnce(&AddDispatcher, base::Unretained(&third)));
- list.clear();
- source()->Dispatch(*event);
- ASSERT_EQ(3u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(15, list[1]);
- EXPECT_EQ(20, list[2]);
- second.set_callback(
- base::BindOnce(&AddDispatcher, base::Unretained(&fourth)));
- list.clear();
- source()->Dispatch(*event);
- ASSERT_EQ(4u, list.size());
- EXPECT_EQ(10, list[0]);
- EXPECT_EQ(15, list[1]);
- EXPECT_EQ(20, list[2]);
- EXPECT_EQ(30, list[3]);
- }
- // Provides mechanism for running tests from inside an active message-loop.
- class PlatformEventTestWithMessageLoop : public PlatformEventTest {
- public:
- PlatformEventTestWithMessageLoop() {}
- PlatformEventTestWithMessageLoop(const PlatformEventTestWithMessageLoop&) =
- delete;
- PlatformEventTestWithMessageLoop& operator=(
- const PlatformEventTestWithMessageLoop&) = delete;
- ~PlatformEventTestWithMessageLoop() override {}
- void Run() {
- task_environment_.GetMainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&PlatformEventTestWithMessageLoop::RunTestImpl,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
- }
- protected:
- virtual void RunTestImpl() = 0;
- private:
- base::test::SingleThreadTaskEnvironment task_environment_{
- base::test::SingleThreadTaskEnvironment::MainThreadType::UI};
- };
- #define RUN_TEST_IN_MESSAGE_LOOP(name) \
- TEST_F(name, Run) { Run(); }
- // Tests that a ScopedEventDispatcher restores the previous dispatcher when
- // destroyed.
- class ScopedDispatcherRestoresAfterDestroy
- : public PlatformEventTestWithMessageLoop {
- public:
- // PlatformEventTestWithMessageLoop:
- void RunTestImpl() override {
- std::vector<int> list;
- TestPlatformEventDispatcher dispatcher(10, &list);
- TestPlatformEventObserver observer(15, &list);
- TestPlatformEventDispatcher first_overriding(20, &list);
- source()->RemovePlatformEventDispatcher(&first_overriding);
- std::unique_ptr<ScopedEventDispatcher> first_override_handle =
- source()->OverrideDispatcher(&first_overriding);
- // Install a second overriding dispatcher.
- TestPlatformEventDispatcher second_overriding(50, &list);
- source()->RemovePlatformEventDispatcher(&second_overriding);
- std::unique_ptr<ScopedEventDispatcher> second_override_handle =
- source()->OverrideDispatcher(&second_overriding);
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(50, list[1]);
- list.clear();
- second_override_handle.reset();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(20, list[1]);
- }
- };
- RUN_TEST_IN_MESSAGE_LOOP(ScopedDispatcherRestoresAfterDestroy)
- // This dispatcher destroys the handle to the ScopedEventDispatcher when
- // dispatching an event.
- class DestroyScopedHandleDispatcher : public TestPlatformEventDispatcher {
- public:
- DestroyScopedHandleDispatcher(int id, std::vector<int>* list)
- : TestPlatformEventDispatcher(id, list) {}
- DestroyScopedHandleDispatcher(const DestroyScopedHandleDispatcher&) = delete;
- DestroyScopedHandleDispatcher& operator=(
- const DestroyScopedHandleDispatcher&) = delete;
- ~DestroyScopedHandleDispatcher() override {}
- void SetScopedHandle(std::unique_ptr<ScopedEventDispatcher> handler) {
- handler_ = std::move(handler);
- }
- void set_callback(base::OnceClosure callback) {
- callback_ = std::move(callback);
- }
- private:
- // PlatformEventDispatcher:
- bool CanDispatchEvent(const PlatformEvent& event) override { return true; }
- uint32_t DispatchEvent(const PlatformEvent& event) override {
- handler_.reset();
- uint32_t action = TestPlatformEventDispatcher::DispatchEvent(event);
- if (!callback_.is_null()) {
- std::move(callback_).Run();
- }
- return action;
- }
- std::unique_ptr<ScopedEventDispatcher> handler_;
- base::OnceClosure callback_;
- };
- // Tests that resetting an overridden dispatcher, and installing another
- // overridden dispatcher before the nested message-loop completely unwinds
- // function correctly.
- class ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration
- : public PlatformEventTestWithMessageLoop {
- public:
- void NestedTask(std::unique_ptr<ScopedEventDispatcher> dispatch_handle,
- std::vector<int>* list) {
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list->size());
- EXPECT_EQ(15, (*list)[0]);
- EXPECT_EQ(20, (*list)[1]);
- list->clear();
- // Reset the override dispatcher. This should restore the default
- // dispatcher.
- dispatch_handle.reset();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list->size());
- EXPECT_EQ(15, (*list)[0]);
- EXPECT_EQ(10, (*list)[1]);
- list->clear();
- // Install another override-dispatcher.
- DestroyScopedHandleDispatcher second_overriding(70, list);
- source()->RemovePlatformEventDispatcher(&second_overriding);
- std::unique_ptr<ScopedEventDispatcher> second_override_handle =
- source()->OverrideDispatcher(&second_overriding);
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list->size());
- EXPECT_EQ(15, (*list)[0]);
- EXPECT_EQ(70, (*list)[1]);
- list->clear();
- second_overriding.SetScopedHandle(std::move(second_override_handle));
- second_overriding.set_post_dispatch_action(POST_DISPATCH_NONE);
- base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
- second_overriding.set_callback(run_loop.QuitClosure());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(base::IgnoreResult(&TestPlatformEventSource::Dispatch),
- base::Unretained(source()), *event));
- run_loop.Run();
- ASSERT_EQ(2u, list->size());
- EXPECT_EQ(15, (*list)[0]);
- EXPECT_EQ(70, (*list)[1]);
- list->clear();
- // Terminate the message-loop.
- run_loop_.Quit();
- }
- // PlatformEventTestWithMessageLoop:
- void RunTestImpl() override {
- std::vector<int> list;
- TestPlatformEventDispatcher dispatcher(10, &list);
- TestPlatformEventObserver observer(15, &list);
- TestPlatformEventDispatcher overriding(20, &list);
- source()->RemovePlatformEventDispatcher(&overriding);
- std::unique_ptr<ScopedEventDispatcher> override_handle =
- source()->OverrideDispatcher(&overriding);
- std::unique_ptr<PlatformEvent> event = CreatePlatformEvent();
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(20, list[1]);
- list.clear();
- // Start a nested message-loop, and destroy |override_handle| in the nested
- // loop. That should terminate the nested loop, restore the previous
- // dispatchers, and return control to this function.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(
- &ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration::
- NestedTask,
- base::Unretained(this), std::move(override_handle),
- base::Unretained(&list)));
- run_loop_.Run();
- // Dispatching the event should now reach the default dispatcher.
- source()->Dispatch(*event);
- ASSERT_EQ(2u, list.size());
- EXPECT_EQ(15, list[0]);
- EXPECT_EQ(10, list[1]);
- }
- private:
- base::RunLoop run_loop_{base::RunLoop::Type::kNestableTasksAllowed};
- };
- RUN_TEST_IN_MESSAGE_LOOP(
- ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration)
- } // namespace ui
|