This source file includes following definitions.
- CreatePlatformEvent
- DestroyScopedPtr
- Dispatch
- DispatchEventStream
- post_dispatch_action_
- set_post_dispatch_action
- CanDispatchEvent
- DispatchEvent
- consume_event_
- set_consume_event
- WillProcessEvent
- DidProcessEvent
- source
- SetUp
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- Run
- RunTest
- RunTestImpl
- RUN_TEST_IN_MESSAGE_LOOP
- NestedTask
- RunTestImpl
- RUN_TEST_IN_MESSAGE_LOOP
#include "ui/events/platform/platform_event_source.h"
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.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 {
scoped_ptr<PlatformEvent> CreatePlatformEvent() {
scoped_ptr<PlatformEvent> event(new PlatformEvent());
memset(event.get(), 0, sizeof(PlatformEvent));
return event.Pass();
}
template <typename T>
void DestroyScopedPtr(scoped_ptr<T> object) {}
}
class TestPlatformEventSource : public PlatformEventSource {
public:
TestPlatformEventSource() {}
virtual ~TestPlatformEventSource() {}
uint32_t Dispatch(const PlatformEvent& event) { return DispatchEvent(event); }
size_t DispatchEventStream(const ScopedVector<PlatformEvent>& events) {
for (size_t count = 0; count < events.size(); ++count) {
uint32_t action = DispatchEvent(*events[count]);
if (action & POST_DISPATCH_QUIT_LOOP)
return count + 1;
}
return events.size();
}
private:
DISALLOW_COPY_AND_ASSIGN(TestPlatformEventSource);
};
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);
}
virtual ~TestPlatformEventDispatcher() {
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}
void set_post_dispatch_action(uint32_t action) {
post_dispatch_action_ = action;
}
protected:
virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE {
return true;
}
virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
list_->push_back(id_);
return post_dispatch_action_;
}
private:
int id_;
std::vector<int>* list_;
uint32_t post_dispatch_action_;
DISALLOW_COPY_AND_ASSIGN(TestPlatformEventDispatcher);
};
class TestPlatformEventObserver : public PlatformEventObserver {
public:
TestPlatformEventObserver(int id, std::vector<int>* list)
: id_(id), list_(list), consume_event_(false) {
PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
}
virtual ~TestPlatformEventObserver() {
PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
}
void set_consume_event(bool consume) { consume_event_ = consume; }
protected:
virtual EventStatus WillProcessEvent(const PlatformEvent& event) OVERRIDE {
list_->push_back(id_);
return consume_event_ ? EVENT_STATUS_HANDLED : EVENT_STATUS_CONTINUE;
}
virtual void DidProcessEvent(const PlatformEvent& event) OVERRIDE {}
private:
int id_;
std::vector<int>* list_;
bool consume_event_;
DISALLOW_COPY_AND_ASSIGN(TestPlatformEventObserver);
};
class PlatformEventTest : public testing::Test {
public:
PlatformEventTest() {}
virtual ~PlatformEventTest() {}
TestPlatformEventSource* source() { return source_.get(); }
protected:
virtual void SetUp() OVERRIDE {
source_.reset(new TestPlatformEventSource());
}
private:
scoped_ptr<TestPlatformEventSource> source_;
DISALLOW_COPY_AND_ASSIGN(PlatformEventTest);
};
TEST_F(PlatformEventTest, DispatcherBasic) {
std::vector<int> list_dispatcher;
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
EXPECT_EQ(0u, list_dispatcher.size());
{
TestPlatformEventDispatcher dispatcher(1, &list_dispatcher);
scoped_ptr<PlatformEvent> 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());
}
TEST_F(PlatformEventTest, DispatcherOrder) {
std::vector<int> list_dispatcher;
int sequence[] = {21, 3, 6, 45};
ScopedVector<TestPlatformEventDispatcher> dispatchers;
for (size_t i = 0; i < arraysize(sequence); ++i) {
dispatchers.push_back(
new TestPlatformEventDispatcher(sequence[i], &list_dispatcher));
}
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
ASSERT_EQ(arraysize(sequence), list_dispatcher.size());
EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)),
list_dispatcher);
}
TEST_F(PlatformEventTest, DispatcherConsumesEventToStopDispatch) {
std::vector<int> list_dispatcher;
TestPlatformEventDispatcher first(12, &list_dispatcher);
TestPlatformEventDispatcher second(23, &list_dispatcher);
scoped_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]);
}
TEST_F(PlatformEventTest, ObserverBasic) {
std::vector<int> list_observer;
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
EXPECT_EQ(0u, list_observer.size());
{
TestPlatformEventObserver observer(31, &list_observer);
scoped_ptr<PlatformEvent> 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());
}
TEST_F(PlatformEventTest, ObserverOrder) {
std::vector<int> list_observer;
const int sequence[] = {21, 3, 6, 45};
ScopedVector<TestPlatformEventObserver> observers;
for (size_t i = 0; i < arraysize(sequence); ++i) {
observers.push_back(
new TestPlatformEventObserver(sequence[i], &list_observer));
}
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
ASSERT_EQ(arraysize(sequence), list_observer.size());
EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)),
list_observer);
}
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);
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
const int expected[] = {10, 20, 12, 23};
EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list);
}
TEST_F(PlatformEventTest, ObserverConsumesEventToStopDispatch) {
std::vector<int> list;
TestPlatformEventDispatcher first_d(12, &list);
TestPlatformEventObserver first_o(10, &list);
TestPlatformEventDispatcher second_d(23, &list);
TestPlatformEventObserver second_o(20, &list);
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
const int expected[] = {10, 20, 12, 23};
EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list);
list.clear();
first_o.set_consume_event(true);
event = CreatePlatformEvent();
source()->Dispatch(*event);
ASSERT_EQ(1u, list.size());
EXPECT_EQ(10, list[0]);
}
TEST_F(PlatformEventTest, OverriddenDispatcherBasic) {
std::vector<int> list;
TestPlatformEventDispatcher dispatcher(10, &list);
TestPlatformEventObserver observer(15, &list);
scoped_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);
scoped_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]);
}
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);
scoped_ptr<ScopedEventDispatcher> handle =
source()->OverrideDispatcher(&overriding_dispatcher);
overriding_dispatcher.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT);
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
ASSERT_EQ(3u, list.size());
EXPECT_EQ(15, list[0]);
EXPECT_EQ(20, list[1]);
EXPECT_EQ(10, list[2]);
list.clear();
TestPlatformEventDispatcher second_overriding(50, &list);
source()->RemovePlatformEventDispatcher(&second_overriding);
scoped_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);
ASSERT_EQ(3u, list.size());
EXPECT_EQ(15, list[0]);
EXPECT_EQ(50, list[1]);
EXPECT_EQ(10, list[2]);
}
class PlatformEventTestWithMessageLoop : public PlatformEventTest {
public:
PlatformEventTestWithMessageLoop() {}
virtual ~PlatformEventTestWithMessageLoop() {}
void Run() {
message_loop_.PostTask(
FROM_HERE,
base::Bind(&PlatformEventTestWithMessageLoop::RunTest,
base::Unretained(this)));
message_loop_.Run();
}
protected:
void RunTest() {
RunTestImpl();
message_loop_.Quit();
}
virtual void RunTestImpl() = 0;
private:
base::MessageLoopForUI message_loop_;
DISALLOW_COPY_AND_ASSIGN(PlatformEventTestWithMessageLoop);
};
#define RUN_TEST_IN_MESSAGE_LOOP(name) \
TEST_F(name, Run) { Run(); }
class ScopedDispatcherRestoresAfterDestroy
: public PlatformEventTestWithMessageLoop {
public:
virtual void RunTestImpl() OVERRIDE {
std::vector<int> list;
TestPlatformEventDispatcher dispatcher(10, &list);
TestPlatformEventObserver observer(15, &list);
TestPlatformEventDispatcher first_overriding(20, &list);
source()->RemovePlatformEventDispatcher(&first_overriding);
scoped_ptr<ScopedEventDispatcher> first_override_handle =
source()->OverrideDispatcher(&first_overriding);
TestPlatformEventDispatcher second_overriding(50, &list);
source()->RemovePlatformEventDispatcher(&second_overriding);
scoped_ptr<ScopedEventDispatcher> second_override_handle =
source()->OverrideDispatcher(&second_overriding);
scoped_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)
class DestroyScopedHandleDispatcher : public TestPlatformEventDispatcher {
public:
DestroyScopedHandleDispatcher(int id, std::vector<int>* list)
: TestPlatformEventDispatcher(id, list) {}
virtual ~DestroyScopedHandleDispatcher() {}
void SetScopedHandle(scoped_ptr<ScopedEventDispatcher> handler) {
handler_ = handler.Pass();
}
private:
virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE {
return true;
}
virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
handler_.reset();
return TestPlatformEventDispatcher::DispatchEvent(event);
}
scoped_ptr<ScopedEventDispatcher> handler_;
DISALLOW_COPY_AND_ASSIGN(DestroyScopedHandleDispatcher);
};
class DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration
: public PlatformEventTestWithMessageLoop {
public:
void NestedTask(std::vector<int>* list,
TestPlatformEventDispatcher* dispatcher) {
ScopedVector<PlatformEvent> events;
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
events.push_back(event.release());
event = CreatePlatformEvent();
events.push_back(event.release());
size_t count = source()->DispatchEventStream(events);
EXPECT_EQ(1u, count);
ASSERT_EQ(2u, list->size());
EXPECT_EQ(15, (*list)[0]);
EXPECT_EQ(20, (*list)[1]);
list->clear();
ASSERT_LT(count, events.size());
events.erase(events.begin(), events.begin() + count);
count = source()->DispatchEventStream(events);
EXPECT_EQ(1u, count);
ASSERT_EQ(2u, list->size());
EXPECT_EQ(15, (*list)[0]);
EXPECT_EQ(10, (*list)[1]);
list->clear();
base::MessageLoopForUI::current()->QuitNow();
}
virtual void RunTestImpl() OVERRIDE {
std::vector<int> list;
TestPlatformEventDispatcher dispatcher(10, &list);
TestPlatformEventObserver observer(15, &list);
DestroyScopedHandleDispatcher overriding(20, &list);
source()->RemovePlatformEventDispatcher(&overriding);
scoped_ptr<ScopedEventDispatcher> override_handle =
source()->OverrideDispatcher(&overriding);
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
ASSERT_EQ(2u, list.size());
EXPECT_EQ(15, list[0]);
EXPECT_EQ(20, list[1]);
list.clear();
overriding.SetScopedHandle(override_handle.Pass());
base::RunLoop run_loop;
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
loop->PostTask(
FROM_HERE,
base::Bind(
&DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration::
NestedTask,
base::Unretained(this),
base::Unretained(&list),
base::Unretained(&overriding)));
run_loop.Run();
source()->Dispatch(*event);
ASSERT_EQ(2u, list.size());
EXPECT_EQ(15, list[0]);
EXPECT_EQ(10, list[1]);
}
};
RUN_TEST_IN_MESSAGE_LOOP(
DestroyedNestedOverriddenDispatcherQuitsNestedLoopIteration)
class ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration
: public PlatformEventTestWithMessageLoop {
public:
void NestedTask(scoped_ptr<ScopedEventDispatcher> dispatch_handle,
std::vector<int>* list) {
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
ASSERT_EQ(2u, list->size());
EXPECT_EQ(15, (*list)[0]);
EXPECT_EQ(20, (*list)[1]);
list->clear();
dispatch_handle.reset();
source()->Dispatch(*event);
ASSERT_EQ(2u, list->size());
EXPECT_EQ(15, (*list)[0]);
EXPECT_EQ(10, (*list)[1]);
list->clear();
DestroyScopedHandleDispatcher second_overriding(70, list);
source()->RemovePlatformEventDispatcher(&second_overriding);
scoped_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(second_override_handle.Pass());
second_overriding.set_post_dispatch_action(POST_DISPATCH_QUIT_LOOP);
base::RunLoop run_loop;
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
loop->PostTask(
FROM_HERE,
base::Bind(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();
base::MessageLoopForUI::current()->QuitNow();
}
virtual void RunTestImpl() OVERRIDE {
std::vector<int> list;
TestPlatformEventDispatcher dispatcher(10, &list);
TestPlatformEventObserver observer(15, &list);
TestPlatformEventDispatcher overriding(20, &list);
source()->RemovePlatformEventDispatcher(&overriding);
scoped_ptr<ScopedEventDispatcher> override_handle =
source()->OverrideDispatcher(&overriding);
scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
source()->Dispatch(*event);
ASSERT_EQ(2u, list.size());
EXPECT_EQ(15, list[0]);
EXPECT_EQ(20, list[1]);
list.clear();
base::RunLoop run_loop;
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
loop->PostTask(
FROM_HERE,
base::Bind(
&ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration::
NestedTask,
base::Unretained(this),
base::Passed(&override_handle),
base::Unretained(&list)));
run_loop.Run();
source()->Dispatch(*event);
ASSERT_EQ(2u, list.size());
EXPECT_EQ(15, list[0]);
EXPECT_EQ(10, list[1]);
}
};
RUN_TEST_IN_MESSAGE_LOOP(
ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration)
}