| 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 1aace83da9fa246bdb5fe07697ae4666b5d1efd8..8027752a6ecafa2f72b053421e65f73711069dc3 100644
|
| --- a/content/renderer/input/input_event_filter_unittest.cc
|
| +++ b/content/renderer/input/input_event_filter_unittest.cc
|
| @@ -23,6 +23,8 @@
|
|
|
| using blink::WebInputEvent;
|
| using blink::WebMouseEvent;
|
| +using blink::WebMouseWheelEvent;
|
| +using blink::WebTouchEvent;
|
|
|
| namespace content {
|
| namespace {
|
| @@ -34,12 +36,13 @@ class InputEventRecorder {
|
| InputEventRecorder()
|
| : filter_(NULL),
|
| handle_events_(false),
|
| - send_to_widget_(false) {
|
| - }
|
| + send_to_widget_(false),
|
| + passive_(false) {}
|
|
|
| void set_filter(InputEventFilter* filter) { filter_ = filter; }
|
| void set_handle_events(bool value) { handle_events_ = value; }
|
| void set_send_to_widget(bool value) { send_to_widget_ = value; }
|
| + void set_passive(bool value) { passive_ = value; }
|
|
|
| size_t record_count() const { return records_.size(); }
|
|
|
| @@ -61,9 +64,13 @@ class InputEventRecorder {
|
|
|
| if (handle_events_) {
|
| return INPUT_EVENT_ACK_STATE_CONSUMED;
|
| + } else if (send_to_widget_) {
|
| + if (passive_)
|
| + return INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING;
|
| + else
|
| + return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
|
| } else {
|
| - return send_to_widget_ ? INPUT_EVENT_ACK_STATE_NOT_CONSUMED
|
| - : INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
|
| + return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
|
| }
|
| }
|
|
|
| @@ -79,6 +86,7 @@ class InputEventRecorder {
|
| InputEventFilter* filter_;
|
| bool handle_events_;
|
| bool send_to_widget_;
|
| + bool passive_;
|
| std::vector<Record> records_;
|
| };
|
|
|
| @@ -112,13 +120,15 @@ void AddMessagesToFilter(IPC::MessageFilter* message_filter,
|
| base::MessageLoop::current()->RunUntilIdle();
|
| }
|
|
|
| +template <typename T>
|
| void AddEventsToFilter(IPC::MessageFilter* message_filter,
|
| - const WebMouseEvent events[],
|
| + const T events[],
|
| size_t count) {
|
| std::vector<IPC::Message> messages;
|
| for (size_t i = 0; i < count; ++i) {
|
| - messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID, &events[i],
|
| - ui::LatencyInfo()));
|
| + messages.push_back(InputMsg_HandleInputEvent(
|
| + kTestRoutingID, &events[i], ui::LatencyInfo(),
|
| + InputEventDispatchType::DISPATCH_TYPE_NORMAL));
|
| }
|
|
|
| AddMessagesToFilter(message_filter, messages);
|
| @@ -254,8 +264,9 @@ TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
|
| SyntheticWebMouseEventBuilder::Build(WebMouseEvent::MouseUp);
|
|
|
| std::vector<IPC::Message> messages;
|
| - messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID, &mouse_down,
|
| - ui::LatencyInfo()));
|
| + messages.push_back(
|
| + InputMsg_HandleInputEvent(kTestRoutingID, &mouse_down, ui::LatencyInfo(),
|
| + InputEventDispatchType::DISPATCH_TYPE_NORMAL));
|
| // Control where input events are delivered.
|
| messages.push_back(InputMsg_MouseCaptureLost(kTestRoutingID));
|
| messages.push_back(InputMsg_SetFocus(kTestRoutingID, true));
|
| @@ -282,7 +293,8 @@ TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
|
| messages.push_back(InputMsg_MoveCaret(kTestRoutingID, gfx::Point()));
|
|
|
| messages.push_back(
|
| - InputMsg_HandleInputEvent(kTestRoutingID, &mouse_up, ui::LatencyInfo()));
|
| + InputMsg_HandleInputEvent(kTestRoutingID, &mouse_up, ui::LatencyInfo(),
|
| + InputEventDispatchType::DISPATCH_TYPE_NORMAL));
|
| AddMessagesToFilter(filter_.get(), messages);
|
|
|
| // We should have sent all messages back to the main thread and preserved
|
| @@ -293,4 +305,156 @@ TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
|
| }
|
| }
|
|
|
| +TEST_F(InputEventFilterTest, NonBlockingWheel) {
|
| + WebMouseWheelEvent kEvents[4] = {
|
| + SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false),
|
| + SyntheticWebMouseWheelEventBuilder::Build(20, 20, 0, 53, 0, false),
|
| + SyntheticWebMouseWheelEventBuilder::Build(30, 30, 0, 53, 1, false),
|
| + SyntheticWebMouseWheelEventBuilder::Build(30, 30, 0, 53, 1, false),
|
| + };
|
| +
|
| + filter_->DidAddInputHandler(kTestRoutingID, nullptr);
|
| + event_recorder_.set_send_to_widget(true);
|
| + event_recorder_.set_passive(true);
|
| +
|
| + AddEventsToFilter(filter_.get(), kEvents, arraysize(kEvents));
|
| + EXPECT_EQ(arraysize(kEvents), event_recorder_.record_count());
|
| + ASSERT_EQ(4u, ipc_sink_.message_count());
|
| +
|
| + // First event is sent right away.
|
| + EXPECT_EQ(1u, message_recorder_.message_count());
|
| +
|
| + // Second event was queued; ack the first.
|
| + filter_->NonBlockingInputEventHandled(kTestRoutingID,
|
| + WebInputEvent::MouseWheel);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + ASSERT_EQ(4u, ipc_sink_.message_count());
|
| + EXPECT_EQ(2u, message_recorder_.message_count());
|
| +
|
| + // Third event won't be coalesced into the second because modifiers are
|
| + // different.
|
| + filter_->NonBlockingInputEventHandled(kTestRoutingID,
|
| + WebInputEvent::MouseWheel);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(3u, message_recorder_.message_count());
|
| +
|
| + // The last events will be coalesced.
|
| + filter_->NonBlockingInputEventHandled(kTestRoutingID,
|
| + WebInputEvent::MouseWheel);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(3u, message_recorder_.message_count());
|
| +
|
| + // First two messages should be identical.
|
| + for (size_t i = 0; i < 2; ++i) {
|
| + const IPC::Message& message = message_recorder_.message_at(i);
|
| +
|
| + ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| + InputMsg_HandleInputEvent::Param params;
|
| + EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| + const WebInputEvent* event = base::get<0>(params);
|
| + InputEventDispatchType dispatch_type = base::get<2>(params);
|
| +
|
| + EXPECT_EQ(kEvents[i].size, event->size);
|
| + 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);
|
| +
|
| + 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*>(base::get<0>(params));
|
| + InputEventDispatchType dispatch_type = base::get<2>(params);
|
| +
|
| + EXPECT_EQ(kEvents[2].size, event->size);
|
| + EXPECT_EQ(kEvents[2].deltaX + kEvents[3].deltaX, event->deltaX);
|
| + EXPECT_EQ(kEvents[2].deltaY + kEvents[3].deltaY, event->deltaY);
|
| + EXPECT_EQ(InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING,
|
| + dispatch_type);
|
| + }
|
| +}
|
| +
|
| +TEST_F(InputEventFilterTest, NonBlockingTouch) {
|
| + SyntheticWebTouchEvent kEvents[4];
|
| + kEvents[0].PressPoint(10, 10);
|
| + kEvents[1].PressPoint(10, 10);
|
| + kEvents[1].modifiers = 1;
|
| + kEvents[1].MovePoint(0, 20, 20);
|
| + kEvents[2].PressPoint(10, 10);
|
| + kEvents[2].MovePoint(0, 30, 30);
|
| + kEvents[3].PressPoint(10, 10);
|
| + kEvents[3].MovePoint(0, 35, 35);
|
| +
|
| + filter_->DidAddInputHandler(kTestRoutingID, nullptr);
|
| + event_recorder_.set_send_to_widget(true);
|
| + event_recorder_.set_passive(true);
|
| +
|
| + AddEventsToFilter(filter_.get(), kEvents, arraysize(kEvents));
|
| + EXPECT_EQ(arraysize(kEvents), event_recorder_.record_count());
|
| + ASSERT_EQ(4u, ipc_sink_.message_count());
|
| +
|
| + // First event is sent right away.
|
| + EXPECT_EQ(1u, message_recorder_.message_count());
|
| +
|
| + // Second event was queued; ack the first.
|
| + filter_->NonBlockingInputEventHandled(kTestRoutingID,
|
| + WebInputEvent::TouchStart);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + ASSERT_EQ(4u, ipc_sink_.message_count());
|
| + EXPECT_EQ(2u, message_recorder_.message_count());
|
| +
|
| + // Third event won't be coalesced into the second because modifiers are
|
| + // different.
|
| + filter_->NonBlockingInputEventHandled(kTestRoutingID,
|
| + WebInputEvent::TouchMove);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(3u, message_recorder_.message_count());
|
| +
|
| + // The last events will be coalesced.
|
| + filter_->NonBlockingInputEventHandled(kTestRoutingID,
|
| + WebInputEvent::TouchMove);
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + EXPECT_EQ(3u, message_recorder_.message_count());
|
| +
|
| + // First two messages should be identical.
|
| + for (size_t i = 0; i < 2; ++i) {
|
| + const IPC::Message& message = message_recorder_.message_at(i);
|
| +
|
| + ASSERT_EQ(InputMsg_HandleInputEvent::ID, message.type());
|
| + InputMsg_HandleInputEvent::Param params;
|
| + EXPECT_TRUE(InputMsg_HandleInputEvent::Read(&message, ¶ms));
|
| + const WebInputEvent* event = base::get<0>(params);
|
| + InputEventDispatchType dispatch_type = base::get<2>(params);
|
| +
|
| + EXPECT_EQ(kEvents[i].size, event->size);
|
| + 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);
|
| +
|
| + 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*>(base::get<0>(params));
|
| + InputEventDispatchType dispatch_type = base::get<2>(params);
|
| +
|
| + EXPECT_EQ(kEvents[3].size, event->size);
|
| + EXPECT_EQ(1u, kEvents[3].touchesLength);
|
| + 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);
|
| + }
|
| +}
|
| +
|
| } // namespace content
|
|
|