Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(739)

Unified Diff: content/renderer/gpu/input_event_filter_unittest.cc

Issue 19220002: [WIP] BufferedInputRouter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix client assignment Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/gpu/input_event_filter.cc ('k') | content/renderer/gpu/renderer_event_packet.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/gpu/input_event_filter_unittest.cc
diff --git a/content/renderer/gpu/input_event_filter_unittest.cc b/content/renderer/gpu/input_event_filter_unittest.cc
index d8e605268b04d1803597488d5b4ca7945b9a5082..7c74adfb1881069c95ccc3072947698cbc566e29 100644
--- a/content/renderer/gpu/input_event_filter_unittest.cc
+++ b/content/renderer/gpu/input_event_filter_unittest.cc
@@ -8,6 +8,8 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
+#include "content/common/input/event_packet.h"
+#include "content/common/input/input_event.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/renderer/gpu/input_event_filter.h"
@@ -16,6 +18,7 @@
using WebKit::WebInputEvent;
using WebKit::WebMouseEvent;
+using WebKit::WebTouchEvent;
namespace content {
namespace {
@@ -107,11 +110,20 @@ void InitMouseEvent(WebMouseEvent* event, WebInputEvent::Type type,
event->y = y;
}
+void InitTouchEvent(WebTouchEvent* event, WebInputEvent::Type type,
+ int touchesLength) {
+ // Avoid valgrind false positives by initializing memory completely.
+ memset(event, 0, sizeof(*event));
+
+ new (event) WebTouchEvent();
+ event->type = type;
+ event->touchesLength = touchesLength;
+}
+
void AddMessagesToFilter(IPC::ChannelProxy::MessageFilter* message_filter,
const std::vector<IPC::Message>& events) {
- for (size_t i = 0; i < events.size(); ++i) {
+ for (size_t i = 0; i < events.size(); ++i)
message_filter->OnMessageReceived(events[i]);
- }
base::MessageLoop::current()->RunUntilIdle();
}
@@ -129,6 +141,35 @@ void AddEventsToFilter(IPC::ChannelProxy::MessageFilter* message_filter,
AddMessagesToFilter(message_filter, messages);
}
+void AddPacketToFilter(IPC::ChannelProxy::MessageFilter* message_filter,
+ const EventPacket& packet) {
+ message_filter->OnMessageReceived(
+ InputMsg_HandleEventPacket(kTestRoutingID,
+ packet,
+ InputEventDispositions()));
+ base::MessageLoop::current()->RunUntilIdle();
+}
+
+void AddMessagesToPacket(EventPacket* packet,
+ const std::vector<IPC::Message>& messages) {
+ for (size_t i = 0; i < messages.size(); ++i) {
+ const IPC::Message& message = messages[i];
+ scoped_ptr<InputEvent> event_from_message;
+ if (message.type() == InputMsg_HandleInputEvent::ID) {
+ InputMsg_HandleInputEvent::Param param;
+ ASSERT_TRUE(InputMsg_HandleInputEvent::Read(&message, &param));
+ event_from_message = InputEvent::Create(i+1,
+ WebInputEventPayload::Create(*param.a, param.b, param.c));
+ } else {
+ event_from_message = InputEvent::Create(i+1,
+ IPCInputEventPayload::Create(
+ make_scoped_ptr(new IPC::Message(message))));
+ }
+ ASSERT_TRUE(!!event_from_message);
+ packet->Add(event_from_message.Pass());
+ }
+}
+
} // namespace
class InputEventFilterTest : public testing::Test {
@@ -148,6 +189,65 @@ class InputEventFilterTest : public testing::Test {
protected:
+
+ void CheckEventPacket(const IPC::Message* packet_message,
+ const EventPacket& source_packet,
+ const InputEventDispositions& expected_dispositions) {
+ EXPECT_EQ(kTestRoutingID, packet_message->routing_id());
+
+ InputMsg_HandleEventPacket::Param param;
+ ASSERT_TRUE(InputMsg_HandleEventPacket::Read(packet_message, &param));
+ const EventPacket& packet = param.a;
+ const InputEventDispositions& dispositions = param.b;
+
+ EXPECT_EQ(source_packet.id(), packet.id());
+ ASSERT_EQ(packet.size(), dispositions.size());
+ ASSERT_EQ(source_packet.size(), packet.size());
+
+ for (size_t i = 0; i < packet.size(); ++i) {
+ const InputEvent& event = *packet.events()[i];
+ const InputEventDisposition disposition = dispositions[i];
+ EXPECT_EQ(source_packet.events()[i]->id(), event.id());
+ EXPECT_EQ(source_packet.events()[i]->payload()->GetType(),
+ event.payload()->GetType());
+ EXPECT_EQ(expected_dispositions[i], disposition) << i;
+ }
+ }
+
+ void CheckEventPacketAck(
+ const IPC::Message* packet_message,
+ const EventPacket& source_packet,
+ const InputEventDispositions& expected_dispositions) {
+ EXPECT_EQ(kTestRoutingID, packet_message->routing_id());
+
+ InputHostMsg_HandleEventPacket_ACK::Param param;
+ ASSERT_TRUE(
+ InputHostMsg_HandleEventPacket_ACK::Read(packet_message, &param));
+ const int64 packet_ack_id = param.a;
+ const InputEventDispositions& dispositions = param.b;
+
+ EXPECT_EQ(source_packet.id(), packet_ack_id);
+ EXPECT_EQ(expected_dispositions, dispositions);
+ }
+
+ void CheckEventPacket(const IPC::Message* packet_message,
+ const EventPacket& source_packet,
+ InputEventDisposition expected_disposition) {
+ CheckEventPacket(
+ packet_message,
+ source_packet,
+ InputEventDispositions(source_packet.size(), expected_disposition));
+ }
+
+ void CheckEventPacketAck(const IPC::Message* packet_message,
+ const EventPacket& source_packet,
+ InputEventDisposition expected_disposition) {
+ CheckEventPacketAck(
+ packet_message,
+ source_packet,
+ InputEventDispositions(source_packet.size(), expected_disposition));
+ }
+
base::MessageLoop message_loop_;
// Used to record IPCs sent by the filter to the RenderWidgetHost.
@@ -188,10 +288,8 @@ TEST_F(InputEventFilterTest, Basic) {
WebInputEvent::Type event_type = WebInputEvent::Undefined;
InputEventAckState ack_result = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
ui::LatencyInfo latency_info;
- EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(message,
- &event_type,
- &ack_result,
- &latency_info));
+ EXPECT_TRUE(InputHostMsg_HandleInputEvent_ACK::Read(
+ message, &event_type, &ack_result, &latency_info));
EXPECT_EQ(kEvents[i].type, event_type);
EXPECT_EQ(ack_result, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
@@ -267,9 +365,9 @@ TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
std::vector<IPC::Message> messages;
messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID,
- &mouse_down,
- ui::LatencyInfo(),
- false));
+ &mouse_down,
+ ui::LatencyInfo(),
+ false));
// Control where input events are delivered.
messages.push_back(InputMsg_MouseCaptureLost(kTestRoutingID));
messages.push_back(InputMsg_SetFocus(kTestRoutingID, true));
@@ -296,9 +394,9 @@ TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
messages.push_back(InputMsg_MoveCaret(kTestRoutingID, gfx::Point()));
messages.push_back(InputMsg_HandleInputEvent(kTestRoutingID,
- &mouse_up,
- ui::LatencyInfo(),
- false));
+ &mouse_up,
+ ui::LatencyInfo(),
+ false));
AddMessagesToFilter(filter_.get(), messages);
// We should have sent all messages back to the main thread and preserved
@@ -307,6 +405,188 @@ TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
for (size_t i = 0; i < messages.size(); ++i) {
EXPECT_EQ(message_recorder_.message_at(i).type(), messages[i].type()) << i;
}
+
+ message_recorder_.Clear();
+
+ // Now test ordering for packets.
+ EventPacket packet;
+ packet.set_id(1);
+ AddMessagesToPacket(&packet, messages);
+ AddPacketToFilter(filter_.get(), packet);
+
+ // We should have sent the packet sent back to the main thread, with message
+ // order preserved.
+ ASSERT_EQ(1U, message_recorder_.message_count());
+
+ // The first bounced WebInputEvent message will send the entire packet to
+ // the main thread; all subsequents events that are only handled on the main
+ // thread will be marked accordingly.
+ InputEventDispositions expected_dispositions(
+ messages.size(), INPUT_EVENT_IMPL_THREAD_BOUNCE_TO_MAIN);
+ // The final WebInputEvent is marked undeliverable; WebInputEvents should
+ // always be offered to the impl thread first, in order.
+ expected_dispositions.back() = INPUT_EVENT_COULD_NOT_DELIVER;
+
+ {
+ SCOPED_TRACE("EventPacketBounceToMain");
+ CheckEventPacket(&message_recorder_.message_at(0),
+ packet,
+ expected_dispositions);
+ }
+
+ message_recorder_.Clear();
+
+ // Remove the first WebInputEvent; all main-thread bound messages will be
+ // sent to main singly until a WebInputEvent is reached, which will finish
+ // the packet processing.
+ messages.erase(messages.begin());
+ event_recorder_.set_handle_events(true);
+
+ EventPacket next_packet;
+ packet.set_id(2);
+ AddMessagesToPacket(&next_packet, messages);
+ AddPacketToFilter(filter_.get(), next_packet);
+ ASSERT_EQ(messages.size() - 1, message_recorder_.message_count());
+ ASSERT_EQ(1U, ipc_sink_.message_count());
+
+ expected_dispositions =
+ InputEventDispositions(messages.size(), INPUT_EVENT_MAIN_THREAD_CONSUMED);
+ expected_dispositions.back() = INPUT_EVENT_IMPL_THREAD_CONSUMED;
+
+ {
+ SCOPED_TRACE("EventPacketImplConsumed");
+ CheckEventPacketAck(ipc_sink_.GetMessageAt(0),
+ next_packet,
+ expected_dispositions);
+ }
+}
+
+TEST_F(InputEventFilterTest, EventPacketBasic) {
+ WebMouseEvent kEvents[3];
+ InitMouseEvent(&kEvents[0], WebInputEvent::MouseDown, 10, 10);
+ InitMouseEvent(&kEvents[1], WebInputEvent::MouseMove, 20, 20);
+ InitMouseEvent(&kEvents[2], WebInputEvent::MouseUp, 30, 30);
+
+ EventPacket packet;
+ packet.set_id(13);
+ for (size_t i = 0; i < arraysize(kEvents); ++i) {
+ ASSERT_TRUE(
+ packet.Add(InputEvent::Create(i+1, WebInputEventPayload::Create(
+ kEvents[i], ui::LatencyInfo(), false))));
+ }
+
+ AddPacketToFilter(filter_.get(), packet);
+ EXPECT_EQ(0U, ipc_sink_.message_count());
+ EXPECT_EQ(0U, event_recorder_.record_count());
+ EXPECT_EQ(0U, message_recorder_.message_count());
+
+ filter_->DidAddInputHandler(kTestRoutingID, NULL);
+
+ AddPacketToFilter(filter_.get(), packet);
+ // The packet is not forwarded to the the listener.
+ ASSERT_EQ(1U, ipc_sink_.message_count());
+ ASSERT_EQ(arraysize(kEvents), event_recorder_.record_count());
+ EXPECT_EQ(0U, message_recorder_.message_count());
+
+ {
+ SCOPED_TRACE("EventPacketImplNoConsumer");
+ CheckEventPacketAck(ipc_sink_.GetMessageAt(0),
+ packet,
+ INPUT_EVENT_IMPL_THREAD_NO_CONSUMER_EXISTS);
+ }
+
+ event_recorder_.set_send_to_widget(true);
+
+ AddPacketToFilter(filter_.get(), packet);
+ // The entire packet is forwarded to the the listener; only the first event is
+ // offered to the event handler.
+ EXPECT_EQ(1U, ipc_sink_.message_count());
+ EXPECT_EQ(arraysize(kEvents) + 1, event_recorder_.record_count());
+ EXPECT_EQ(1U, message_recorder_.message_count());
+
+ InputEventDispositions expected_dispositions;
+ expected_dispositions.push_back(INPUT_EVENT_IMPL_THREAD_BOUNCE_TO_MAIN);
+ expected_dispositions.push_back(INPUT_EVENT_COULD_NOT_DELIVER);
+ expected_dispositions.push_back(INPUT_EVENT_COULD_NOT_DELIVER);
+ {
+ SCOPED_TRACE("EventPacketBounceToMain");
+ CheckEventPacket(&message_recorder_.message_at(0),
+ packet,
+ expected_dispositions);
+ }
+
+ ipc_sink_.ClearMessages();
+ event_recorder_.Clear();
+ message_recorder_.Clear();
+
+ event_recorder_.set_handle_events(true);
+
+ AddPacketToFilter(filter_.get(), packet);
+ // The packet is not forwarded to the listener; all events are offered to the
+ // event handler.
+ EXPECT_EQ(1U, ipc_sink_.message_count());
+ EXPECT_EQ(arraysize(kEvents), event_recorder_.record_count());
+ EXPECT_EQ(0U, message_recorder_.message_count());
+
+ {
+ SCOPED_TRACE("EventPacketImplConsumed");
+ CheckEventPacketAck(ipc_sink_.GetMessageAt(0),
+ packet,
+ INPUT_EVENT_IMPL_THREAD_CONSUMED);
+ }
+
+ filter_->OnFilterRemoved();
+}
+
+TEST_F(InputEventFilterTest, EventPacketWithFollowup) {
+ WebTouchEvent kTouchEvent;
+ WebMouseEvent kMouseEvents[2];
+ InitTouchEvent(&kTouchEvent, WebInputEvent::TouchStart, 1);
+ InitMouseEvent(&kMouseEvents[0], WebInputEvent::MouseDown, 10, 10);
+ InitMouseEvent(&kMouseEvents[1], WebInputEvent::MouseMove, 20, 20);
+ const WebInputEvent* kEvents[3] = {
+ &kMouseEvents[0],
+ &kTouchEvent,
+ &kMouseEvents[1]
+ };
+
+ EventPacket packet;
+ packet.set_id(7);
+ for (size_t i = 0; i < arraysize(kEvents); ++i) {
+ ASSERT_TRUE(packet.Add(InputEvent::Create(i+1,
+ WebInputEventPayload::Create(*kEvents[i], ui::LatencyInfo(), false))));
+ }
+ ASSERT_TRUE(packet.Add(
+ InputEvent::Create(arraysize(kEvents)+1,
+ IPCInputEventPayload::Create(
+ scoped_ptr<IPC::Message>(new InputMsg_Undo(kTestRoutingID))))));
+
+ event_recorder_.set_handle_events(false);
+ event_recorder_.set_send_to_widget(false);
+
+ filter_->DidAddInputHandler(kTestRoutingID, NULL);
+
+ AddPacketToFilter(filter_.get(), packet);
+
+ // The unhandled, injecting touch event prevents subsequent event handling.
+ EXPECT_EQ(1U, ipc_sink_.message_count());
+ EXPECT_EQ(arraysize(kEvents) - 1, event_recorder_.record_count());
+ EXPECT_EQ(0U, message_recorder_.message_count());
+
+ InputEventDispositions expected_dispositions;
+ expected_dispositions.push_back(INPUT_EVENT_IMPL_THREAD_NO_CONSUMER_EXISTS);
+ expected_dispositions.push_back(INPUT_EVENT_IMPL_THREAD_NO_CONSUMER_EXISTS);
+ expected_dispositions.push_back(INPUT_EVENT_COULD_NOT_DELIVER);
+ expected_dispositions.push_back(INPUT_EVENT_COULD_NOT_DELIVER);
+
+ {
+ SCOPED_TRACE("EventPacketImplWithFollowup");
+ CheckEventPacketAck(ipc_sink_.GetMessageAt(0),
+ packet,
+ expected_dispositions);
+ }
+
+ filter_->OnFilterRemoved();
}
} // namespace content
« no previous file with comments | « content/renderer/gpu/input_event_filter.cc ('k') | content/renderer/gpu/renderer_event_packet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698