WebCompositorInputHandlerImplTest.cpp [plain text]
#include "config.h"
#include "WebCompositorInputHandlerImpl.h"
#include "WebCompositor.h"
#include "WebCompositorInputHandlerClient.h"
#include "WebInputEvent.h"
#include "cc/CCActiveGestureAnimation.h"
#include "cc/CCInputHandler.h"
#include "cc/CCSingleThreadProxy.h"
#include "platform/WebFloatPoint.h"
#include "platform/WebPoint.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <wtf/OwnPtr.h>
using namespace WebKit;
namespace {
class MockCCInputHandlerClient : public WebCore::CCInputHandlerClient {
WTF_MAKE_NONCOPYABLE(MockCCInputHandlerClient);
public:
MockCCInputHandlerClient()
{
}
virtual ~MockCCInputHandlerClient() { }
MOCK_METHOD0(pinchGestureBegin, void());
MOCK_METHOD2(pinchGestureUpdate, void(float magnifyDelta, const WebCore::IntPoint& anchor));
MOCK_METHOD0(pinchGestureEnd, void());
MOCK_METHOD0(scheduleAnimation, void());
MOCK_METHOD2(scrollBegin, ScrollStatus(const WebCore::IntPoint&, WebCore::CCInputHandlerClient::ScrollInputType));
MOCK_METHOD1(scrollBy, void(const WebCore::IntSize&));
MOCK_METHOD0(scrollEnd, void());
private:
virtual void startPageScaleAnimation(const WebCore::IntSize& targetPosition,
bool anchorPoint,
float pageScale,
double startTimeMs,
double durationMs) OVERRIDE { }
virtual WebCore::CCActiveGestureAnimation* activeGestureAnimation() OVERRIDE { return 0; }
virtual void setActiveGestureAnimation(PassOwnPtr<WebCore::CCActiveGestureAnimation>) OVERRIDE { }
};
class MockWebCompositorInputHandlerClient : public WebCompositorInputHandlerClient {
WTF_MAKE_NONCOPYABLE(MockWebCompositorInputHandlerClient);
public:
MockWebCompositorInputHandlerClient()
: WebCompositorInputHandlerClient()
{
}
virtual ~MockWebCompositorInputHandlerClient() { }
MOCK_METHOD0(willShutdown, void());
MOCK_METHOD0(didHandleInputEvent, void());
MOCK_METHOD1(didNotHandleInputEvent, void(bool sendToWidget));
MOCK_METHOD1(transferActiveWheelFlingAnimation, void(const WebActiveWheelFlingParameters&));
};
TEST(WebCompositorInputHandlerImpl, fromIdentifier)
{
WebCompositor::initialize(0);
WebCore::DebugScopedSetImplThread alwaysImplThread;
EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(2));
EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(0));
EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(-1));
int compositorIdentifier = -1;
{
OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(0);
compositorIdentifier = inputHandler->identifier();
EXPECT_EQ(inputHandler.get(), WebCompositorInputHandler::fromIdentifier(compositorIdentifier));
EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(inputHandler->identifier() + 10));
}
EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(compositorIdentifier));
WebCompositor::shutdown();
}
class WebCompositorInputHandlerImplTest : public testing::Test {
public:
WebCompositorInputHandlerImplTest()
: m_expectedDisposition(DidHandle)
{
WebCompositor::initialize(0);
m_inputHandler = WebCompositorInputHandlerImpl::create(&m_mockCCInputHandlerClient);
m_inputHandler->setClient(&m_mockClient);
}
~WebCompositorInputHandlerImplTest()
{
m_inputHandler->setClient(0);
m_inputHandler.clear();
WebCompositor::shutdown();
}
#define VERIFY_AND_RESET_MOCKS() do \
{ \
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient); \
testing::Mock::VerifyAndClearExpectations(&m_mockClient); \
switch (m_expectedDisposition) { \
case DidHandle: \
\
EXPECT_CALL(m_mockClient, didNotHandleInputEvent(::testing::_)).Times(0); \
EXPECT_CALL(m_mockClient, didHandleInputEvent()); \
break; \
case DidNotHandle: \
\
EXPECT_CALL(m_mockClient, didHandleInputEvent()).Times(0); \
EXPECT_CALL(m_mockClient, didNotHandleInputEvent(false)).Times(0); \
EXPECT_CALL(m_mockClient, didNotHandleInputEvent(true)); \
break; \
case DropEvent: \
\
EXPECT_CALL(m_mockClient, didHandleInputEvent()).Times(0); \
EXPECT_CALL(m_mockClient, didNotHandleInputEvent(true)).Times(0); \
EXPECT_CALL(m_mockClient, didNotHandleInputEvent(false)); \
break; \
} \
} while (0)
protected:
MockCCInputHandlerClient m_mockCCInputHandlerClient;
OwnPtr<WebCompositorInputHandlerImpl> m_inputHandler;
MockWebCompositorInputHandlerClient m_mockClient;
WebGestureEvent gesture;
enum ExpectedDisposition { DidHandle, DidNotHandle, DropEvent };
ExpectedDisposition m_expectedDisposition;
private:
WebCore::DebugScopedSetImplThread m_alwaysImplThread;
};
TEST_F(WebCompositorInputHandlerImplTest, gestureScrollStarted)
{
m_expectedDisposition = DidHandle;
VERIFY_AND_RESET_MOCKS();
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
gesture.type = WebInputEvent::GestureScrollBegin;
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureScrollUpdate;
gesture.deltaY = -40; EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::Property(&WebCore::IntSize::height, testing::Gt(0))));
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureScrollEnd;
gesture.deltaY = 0;
EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd());
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gestureScrollFailed)
{
m_expectedDisposition = DidNotHandle;
VERIFY_AND_RESET_MOCKS();
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(::testing::_, ::testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollFailed));
gesture.type = WebInputEvent::GestureScrollBegin;
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureScrollUpdate;
gesture.deltaY = 40;
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureScrollEnd;
gesture.deltaY = 0;
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gestureScrollIgnored)
{
m_expectedDisposition = DropEvent;
VERIFY_AND_RESET_MOCKS();
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollIgnored));
gesture.type = WebInputEvent::GestureScrollBegin;
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gesturePinch)
{
m_expectedDisposition = DidHandle;
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GesturePinchBegin;
EXPECT_CALL(m_mockCCInputHandlerClient, pinchGestureBegin());
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GesturePinchUpdate;
gesture.deltaX = 1.5;
gesture.x = 7;
gesture.y = 13;
EXPECT_CALL(m_mockCCInputHandlerClient, pinchGestureUpdate(1.5, WebCore::IntPoint(7, 13)));
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GesturePinchUpdate;
gesture.deltaX = 0.5;
gesture.x = 9;
gesture.y = 6;
EXPECT_CALL(m_mockCCInputHandlerClient, pinchGestureUpdate(.5, WebCore::IntPoint(9, 6)));
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GesturePinchEnd;
EXPECT_CALL(m_mockCCInputHandlerClient, pinchGestureEnd());
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gestureFlingStarted)
{
m_expectedDisposition = DidHandle;
VERIFY_AND_RESET_MOCKS();
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
gesture.type = WebInputEvent::GestureFlingStart;
gesture.deltaX = 10;
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureFlingCancel;
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gestureFlingFailed)
{
m_expectedDisposition = DidNotHandle;
VERIFY_AND_RESET_MOCKS();
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollFailed));
gesture.type = WebInputEvent::GestureFlingStart;
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureFlingCancel;
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gestureFlingIgnored)
{
m_expectedDisposition = DidNotHandle;
VERIFY_AND_RESET_MOCKS();
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollIgnored));
gesture.type = WebInputEvent::GestureFlingStart;
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureFlingCancel;
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gestureFlingAnimates)
{
m_expectedDisposition = DidHandle;
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureFlingStart;
WebFloatPoint flingDelta = WebFloatPoint(1000, 0);
WebPoint flingPoint = WebPoint(7, 13);
WebPoint flingGlobalPoint = WebPoint(17, 23);
int modifiers = 7;
gesture.deltaX = flingDelta.x;
gesture.deltaY = flingDelta.y;
gesture.x = flingPoint.x;
gesture.y = flingPoint.y;
gesture.globalX = flingGlobalPoint.x;
gesture.globalY = flingGlobalPoint.y;
gesture.modifiers = modifiers;
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
m_inputHandler->handleInputEvent(gesture);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)).Times(0);
m_inputHandler->animate(10);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::Property(&WebCore::IntSize::width, testing::Lt(0))));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd());
m_inputHandler->animate(10.1);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollFailed));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::_)).Times(0);
EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd()).Times(0);
EXPECT_CALL(m_mockClient, transferActiveWheelFlingAnimation(testing::AllOf(
testing::Field(&WebActiveWheelFlingParameters::delta, testing::Eq(flingDelta)),
testing::Field(&WebActiveWheelFlingParameters::point, testing::Eq(flingPoint)),
testing::Field(&WebActiveWheelFlingParameters::globalPoint, testing::Eq(flingGlobalPoint)),
testing::Field(&WebActiveWheelFlingParameters::modifiers, testing::Eq(modifiers)),
testing::Field(&WebActiveWheelFlingParameters::startTime, testing::Eq(10)),
testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
testing::Field(&WebSize::width, testing::Gt(0))))));
m_inputHandler->animate(10.2);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
testing::Mock::VerifyAndClearExpectations(&m_mockClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation()).Times(0);
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)).Times(0);
m_inputHandler->animate(10.3);
EXPECT_CALL(m_mockClient, didNotHandleInputEvent(true));
gesture.type = WebInputEvent::GestureFlingCancel;
m_inputHandler->handleInputEvent(gesture);
}
TEST_F(WebCompositorInputHandlerImplTest, gestureFlingTransferResets)
{
m_expectedDisposition = DidHandle;
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureFlingStart;
WebFloatPoint flingDelta = WebFloatPoint(1000, 0);
WebPoint flingPoint = WebPoint(7, 13);
WebPoint flingGlobalPoint = WebPoint(17, 23);
int modifiers = 1;
gesture.deltaX = flingDelta.x;
gesture.deltaY = flingDelta.y;
gesture.x = flingPoint.x;
gesture.y = flingPoint.y;
gesture.globalX = flingGlobalPoint.x;
gesture.globalY = flingGlobalPoint.y;
gesture.modifiers = modifiers;
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
m_inputHandler->handleInputEvent(gesture);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)).Times(0);
m_inputHandler->animate(10);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::Property(&WebCore::IntSize::width, testing::Lt(0))));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd());
m_inputHandler->animate(10.1);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollFailed));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::_)).Times(0);
EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd()).Times(0);
EXPECT_CALL(m_mockClient, transferActiveWheelFlingAnimation(testing::AllOf(
testing::Field(&WebActiveWheelFlingParameters::delta, testing::Eq(flingDelta)),
testing::Field(&WebActiveWheelFlingParameters::point, testing::Eq(flingPoint)),
testing::Field(&WebActiveWheelFlingParameters::globalPoint, testing::Eq(flingGlobalPoint)),
testing::Field(&WebActiveWheelFlingParameters::modifiers, testing::Eq(modifiers)),
testing::Field(&WebActiveWheelFlingParameters::startTime, testing::Eq(10)),
testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
testing::Field(&WebSize::width, testing::Gt(0))))));
m_inputHandler->animate(10.2);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
testing::Mock::VerifyAndClearExpectations(&m_mockClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation()).Times(0);
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)).Times(0);
m_inputHandler->animate(10.3);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockClient, didNotHandleInputEvent(true));
gesture.type = WebInputEvent::GestureFlingCancel;
m_inputHandler->handleInputEvent(gesture);
VERIFY_AND_RESET_MOCKS();
gesture.type = WebInputEvent::GestureFlingStart;
flingDelta = WebFloatPoint(0, -1000);
flingPoint = WebPoint(95, 87);
flingGlobalPoint = WebPoint(32, 71);
modifiers = 2;
gesture.deltaX = flingDelta.x;
gesture.deltaY = flingDelta.y;
gesture.x = flingPoint.x;
gesture.y = flingPoint.y;
gesture.globalX = flingGlobalPoint.x;
gesture.globalY = flingGlobalPoint.y;
gesture.modifiers = modifiers;
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
m_inputHandler->handleInputEvent(gesture);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)).Times(0);
m_inputHandler->animate(30);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollStarted));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::Property(&WebCore::IntSize::height, testing::Gt(0))));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd());
m_inputHandler->animate(30.1);
testing::Mock::VerifyAndClearExpectations(&m_mockCCInputHandlerClient);
EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation());
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollFailed));
EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::_)).Times(0);
EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd()).Times(0);
EXPECT_CALL(m_mockClient, transferActiveWheelFlingAnimation(testing::AllOf(
testing::Field(&WebActiveWheelFlingParameters::delta, testing::Eq(flingDelta)),
testing::Field(&WebActiveWheelFlingParameters::point, testing::Eq(flingPoint)),
testing::Field(&WebActiveWheelFlingParameters::globalPoint, testing::Eq(flingGlobalPoint)),
testing::Field(&WebActiveWheelFlingParameters::modifiers, testing::Eq(modifiers)),
testing::Field(&WebActiveWheelFlingParameters::startTime, testing::Eq(30)),
testing::Field(&WebActiveWheelFlingParameters::cumulativeScroll,
testing::Field(&WebSize::height, testing::Lt(0))))));
m_inputHandler->animate(30.2);
}
}