Add support for pinch gesture processing in the MT compositor.
[WebKit-https.git] / Source / WebKit / chromium / tests / WebCompositorInputHandlerImplTest.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #include "WebCompositorInputHandlerImpl.h"
29
30 #include "WebCompositor.h"
31 #include "WebCompositorInputHandlerClient.h"
32 #include "WebInputEvent.h"
33 #include "cc/CCInputHandler.h"
34 #include "cc/CCSingleThreadProxy.h"
35
36 #include <gtest/gtest.h>
37 #include <wtf/OwnPtr.h>
38
39 using WebKit::WebCompositorInputHandler;
40 using WebKit::WebCompositorInputHandlerImpl;
41
42 namespace {
43
44 class MockInputHandlerClient : public WebCore::CCInputHandlerClient {
45     WTF_MAKE_NONCOPYABLE(MockInputHandlerClient);
46 public:
47     MockInputHandlerClient()
48         : m_scrollStatus(ScrollStarted)
49         , m_pinchStarted(false)
50         , m_pinchEnded(false)
51         , m_pinchMagnification(0)
52     {
53     }
54     virtual ~MockInputHandlerClient() { }
55
56     void setScrollStatus(ScrollStatus status) { m_scrollStatus = status; }
57
58     bool pinchStarted() const { return m_pinchStarted; }
59     bool pinchEnded() const { return m_pinchEnded; }
60     float pinchMaginifcation() const { return m_pinchMagnification; }
61
62     void resetPinch()
63     {
64         m_pinchStarted = m_pinchStarted = false;
65         m_pinchMagnification = 0;
66     }
67
68 private:
69     virtual void setNeedsRedraw() OVERRIDE { }
70     virtual ScrollStatus scrollBegin(const WebCore::IntPoint&) OVERRIDE
71     {
72         return m_scrollStatus;
73     }
74     virtual void scrollBy(const WebCore::IntSize&) OVERRIDE { }
75     virtual void scrollEnd() OVERRIDE { }
76
77     virtual bool haveWheelEventHandlers() OVERRIDE { return false; }
78     virtual void pinchGestureBegin() OVERRIDE
79     {
80         m_pinchStarted = true;
81     }
82     virtual void pinchGestureUpdate(float magnifyDelta, const WebCore::IntPoint& anchor) OVERRIDE
83     {
84         m_pinchMagnification = magnifyDelta;
85     }
86     virtual void pinchGestureEnd() OVERRIDE
87     {
88         m_pinchEnded = true;
89     }
90     virtual void startPageScaleAnimation(const WebCore::IntSize& targetPosition,
91                                          bool anchorPoint,
92                                          float pageScale,
93                                          double startTimeMs,
94                                          double durationMs) OVERRIDE { }
95
96     ScrollStatus m_scrollStatus;
97     bool m_pinchStarted;
98     bool m_pinchEnded;
99     float m_pinchMagnification;
100 };
101
102 class MockWebCompositorInputHandlerClient : public WebKit::WebCompositorInputHandlerClient {
103     WTF_MAKE_NONCOPYABLE(MockWebCompositorInputHandlerClient);
104 public:
105     MockWebCompositorInputHandlerClient()
106         : m_handled(false)
107         , m_sendToWidget(false)
108     {
109     }
110     virtual ~MockWebCompositorInputHandlerClient() { }
111
112     void reset()
113     {
114         m_handled = false;
115         m_sendToWidget = false;
116     }
117
118     bool handled() const { return m_handled; }
119     bool sendToWidget() const { return m_sendToWidget; }
120
121 private:
122     virtual void willShutdown() OVERRIDE { }
123     virtual void didHandleInputEvent() OVERRIDE
124     {
125         m_handled = true;
126     }
127     virtual void didNotHandleInputEvent(bool sendToWidget) OVERRIDE
128     {
129         m_sendToWidget = sendToWidget;
130     }
131
132     bool m_handled;
133     bool m_sendToWidget;
134 };
135
136 TEST(WebCompositorInputHandlerImpl, fromIdentifier)
137 {
138     WebKit::WebCompositor::initialize(0);
139 #ifndef NDEBUG
140     // WebCompositorInputHandler APIs can only be called from the compositor thread.
141     WebCore::DebugScopedSetImplThread alwaysImplThread;
142 #endif
143
144     // Before creating any WebCompositorInputHandlers, lookups for any value should fail and not crash.
145     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(2));
146     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(0));
147     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(-1));
148
149     int compositorIdentifier = -1;
150     {
151         OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(0);
152         compositorIdentifier = inputHandler->identifier();
153         // The compositor we just created should be locatable.
154         EXPECT_EQ(inputHandler.get(), WebCompositorInputHandler::fromIdentifier(compositorIdentifier));
155
156         // But nothing else.
157         EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(inputHandler->identifier() + 10));
158     }
159
160     // After the compositor is destroyed, its entry should be removed from the map.
161     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(compositorIdentifier));
162
163     WebKit::WebCompositor::shutdown();
164 }
165
166 TEST(WebCompositorInputHandlerImpl, gestureScroll)
167 {
168     WebKit::WebCompositor::initialize(0);
169 #ifndef NDEBUG
170     // WebCompositorInputHandler APIs can only be called from the compositor thread.
171     WebCore::DebugScopedSetImplThread alwaysImplThread;
172 #endif
173
174     MockInputHandlerClient mockInputHandler;
175     OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(&mockInputHandler);
176     MockWebCompositorInputHandlerClient mockClient;
177     inputHandler->setClient(&mockClient);
178
179     WebKit::WebGestureEvent gesture;
180
181     gesture.type = WebKit::WebInputEvent::GestureScrollBegin;
182     inputHandler->handleInputEvent(gesture);
183     EXPECT_TRUE(mockClient.handled());
184     EXPECT_FALSE(mockClient.sendToWidget());
185     mockClient.reset();
186
187     gesture.type = WebKit::WebInputEvent::GestureScrollUpdate;
188     gesture.deltaY = 40;
189     inputHandler->handleInputEvent(gesture);
190     EXPECT_TRUE(mockClient.handled());
191     EXPECT_FALSE(mockClient.sendToWidget());
192     mockClient.reset();
193
194     gesture.type = WebKit::WebInputEvent::GestureScrollEnd;
195     gesture.deltaY = 0;
196     inputHandler->handleInputEvent(gesture);
197     EXPECT_TRUE(mockClient.handled());
198     EXPECT_FALSE(mockClient.sendToWidget());
199     mockClient.reset();
200
201     mockInputHandler.setScrollStatus(WebCore::CCInputHandlerClient::ScrollFailed);
202
203     gesture.type = WebKit::WebInputEvent::GestureScrollBegin;
204     inputHandler->handleInputEvent(gesture);
205     EXPECT_FALSE(mockClient.handled());
206     EXPECT_TRUE(mockClient.sendToWidget());
207     mockClient.reset();
208
209     gesture.type = WebKit::WebInputEvent::GestureScrollUpdate;
210     gesture.deltaY = 40;
211     inputHandler->handleInputEvent(gesture);
212     EXPECT_FALSE(mockClient.handled());
213     EXPECT_TRUE(mockClient.sendToWidget());
214     mockClient.reset();
215
216     gesture.type = WebKit::WebInputEvent::GestureScrollEnd;
217     gesture.deltaY = 0;
218     inputHandler->handleInputEvent(gesture);
219     EXPECT_FALSE(mockClient.handled());
220     EXPECT_TRUE(mockClient.sendToWidget());
221     mockClient.reset();
222
223     inputHandler->setClient(0);
224
225     WebKit::WebCompositor::shutdown();
226 }
227
228 TEST(WebCompositorInputHandlerImpl, gesturePinch)
229 {
230     WebKit::WebCompositor::initialize(0);
231 #ifndef NDEBUG
232     // WebCompositorInputHandler APIs can only be called from the compositor thread.
233     WebCore::DebugScopedSetImplThread alwaysImplThread;
234 #endif
235
236     MockInputHandlerClient mockInputHandler;
237     OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(&mockInputHandler);
238     MockWebCompositorInputHandlerClient mockClient;
239     inputHandler->setClient(&mockClient);
240
241     WebKit::WebGestureEvent gesture;
242
243     gesture.type = WebKit::WebInputEvent::GesturePinchBegin;
244     inputHandler->handleInputEvent(gesture);
245     EXPECT_TRUE(mockClient.handled());
246     EXPECT_FALSE(mockClient.sendToWidget());
247     EXPECT_TRUE(mockInputHandler.pinchStarted());
248     mockClient.reset();
249     mockInputHandler.resetPinch();
250
251     gesture.type = WebKit::WebInputEvent::GesturePinchUpdate;
252     gesture.deltaX = 1.5;
253     inputHandler->handleInputEvent(gesture);
254     EXPECT_TRUE(mockClient.handled());
255     EXPECT_FALSE(mockClient.sendToWidget());
256     EXPECT_FALSE(mockInputHandler.pinchEnded());
257     EXPECT_EQ(1.5, mockInputHandler.pinchMaginifcation());
258     mockClient.reset();
259     mockInputHandler.resetPinch();
260
261     gesture.type = WebKit::WebInputEvent::GesturePinchUpdate;
262     gesture.deltaX = 0.5;
263     inputHandler->handleInputEvent(gesture);
264     EXPECT_TRUE(mockClient.handled());
265     EXPECT_FALSE(mockClient.sendToWidget());
266     EXPECT_FALSE(mockInputHandler.pinchEnded());
267     EXPECT_EQ(0.5, mockInputHandler.pinchMaginifcation());
268     mockClient.reset();
269     mockInputHandler.resetPinch();
270
271     gesture.type = WebKit::WebInputEvent::GesturePinchEnd;
272     inputHandler->handleInputEvent(gesture);
273     EXPECT_TRUE(mockClient.handled());
274     EXPECT_FALSE(mockClient.sendToWidget());
275     EXPECT_TRUE(mockInputHandler.pinchEnded());
276     mockClient.reset();
277     mockInputHandler.resetPinch();
278
279     inputHandler->setClient(0);
280
281     WebKit::WebCompositor::shutdown();
282 }
283
284 }