Index: content/browser/renderer_host/render_widget_host_unittest.cc |
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc |
index fc1bf8ef4f25469f32e0257c59e9c91cab35ec0b..0d66b0892a9ad17fbc1bc4da2480230fa0789cd9 100644 |
--- a/content/browser/renderer_host/render_widget_host_unittest.cc |
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc |
@@ -48,6 +48,7 @@ using base::TimeDelta; |
using blink::WebGestureEvent; |
using blink::WebInputEvent; |
using blink::WebKeyboardEvent; |
+using blink::WebMouseEvent; |
using blink::WebMouseWheelEvent; |
using blink::WebTouchEvent; |
using blink::WebTouchPoint; |
@@ -643,9 +644,14 @@ class RenderWidgetHostTest : public testing::Test { |
} |
void SimulateKeyboardEvent(WebInputEvent::Type type) { |
- WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type); |
- NativeWebKeyboardEvent native_event; |
- memcpy(&native_event, &event, sizeof(event)); |
+ SimulateKeyboardEvent(type, 0); |
+ } |
+ |
+ void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) { |
+ WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type); |
+ event.modifiers = modifiers; |
+ NativeWebKeyboardEvent native_event; |
+ memcpy(&native_event, &event, sizeof(event)); |
host_->ForwardKeyboardEvent(native_event); |
} |
@@ -676,11 +682,17 @@ class RenderWidgetHostTest : public testing::Test { |
} |
void SimulateMouseMove(int x, int y, int modifiers) { |
- host_->ForwardMouseEvent( |
- SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove, |
- x, |
- y, |
- modifiers)); |
+ SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false); |
+ } |
+ |
+ void SimulateMouseEvent( |
+ WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) { |
+ WebMouseEvent event = |
+ SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); |
+ if (pressed) |
+ event.button = WebMouseEvent::ButtonLeft; |
+ event.timeStampSeconds = base::Time::Now().ToDoubleT(); |
+ host_->ForwardMouseEvent(event); |
} |
void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) { |
@@ -2378,6 +2390,203 @@ TEST_F(RenderWidgetHostTest, OverscrollResetsOnBlur) { |
process_->sink().ClearMessages(); |
} |
+std::string GetInputMessageTypes(RenderWidgetHostProcess* process) { |
+ const WebInputEvent* event = NULL; |
+ ui::LatencyInfo latency_info; |
+ bool is_keyboard_shortcut; |
+ std::string result; |
+ for (size_t i = 0; i < process->sink().message_count(); ++i) { |
+ const IPC::Message *message = process->sink().GetMessageAt(i); |
+ EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type()); |
+ EXPECT_TRUE(InputMsg_HandleInputEvent::Read( |
+ message, &event, &latency_info, &is_keyboard_shortcut)); |
+ if (i != 0) |
+ result += " "; |
+ result += WebInputEventTraits::GetName(event->type); |
+ } |
+ process->sink().ClearMessages(); |
+ return result; |
+} |
+ |
+TEST_F(RenderWidgetHostTest, TouchEmulator) { |
+ host_->DisableGestureDebounce(); |
jdduke (slow)
2014/04/08 19:14:11
Nice.
|
+ host_->OnMessageReceived(ViewHostMsg_SetTouchEventEmulationEnabled(0, true)); |
+ process_->sink().ClearMessages(); |
+ view_->set_bounds(gfx::Rect(0, 0, 400, 200)); |
+ view_->Show(); |
+ |
+ SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Mouse press becomes touch start which in turn becomes tap. |
+ SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true); |
+ EXPECT_EQ("TouchStart", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::TouchStart, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureTapDown, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ |
+ // Mouse drag generates touch move, cancels tap and starts scroll. |
+ SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true); |
+ EXPECT_EQ("TouchMove", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::TouchMove, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ("GestureTapCancel GestureScrollBegin GestureScrollUpdate", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureTapCancel, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GestureScrollBegin, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Mouse drag with shift becomes pinch. |
+ SimulateMouseEvent( |
+ WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true); |
+ EXPECT_EQ("GesturePinchBegin", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GesturePinchBegin, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ SimulateMouseEvent( |
+ WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true); |
+ EXPECT_EQ("GesturePinchUpdate", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GesturePinchUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Mouse drag without shift becomes scroll again. |
+ SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true); |
+ EXPECT_EQ("GesturePinchEnd GestureScrollUpdate", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true); |
+ EXPECT_EQ("GestureScrollUpdate", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true); |
+ EXPECT_EQ("TouchEnd", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::TouchEnd, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureScrollEnd, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Mouse move does nothing. |
+ SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Another mouse down continues scroll. |
+ SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true); |
+ EXPECT_EQ("TouchStart", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::TouchStart, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureTapDown, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true); |
+ EXPECT_EQ("TouchMove", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::TouchMove, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ("GestureTapCancel GestureScrollBegin GestureScrollUpdate", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureTapCancel, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GestureScrollBegin, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Another pinch. |
+ SimulateMouseEvent( |
+ WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true); |
+ EXPECT_EQ("GesturePinchBegin", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GesturePinchBegin, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ SimulateMouseEvent( |
+ WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true); |
+ EXPECT_EQ("GesturePinchUpdate", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GesturePinchUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Turn off emulation. |
+ host_->OnMessageReceived(ViewHostMsg_SetTouchEventEmulationEnabled(0, false)); |
+ EXPECT_EQ("TouchCancel GesturePinchEnd GestureScrollEnd", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::TouchCancel, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GesturePinchEnd, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GestureScrollEnd, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Mouse event should pass untouched. |
+ SimulateMouseEvent( |
+ WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true); |
+ EXPECT_EQ("MouseMove", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::MouseMove, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Turn on emulation. |
+ host_->OnMessageReceived(ViewHostMsg_SetTouchEventEmulationEnabled(0, true)); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Another touch. |
+ SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true); |
+ EXPECT_EQ("TouchStart", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::TouchStart, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureTapDown, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Now move mouse, and disable emulation before ack. |
+ SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true); |
+ EXPECT_EQ("TouchMove", GetInputMessageTypes(process_)); |
+ host_->OnMessageReceived(ViewHostMsg_SetTouchEventEmulationEnabled(0, false)); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ SendInputEventACK(WebInputEvent::TouchMove, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ( |
+ "GestureTapCancel GestureScrollBegin GestureScrollUpdate TouchCancel", |
+ GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureTapCancel, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GestureScrollBegin, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ SendInputEventACK(WebInputEvent::TouchCancel, |
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_)); |
+ SendInputEventACK(WebInputEvent::GestureScrollEnd, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+} |
+ |
#define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \ |
TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \ |
host_->SetupForInputRouterTest(); \ |