This source file includes following definitions.
- GetInputEventFromMessage
- GetIsShortcutFromHandleInputEventMessage
- ExpectIPCMessageWithArg1
- ExpectIPCMessageWithArg2
- TouchEventsAreEquivalent
- EventListIsSubset
- SetUp
- TearDown
- SimulateKeyboardEvent
- SimulateWheelEvent
- SimulateMouseEvent
- SimulateWheelEventWithPhase
- SimulateGestureEvent
- SimulateGestureEvent
- SimulateGestureScrollUpdateEvent
- SimulateGesturePinchUpdateEvent
- SimulateGestureFlingStartEvent
- SimulateTouchEvent
- SetTouchTimestamp
- SendTouchEvent
- PressTouchPoint
- MoveTouchPoint
- ReleaseTouchPoint
- CancelTouchPoint
- SendInputEventACK
- input_router
- TouchEventQueueEmpty
- TouchEventTimeoutEnabled
- Flush
- GetAndResetDidFlushCount
- HasPendingEvents
- OnHasTouchEventHandlers
- OnSetTouchAction
- GetSentMessageCountAndResetSink
- RunTasksAndWait
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/input_router_client.h"
#include "content/browser/renderer_host/input/input_router_impl.h"
#include "content/browser/renderer_host/input/mock_input_ack_handler.h"
#include "content/browser/renderer_host/input/mock_input_router_client.h"
#include "content/common/content_constants_internal.h"
#include "content/common/edit_command.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/input/touch_action.h"
#include "content/common/input/web_input_event_traits.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/keycodes/keyboard_codes.h"
#if defined(OS_WIN) || defined(USE_AURA)
#include "content/browser/renderer_host/ui_events_helper.h"
#include "ui/events/event.h"
#endif
using base::TimeDelta;
using blink::WebGestureEvent;
using blink::WebKeyboardEvent;
using blink::WebInputEvent;
using blink::WebMouseEvent;
using blink::WebMouseWheelEvent;
using blink::WebTouchEvent;
using blink::WebTouchPoint;
namespace content {
namespace {
const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
PickleIterator iter(message);
const char* data;
int data_length;
if (!message.ReadData(&iter, &data, &data_length))
return NULL;
return reinterpret_cast<const WebInputEvent*>(data);
}
bool GetIsShortcutFromHandleInputEventMessage(const IPC::Message* msg) {
InputMsg_HandleInputEvent::Schema::Param param;
InputMsg_HandleInputEvent::Read(msg, ¶m);
return param.c;
}
template<typename MSG_T, typename ARG_T1>
void ExpectIPCMessageWithArg1(const IPC::Message* msg, const ARG_T1& arg1) {
ASSERT_EQ(MSG_T::ID, msg->type());
typename MSG_T::Schema::Param param;
ASSERT_TRUE(MSG_T::Read(msg, ¶m));
EXPECT_EQ(arg1, param.a);
}
template<typename MSG_T, typename ARG_T1, typename ARG_T2>
void ExpectIPCMessageWithArg2(const IPC::Message* msg,
const ARG_T1& arg1,
const ARG_T2& arg2) {
ASSERT_EQ(MSG_T::ID, msg->type());
typename MSG_T::Schema::Param param;
ASSERT_TRUE(MSG_T::Read(msg, ¶m));
EXPECT_EQ(arg1, param.a);
EXPECT_EQ(arg2, param.b);
}
#if defined(OS_WIN) || defined(USE_AURA)
bool TouchEventsAreEquivalent(const ui::TouchEvent& first,
const ui::TouchEvent& second) {
if (first.type() != second.type())
return false;
if (first.location() != second.location())
return false;
if (first.touch_id() != second.touch_id())
return false;
if (second.time_stamp().InSeconds() != first.time_stamp().InSeconds())
return false;
return true;
}
bool EventListIsSubset(const ScopedVector<ui::TouchEvent>& subset,
const ScopedVector<ui::TouchEvent>& set) {
if (subset.size() > set.size())
return false;
for (size_t i = 0; i < subset.size(); ++i) {
const ui::TouchEvent* first = subset[i];
const ui::TouchEvent* second = set[i];
bool equivalent = TouchEventsAreEquivalent(*first, *second);
if (!equivalent)
return false;
}
return true;
}
#endif
}
class InputRouterImplTest : public testing::Test {
public:
InputRouterImplTest() {}
virtual ~InputRouterImplTest() {}
protected:
virtual void SetUp() OVERRIDE {
browser_context_.reset(new TestBrowserContext());
process_.reset(new MockRenderProcessHost(browser_context_.get()));
client_.reset(new MockInputRouterClient());
ack_handler_.reset(new MockInputAckHandler());
CommandLine* command_line = CommandLine::ForCurrentProcess();
command_line->AppendSwitch(switches::kValidateInputEventStream);
input_router_.reset(new InputRouterImpl(
process_.get(), client_.get(), ack_handler_.get(), MSG_ROUTING_NONE));
input_router_->gesture_event_queue_.set_debounce_enabled_for_testing(
false);
client_->set_input_router(input_router());
ack_handler_->set_input_router(input_router());
}
virtual void TearDown() OVERRIDE {
base::MessageLoop::current()->RunUntilIdle();
input_router_.reset();
client_.reset();
process_.reset();
browser_context_.reset();
}
void SimulateKeyboardEvent(WebInputEvent::Type type, bool is_shortcut) {
WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
NativeWebKeyboardEvent native_event;
memcpy(&native_event, &event, sizeof(event));
input_router_->SendKeyboardEvent(
native_event,
ui::LatencyInfo(),
is_shortcut);
}
void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
ui::LatencyInfo()));
}
void SimulateMouseEvent(WebInputEvent::Type type, int x, int y) {
input_router_->SendMouseEvent(MouseEventWithLatencyInfo(
SyntheticWebMouseEventBuilder::Build(type, x, y, 0),
ui::LatencyInfo()));
}
void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
SyntheticWebMouseWheelEventBuilder::Build(phase), ui::LatencyInfo()));
}
void SimulateGestureEvent(const WebGestureEvent& gesture) {
input_router_->SendGestureEvent(
GestureEventWithLatencyInfo(gesture, ui::LatencyInfo()));
}
void SimulateGestureEvent(WebInputEvent::Type type,
WebGestureEvent::SourceDevice sourceDevice) {
SimulateGestureEvent(
SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
}
void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers) {
SimulateGestureEvent(
SyntheticWebGestureEventBuilder::BuildScrollUpdate(dX, dY, modifiers));
}
void SimulateGesturePinchUpdateEvent(float scale,
float anchorX,
float anchorY,
int modifiers) {
SimulateGestureEvent(
SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
anchorX,
anchorY,
modifiers));
}
void SimulateGestureFlingStartEvent(
float velocityX,
float velocityY,
WebGestureEvent::SourceDevice sourceDevice) {
SimulateGestureEvent(
SyntheticWebGestureEventBuilder::BuildFling(velocityX,
velocityY,
sourceDevice));
}
void SimulateTouchEvent(WebInputEvent::Type type) {
touch_event_.ResetPoints();
int index = PressTouchPoint(0, 0);
switch (type) {
case WebInputEvent::TouchStart:
break;
case WebInputEvent::TouchMove:
MoveTouchPoint(index, 5, 5);
break;
case WebInputEvent::TouchEnd:
ReleaseTouchPoint(index);
break;
case WebInputEvent::TouchCancel:
CancelTouchPoint(index);
break;
default:
FAIL() << "Invalid touch event type.";
break;
}
SendTouchEvent();
}
void SetTouchTimestamp(base::TimeDelta timestamp) {
touch_event_.SetTimestamp(timestamp);
}
void SendTouchEvent() {
input_router_->SendTouchEvent(
TouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo()));
touch_event_.ResetPoints();
}
int PressTouchPoint(int x, int y) {
return touch_event_.PressPoint(x, y);
}
void MoveTouchPoint(int index, int x, int y) {
touch_event_.MovePoint(index, x, y);
}
void ReleaseTouchPoint(int index) {
touch_event_.ReleasePoint(index);
}
void CancelTouchPoint(int index) {
touch_event_.CancelPoint(index);
}
void SendInputEventACK(blink::WebInputEvent::Type type,
InputEventAckState ack_result) {
scoped_ptr<IPC::Message> response(
new InputHostMsg_HandleInputEvent_ACK(0, type, ack_result,
ui::LatencyInfo()));
input_router_->OnMessageReceived(*response);
}
InputRouterImpl* input_router() const {
return input_router_.get();
}
bool TouchEventQueueEmpty() const {
return input_router()->touch_event_queue_.empty();
}
bool TouchEventTimeoutEnabled() const {
return input_router()->touch_event_queue_.ack_timeout_enabled();
}
void Flush() const {
return input_router_->Flush();
}
size_t GetAndResetDidFlushCount() {
return client_->GetAndResetDidFlushCount();
}
bool HasPendingEvents() const {
return input_router_->HasPendingEvents();
}
void OnHasTouchEventHandlers(bool has_handlers) {
input_router_->OnMessageReceived(
ViewHostMsg_HasTouchEventHandlers(0, has_handlers));
}
void OnSetTouchAction(content::TouchAction touch_action) {
input_router_->OnMessageReceived(
InputHostMsg_SetTouchAction(0, touch_action));
}
size_t GetSentMessageCountAndResetSink() {
size_t count = process_->sink().message_count();
process_->sink().ClearMessages();
return count;
}
static void RunTasksAndWait(base::TimeDelta delay) {
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE, base::MessageLoop::QuitClosure(), delay);
base::MessageLoop::current()->Run();
}
scoped_ptr<MockRenderProcessHost> process_;
scoped_ptr<MockInputRouterClient> client_;
scoped_ptr<MockInputAckHandler> ack_handler_;
scoped_ptr<InputRouterImpl> input_router_;
private:
base::MessageLoopForUI message_loop_;
SyntheticWebTouchEvent touch_event_;
scoped_ptr<TestBrowserContext> browser_context_;
};
TEST_F(InputRouterImplTest, CoalescesRangeSelection) {
input_router_->SendInput(scoped_ptr<IPC::Message>(
new InputMsg_SelectRange(0, gfx::Point(1, 2), gfx::Point(3, 4))));
ExpectIPCMessageWithArg2<InputMsg_SelectRange>(
process_->sink().GetMessageAt(0),
gfx::Point(1, 2),
gfx::Point(3, 4));
EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
input_router_->SendInput(scoped_ptr<IPC::Message>(
new InputMsg_SelectRange(0, gfx::Point(5, 6), gfx::Point(7, 8))));
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
input_router_->SendInput(scoped_ptr<IPC::Message>(
new InputMsg_SelectRange(0, gfx::Point(9, 10), gfx::Point(11, 12))));
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
{
scoped_ptr<IPC::Message> response(new ViewHostMsg_SelectRange_ACK(0));
input_router_->OnMessageReceived(*response);
}
ExpectIPCMessageWithArg2<InputMsg_SelectRange>(
process_->sink().GetMessageAt(0),
gfx::Point(9, 10),
gfx::Point(11, 12));
EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
{
scoped_ptr<IPC::Message> response(new ViewHostMsg_SelectRange_ACK(0));
input_router_->OnMessageReceived(*response);
}
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
}
TEST_F(InputRouterImplTest, CoalescesCaretMove) {
input_router_->SendInput(
scoped_ptr<IPC::Message>(new InputMsg_MoveCaret(0, gfx::Point(1, 2))));
ExpectIPCMessageWithArg1<InputMsg_MoveCaret>(
process_->sink().GetMessageAt(0), gfx::Point(1, 2));
EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
input_router_->SendInput(
scoped_ptr<IPC::Message>(new InputMsg_MoveCaret(0, gfx::Point(5, 6))));
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
input_router_->SendInput(
scoped_ptr<IPC::Message>(new InputMsg_MoveCaret(0, gfx::Point(9, 10))));
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
{
scoped_ptr<IPC::Message> response(new ViewHostMsg_MoveCaret_ACK(0));
input_router_->OnMessageReceived(*response);
}
ExpectIPCMessageWithArg1<InputMsg_MoveCaret>(
process_->sink().GetMessageAt(0), gfx::Point(9, 10));
EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
{
scoped_ptr<IPC::Message> response(new ViewHostMsg_MoveCaret_ACK(0));
input_router_->OnMessageReceived(*response);
}
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
}
TEST_F(InputRouterImplTest, HandledInputEvent) {
client_->set_filter_state(INPUT_EVENT_ACK_STATE_CONSUMED);
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
ASSERT_EQ(NULL, input_router_->GetLastKeyboardEvent());
}
TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
client_->set_filter_state(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
client_->set_filter_state(INPUT_EVENT_ACK_STATE_UNKNOWN);
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
}
TEST_F(InputRouterImplTest, ShortcutKeyboardEvent) {
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, true);
EXPECT_TRUE(GetIsShortcutFromHandleInputEventMessage(
process_->sink().GetMessageAt(0)));
process_->sink().ClearMessages();
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
EXPECT_FALSE(GetIsShortcutFromHandleInputEventMessage(
process_->sink().GetMessageAt(0)));
}
TEST_F(InputRouterImplTest, NoncorrespondingKeyEvents) {
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
SendInputEventACK(WebInputEvent::KeyUp,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_TRUE(ack_handler_->unexpected_event_ack_called());
}
TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) {
SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
ASSERT_TRUE(input_router_->GetLastKeyboardEvent());
EXPECT_EQ(WebInputEvent::RawKeyDown,
input_router_->GetLastKeyboardEvent()->type);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
InputMsg_HandleInputEvent::ID));
process_->sink().ClearMessages();
SendInputEventACK(WebInputEvent::RawKeyDown,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::RawKeyDown,
ack_handler_->acked_keyboard_event().type);
}
TEST_F(InputRouterImplTest, IgnoreKeyEventsWeDidntSend) {
SendInputEventACK(WebInputEvent::RawKeyDown,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
}
TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
SimulateWheelEvent(0, -5, 0, false);
SimulateWheelEvent(0, -10, 0, false);
SimulateWheelEvent(8, -6, 0, false);
SimulateWheelEvent(9, -7, 1, false);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
InputMsg_HandleInputEvent::ID));
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
InputMsg_HandleInputEvent::ID));
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
InputMsg_HandleInputEvent::ID));
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_CONSUMED);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
}
TEST_F(InputRouterImplTest,
CoalescesWheelEventsQueuedPhaseEndIsNotDropped) {
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchpad);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::GestureScrollBegin,
INPUT_EVENT_ACK_STATE_CONSUMED);
base::MessageLoop::current()->RunUntilIdle();
SimulateWheelEvent(0, -5, 0, false);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateWheelEventWithPhase(WebMouseWheelEvent::PhaseEnded);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
WebGestureEvent::Touchpad);
const WebInputEvent* input_event =
GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
const WebMouseWheelEvent* wheel_event =
static_cast<const WebMouseWheelEvent*>(input_event);
ASSERT_EQ(WebMouseWheelEvent::PhaseEnded, wheel_event->phase);
input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(1));
EXPECT_EQ(WebInputEvent::GestureScrollEnd, input_event->type);
ASSERT_EQ(2U, GetSentMessageCountAndResetSink());
}
TEST_F(InputRouterImplTest, TouchEventQueue) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_FALSE(TouchEventQueueEmpty());
MoveTouchPoint(0, 5, 5);
SendTouchEvent();
EXPECT_FALSE(client_->GetAndResetFilterEventCalled());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_FALSE(TouchEventQueueEmpty());
SendInputEventACK(WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(TouchEventQueueEmpty());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::TouchStart,
ack_handler_->acked_touch_event().event.type);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::TouchMove,
INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_TRUE(TouchEventQueueEmpty());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(WebInputEvent::TouchMove,
ack_handler_->acked_touch_event().event.type);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
}
TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
OnHasTouchEventHandlers(true);
EXPECT_TRUE(client_->has_touch_handler());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty());
EXPECT_TRUE(input_router_->ShouldForwardTouchEvent());
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_FALSE(TouchEventQueueEmpty());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
OnHasTouchEventHandlers(false);
EXPECT_FALSE(client_->has_touch_handler());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty());
EXPECT_FALSE(input_router_->ShouldForwardTouchEvent());
}
#if defined(OS_WIN) || defined(USE_AURA)
TEST_F(InputRouterImplTest, AckedTouchEventState) {
input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty());
EXPECT_TRUE(input_router_->ShouldForwardTouchEvent());
ScopedVector<ui::TouchEvent> expected_events;
base::TimeDelta timestamp = base::Time::NowFromSystemTime() - base::Time();
timestamp -= base::TimeDelta::FromSeconds(600);
PressTouchPoint(1, 1);
SetTouchTimestamp(timestamp);
SendTouchEvent();
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
gfx::Point(1, 1), 0, timestamp));
timestamp += base::TimeDelta::FromSeconds(10);
MoveTouchPoint(0, 500, 500);
SetTouchTimestamp(timestamp);
SendTouchEvent();
EXPECT_FALSE(TouchEventQueueEmpty());
expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
gfx::Point(500, 500), 0, timestamp));
timestamp += base::TimeDelta::FromSeconds(10);
PressTouchPoint(2, 2);
SetTouchTimestamp(timestamp);
SendTouchEvent();
EXPECT_FALSE(TouchEventQueueEmpty());
expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
gfx::Point(2, 2), 1, timestamp));
timestamp += base::TimeDelta::FromSeconds(10);
MoveTouchPoint(0, 10, 10);
MoveTouchPoint(1, 20, 20);
SetTouchTimestamp(timestamp);
SendTouchEvent();
EXPECT_FALSE(TouchEventQueueEmpty());
expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
gfx::Point(10, 10), 0, timestamp));
expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
gfx::Point(20, 20), 1, timestamp));
WebInputEvent::Type acks[] = { WebInputEvent::TouchStart,
WebInputEvent::TouchMove,
WebInputEvent::TouchStart,
WebInputEvent::TouchMove };
TouchEventCoordinateSystem coordinate_system = LOCAL_COORDINATES;
#if !defined(OS_WIN)
coordinate_system = SCREEN_COORDINATES;
#endif
for (size_t i = 0; i < arraysize(acks); ++i) {
SendInputEventACK(acks[i],
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(acks[i], ack_handler_->acked_touch_event().event.type);
ScopedVector<ui::TouchEvent> acked;
MakeUITouchEventsFromWebTouchEvents(
ack_handler_->acked_touch_event(), &acked, coordinate_system);
bool success = EventListIsSubset(acked, expected_events);
EXPECT_TRUE(success) << "Failed on step: " << i;
if (!success)
break;
expected_events.erase(expected_events.begin(),
expected_events.begin() + acked.size());
}
EXPECT_TRUE(TouchEventQueueEmpty());
EXPECT_EQ(0U, expected_events.size());
}
#endif
TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
SimulateWheelEvent(0, -5, 0, false);
SimulateWheelEvent(0, -10, 0, false);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
InputMsg_HandleInputEvent::ID));
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::MouseWheel,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_handler_->ack_state());
EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -5);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
InputMsg_HandleInputEvent::ID));
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -5);
}
TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
OnHasTouchEventHandlers(true);
int start_type = static_cast<int>(WebInputEvent::TouchStart);
int end_type = static_cast<int>(WebInputEvent::TouchCancel);
ASSERT_LT(start_type, end_type);
for (int i = start_type; i <= end_type; ++i) {
WebInputEvent::Type type = static_cast<WebInputEvent::Type>(i);
if (!WebInputEventTraits::IgnoresAckDisposition(type))
continue;
if (type != WebInputEvent::TouchStart) {
SimulateTouchEvent(WebInputEvent::TouchStart);
SendInputEventACK(WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_CONSUMED);
ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
ASSERT_EQ(1U, ack_handler_->GetAndResetAckCount());
ASSERT_EQ(0, client_->in_flight_event_count());
}
SimulateTouchEvent(type);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
EXPECT_FALSE(HasPendingEvents());
SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_FALSE(HasPendingEvents());
}
}
TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
const int kEventTypesLength = 29;
WebInputEvent::Type eventTypes[kEventTypesLength] = {
WebInputEvent::GestureTapDown,
WebInputEvent::GestureShowPress,
WebInputEvent::GestureTapCancel,
WebInputEvent::GestureScrollBegin,
WebInputEvent::GestureFlingStart,
WebInputEvent::GestureFlingCancel,
WebInputEvent::GestureTapDown,
WebInputEvent::GestureTap,
WebInputEvent::GestureTapDown,
WebInputEvent::GestureLongPress,
WebInputEvent::GestureTapCancel,
WebInputEvent::GestureLongTap,
WebInputEvent::GestureTapDown,
WebInputEvent::GestureTapUnconfirmed,
WebInputEvent::GestureTapCancel,
WebInputEvent::GestureTapDown,
WebInputEvent::GestureDoubleTap,
WebInputEvent::GestureTapDown,
WebInputEvent::GestureTapCancel,
WebInputEvent::GestureTwoFingerTap,
WebInputEvent::GestureTapDown,
WebInputEvent::GestureTapCancel,
WebInputEvent::GestureScrollBegin,
WebInputEvent::GestureScrollUpdate,
WebInputEvent::GestureScrollUpdateWithoutPropagation,
WebInputEvent::GesturePinchBegin,
WebInputEvent::GesturePinchUpdate,
WebInputEvent::GesturePinchEnd,
WebInputEvent::GestureScrollEnd};
for (int i = 0; i < kEventTypesLength; ++i) {
WebInputEvent::Type type = eventTypes[i];
if (!WebInputEventTraits::IgnoresAckDisposition(type)) {
SimulateGestureEvent(type, WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
EXPECT_TRUE(HasPendingEvents());
SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
EXPECT_FALSE(HasPendingEvents());
continue;
}
SimulateGestureEvent(type, WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
EXPECT_FALSE(HasPendingEvents());
SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_FALSE(HasPendingEvents());
}
}
TEST_F(InputRouterImplTest, MouseTypesIgnoringAck) {
int start_type = static_cast<int>(WebInputEvent::MouseDown);
int end_type = static_cast<int>(WebInputEvent::ContextMenu);
ASSERT_LT(start_type, end_type);
for (int i = start_type; i <= end_type; ++i) {
WebInputEvent::Type type = static_cast<WebInputEvent::Type>(i);
int expected_in_flight_event_count =
WebInputEventTraits::IgnoresAckDisposition(type) ? 0 : 1;
SimulateMouseEvent(type, 0, 0);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(expected_in_flight_event_count, client_->in_flight_event_count());
SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}
}
TEST_F(InputRouterImplTest, RequiredEventAckTypes) {
const WebInputEvent::Type kRequiredEventAckTypes[] = {
WebInputEvent::MouseMove,
WebInputEvent::MouseWheel,
WebInputEvent::RawKeyDown,
WebInputEvent::KeyDown,
WebInputEvent::KeyUp,
WebInputEvent::Char,
WebInputEvent::GestureScrollUpdate,
WebInputEvent::GestureFlingStart,
WebInputEvent::GestureFlingCancel,
WebInputEvent::GesturePinchUpdate,
WebInputEvent::TouchStart,
WebInputEvent::TouchMove
};
for (size_t i = 0; i < arraysize(kRequiredEventAckTypes); ++i) {
const WebInputEvent::Type required_ack_type = kRequiredEventAckTypes[i];
EXPECT_FALSE(WebInputEventTraits::IgnoresAckDisposition(required_ack_type));
}
}
TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchscreen);
ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchscreen);
ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::GestureTapDown,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::GestureShowPress,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::GestureTapCancel,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SendInputEventACK(WebInputEvent::GestureScrollBegin,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
SendInputEventACK(WebInputEvent::GestureTapDown,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
SendInputEventACK(WebInputEvent::GestureShowPress,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
SendInputEventACK(WebInputEvent::GestureTapCancel,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}
TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::GesturePinchBegin,
WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::GestureShowPress,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SimulateGestureEvent(WebInputEvent::GestureShowPress,
WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SendInputEventACK(WebInputEvent::GesturePinchBegin,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
SendInputEventACK(WebInputEvent::GesturePinchUpdate,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
EXPECT_EQ(3U, ack_handler_->GetAndResetAckCount());
}
TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
EXPECT_FALSE(TouchEventTimeoutEnabled());
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kTouchAckTimeoutDelayMs, "1");
TearDown();
SetUp();
ASSERT_TRUE(TouchEventTimeoutEnabled());
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
ReleaseTouchPoint(0);
SendTouchEvent();
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
ASSERT_TRUE(TouchEventTimeoutEnabled());
input_router()->OnViewUpdated(InputRouter::FIXED_PAGE_SCALE);
EXPECT_FALSE(TouchEventTimeoutEnabled());
input_router()->OnViewUpdated(InputRouter::VIEW_FLAGS_NONE);
EXPECT_TRUE(TouchEventTimeoutEnabled());
input_router()->OnViewUpdated(InputRouter::MOBILE_VIEWPORT);
EXPECT_FALSE(TouchEventTimeoutEnabled());
input_router()->OnViewUpdated(InputRouter::MOBILE_VIEWPORT |
InputRouter::FIXED_PAGE_SCALE);
EXPECT_FALSE(TouchEventTimeoutEnabled());
input_router()->OnViewUpdated(InputRouter::VIEW_FLAGS_NONE);
EXPECT_TRUE(TouchEventTimeoutEnabled());
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_PAN_Y);
EXPECT_TRUE(TouchEventTimeoutEnabled());
ReleaseTouchPoint(0);
SendTouchEvent();
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
PressTouchPoint(1, 1);
SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
EXPECT_FALSE(TouchEventTimeoutEnabled());
ReleaseTouchPoint(0);
SendTouchEvent();
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(TouchEventTimeoutEnabled());
}
TEST_F(InputRouterImplTest,
TouchAckTimeoutDisabledForTouchSequenceAfterTouchActionNone) {
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kTouchAckTimeoutDelayMs, "1");
TearDown();
SetUp();
ASSERT_TRUE(TouchEventTimeoutEnabled());
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(TouchEventTimeoutEnabled());
ReleaseTouchPoint(0);
SendTouchEvent();
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_FALSE(TouchEventTimeoutEnabled());
ack_handler_->GetAndResetAckCount();
GetSentMessageCountAndResetSink();
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(TouchEventTimeoutEnabled());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_TRUE(TouchEventTimeoutEnabled());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
ReleaseTouchPoint(0);
SendTouchEvent();
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(TouchEventTimeoutEnabled());
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
}
TEST_F(InputRouterImplTest, ResetTouchActionBeforeEventReachesRenderer) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
MoveTouchPoint(0, 5, 5);
SendTouchEvent();
ReleaseTouchPoint(0);
SendTouchEvent();
PressTouchPoint(1, 1);
SendTouchEvent();
MoveTouchPoint(0, 5, 5);
SendTouchEvent();
ReleaseTouchPoint(0);
SendTouchEvent();
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
SendInputEventACK(WebInputEvent::TouchMove, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(3U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchpad);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
WebGestureEvent::Touchpad);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchpad);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
WebGestureEvent::Touchpad);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
SendInputEventACK(WebInputEvent::TouchMove, INPUT_EVENT_ACK_STATE_CONSUMED);
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
}
TEST_F(InputRouterImplTest, OnStartNewTouchSequenceWhenTouchHandlerRemoved) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
ReleaseTouchPoint(0);
SendTouchEvent();
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchpad);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
WebGestureEvent::Touchpad);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
SendInputEventACK(WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchpad);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
WebGestureEvent::Touchpad);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
}
TEST_F(InputRouterImplTest, DoubleTapGestureDependsOnFirstTap) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
OnSetTouchAction(TOUCH_ACTION_NONE);
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
ReleaseTouchPoint(0);
SendTouchEvent();
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureTapDown,
WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureTapUnconfirmed,
WebGestureEvent::Touchscreen);
SendInputEventACK(WebInputEvent::GestureTap,
INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureTap, WebGestureEvent::Touchscreen);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
SendInputEventACK(WebInputEvent::TouchEnd, INPUT_EVENT_ACK_STATE_CONSUMED);
SendInputEventACK(WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureTapDown,
WebGestureEvent::Touchscreen);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
SimulateGestureEvent(WebInputEvent::GestureDoubleTap,
WebGestureEvent::Touchscreen);
DCHECK(!WebInputEventTraits::IgnoresAckDisposition(
WebInputEvent::GestureDoubleTap));
EXPECT_EQ(0, client_->in_flight_event_count());
}
TEST_F(InputRouterImplTest, InputFlush) {
EXPECT_FALSE(HasPendingEvents());
Flush();
EXPECT_EQ(1U, GetAndResetDidFlushCount());
EXPECT_FALSE(HasPendingEvents());
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1);
SendTouchEvent();
EXPECT_TRUE(HasPendingEvents());
Flush();
EXPECT_EQ(0U, GetAndResetDidFlushCount());
SendInputEventACK(WebInputEvent::TouchStart,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(1U, GetAndResetDidFlushCount());
MoveTouchPoint(0, 50, 50);
SendTouchEvent();
ASSERT_TRUE(HasPendingEvents());
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchscreen);
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchscreen);
Flush();
EXPECT_EQ(0U, GetAndResetDidFlushCount());
Flush();
EXPECT_EQ(0U, GetAndResetDidFlushCount());
SendInputEventACK(WebInputEvent::TouchMove,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(0U, GetAndResetDidFlushCount());
EXPECT_TRUE(HasPendingEvents());
SendInputEventACK(WebInputEvent::GestureScrollBegin,
INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, GetAndResetDidFlushCount());
EXPECT_TRUE(HasPendingEvents());
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetAndResetDidFlushCount());
EXPECT_FALSE(HasPendingEvents());
}
TEST_F(InputRouterImplTest, TrackpadPinchUpdate) {
SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
WebGestureEvent::Touchpad);
ASSERT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_handler_->ack_state());
EXPECT_EQ(0, client_->in_flight_event_count());
}
TEST_F(InputRouterImplTest, TrackpadPinchAndScrollUpdate) {
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchpad);
ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
WebGestureEvent::Touchpad);
ASSERT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchpad);
ASSERT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
WebGestureEvent::Touchpad);
ASSERT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1, client_->in_flight_event_count());
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchpad);
ASSERT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1, client_->in_flight_event_count());
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1, client_->in_flight_event_count());
SendInputEventACK(WebInputEvent::GestureScrollUpdate,
INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
}
}