Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/input/event_with_latency_info.h" | 5 #include "content/common/input/event_with_latency_info.h" |
| 6 | 6 |
| 7 #include <limits> | |
| 8 | |
| 7 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 8 #include "third_party/WebKit/public/web/WebInputEvent.h" | 10 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 9 | 11 |
| 10 using blink::WebGestureEvent; | 12 using blink::WebGestureEvent; |
| 11 using blink::WebInputEvent; | 13 using blink::WebInputEvent; |
| 12 using blink::WebMouseEvent; | 14 using blink::WebMouseEvent; |
| 13 using blink::WebMouseWheelEvent; | 15 using blink::WebMouseWheelEvent; |
| 14 using blink::WebTouchEvent; | 16 using blink::WebTouchEvent; |
| 17 using blink::WebTouchPoint; | |
| 18 using std::numeric_limits; | |
| 15 | 19 |
| 16 namespace content { | 20 namespace content { |
| 17 namespace { | 21 namespace { |
| 18 | 22 |
| 19 class EventWithLatencyInfoTest : public testing::Test { | 23 using EventWithLatencyInfoTest = testing::Test; |
| 20 protected: | |
| 21 TouchEventWithLatencyInfo CreateTouchEvent(WebInputEvent::Type type, | |
| 22 double timestamp) { | |
| 23 TouchEventWithLatencyInfo touch; | |
| 24 touch.event.touchesLength = 1; | |
| 25 touch.event.type = type; | |
| 26 touch.event.timeStampSeconds = timestamp; | |
| 27 return touch; | |
| 28 } | |
| 29 | 24 |
| 30 MouseEventWithLatencyInfo CreateMouseEvent(WebInputEvent::Type type, | 25 TouchEventWithLatencyInfo CreateTouchEvent(WebInputEvent::Type type, |
| 31 double timestamp) { | 26 double timestamp, |
| 32 MouseEventWithLatencyInfo mouse; | 27 unsigned touch_count = 1) { |
| 33 mouse.event.type = type; | 28 TouchEventWithLatencyInfo touch; |
| 34 mouse.event.timeStampSeconds = timestamp; | 29 touch.event.touchesLength = touch_count; |
| 35 return mouse; | 30 touch.event.type = type; |
| 36 } | 31 touch.event.timeStampSeconds = timestamp; |
| 32 return touch; | |
| 33 } | |
| 37 | 34 |
| 38 MouseWheelEventWithLatencyInfo CreateMouseWheelEvent(double timestamp) { | 35 MouseEventWithLatencyInfo CreateMouseEvent(WebInputEvent::Type type, |
| 39 MouseWheelEventWithLatencyInfo mouse_wheel; | 36 double timestamp) { |
| 40 mouse_wheel.event.type = WebInputEvent::MouseWheel; | 37 MouseEventWithLatencyInfo mouse; |
| 41 mouse_wheel.event.timeStampSeconds = timestamp; | 38 mouse.event.type = type; |
| 42 return mouse_wheel; | 39 mouse.event.timeStampSeconds = timestamp; |
| 43 } | 40 return mouse; |
| 41 } | |
| 44 | 42 |
| 45 GestureEventWithLatencyInfo CreateGestureEvent(WebInputEvent::Type type, | 43 MouseWheelEventWithLatencyInfo CreateMouseWheelEvent(double timestamp, |
| 46 double timestamp) { | 44 float deltaX = 0.0f, |
| 47 GestureEventWithLatencyInfo gesture; | 45 float deltaY = 0.0f) { |
| 48 gesture.event.type = type; | 46 MouseWheelEventWithLatencyInfo mouse_wheel; |
| 49 gesture.event.timeStampSeconds = timestamp; | 47 mouse_wheel.event.type = WebInputEvent::MouseWheel; |
| 50 return gesture; | 48 mouse_wheel.event.deltaX = deltaX; |
| 51 } | 49 mouse_wheel.event.deltaY = deltaY; |
| 52 }; | 50 mouse_wheel.event.timeStampSeconds = timestamp; |
| 51 return mouse_wheel; | |
| 52 } | |
| 53 | |
| 54 GestureEventWithLatencyInfo CreateGestureEvent(WebInputEvent::Type type, | |
| 55 double timestamp, | |
| 56 float x = 0.0f, | |
| 57 float y = 0.0f) { | |
| 58 GestureEventWithLatencyInfo gesture; | |
| 59 gesture.event.type = type; | |
| 60 gesture.event.x = x; | |
| 61 gesture.event.y = y; | |
| 62 gesture.event.timeStampSeconds = timestamp; | |
| 63 return gesture; | |
| 64 } | |
| 53 | 65 |
| 54 TEST_F(EventWithLatencyInfoTest, TimestampCoalescingForMouseEvent) { | 66 TEST_F(EventWithLatencyInfoTest, TimestampCoalescingForMouseEvent) { |
| 55 MouseEventWithLatencyInfo mouse_0 = CreateMouseEvent( | 67 MouseEventWithLatencyInfo mouse_0 = CreateMouseEvent( |
| 56 WebInputEvent::MouseMove, 5.0); | 68 WebInputEvent::MouseMove, 5.0); |
| 57 MouseEventWithLatencyInfo mouse_1 = CreateMouseEvent( | 69 MouseEventWithLatencyInfo mouse_1 = CreateMouseEvent( |
| 58 WebInputEvent::MouseMove, 10.0); | 70 WebInputEvent::MouseMove, 10.0); |
| 59 | 71 |
| 60 ASSERT_TRUE(mouse_0.CanCoalesceWith(mouse_1)); | 72 ASSERT_TRUE(mouse_0.CanCoalesceWith(mouse_1)); |
| 61 mouse_0.CoalesceWith(mouse_1); | 73 mouse_0.CoalesceWith(mouse_1); |
| 62 // Coalescing WebMouseEvent preserves newer timestamp. | 74 // Coalescing WebMouseEvent preserves newer timestamp. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 EXPECT_FALSE(mouse_1.latency.FindLatency( | 123 EXPECT_FALSE(mouse_1.latency.FindLatency( |
| 112 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component)); | 124 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component)); |
| 113 | 125 |
| 114 mouse_0.CoalesceWith(mouse_1); | 126 mouse_0.CoalesceWith(mouse_1); |
| 115 | 127 |
| 116 // Coalescing WebMouseEvent preservers older LatencyInfo. | 128 // Coalescing WebMouseEvent preservers older LatencyInfo. |
| 117 EXPECT_TRUE(mouse_1.latency.FindLatency( | 129 EXPECT_TRUE(mouse_1.latency.FindLatency( |
| 118 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component)); | 130 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component)); |
| 119 } | 131 } |
| 120 | 132 |
| 133 WebTouchPoint CreateTouchPoint(WebTouchPoint::State state, int id) { | |
| 134 WebTouchPoint touch; | |
| 135 touch.state = state; | |
| 136 touch.id = id; | |
| 137 return touch; | |
| 138 } | |
| 139 | |
| 140 TouchEventWithLatencyInfo CreateTouch(WebInputEvent::Type type, | |
| 141 unsigned touch_count = 1) { | |
| 142 return CreateTouchEvent(type, 0.0, touch_count); | |
| 143 } | |
| 144 | |
| 145 GestureEventWithLatencyInfo CreateGesture(WebInputEvent::Type type, | |
| 146 float x, | |
| 147 float y) { | |
| 148 return CreateGestureEvent(type, 0.0, x, y); | |
| 149 } | |
| 150 | |
| 151 MouseWheelEventWithLatencyInfo CreateMouseWheel(float deltaX, float deltaY) { | |
| 152 return CreateMouseWheelEvent(0.0, deltaX, deltaY); | |
| 153 } | |
| 154 | |
| 155 template <class T> | |
| 156 bool CanCoalesce(const T& event_to_coalesce, const T& event) { | |
| 157 return event.CanCoalesceWith(event_to_coalesce); | |
| 158 } | |
| 159 | |
| 160 template <class T> | |
| 161 void Coalesce(const T& event_to_coalesce, T* event) { | |
| 162 return event->CoalesceWith(event_to_coalesce); | |
| 163 } | |
| 164 | |
|
tapted
2016/07/01 07:39:40
Everything below here is a verbatim move except wi
tdresser
2016/07/01 12:52:42
If anything, I'd be a fan of getting rid of the Ca
| |
| 165 TEST_F(EventWithLatencyInfoTest, TouchEventCoalescing) { | |
| 166 TouchEventWithLatencyInfo touch0 = CreateTouch(WebInputEvent::TouchStart); | |
| 167 TouchEventWithLatencyInfo touch1 = CreateTouch(WebInputEvent::TouchMove); | |
| 168 | |
| 169 // Non touch-moves won't coalesce. | |
| 170 EXPECT_FALSE(CanCoalesce(touch0, touch0)); | |
| 171 | |
| 172 // Touches of different types won't coalesce. | |
| 173 EXPECT_FALSE(CanCoalesce(touch0, touch1)); | |
| 174 | |
| 175 // Touch moves with idential touch lengths and touch ids should coalesce. | |
| 176 EXPECT_TRUE(CanCoalesce(touch1, touch1)); | |
| 177 | |
| 178 // Touch moves with different touch ids should not coalesce. | |
| 179 touch0 = CreateTouch(WebInputEvent::TouchMove); | |
| 180 touch1 = CreateTouch(WebInputEvent::TouchMove); | |
| 181 touch0.event.touches[0].id = 7; | |
| 182 EXPECT_FALSE(CanCoalesce(touch0, touch1)); | |
| 183 touch0 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 184 touch1 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 185 touch0.event.touches[0].id = 1; | |
| 186 touch1.event.touches[0].id = 0; | |
| 187 EXPECT_FALSE(CanCoalesce(touch0, touch1)); | |
| 188 | |
| 189 // Touch moves with different touch lengths should not coalesce. | |
| 190 touch0 = CreateTouch(WebInputEvent::TouchMove, 1); | |
| 191 touch1 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 192 EXPECT_FALSE(CanCoalesce(touch0, touch1)); | |
| 193 | |
| 194 // Touch moves with identical touch ids in different orders should coalesce. | |
| 195 touch0 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 196 touch1 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 197 touch0.event.touches[0] = touch1.event.touches[1] = | |
| 198 CreateTouchPoint(WebTouchPoint::StateMoved, 1); | |
| 199 touch0.event.touches[1] = touch1.event.touches[0] = | |
| 200 CreateTouchPoint(WebTouchPoint::StateMoved, 0); | |
| 201 EXPECT_TRUE(CanCoalesce(touch0, touch1)); | |
| 202 | |
| 203 // Pointers with the same ID's should coalesce. | |
| 204 touch0 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 205 touch1 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 206 touch0.event.touches[0] = touch1.event.touches[1] = | |
| 207 CreateTouchPoint(WebTouchPoint::StateMoved, 1); | |
| 208 Coalesce(touch0, &touch1); | |
| 209 ASSERT_EQ(1, touch1.event.touches[0].id); | |
| 210 ASSERT_EQ(0, touch1.event.touches[1].id); | |
| 211 EXPECT_EQ(WebTouchPoint::StateUndefined, touch1.event.touches[1].state); | |
| 212 EXPECT_EQ(WebTouchPoint::StateMoved, touch1.event.touches[0].state); | |
| 213 | |
| 214 // Movement from now-stationary pointers should be preserved. | |
| 215 touch0 = touch1 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 216 touch0.event.touches[0] = CreateTouchPoint(WebTouchPoint::StateMoved, 1); | |
| 217 touch1.event.touches[1] = CreateTouchPoint(WebTouchPoint::StateStationary, 1); | |
| 218 touch0.event.touches[1] = CreateTouchPoint(WebTouchPoint::StateStationary, 0); | |
| 219 touch1.event.touches[0] = CreateTouchPoint(WebTouchPoint::StateMoved, 0); | |
| 220 Coalesce(touch0, &touch1); | |
| 221 ASSERT_EQ(1, touch1.event.touches[0].id); | |
| 222 ASSERT_EQ(0, touch1.event.touches[1].id); | |
| 223 EXPECT_EQ(WebTouchPoint::StateMoved, touch1.event.touches[0].state); | |
| 224 EXPECT_EQ(WebTouchPoint::StateMoved, touch1.event.touches[1].state); | |
| 225 | |
| 226 // Touch moves with different dispatchTypes coalesce. | |
| 227 touch0 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 228 touch0.event.dispatchType = WebInputEvent::DispatchType::Blocking; | |
| 229 touch1 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 230 touch1.event.dispatchType = WebInputEvent::DispatchType::EventNonBlocking; | |
| 231 touch0.event.touches[0] = touch1.event.touches[1] = | |
| 232 CreateTouchPoint(WebTouchPoint::StateMoved, 1); | |
| 233 touch0.event.touches[1] = touch1.event.touches[0] = | |
| 234 CreateTouchPoint(WebTouchPoint::StateMoved, 0); | |
| 235 EXPECT_TRUE(CanCoalesce(touch0, touch1)); | |
| 236 Coalesce(touch0, &touch1); | |
| 237 ASSERT_EQ(WebInputEvent::DispatchType::Blocking, touch1.event.dispatchType); | |
| 238 | |
| 239 touch0 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 240 touch0.event.dispatchType = | |
| 241 WebInputEvent::DispatchType::ListenersForcedNonBlockingPassive; | |
| 242 touch1 = CreateTouch(WebInputEvent::TouchMove, 2); | |
| 243 touch1.event.dispatchType = | |
| 244 WebInputEvent::DispatchType::ListenersNonBlockingPassive; | |
| 245 touch0.event.touches[0] = touch1.event.touches[1] = | |
| 246 CreateTouchPoint(WebTouchPoint::StateMoved, 1); | |
| 247 touch0.event.touches[1] = touch1.event.touches[0] = | |
| 248 CreateTouchPoint(WebTouchPoint::StateMoved, 0); | |
| 249 EXPECT_TRUE(CanCoalesce(touch0, touch1)); | |
| 250 Coalesce(touch0, &touch1); | |
| 251 ASSERT_EQ(WebInputEvent::DispatchType::ListenersNonBlockingPassive, | |
| 252 touch1.event.dispatchType); | |
| 253 } | |
| 254 | |
| 255 TEST_F(EventWithLatencyInfoTest, PinchEventCoalescing) { | |
| 256 GestureEventWithLatencyInfo pinch0 = | |
| 257 CreateGesture(WebInputEvent::GesturePinchBegin, 1, 1); | |
| 258 GestureEventWithLatencyInfo pinch1 = | |
| 259 CreateGesture(WebInputEvent::GesturePinchUpdate, 2, 2); | |
| 260 | |
| 261 // Only GesturePinchUpdate's coalesce. | |
| 262 EXPECT_FALSE(CanCoalesce(pinch0, pinch0)); | |
| 263 | |
| 264 // Pinch gestures of different types should not coalesce. | |
| 265 EXPECT_FALSE(CanCoalesce(pinch0, pinch1)); | |
| 266 | |
| 267 // Pinches with different focal points should not coalesce. | |
| 268 pinch0 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1); | |
| 269 pinch1 = CreateGesture(WebInputEvent::GesturePinchUpdate, 2, 2); | |
| 270 EXPECT_FALSE(CanCoalesce(pinch0, pinch1)); | |
| 271 EXPECT_TRUE(CanCoalesce(pinch0, pinch0)); | |
| 272 | |
| 273 // Coalesced scales are multiplicative. | |
| 274 pinch0 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1); | |
| 275 pinch0.event.data.pinchUpdate.scale = 2.f; | |
| 276 pinch1 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1); | |
| 277 pinch1.event.data.pinchUpdate.scale = 3.f; | |
| 278 EXPECT_TRUE(CanCoalesce(pinch0, pinch0)); | |
| 279 Coalesce(pinch0, &pinch1); | |
| 280 EXPECT_EQ(2.f * 3.f, pinch1.event.data.pinchUpdate.scale); | |
| 281 | |
| 282 // Scales have a minimum value and can never reach 0. | |
| 283 ASSERT_GT(numeric_limits<float>::min(), 0); | |
| 284 pinch0 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1); | |
| 285 pinch0.event.data.pinchUpdate.scale = numeric_limits<float>::min() * 2.0f; | |
| 286 pinch1 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1); | |
| 287 pinch1.event.data.pinchUpdate.scale = numeric_limits<float>::min() * 5.0f; | |
| 288 EXPECT_TRUE(CanCoalesce(pinch0, pinch1)); | |
| 289 Coalesce(pinch0, &pinch1); | |
| 290 EXPECT_EQ(numeric_limits<float>::min(), pinch1.event.data.pinchUpdate.scale); | |
| 291 | |
| 292 // Scales have a maximum value and can never reach Infinity. | |
| 293 pinch0 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1); | |
| 294 pinch0.event.data.pinchUpdate.scale = numeric_limits<float>::max() / 2.0f; | |
| 295 pinch1 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1); | |
| 296 pinch1.event.data.pinchUpdate.scale = 10.0f; | |
| 297 EXPECT_TRUE(CanCoalesce(pinch0, pinch1)); | |
| 298 Coalesce(pinch0, &pinch1); | |
| 299 EXPECT_EQ(numeric_limits<float>::max(), pinch1.event.data.pinchUpdate.scale); | |
| 300 } | |
| 301 | |
| 302 TEST_F(EventWithLatencyInfoTest, WebMouseWheelEventCoalescing) { | |
| 303 MouseWheelEventWithLatencyInfo mouse_wheel_0 = CreateMouseWheel(1, 1); | |
| 304 MouseWheelEventWithLatencyInfo mouse_wheel_1 = CreateMouseWheel(2, 2); | |
| 305 | |
| 306 // WebMouseWheelEvent objects with same values except different deltaX and | |
| 307 // deltaY should coalesce. | |
| 308 EXPECT_TRUE(CanCoalesce(mouse_wheel_0, mouse_wheel_1)); | |
| 309 | |
| 310 // WebMouseWheelEvent objects with different modifiers should not coalesce. | |
| 311 mouse_wheel_0 = CreateMouseWheel(1, 1); | |
| 312 mouse_wheel_1 = CreateMouseWheel(1, 1); | |
| 313 mouse_wheel_0.event.modifiers = WebInputEvent::ControlKey; | |
| 314 mouse_wheel_1.event.modifiers = WebInputEvent::ShiftKey; | |
| 315 EXPECT_FALSE(CanCoalesce(mouse_wheel_0, mouse_wheel_1)); | |
| 316 } | |
| 317 | |
| 318 // Coalescing preserves the newer timestamp. | |
| 319 TEST_F(EventWithLatencyInfoTest, TimestampCoalescing) { | |
| 320 MouseWheelEventWithLatencyInfo mouse_wheel_0 = CreateMouseWheel(1, 1); | |
| 321 mouse_wheel_0.event.timeStampSeconds = 5.0; | |
| 322 MouseWheelEventWithLatencyInfo mouse_wheel_1 = CreateMouseWheel(2, 2); | |
| 323 mouse_wheel_1.event.timeStampSeconds = 10.0; | |
| 324 | |
| 325 EXPECT_TRUE(CanCoalesce(mouse_wheel_0, mouse_wheel_1)); | |
| 326 Coalesce(mouse_wheel_1, &mouse_wheel_0); | |
| 327 EXPECT_EQ(10.0, mouse_wheel_0.event.timeStampSeconds); | |
| 328 } | |
| 329 | |
| 121 } // namespace | 330 } // namespace |
| 122 } // namespace content | 331 } // namespace content |
| OLD | NEW |