| Index: trunk/src/content/browser/renderer_host/render_widget_host_unittest.cc
|
| ===================================================================
|
| --- trunk/src/content/browser/renderer_host/render_widget_host_unittest.cc (revision 263805)
|
| +++ trunk/src/content/browser/renderer_host/render_widget_host_unittest.cc (working copy)
|
| @@ -48,6 +48,7 @@
|
| using blink::WebGestureEvent;
|
| using blink::WebInputEvent;
|
| using blink::WebKeyboardEvent;
|
| +using blink::WebMouseEvent;
|
| using blink::WebMouseWheelEvent;
|
| using blink::WebTouchEvent;
|
| using blink::WebTouchPoint;
|
| @@ -199,6 +200,7 @@
|
| : RenderWidgetHostImpl(delegate, process, routing_id, false),
|
| unresponsive_timer_fired_(false) {
|
| input_router_impl_ = static_cast<InputRouterImpl*>(input_router_.get());
|
| + acked_touch_event_type_ = blink::WebInputEvent::Undefined;
|
| }
|
|
|
| // Allow poking at a few private members.
|
| @@ -261,6 +263,18 @@
|
| return touch_event_queue().empty();
|
| }
|
|
|
| + virtual void OnTouchEventAck(
|
| + const TouchEventWithLatencyInfo& event,
|
| + InputEventAckState ack_result) OVERRIDE {
|
| + // Sniff touch acks.
|
| + acked_touch_event_type_ = event.event.type;
|
| + RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
|
| + }
|
| +
|
| + WebInputEvent::Type acked_touch_event_type() const {
|
| + return acked_touch_event_type_;
|
| + }
|
| +
|
| bool ScrollStateIsContentScrolling() const {
|
| return scroll_state() == OverscrollController::STATE_CONTENT_SCROLLING;
|
| }
|
| @@ -321,6 +335,7 @@
|
|
|
| private:
|
| bool unresponsive_timer_fired_;
|
| + WebInputEvent::Type acked_touch_event_type_;
|
|
|
| // |input_router_impl_| and |mock_input_router_| are owned by
|
| // RenderWidgetHostImpl. The handles below are provided for convenience so
|
| @@ -582,7 +597,10 @@
|
| RenderWidgetHostTest()
|
| : process_(NULL),
|
| handle_key_press_event_(false),
|
| - handle_mouse_event_(false) {
|
| + handle_mouse_event_(false),
|
| + simulated_event_time_delta_seconds_(0) {
|
| + last_simulated_event_time_seconds_ =
|
| + (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
|
| }
|
| virtual ~RenderWidgetHostTest() {
|
| }
|
| @@ -645,10 +663,20 @@
|
| host_->OnMessageReceived(*response);
|
| }
|
|
|
| + double GetNextSimulatedEventTimeSeconds() {
|
| + last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
|
| + return last_simulated_event_time_seconds_;
|
| + }
|
| +
|
| 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);
|
| }
|
|
|
| @@ -679,13 +707,19 @@
|
| }
|
|
|
| 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 = GetNextSimulatedEventTimeSeconds();
|
| + host_->ForwardMouseEvent(event);
|
| + }
|
| +
|
| void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
|
| host_->ForwardWheelEvent(SyntheticWebMouseWheelEventBuilder::Build(phase));
|
| }
|
| @@ -788,6 +822,8 @@
|
| scoped_ptr<gfx::Screen> screen_;
|
| bool handle_key_press_event_;
|
| bool handle_mouse_event_;
|
| + double last_simulated_event_time_seconds_;
|
| + double simulated_event_time_delta_seconds_;
|
|
|
| private:
|
| SyntheticWebTouchEvent touch_event_;
|
| @@ -2381,6 +2417,203 @@
|
| 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) {
|
| + simulated_event_time_delta_seconds_ = 0.1;
|
| + host_->DisableGestureDebounce();
|
| + // Immediately ack all touches instead of sending them to the renderer.
|
| + host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
|
| + host_->OnMessageReceived(
|
| + ViewHostMsg_SetTouchEventEmulationEnabled(0, true, 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(WebInputEvent::TouchStart, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchStart, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + EXPECT_EQ("GesturePinchUpdate",
|
| + GetInputMessageTypes(process_));
|
| + SendInputEventACK(WebInputEvent::GesturePinchUpdate,
|
| + INPUT_EVENT_ACK_STATE_CONSUMED);
|
| + EXPECT_EQ(0U, process_->sink().message_count());
|
| +
|
| + // Turn off emulation during a pinch.
|
| + host_->OnMessageReceived(
|
| + ViewHostMsg_SetTouchEventEmulationEnabled(0, false, false));
|
| + EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
|
| + EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
|
| + GetInputMessageTypes(process_));
|
| + 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, true));
|
| + EXPECT_EQ(0U, process_->sink().message_count());
|
| +
|
| + // Another touch.
|
| + SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
|
| + EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
|
| + EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
|
| + SendInputEventACK(WebInputEvent::GestureTapDown,
|
| + INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
|
| + EXPECT_EQ(0U, process_->sink().message_count());
|
| +
|
| + // Scroll.
|
| + SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
|
| + EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
|
| + 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);
|
| +
|
| + // Turn off emulation during a scroll.
|
| + host_->OnMessageReceived(
|
| + ViewHostMsg_SetTouchEventEmulationEnabled(0, false, false));
|
| + EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
|
| +
|
| + 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(); \
|
|
|