[chromium] Wire up PlatformGestureCurves for CC, ScrollAnimatorNone.
[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/CCActiveGestureAnimation.h"
34 #include "cc/CCInputHandler.h"
35 #include "cc/CCSingleThreadProxy.h"
36
37 #include <gtest/gtest.h>
38 #include <wtf/OwnPtr.h>
39
40 using WebKit::WebCompositorInputHandler;
41 using WebKit::WebCompositorInputHandlerImpl;
42
43 namespace {
44
45 class MockInputHandlerClient : public WebCore::CCInputHandlerClient {
46     WTF_MAKE_NONCOPYABLE(MockInputHandlerClient);
47 public:
48     MockInputHandlerClient()
49         : m_scrollStatus(ScrollStarted)
50         , m_pinchStarted(false)
51         , m_pinchEnded(false)
52         , m_pinchMagnification(0)
53         , m_scrollByCalled(false)
54     {
55     }
56     virtual ~MockInputHandlerClient() { }
57
58     void setScrollStatus(ScrollStatus status) { m_scrollStatus = status; }
59
60     bool pinchStarted() const { return m_pinchStarted; }
61     bool pinchEnded() const { return m_pinchEnded; }
62     float pinchMaginifcation() const { return m_pinchMagnification; }
63     bool scrollByCalled() const { return m_scrollByCalled; }
64
65     void resetPinch()
66     {
67         m_pinchStarted = m_pinchEnded = m_scrollByCalled = false;
68         m_pinchMagnification = 0;
69     }
70
71     virtual WebCore::CCActiveGestureAnimation* activeGestureAnimation() { return m_activeGestureAnimation.get(); }
72     virtual void setActiveGestureAnimation(PassOwnPtr<WebCore::CCActiveGestureAnimation> animation) { m_activeGestureAnimation = animation; }
73
74 private:
75     virtual void setNeedsRedraw() OVERRIDE { }
76     virtual ScrollStatus scrollBegin(const WebCore::IntPoint&, WebCore::CCInputHandlerClient::ScrollInputType) OVERRIDE
77     {
78         return m_scrollStatus;
79     }
80     virtual void scrollBy(const WebCore::IntSize&) OVERRIDE { m_scrollByCalled = true; }
81     virtual void scrollEnd() OVERRIDE { }
82
83     virtual void pinchGestureBegin() OVERRIDE
84     {
85         m_pinchStarted = true;
86     }
87     virtual void pinchGestureUpdate(float magnifyDelta, const WebCore::IntPoint& anchor) OVERRIDE
88     {
89         m_pinchMagnification = magnifyDelta;
90     }
91     virtual void pinchGestureEnd() OVERRIDE
92     {
93         m_pinchEnded = true;
94     }
95     virtual void startPageScaleAnimation(const WebCore::IntSize& targetPosition,
96                                          bool anchorPoint,
97                                          float pageScale,
98                                          double startTimeMs,
99                                          double durationMs) OVERRIDE { }
100
101     ScrollStatus m_scrollStatus;
102     bool m_pinchStarted;
103     bool m_pinchEnded;
104     float m_pinchMagnification;
105     bool m_scrollByCalled;
106
107     OwnPtr<WebCore::CCActiveGestureAnimation> m_activeGestureAnimation;
108 };
109
110 class MockWebCompositorInputHandlerClient : public WebKit::WebCompositorInputHandlerClient {
111     WTF_MAKE_NONCOPYABLE(MockWebCompositorInputHandlerClient);
112 public:
113     MockWebCompositorInputHandlerClient()
114         : m_handled(false)
115         , m_sendToWidget(false)
116     {
117     }
118     virtual ~MockWebCompositorInputHandlerClient() { }
119
120     void reset()
121     {
122         m_handled = false;
123         m_sendToWidget = false;
124     }
125
126     bool handled() const { return m_handled; }
127     bool sendToWidget() const { return m_sendToWidget; }
128
129 private:
130     virtual void willShutdown() OVERRIDE { }
131     virtual void didHandleInputEvent() OVERRIDE
132     {
133         m_handled = true;
134     }
135     virtual void didNotHandleInputEvent(bool sendToWidget) OVERRIDE
136     {
137         m_sendToWidget = sendToWidget;
138     }
139
140     bool m_handled;
141     bool m_sendToWidget;
142 };
143
144 TEST(WebCompositorInputHandlerImpl, fromIdentifier)
145 {
146     WebKit::WebCompositor::initialize(0);
147 #ifndef NDEBUG
148     // WebCompositorInputHandler APIs can only be called from the compositor thread.
149     WebCore::DebugScopedSetImplThread alwaysImplThread;
150 #endif
151
152     // Before creating any WebCompositorInputHandlers, lookups for any value should fail and not crash.
153     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(2));
154     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(0));
155     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(-1));
156
157     int compositorIdentifier = -1;
158     {
159         OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(0);
160         compositorIdentifier = inputHandler->identifier();
161         // The compositor we just created should be locatable.
162         EXPECT_EQ(inputHandler.get(), WebCompositorInputHandler::fromIdentifier(compositorIdentifier));
163
164         // But nothing else.
165         EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(inputHandler->identifier() + 10));
166     }
167
168     // After the compositor is destroyed, its entry should be removed from the map.
169     EXPECT_EQ(0, WebCompositorInputHandler::fromIdentifier(compositorIdentifier));
170
171     WebKit::WebCompositor::shutdown();
172 }
173
174 TEST(WebCompositorInputHandlerImpl, gestureScroll)
175 {
176     WebKit::WebCompositor::initialize(0);
177 #ifndef NDEBUG
178     // WebCompositorInputHandler APIs can only be called from the compositor thread.
179     WebCore::DebugScopedSetImplThread alwaysImplThread;
180 #endif
181
182     MockInputHandlerClient mockInputHandler;
183     OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(&mockInputHandler);
184     MockWebCompositorInputHandlerClient mockClient;
185     inputHandler->setClient(&mockClient);
186
187     WebKit::WebGestureEvent gesture;
188
189     gesture.type = WebKit::WebInputEvent::GestureScrollBegin;
190     inputHandler->handleInputEvent(gesture);
191     EXPECT_TRUE(mockClient.handled());
192     EXPECT_FALSE(mockClient.sendToWidget());
193     mockClient.reset();
194
195     gesture.type = WebKit::WebInputEvent::GestureScrollUpdate;
196     gesture.deltaY = 40;
197     inputHandler->handleInputEvent(gesture);
198     EXPECT_TRUE(mockClient.handled());
199     EXPECT_FALSE(mockClient.sendToWidget());
200     mockClient.reset();
201
202     gesture.type = WebKit::WebInputEvent::GestureScrollEnd;
203     gesture.deltaY = 0;
204     inputHandler->handleInputEvent(gesture);
205     EXPECT_TRUE(mockClient.handled());
206     EXPECT_FALSE(mockClient.sendToWidget());
207     mockClient.reset();
208
209     mockInputHandler.setScrollStatus(WebCore::CCInputHandlerClient::ScrollFailed);
210
211     gesture.type = WebKit::WebInputEvent::GestureScrollBegin;
212     inputHandler->handleInputEvent(gesture);
213     EXPECT_FALSE(mockClient.handled());
214     EXPECT_TRUE(mockClient.sendToWidget());
215     mockClient.reset();
216
217     gesture.type = WebKit::WebInputEvent::GestureScrollUpdate;
218     gesture.deltaY = 40;
219     inputHandler->handleInputEvent(gesture);
220     EXPECT_FALSE(mockClient.handled());
221     EXPECT_TRUE(mockClient.sendToWidget());
222     mockClient.reset();
223
224     gesture.type = WebKit::WebInputEvent::GestureScrollEnd;
225     gesture.deltaY = 0;
226     inputHandler->handleInputEvent(gesture);
227     EXPECT_FALSE(mockClient.handled());
228     EXPECT_TRUE(mockClient.sendToWidget());
229     mockClient.reset();
230
231     inputHandler->setClient(0);
232
233     WebKit::WebCompositor::shutdown();
234 }
235
236 TEST(WebCompositorInputHandlerImpl, gesturePinch)
237 {
238     WebKit::WebCompositor::initialize(0);
239 #ifndef NDEBUG
240     // WebCompositorInputHandler APIs can only be called from the compositor thread.
241     WebCore::DebugScopedSetImplThread alwaysImplThread;
242 #endif
243
244     MockInputHandlerClient mockInputHandler;
245     OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(&mockInputHandler);
246     MockWebCompositorInputHandlerClient mockClient;
247     inputHandler->setClient(&mockClient);
248
249     WebKit::WebGestureEvent gesture;
250
251     gesture.type = WebKit::WebInputEvent::GesturePinchBegin;
252     inputHandler->handleInputEvent(gesture);
253     EXPECT_TRUE(mockClient.handled());
254     EXPECT_FALSE(mockClient.sendToWidget());
255     EXPECT_TRUE(mockInputHandler.pinchStarted());
256     mockClient.reset();
257     mockInputHandler.resetPinch();
258
259     gesture.type = WebKit::WebInputEvent::GesturePinchUpdate;
260     gesture.deltaX = 1.5;
261     inputHandler->handleInputEvent(gesture);
262     EXPECT_TRUE(mockClient.handled());
263     EXPECT_FALSE(mockClient.sendToWidget());
264     EXPECT_FALSE(mockInputHandler.pinchEnded());
265     EXPECT_EQ(1.5, mockInputHandler.pinchMaginifcation());
266     mockClient.reset();
267     mockInputHandler.resetPinch();
268
269     gesture.type = WebKit::WebInputEvent::GesturePinchUpdate;
270     gesture.deltaX = 0.5;
271     inputHandler->handleInputEvent(gesture);
272     EXPECT_TRUE(mockClient.handled());
273     EXPECT_FALSE(mockClient.sendToWidget());
274     EXPECT_FALSE(mockInputHandler.pinchEnded());
275     EXPECT_EQ(0.5, mockInputHandler.pinchMaginifcation());
276     mockClient.reset();
277     mockInputHandler.resetPinch();
278
279     gesture.type = WebKit::WebInputEvent::GesturePinchEnd;
280     inputHandler->handleInputEvent(gesture);
281     EXPECT_TRUE(mockClient.handled());
282     EXPECT_FALSE(mockClient.sendToWidget());
283     EXPECT_TRUE(mockInputHandler.pinchEnded());
284     mockClient.reset();
285     mockInputHandler.resetPinch();
286
287     inputHandler->setClient(0);
288
289     WebKit::WebCompositor::shutdown();
290 }
291
292 TEST(WebCompositorInputHandlerImpl, gestureFling)
293 {
294     WebKit::WebCompositor::initialize(0);
295
296     // WebCompositorInputHandler APIs can only be called from the compositor thread.
297     WebCore::DebugScopedSetImplThread alwaysImplThread;
298
299     MockInputHandlerClient mockInputHandler;
300     OwnPtr<WebCompositorInputHandlerImpl> inputHandler = WebCompositorInputHandlerImpl::create(&mockInputHandler);
301     MockWebCompositorInputHandlerClient mockClient;
302     inputHandler->setClient(&mockClient);
303
304     WebKit::WebGestureEvent gesture;
305
306     // Need scrollBegin before sending a scrollEnd event.
307     gesture.type = WebKit::WebInputEvent::GestureScrollBegin;
308     inputHandler->handleInputEvent(gesture);
309     EXPECT_TRUE(mockClient.handled());
310     EXPECT_FALSE(mockClient.sendToWidget());
311     mockClient.reset();
312
313     gesture.type = WebKit::WebInputEvent::GestureScrollEnd;
314     gesture.deltaX = 2;
315     inputHandler->handleInputEvent(gesture);
316     EXPECT_TRUE(mockClient.handled());
317     EXPECT_FALSE(mockClient.sendToWidget());
318     ASSERT_TRUE(mockInputHandler.activeGestureAnimation());
319     EXPECT_FALSE(mockInputHandler.scrollByCalled());
320     mockInputHandler.activeGestureAnimation()->animate(0.001);
321     EXPECT_TRUE(mockInputHandler.scrollByCalled());
322     mockClient.reset();
323
324     // Verify that a GestureTapDown during an animation cancels it.
325     gesture.type = WebKit::WebInputEvent::GestureTapDown;
326     inputHandler->handleInputEvent(gesture);
327     EXPECT_FALSE(mockInputHandler.activeGestureAnimation());
328     mockClient.reset();
329
330     // Verify that a GestureTapDown when no animation is active is not handled.
331     gesture.type = WebKit::WebInputEvent::GestureTapDown;
332     inputHandler->handleInputEvent(gesture);
333     EXPECT_FALSE(mockClient.handled());
334     EXPECT_TRUE(mockClient.sendToWidget());
335
336     inputHandler->setClient(0);
337     WebKit::WebCompositor::shutdown();
338 }
339
340 }