Chromium Code Reviews| 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..236f552712cc712b0d563724fdbe3c1631f1d954 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 |
| + // differnt. |
| + 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 |
| + // differnt. |
|
tdresser
2016/02/08 17:51:32
different
dtapuska
2016/02/09 19:40:11
Done.
|
| + 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 |