| Index: content/renderer/input/input_event_filter_unittest.cc
|
| diff --git a/content/renderer/input/input_event_filter_unittest.cc b/content/renderer/input/input_event_filter_unittest.cc
|
| index bc49c00b0eaf5f9be6642af46206b0cc0fb45dd7..e52bfd4a12ab474751d9a6fbf640135002354f67 100644
|
| --- a/content/renderer/input/input_event_filter_unittest.cc
|
| +++ b/content/renderer/input/input_event_filter_unittest.cc
|
| @@ -27,6 +27,7 @@
|
| #include "ipc/ipc_test_sink.h"
|
| #include "ipc/message_filter.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| +#include "third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h"
|
| #include "ui/events/blink/web_input_event_traits.h"
|
|
|
| using blink::WebInputEvent;
|
| @@ -48,6 +49,8 @@ bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
|
| base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents));
|
| }
|
|
|
| +class MainThreadEventQueueTest;
|
| +
|
| class InputEventRecorder : public content::InputHandlerManager {
|
| public:
|
| InputEventRecorder(InputEventFilter* filter)
|
| @@ -100,10 +103,7 @@ class InputEventRecorder : public content::InputHandlerManager {
|
| }
|
| }
|
|
|
| - void NeedsMainFrame(int routing_id) override {
|
| - DCHECK_EQ(kTestRoutingID, routing_id);
|
| - needs_main_frame_ = true;
|
| - }
|
| + void NeedsMainFrame() { needs_main_frame_ = true; }
|
|
|
| private:
|
| struct Record {
|
| @@ -121,17 +121,81 @@ class InputEventRecorder : public content::InputHandlerManager {
|
| std::vector<Record> records_;
|
| };
|
|
|
| +class ReceivedEvent;
|
| +class ReceivedMessage;
|
| +
|
| +class ReceivedItem {
|
| + public:
|
| + ReceivedItem() {}
|
| + virtual ~ReceivedItem() {}
|
| +
|
| + virtual const ReceivedMessage* ItemAsmessage() const {
|
| + NOTREACHED();
|
| + return nullptr;
|
| + }
|
| +
|
| + virtual const ReceivedEvent* ItemAsEvent() const {
|
| + NOTREACHED();
|
| + return nullptr;
|
| + }
|
| +};
|
| +
|
| +class ReceivedMessage : public ReceivedItem {
|
| + public:
|
| + ReceivedMessage(const IPC::Message& message) : message_(message) {}
|
| +
|
| + ~ReceivedMessage() override {}
|
| +
|
| + const IPC::Message& message() const { return message_; }
|
| +
|
| + const ReceivedMessage* ItemAsmessage() const override { return this; }
|
| +
|
| + private:
|
| + IPC::Message message_;
|
| +};
|
| +
|
| +class ReceivedEvent : public ReceivedItem {
|
| + public:
|
| + ReceivedEvent(const blink::WebCoalescedInputEvent& event,
|
| + InputEventDispatchType dispatch_type)
|
| + : event_(event.Event(), event.GetCoalescedEventsPointers()),
|
| + dispatch_type_(dispatch_type) {}
|
| +
|
| + ~ReceivedEvent() override {}
|
| +
|
| + const ReceivedEvent* ItemAsEvent() const override { return this; }
|
| +
|
| + InputEventDispatchType dispatch_type() const { return dispatch_type_; }
|
| +
|
| + const blink::WebInputEvent& event() const { return event_.Event(); }
|
| +
|
| + private:
|
| + blink::WebCoalescedInputEvent event_;
|
| + InputEventDispatchType dispatch_type_;
|
| +};
|
| +
|
| class IPCMessageRecorder : public IPC::Listener {
|
| public:
|
| bool OnMessageReceived(const IPC::Message& message) override {
|
| - messages_.push_back(message);
|
| + std::unique_ptr<ReceivedItem> item(new ReceivedMessage(message));
|
| + messages_.push_back(std::move(item));
|
| return true;
|
| }
|
|
|
| size_t message_count() const { return messages_.size(); }
|
|
|
| - const IPC::Message& message_at(size_t i) const {
|
| - return messages_[i];
|
| + const ReceivedMessage& message_at(size_t i) const {
|
| + return *(messages_[i]->ItemAsmessage());
|
| + }
|
| +
|
| + const ReceivedEvent& event_at(size_t i) const {
|
| + return *(messages_[i]->ItemAsEvent());
|
| + }
|
| +
|
| + void AppendEvent(const blink::WebCoalescedInputEvent& event,
|
| + InputEventDispatchType dispatch_type) {
|
| + std::unique_ptr<ReceivedItem> item(new ReceivedEvent(event, dispatch_type));
|
| + messages_.push_back(std::move(item));
|
| }
|
|
|
| void Clear() {
|
| @@ -139,12 +203,13 @@ class IPCMessageRecorder : public IPC::Listener {
|
| }
|
|
|
| private:
|
| - std::vector<IPC::Message> messages_;
|
| + std::vector<std::unique_ptr<ReceivedItem>> messages_;
|
| };
|
|
|
| } // namespace
|
|
|
| -class InputEventFilterTest : public testing::Test {
|
| +class InputEventFilterTest : public testing::Test,
|
| + public MainThreadEventQueueClient {
|
| public:
|
| InputEventFilterTest()
|
| : main_task_runner_(new base::TestSimpleTaskRunner()) {}
|
| @@ -171,7 +236,7 @@ class InputEventFilterTest : public testing::Test {
|
| main_task_runner_->RunUntilIdle();
|
| frame_time_ += kFrameInterval;
|
| event_recorder_->reset_needs_main_frame();
|
| - filter_->ProcessRafAlignedInput(kTestRoutingID, frame_time_);
|
| + input_event_queue_->DispatchRafAlignedInput(frame_time_);
|
|
|
| // Run queued io thread tasks.
|
| base::RunLoop().RunUntilIdle();
|
| @@ -193,6 +258,26 @@ class InputEventFilterTest : public testing::Test {
|
| AddMessagesToFilter(messages);
|
| }
|
|
|
| + void RegisterRoute() {
|
| + input_event_queue_ =
|
| + new MainThreadEventQueue(this, main_task_runner_, &renderer_scheduler_);
|
| + filter_->RegisterRoutingID(kTestRoutingID, input_event_queue_);
|
| + }
|
| +
|
| + InputEventAckState HandleInputEvent(
|
| + const blink::WebCoalescedInputEvent& event,
|
| + const ui::LatencyInfo& latency,
|
| + InputEventDispatchType dispatch_type) override {
|
| + message_recorder_.AppendEvent(event, dispatch_type);
|
| + return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
|
| + }
|
| +
|
| + void SendInputEventAck(blink::WebInputEvent::Type type,
|
| + InputEventAckState ack_result,
|
| + uint32_t touch_event_id) override {}
|
| +
|
| + void SetNeedsMainFrame() override { event_recorder_->NeedsMainFrame(); }
|
| +
|
| protected:
|
| base::test::ScopedTaskEnvironment scoped_task_environment_;
|
| scoped_refptr<base::TestSimpleTaskRunner> main_task_runner_;
|
| @@ -205,6 +290,9 @@ class InputEventFilterTest : public testing::Test {
|
|
|
| scoped_refptr<InputEventFilter> filter_;
|
|
|
| + blink::scheduler::MockRendererScheduler renderer_scheduler_;
|
| + scoped_refptr<MainThreadEventQueue> input_event_queue_;
|
| +
|
| // Used to record WebInputEvents delivered to the handler.
|
| std::unique_ptr<InputEventRecorder> event_recorder_;
|
|
|
| @@ -224,7 +312,7 @@ TEST_F(InputEventFilterTest, Basic) {
|
| EXPECT_EQ(0U, event_recorder_->record_count());
|
| EXPECT_EQ(0U, message_recorder_.message_count());
|
|
|
| - filter_->RegisterRoutingID(kTestRoutingID);
|
| + RegisterRoute();
|
|
|
| AddEventsToFilter(kEvents, arraysize(kEvents));
|
| ASSERT_EQ(arraysize(kEvents), ipc_sink_.message_count());
|
| @@ -259,15 +347,9 @@ TEST_F(InputEventFilterTest, Basic) {
|
| EXPECT_EQ(1u, message_recorder_.message_count());
|
|
|
| {
|
| - const IPC::Message& message = message_recorder_.message_at(0);
|
| -
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebInputEvent* event = std::get<0>(params);
|
| -
|
| - EXPECT_EQ(kEvents[2].size(), event->size());
|
| - EXPECT_TRUE(memcmp(&kEvents[2], event, event->size()) == 0);
|
| + const WebInputEvent& event = message_recorder_.event_at(0).event();
|
| + EXPECT_EQ(kEvents[2].size(), event.size());
|
| + EXPECT_TRUE(memcmp(&kEvents[2], &event, event.size()) == 0);
|
| }
|
|
|
| // Now reset everything, and test that DidHandleInputEvent is called.
|
| @@ -300,7 +382,7 @@ TEST_F(InputEventFilterTest, Basic) {
|
| }
|
|
|
| TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
|
| - filter_->RegisterRoutingID(kTestRoutingID);
|
| + RegisterRoute();
|
| event_recorder_->set_send_to_widget(true);
|
|
|
| WebMouseEvent mouse_down =
|
| @@ -351,9 +433,15 @@ TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
|
| // We should have sent all messages back to the main thread and preserved
|
| // their relative order.
|
| ASSERT_EQ(message_recorder_.message_count(), messages.size());
|
| - for (size_t i = 0; i < messages.size(); ++i) {
|
| - EXPECT_EQ(message_recorder_.message_at(i).type(), messages[i].type()) << i;
|
| + EXPECT_EQ(WebMouseEvent::kMouseDown,
|
| + message_recorder_.event_at(0).event().GetType());
|
| + for (size_t i = 1; i < messages.size() - 1; ++i) {
|
| + EXPECT_EQ(message_recorder_.message_at(i).message().type(),
|
| + messages[i].type())
|
| + << i;
|
| }
|
| + EXPECT_EQ(WebMouseEvent::kMouseUp,
|
| + message_recorder_.event_at(messages.size() - 1).event().GetType());
|
| }
|
|
|
| TEST_F(InputEventFilterTest, NonBlockingWheel) {
|
| @@ -364,7 +452,7 @@ TEST_F(InputEventFilterTest, NonBlockingWheel) {
|
| SyntheticWebMouseWheelEventBuilder::Build(30, 30, 0, 53, 1, false),
|
| };
|
|
|
| - filter_->RegisterRoutingID(kTestRoutingID);
|
| + RegisterRoute();
|
| event_recorder_->set_send_to_widget(true);
|
| event_recorder_->set_passive(true);
|
|
|
| @@ -377,38 +465,32 @@ TEST_F(InputEventFilterTest, NonBlockingWheel) {
|
|
|
| // First two messages should be identical.
|
| for (size_t i = 0; i < 2; ++i) {
|
| - const IPC::Message& message = message_recorder_.message_at(i);
|
| + const ReceivedEvent& message = message_recorder_.event_at(i);
|
|
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebInputEvent* event = std::get<0>(params);
|
| - InputEventDispatchType dispatch_type = std::get<3>(params);
|
| + const WebInputEvent& event = message.event();
|
| + InputEventDispatchType dispatch_type = message.dispatch_type();
|
|
|
| - EXPECT_EQ(kEvents[i].size(), event->size());
|
| + EXPECT_EQ(kEvents[i].size(), event.size());
|
| kEvents[i].dispatch_type =
|
| WebInputEvent::DispatchType::kListenersNonBlockingPassive;
|
| - EXPECT_TRUE(memcmp(&kEvents[i], event, event->size()) == 0);
|
| + EXPECT_TRUE(memcmp(&kEvents[i], &event, event.size()) == 0);
|
| EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING,
|
| dispatch_type);
|
| }
|
|
|
| // Third message is coalesced.
|
| {
|
| - const IPC::Message& message = message_recorder_.message_at(2);
|
| + const ReceivedEvent& message = message_recorder_.event_at(2);
|
|
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebMouseWheelEvent* event =
|
| - static_cast<const WebMouseWheelEvent*>(std::get<0>(params));
|
| - InputEventDispatchType dispatch_type = std::get<3>(params);
|
| + const WebMouseWheelEvent& event =
|
| + static_cast<const WebMouseWheelEvent&>(message.event());
|
| + InputEventDispatchType dispatch_type = message.dispatch_type();
|
|
|
| kEvents[2].dispatch_type =
|
| WebInputEvent::DispatchType::kListenersNonBlockingPassive;
|
| - EXPECT_EQ(kEvents[2].size(), event->size());
|
| - EXPECT_EQ(kEvents[2].delta_x + kEvents[3].delta_x, event->delta_x);
|
| - EXPECT_EQ(kEvents[2].delta_y + kEvents[3].delta_y, event->delta_y);
|
| + EXPECT_EQ(kEvents[2].size(), event.size());
|
| + EXPECT_EQ(kEvents[2].delta_x + kEvents[3].delta_x, event.delta_x);
|
| + EXPECT_EQ(kEvents[2].delta_y + kEvents[3].delta_y, event.delta_y);
|
| EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING,
|
| dispatch_type);
|
| }
|
| @@ -425,7 +507,7 @@ TEST_F(InputEventFilterTest, NonBlockingTouch) {
|
| kEvents[3].PressPoint(10, 10);
|
| kEvents[3].MovePoint(0, 35, 35);
|
|
|
| - filter_->RegisterRoutingID(kTestRoutingID);
|
| + RegisterRoute();
|
| event_recorder_->set_send_to_widget(true);
|
| event_recorder_->set_passive(true);
|
|
|
| @@ -438,37 +520,31 @@ TEST_F(InputEventFilterTest, NonBlockingTouch) {
|
|
|
| // First two messages should be identical.
|
| for (size_t i = 0; i < 2; ++i) {
|
| - const IPC::Message& message = message_recorder_.message_at(i);
|
| + const ReceivedEvent& message = message_recorder_.event_at(i);
|
|
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebInputEvent* event = std::get<0>(params);
|
| - InputEventDispatchType dispatch_type = std::get<3>(params);
|
| + const WebInputEvent& event = message.event();
|
| + InputEventDispatchType dispatch_type = message.dispatch_type();
|
|
|
| - EXPECT_EQ(kEvents[i].size(), event->size());
|
| + EXPECT_EQ(kEvents[i].size(), event.size());
|
| kEvents[i].dispatch_type =
|
| WebInputEvent::DispatchType::kListenersNonBlockingPassive;
|
| - EXPECT_TRUE(memcmp(&kEvents[i], event, event->size()) == 0);
|
| + EXPECT_TRUE(memcmp(&kEvents[i], &event, event.size()) == 0);
|
| EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING,
|
| dispatch_type);
|
| }
|
|
|
| // Third message is coalesced.
|
| {
|
| - const IPC::Message& message = message_recorder_.message_at(2);
|
| + const ReceivedEvent& message = message_recorder_.event_at(2);
|
|
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebTouchEvent* event =
|
| - static_cast<const WebTouchEvent*>(std::get<0>(params));
|
| - InputEventDispatchType dispatch_type = std::get<3>(params);
|
| + const WebTouchEvent& event =
|
| + static_cast<const WebTouchEvent&>(message.event());
|
| + InputEventDispatchType dispatch_type = message.dispatch_type();
|
|
|
| - EXPECT_EQ(kEvents[3].size(), event->size());
|
| + EXPECT_EQ(kEvents[3].size(), event.size());
|
| EXPECT_EQ(1u, kEvents[3].touches_length);
|
| - EXPECT_EQ(kEvents[3].touches[0].position.x, event->touches[0].position.x);
|
| - EXPECT_EQ(kEvents[3].touches[0].position.y, event->touches[0].position.y);
|
| + EXPECT_EQ(kEvents[3].touches[0].position.x, event.touches[0].position.x);
|
| + EXPECT_EQ(kEvents[3].touches[0].position.y, event.touches[0].position.y);
|
| EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING,
|
| dispatch_type);
|
| }
|
| @@ -482,7 +558,7 @@ TEST_F(InputEventFilterTest, IntermingledNonBlockingTouch) {
|
| SyntheticWebTouchEvent kBlockingEvents[1];
|
| kBlockingEvents[0].PressPoint(10, 10);
|
|
|
| - filter_->RegisterRoutingID(kTestRoutingID);
|
| + RegisterRoute();
|
| event_recorder_->set_send_to_widget(true);
|
| event_recorder_->set_passive(true);
|
| AddEventsToFilter(kEvents, arraysize(kEvents));
|
| @@ -496,47 +572,38 @@ TEST_F(InputEventFilterTest, IntermingledNonBlockingTouch) {
|
| EXPECT_EQ(3u, message_recorder_.message_count());
|
|
|
| {
|
| - const IPC::Message& message = message_recorder_.message_at(0);
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebInputEvent* event = std::get<0>(params);
|
| - InputEventDispatchType dispatch_type = std::get<3>(params);
|
| -
|
| - EXPECT_EQ(kEvents[0].size(), event->size());
|
| + const ReceivedEvent& message = message_recorder_.event_at(0);
|
| + const WebInputEvent& event = message.event();
|
| + InputEventDispatchType dispatch_type = message.dispatch_type();
|
| +
|
| + EXPECT_EQ(kEvents[0].size(), event.size());
|
| kEvents[0].dispatch_type =
|
| WebInputEvent::DispatchType::kListenersNonBlockingPassive;
|
| - EXPECT_TRUE(memcmp(&kEvents[0], event, event->size()) == 0);
|
| + EXPECT_TRUE(memcmp(&kEvents[0], &event, event.size()) == 0);
|
| EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING,
|
| dispatch_type);
|
| }
|
|
|
| {
|
| - const IPC::Message& message = message_recorder_.message_at(1);
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebInputEvent* event = std::get<0>(params);
|
| - InputEventDispatchType dispatch_type = std::get<3>(params);
|
| -
|
| - EXPECT_EQ(kEvents[1].size(), event->size());
|
| + const ReceivedEvent& message = message_recorder_.event_at(1);
|
| + const WebInputEvent& event = message.event();
|
| + InputEventDispatchType dispatch_type = message.dispatch_type();
|
| +
|
| + EXPECT_EQ(kEvents[1].size(), event.size());
|
| kEvents[1].dispatch_type =
|
| WebInputEvent::DispatchType::kListenersNonBlockingPassive;
|
| - EXPECT_TRUE(memcmp(&kEvents[1], event, event->size()) == 0);
|
| + EXPECT_TRUE(memcmp(&kEvents[1], &event, event.size()) == 0);
|
| EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING,
|
| dispatch_type);
|
| }
|
|
|
| {
|
| - const IPC::Message& message = message_recorder_.message_at(2);
|
| - ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| - InputMsg_HandleInputEvent::Param params;
|
| - EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| - const WebInputEvent* event = std::get<0>(params);
|
| - InputEventDispatchType dispatch_type = std::get<3>(params);
|
| -
|
| - EXPECT_EQ(kBlockingEvents[0].size(), event->size());
|
| - EXPECT_TRUE(memcmp(&kBlockingEvents[0], event, event->size()) == 0);
|
| + const ReceivedEvent& message = message_recorder_.event_at(2);
|
| + const WebInputEvent& event = message.event();
|
| + InputEventDispatchType dispatch_type = message.dispatch_type();
|
| +
|
| + EXPECT_EQ(kBlockingEvents[0].size(), event.size());
|
| + EXPECT_TRUE(memcmp(&kBlockingEvents[0], &event, event.size()) == 0);
|
| EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_BLOCKING, dispatch_type);
|
| }
|
| }
|
|
|