Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: ui/events/gesture_detection/gesture_provider.cc

Issue 181833003: [Android] Out with the Android GR, in with the new unified C++ GR (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "ui/events/gesture_detection/gesture_provider.h" 5 #include "ui/events/gesture_detection/gesture_provider.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "ui/events/gesture_detection/gesture_event_params.h" 11 #include "ui/events/gesture_detection/gesture_event_data.h"
12 #include "ui/events/gesture_detection/motion_event.h" 12 #include "ui/events/gesture_detection/motion_event.h"
13 13
14 namespace ui { 14 namespace ui {
15 namespace { 15 namespace {
16 16
17 // Double-tap drag zoom sensitivity (speed). 17 // Double-tap drag zoom sensitivity (speed).
18 const float kDoubleTapDragZoomSpeed = 0.005f; 18 const float kDoubleTapDragZoomSpeed = 0.005f;
19 19
20 const char* GetMotionEventActionName(MotionEvent::Action action) { 20 const char* GetMotionEventActionName(MotionEvent::Action action) {
21 switch(action) { 21 switch(action) {
22 case MotionEvent::ACTION_POINTER_DOWN: return "ACTION_POINTER_DOWN"; 22 case MotionEvent::ACTION_POINTER_DOWN: return "ACTION_POINTER_DOWN";
23 case MotionEvent::ACTION_POINTER_UP: return "ACTION_POINTER_UP"; 23 case MotionEvent::ACTION_POINTER_UP: return "ACTION_POINTER_UP";
24 case MotionEvent::ACTION_DOWN: return "ACTION_DOWN"; 24 case MotionEvent::ACTION_DOWN: return "ACTION_DOWN";
25 case MotionEvent::ACTION_UP: return "ACTION_UP"; 25 case MotionEvent::ACTION_UP: return "ACTION_UP";
26 case MotionEvent::ACTION_CANCEL: return "ACTION_CANCEL"; 26 case MotionEvent::ACTION_CANCEL: return "ACTION_CANCEL";
27 case MotionEvent::ACTION_MOVE: return "ACTION_MOVE"; 27 case MotionEvent::ACTION_MOVE: return "ACTION_MOVE";
28 } 28 }
29 return ""; 29 return "";
30 } 30 }
31 31
32 GestureEventParams CreateGesture(GestureEventType type, 32 GestureEventData CreateGesture(GestureEventType type,
33 base::TimeTicks time, 33 base::TimeTicks time,
34 float x, 34 float x,
35 float y, 35 float y,
36 const GestureEventParams::Data& extra_data) { 36 const GestureEventData::Details& details) {
37 return GestureEventParams(type, time, x, y, extra_data); 37 return GestureEventData(type, time, x, y, details);
38 } 38 }
39 39
40 GestureEventParams CreateGesture(GestureEventType type, 40 GestureEventData CreateGesture(GestureEventType type,
41 base::TimeTicks time, 41 base::TimeTicks time,
42 float x, 42 float x,
43 float y) { 43 float y) {
44 return CreateGesture(type, time, x, y, GestureEventParams::Data()); 44 return CreateGesture(type, time, x, y, GestureEventData::Details());
45 } 45 }
46 46
47 GestureEventParams CreateGesture(GestureEventType type, 47 GestureEventData CreateGesture(GestureEventType type,
48 const MotionEvent& event, 48 const MotionEvent& event,
49 const GestureEventParams::Data& extra_data) { 49 const GestureEventData::Details& details) {
50 return CreateGesture( 50 return CreateGesture(
51 type, event.GetEventTime(), event.GetX(), event.GetY(), extra_data); 51 type, event.GetEventTime(), event.GetX(), event.GetY(), details);
52 } 52 }
53 53
54 GestureEventParams CreateGesture(GestureEventType type, 54 GestureEventData CreateGesture(GestureEventType type,
55 const MotionEvent& event) { 55 const MotionEvent& event) {
56 return CreateGesture(type, event, GestureEventParams::Data()); 56 return CreateGesture(type, event, GestureEventData::Details());
57 } 57 }
58 58
59 float Round(float f) { 59 float Round(float f) {
60 return (f > 0.f) ? std::floor(f + 0.5f) : std::ceil(f - 0.5f); 60 return (f > 0.f) ? std::floor(f + 0.5f) : std::ceil(f - 0.5f);
61 } 61 }
62 62
63 } // namespace 63 } // namespace
64 64
65 // GestureProvider:::Config 65 // GestureProvider:::Config
66 66
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 virtual bool OnScale(const ScaleGestureDetector& detector) OVERRIDE { 111 virtual bool OnScale(const ScaleGestureDetector& detector) OVERRIDE {
112 if (ignore_detector_events_) 112 if (ignore_detector_events_)
113 return false; 113 return false;
114 if (!pinch_event_sent_) { 114 if (!pinch_event_sent_) {
115 pinch_event_sent_ = true; 115 pinch_event_sent_ = true;
116 provider_->Send(CreateGesture(GESTURE_PINCH_BEGIN, 116 provider_->Send(CreateGesture(GESTURE_PINCH_BEGIN,
117 detector.GetEventTime(), 117 detector.GetEventTime(),
118 detector.GetFocusX(), 118 detector.GetFocusX(),
119 detector.GetFocusY())); 119 detector.GetFocusY()));
120 } 120 }
121 GestureEventParams::Data pinch_data; 121 GestureEventData::Details pinch_details;
122 pinch_data.pinch_update.scale = detector.GetScaleFactor(); 122 pinch_details.pinch_update.scale = detector.GetScaleFactor();
123 provider_->Send(CreateGesture(GESTURE_PINCH_UPDATE, 123 provider_->Send(CreateGesture(GESTURE_PINCH_UPDATE,
124 detector.GetEventTime(), 124 detector.GetEventTime(),
125 detector.GetFocusX(), 125 detector.GetFocusX(),
126 detector.GetFocusY(), 126 detector.GetFocusY(),
127 pinch_data)); 127 pinch_details));
128 return true; 128 return true;
129 } 129 }
130 130
131 bool IsScaleGestureDetectionInProgress() const { 131 bool IsScaleGestureDetectionInProgress() const {
132 return !ignore_detector_events_ && scale_gesture_detector_.IsInProgress(); 132 return !ignore_detector_events_ && scale_gesture_detector_.IsInProgress();
133 } 133 }
134 134
135 void set_ignore_detector_events(bool value) { 135 void set_ignore_detector_events(bool value) {
136 // Note that returning false from OnScaleBegin / OnScale makes the 136 // Note that returning false from OnScaleBegin / OnScale makes the
137 // gesture detector not to emit further scaling notifications 137 // gesture detector not to emit further scaling notifications
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 provider_(provider), 171 provider_(provider),
172 px_to_dp_(1.0f / snap_scroll_controller_config.device_scale_factor), 172 px_to_dp_(1.0f / snap_scroll_controller_config.device_scale_factor),
173 disable_click_delay_(disable_click_delay), 173 disable_click_delay_(disable_click_delay),
174 scaled_touch_slop_(gesture_detector_config.scaled_touch_slop), 174 scaled_touch_slop_(gesture_detector_config.scaled_touch_slop),
175 scaled_touch_slop_square_(scaled_touch_slop_ * scaled_touch_slop_), 175 scaled_touch_slop_square_(scaled_touch_slop_ * scaled_touch_slop_),
176 double_tap_timeout_(gesture_detector_config.double_tap_timeout), 176 double_tap_timeout_(gesture_detector_config.double_tap_timeout),
177 ignore_single_tap_(false), 177 ignore_single_tap_(false),
178 seen_first_scroll_event_(false), 178 seen_first_scroll_event_(false),
179 double_tap_mode_(DOUBLE_TAP_MODE_NONE), 179 double_tap_mode_(DOUBLE_TAP_MODE_NONE),
180 double_tap_y_(0), 180 double_tap_y_(0),
181 support_double_tap_(true), 181 double_tap_support_enabled_(true),
182 double_tap_drag_zoom_anchor_x_(0), 182 double_tap_drag_zoom_anchor_x_(0),
183 double_tap_drag_zoom_anchor_y_(0), 183 double_tap_drag_zoom_anchor_y_(0),
184 last_raw_x_(0), 184 last_raw_x_(0),
185 last_raw_y_(0), 185 last_raw_y_(0),
186 accumulated_scroll_error_x_(0), 186 accumulated_scroll_error_x_(0),
187 accumulated_scroll_error_y_(0) { 187 accumulated_scroll_error_y_(0) {
188 UpdateDoubleTapListener(); 188 UpdateDoubleTapListener();
189 } 189 }
190 190
191 virtual ~GestureListenerImpl() {} 191 virtual ~GestureListenerImpl() {}
(...skipping 19 matching lines...) Expand all
211 // GestureDetector::GestureListener implementation. 211 // GestureDetector::GestureListener implementation.
212 virtual bool OnDown(const MotionEvent& e) OVERRIDE { 212 virtual bool OnDown(const MotionEvent& e) OVERRIDE {
213 current_down_time_ = e.GetEventTime(); 213 current_down_time_ = e.GetEventTime();
214 ignore_single_tap_ = false; 214 ignore_single_tap_ = false;
215 seen_first_scroll_event_ = false; 215 seen_first_scroll_event_ = false;
216 last_raw_x_ = e.GetRawX(); 216 last_raw_x_ = e.GetRawX();
217 last_raw_y_ = e.GetRawY(); 217 last_raw_y_ = e.GetRawY();
218 accumulated_scroll_error_x_ = 0; 218 accumulated_scroll_error_x_ = 0;
219 accumulated_scroll_error_y_ = 0; 219 accumulated_scroll_error_y_ = 0;
220 220
221 GestureEventParams::Data tap_down_data; 221 GestureEventData::Details tap_details;
222 tap_down_data.tap.width = tap_down_data.tap.height = e.GetTouchMajor(); 222 tap_details.tap.width = tap_details.tap.height = e.GetTouchMajor();
223 provider_->Send(CreateGesture(GESTURE_TAP_DOWN, e, tap_down_data)); 223 provider_->Send(CreateGesture(GESTURE_TAP_DOWN, e, tap_details));
224 224
225 // Return true to indicate that we want to handle touch. 225 // Return true to indicate that we want to handle touch.
226 return true; 226 return true;
227 } 227 }
228 228
229 virtual bool OnScroll(const MotionEvent& e1, 229 virtual bool OnScroll(const MotionEvent& e1,
230 const MotionEvent& e2, 230 const MotionEvent& e2,
231 float raw_distance_x, 231 float raw_distance_x,
232 float raw_distance_y) OVERRIDE { 232 float raw_distance_y) OVERRIDE {
233 float distance_x = raw_distance_x; 233 float distance_x = raw_distance_x;
(...skipping 18 matching lines...) Expand all
252 } else { 252 } else {
253 distance_x = 0; 253 distance_x = 0;
254 } 254 }
255 } 255 }
256 256
257 last_raw_x_ = e2.GetRawX(); 257 last_raw_x_ = e2.GetRawX();
258 last_raw_y_ = e2.GetRawY(); 258 last_raw_y_ = e2.GetRawY();
259 if (!provider_->IsScrollInProgress()) { 259 if (!provider_->IsScrollInProgress()) {
260 // Note that scroll start hints are in distance traveled, where 260 // Note that scroll start hints are in distance traveled, where
261 // scroll deltas are in the opposite direction. 261 // scroll deltas are in the opposite direction.
262 GestureEventParams::Data scroll_data; 262 GestureEventData::Details scroll_details;
263 scroll_data.scroll_begin.delta_x_hint = -raw_distance_x; 263 scroll_details.scroll_begin.delta_x_hint = -raw_distance_x;
264 scroll_data.scroll_begin.delta_y_hint = -raw_distance_y; 264 scroll_details.scroll_begin.delta_y_hint = -raw_distance_y;
265 provider_->Send(CreateGesture(GESTURE_SCROLL_BEGIN, 265 provider_->Send(CreateGesture(GESTURE_SCROLL_BEGIN,
266 e2.GetEventTime(), 266 e2.GetEventTime(),
267 e1.GetX(), 267 e1.GetX(),
268 e1.GetY(), 268 e1.GetY(),
269 scroll_data)); 269 scroll_details));
270 } 270 }
271 271
272 // distance_x and distance_y is the scrolling offset since last OnScroll. 272 // distance_x and distance_y is the scrolling offset since last OnScroll.
273 // Because we are passing integers to Blink, this could introduce 273 // Because we are passing integers to Blink, this could introduce
274 // rounding errors. The rounding errors will accumulate overtime. 274 // rounding errors. The rounding errors will accumulate overtime.
275 // To solve this, we should be adding back the rounding errors each time 275 // To solve this, we should be adding back the rounding errors each time
276 // when we calculate the new offset. 276 // when we calculate the new offset.
277 // TODO(jdduke): Determine if we can simpy use floating point deltas, as 277 // TODO(jdduke): Determine if we can simpy use floating point deltas, as
278 // WebGestureEvent also takes floating point deltas for GestureScrollUpdate. 278 // WebGestureEvent also takes floating point deltas for GestureScrollUpdate.
279 int dx = (int)(distance_x + accumulated_scroll_error_x_); 279 int dx = (int)(distance_x + accumulated_scroll_error_x_);
280 int dy = (int)(distance_y + accumulated_scroll_error_y_); 280 int dy = (int)(distance_y + accumulated_scroll_error_y_);
281 accumulated_scroll_error_x_ += (distance_x - dx); 281 accumulated_scroll_error_x_ += (distance_x - dx);
282 accumulated_scroll_error_y_ += (distance_y - dy); 282 accumulated_scroll_error_y_ += (distance_y - dy);
283 283
284 if (dx || dy) { 284 if (dx || dy) {
285 GestureEventParams::Data scroll_data; 285 GestureEventData::Details scroll_details;
286 scroll_data.scroll_update.delta_x = -dx; 286 scroll_details.scroll_update.delta_x = -dx;
287 scroll_data.scroll_update.delta_y = -dy; 287 scroll_details.scroll_update.delta_y = -dy;
288 provider_->Send(CreateGesture(GESTURE_SCROLL_UPDATE, e2, scroll_data)); 288 provider_->Send(CreateGesture(GESTURE_SCROLL_UPDATE, e2, scroll_details));
289 } 289 }
290 290
291 return true; 291 return true;
292 } 292 }
293 293
294 virtual bool OnFling(const MotionEvent& e1, 294 virtual bool OnFling(const MotionEvent& e1,
295 const MotionEvent& e2, 295 const MotionEvent& e2,
296 float velocity_x, 296 float velocity_x,
297 float velocity_y) OVERRIDE { 297 float velocity_y) OVERRIDE {
298 if (snap_scroll_controller_.IsSnappingScrolls()) { 298 if (snap_scroll_controller_.IsSnappingScrolls()) {
299 if (snap_scroll_controller_.IsSnapHorizontal()) { 299 if (snap_scroll_controller_.IsSnapHorizontal()) {
300 velocity_y = 0; 300 velocity_y = 0;
301 } else { 301 } else {
302 velocity_x = 0; 302 velocity_x = 0;
303 } 303 }
304 } 304 }
305 305
306 provider_->Fling( 306 provider_->Fling(
307 e2.GetEventTime(), e1.GetX(), e1.GetY(), velocity_x, velocity_y); 307 e2.GetEventTime(), e1.GetX(), e1.GetY(), velocity_x, velocity_y);
308 return true; 308 return true;
309 } 309 }
310 310
311 virtual void OnShowPress(const MotionEvent& e) OVERRIDE { 311 virtual void OnShowPress(const MotionEvent& e) OVERRIDE {
312 GestureEventParams::Data show_press_data; 312 GestureEventData::Details show_press_details;
313 // TODO(jdduke): Expose minor axis length and rotation in |MotionEvent|. 313 // TODO(jdduke): Expose minor axis length and rotation in |MotionEvent|.
314 show_press_data.show_press.width = e.GetTouchMajor(); 314 show_press_details.show_press.width = e.GetTouchMajor();
315 show_press_data.show_press.height = show_press_data.show_press.width; 315 show_press_details.show_press.height = show_press_details.show_press.width;
316 provider_->Send(CreateGesture(GESTURE_SHOW_PRESS, e, show_press_data)); 316 provider_->Send(CreateGesture(GESTURE_SHOW_PRESS, e, show_press_details));
317 } 317 }
318 318
319 virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE { 319 virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE {
320 if (IsPointOutsideCurrentSlopRegion(e.GetRawX(), e.GetRawY())) { 320 if (IsPointOutsideCurrentSlopRegion(e.GetRawX(), e.GetRawY())) {
321 provider_->SendTapCancelIfNecessary(e); 321 provider_->SendTapCancelIfNecessary(e);
322 ignore_single_tap_ = true; 322 ignore_single_tap_ = true;
323 return true; 323 return true;
324 } 324 }
325 // This is a hack to address the issue where user hovers 325 // This is a hack to address the issue where user hovers
326 // over a link for longer than double_tap_timeout_, then 326 // over a link for longer than double_tap_timeout_, then
327 // OnSingleTapConfirmed() is not triggered. But we still 327 // OnSingleTapConfirmed() is not triggered. But we still
328 // want to trigger the tap event at UP. So we override 328 // want to trigger the tap event at UP. So we override
329 // OnSingleTapUp() in this case. This assumes singleTapUp 329 // OnSingleTapUp() in this case. This assumes singleTapUp
330 // gets always called before singleTapConfirmed. 330 // gets always called before singleTapConfirmed.
331 if (!ignore_single_tap_) { 331 if (!ignore_single_tap_) {
332 if (e.GetEventTime() - current_down_time_ > double_tap_timeout_) { 332 if (e.GetEventTime() - current_down_time_ > double_tap_timeout_) {
333 return OnSingleTapConfirmed(e); 333 return OnSingleTapConfirmed(e);
334 } else if (IsDoubleTapDisabled() || disable_click_delay_) { 334 } else if (IsDoubleTapDisabled() || disable_click_delay_) {
335 // If double-tap has been disabled, there is no need to wait 335 // If double-tap has been disabled, there is no need to wait
336 // for the double-tap timeout. 336 // for the double-tap timeout.
337 return OnSingleTapConfirmed(e); 337 return OnSingleTapConfirmed(e);
338 } else { 338 } else {
339 // Notify Blink about this tapUp event anyway, 339 // Notify Blink about this tapUp event anyway,
340 // when none of the above conditions applied. 340 // when none of the above conditions applied.
341 provider_->Send(CreateGesture(GESTURE_SINGLE_TAP_UNCONFIRMED, e)); 341 provider_->Send(CreateGesture(GESTURE_TAP_UNCONFIRMED, e));
342 } 342 }
343 } 343 }
344 344
345 return provider_->SendLongTapIfNecessary(e); 345 return provider_->SendLongTapIfNecessary(e);
346 } 346 }
347 347
348 // GestureDetector::DoubleTapListener implementation. 348 // GestureDetector::DoubleTapListener implementation.
349 virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE { 349 virtual bool OnSingleTapConfirmed(const MotionEvent& e) OVERRIDE {
350 // Long taps in the edges of the screen have their events delayed by 350 // Long taps in the edges of the screen have their events delayed by
351 // ContentViewHolder for tab swipe operations. As a consequence of the delay 351 // ContentViewHolder for tab swipe operations. As a consequence of the delay
352 // this method might be called after receiving the up event. 352 // this method might be called after receiving the up event.
353 // These corner cases should be ignored. 353 // These corner cases should be ignored.
354 if (ignore_single_tap_) 354 if (ignore_single_tap_)
355 return true; 355 return true;
356 356
357 ignore_single_tap_ = true; 357 ignore_single_tap_ = true;
358 358
359 GestureEventParams::Data tap_data; 359 GestureEventData::Details tap_details;
360 tap_data.tap.tap_count = 1; 360 tap_details.tap.tap_count = 1;
361 tap_data.tap.width = tap_data.tap.height = e.GetTouchMajor(); 361 tap_details.tap.width = tap_details.tap.height = e.GetTouchMajor();
362 provider_->Send(CreateGesture(GESTURE_SINGLE_TAP_CONFIRMED, e, tap_data)); 362 provider_->Send(CreateGesture(GESTURE_TAP, e, tap_details));
363 return true; 363 return true;
364 } 364 }
365 365
366 virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE { return false; } 366 virtual bool OnDoubleTap(const MotionEvent& e) OVERRIDE { return false; }
367 367
368 virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE { 368 virtual bool OnDoubleTapEvent(const MotionEvent& e) OVERRIDE {
369 switch (e.GetAction()) { 369 switch (e.GetAction()) {
370 case MotionEvent::ACTION_DOWN: 370 case MotionEvent::ACTION_DOWN:
371 // Note that this will be called before the corresponding |onDown()| 371 // Note that this will be called before the corresponding |onDown()|
372 // of the same ACTION_DOWN event. Thus, the preceding TAP_DOWN 372 // of the same ACTION_DOWN event. Thus, the preceding TAP_DOWN
373 // should be cancelled prior to sending a new one (in |onDown()|). 373 // should be cancelled prior to sending a new one (in |onDown()|).
374 double_tap_drag_zoom_anchor_x_ = e.GetX(); 374 double_tap_drag_zoom_anchor_x_ = e.GetX();
375 double_tap_drag_zoom_anchor_y_ = e.GetY(); 375 double_tap_drag_zoom_anchor_y_ = e.GetY();
376 double_tap_mode_ = DOUBLE_TAP_MODE_DRAG_DETECTION_IN_PROGRESS; 376 double_tap_mode_ = DOUBLE_TAP_MODE_DRAG_DETECTION_IN_PROGRESS;
377 // If a long-press fires during a double-tap, the GestureDetector 377 // If a long-press fires during a double-tap, the GestureDetector
378 // will stop feeding MotionEvents to |onDoubleTapEvent()|, 378 // will stop feeding MotionEvents to |onDoubleTapEvent()|,
379 // preventing double-tap drag zoom. Long press detection will be 379 // preventing double-tap drag zoom. Long press detection will be
380 // re-enabled on the next ACTION_DOWN. 380 // re-enabled on the next ACTION_DOWN.
381 gesture_detector_.set_is_longpress_enabled(false); 381 gesture_detector_.set_is_longpress_enabled(false);
382 break; 382 break;
383 case MotionEvent::ACTION_MOVE: 383 case MotionEvent::ACTION_MOVE:
384 if (double_tap_mode_ == DOUBLE_TAP_MODE_DRAG_DETECTION_IN_PROGRESS) { 384 if (double_tap_mode_ == DOUBLE_TAP_MODE_DRAG_DETECTION_IN_PROGRESS) {
385 float distance_x = double_tap_drag_zoom_anchor_x_ - e.GetX(); 385 float distance_x = double_tap_drag_zoom_anchor_x_ - e.GetX();
386 float distance_y = double_tap_drag_zoom_anchor_y_ - e.GetY(); 386 float distance_y = double_tap_drag_zoom_anchor_y_ - e.GetY();
387 387
388 // Begin double-tap drag zoom mode if the move distance is 388 // Begin double-tap drag zoom mode if the move distance is
389 // further than the threshold. 389 // further than the threshold.
390 if (IsDistanceGreaterThanTouchSlop(distance_x, distance_y)) { 390 if (IsDistanceGreaterThanTouchSlop(distance_x, distance_y)) {
391 GestureEventParams::Data scroll_data; 391 GestureEventData::Details scroll_details;
392 scroll_data.scroll_begin.delta_x_hint = -distance_x; 392 scroll_details.scroll_begin.delta_x_hint = -distance_x;
393 scroll_data.scroll_begin.delta_y_hint = -distance_y; 393 scroll_details.scroll_begin.delta_y_hint = -distance_y;
394 provider_->Send( 394 provider_->Send(
395 CreateGesture(GESTURE_SCROLL_BEGIN, e, scroll_data)); 395 CreateGesture(GESTURE_SCROLL_BEGIN, e, scroll_details));
396 provider_->Send( 396 provider_->Send(
397 CreateGesture(GESTURE_PINCH_BEGIN, 397 CreateGesture(GESTURE_PINCH_BEGIN,
398 e.GetEventTime(), 398 e.GetEventTime(),
399 Round(double_tap_drag_zoom_anchor_x_), 399 Round(double_tap_drag_zoom_anchor_x_),
400 Round(double_tap_drag_zoom_anchor_y_))); 400 Round(double_tap_drag_zoom_anchor_y_)));
401 double_tap_mode_ = DOUBLE_TAP_MODE_DRAG_ZOOM; 401 double_tap_mode_ = DOUBLE_TAP_MODE_DRAG_ZOOM;
402 } 402 }
403 } else if (double_tap_mode_ == DOUBLE_TAP_MODE_DRAG_ZOOM) { 403 } else if (double_tap_mode_ == DOUBLE_TAP_MODE_DRAG_ZOOM) {
404 provider_->Send(CreateGesture(GESTURE_SCROLL_UPDATE, e)); 404 provider_->Send(CreateGesture(GESTURE_SCROLL_UPDATE, e));
405 405
406 float dy = double_tap_y_ - e.GetY(); 406 float dy = double_tap_y_ - e.GetY();
407 GestureEventParams::Data pinch_data; 407 GestureEventData::Details pinch_details;
408 pinch_data.pinch_update.scale = 408 pinch_details.pinch_update.scale =
409 std::pow(dy > 0 ? 1.0f - kDoubleTapDragZoomSpeed 409 std::pow(dy > 0 ? 1.0f - kDoubleTapDragZoomSpeed
410 : 1.0f + kDoubleTapDragZoomSpeed, 410 : 1.0f + kDoubleTapDragZoomSpeed,
411 std::abs(dy * px_to_dp_)); 411 std::abs(dy * px_to_dp_));
412 provider_->Send(CreateGesture(GESTURE_PINCH_UPDATE, 412 provider_->Send(CreateGesture(GESTURE_PINCH_UPDATE,
413 e.GetEventTime(), 413 e.GetEventTime(),
414 Round(double_tap_drag_zoom_anchor_x_), 414 Round(double_tap_drag_zoom_anchor_x_),
415 Round(double_tap_drag_zoom_anchor_y_), 415 Round(double_tap_drag_zoom_anchor_y_),
416 pinch_data)); 416 pinch_details));
417 } 417 }
418 break; 418 break;
419 case MotionEvent::ACTION_UP: 419 case MotionEvent::ACTION_UP:
420 if (double_tap_mode_ != DOUBLE_TAP_MODE_DRAG_ZOOM) { 420 if (double_tap_mode_ != DOUBLE_TAP_MODE_DRAG_ZOOM) {
421 // Normal double-tap gesture. 421 // Normal double-tap gesture.
422 provider_->Send(CreateGesture(GESTURE_DOUBLE_TAP, e)); 422 provider_->Send(CreateGesture(GESTURE_DOUBLE_TAP, e));
423 } 423 }
424 EndDoubleTapDragIfNecessary(e); 424 EndDoubleTapDragIfNecessary(e);
425 break; 425 break;
426 case MotionEvent::ACTION_CANCEL: 426 case MotionEvent::ACTION_CANCEL:
427 EndDoubleTapDragIfNecessary(e); 427 EndDoubleTapDragIfNecessary(e);
428 break; 428 break;
429 default: 429 default:
430 NOTREACHED() << "Invalid double-tap event."; 430 NOTREACHED() << "Invalid double-tap event.";
431 break; 431 break;
432 } 432 }
433 double_tap_y_ = e.GetY(); 433 double_tap_y_ = e.GetY();
434 return true; 434 return true;
435 } 435 }
436 436
437 virtual bool OnLongPress(const MotionEvent& e) OVERRIDE { 437 virtual bool OnLongPress(const MotionEvent& e) OVERRIDE {
438 DCHECK(!IsDoubleTapInProgress()); 438 DCHECK(!IsDoubleTapInProgress());
439 SetIgnoreSingleTap(true); 439 SetIgnoreSingleTap(true);
440 440
441 GestureEventParams::Data long_press_data; 441 GestureEventData::Details long_press_details;
442 long_press_data.long_press.width = e.GetTouchMajor(); 442 long_press_details.long_press.width = e.GetTouchMajor();
443 long_press_data.long_press.height = long_press_data.long_press.width; 443 long_press_details.long_press.height = long_press_details.long_press.width;
444 provider_->Send(CreateGesture(GESTURE_LONG_PRESS, e, long_press_data)); 444 provider_->Send(CreateGesture(GESTURE_LONG_PRESS, e, long_press_details));
445 445
446 // Returning true puts the GestureDetector in "longpress" mode, disabling 446 // Returning true puts the GestureDetector in "longpress" mode, disabling
447 // further scrolling. This is undesirable, as it is quite common for a 447 // further scrolling. This is undesirable, as it is quite common for a
448 // longpress gesture to fire on content that won't trigger a context menu. 448 // longpress gesture to fire on content that won't trigger a context menu.
449 return false; 449 return false;
450 } 450 }
451 451
452 void UpdateDoubleTapSupportForPlatform(bool support_double_tap) { 452 void SetDoubleTapSupportForPlatformEnabled(bool enabled) {
453 DCHECK(!IsDoubleTapInProgress()); 453 DCHECK(!IsDoubleTapInProgress());
454 DoubleTapMode double_tap_mode = 454 DoubleTapMode double_tap_mode =
455 support_double_tap ? DOUBLE_TAP_MODE_NONE : DOUBLE_TAP_MODE_DISABLED; 455 enabled ? DOUBLE_TAP_MODE_NONE : DOUBLE_TAP_MODE_DISABLED;
456 if (double_tap_mode_ == double_tap_mode) 456 if (double_tap_mode_ == double_tap_mode)
457 return; 457 return;
458 double_tap_mode_ = double_tap_mode; 458 double_tap_mode_ = double_tap_mode;
459 UpdateDoubleTapListener(); 459 UpdateDoubleTapListener();
460 } 460 }
461 461
462 void UpdateDoubleTapSupportForPage(bool support_double_tap) { 462 void SetDoubleTapSupportForPageEnabled(bool enabled) {
463 if (support_double_tap_ == support_double_tap) 463 if (double_tap_support_enabled_ == enabled)
464 return; 464 return;
465 support_double_tap_ = support_double_tap; 465 double_tap_support_enabled_ = enabled;
466 UpdateDoubleTapListener(); 466 UpdateDoubleTapListener();
467 } 467 }
468 468
469 bool IsDoubleTapDisabled() const { 469 bool IsDoubleTapDisabled() const {
470 return double_tap_mode_ == DOUBLE_TAP_MODE_DISABLED || !support_double_tap_; 470 return double_tap_mode_ == DOUBLE_TAP_MODE_DISABLED ||
471 !double_tap_support_enabled_;
471 } 472 }
472 473
473 bool IsClickDelayDisabled() const { return disable_click_delay_; } 474 bool IsClickDelayDisabled() const { return disable_click_delay_; }
474 475
475 bool IsDoubleTapInProgress() const { 476 bool IsDoubleTapInProgress() const {
476 return double_tap_mode_ != DOUBLE_TAP_MODE_DISABLED && 477 return double_tap_mode_ != DOUBLE_TAP_MODE_DISABLED &&
477 double_tap_mode_ != DOUBLE_TAP_MODE_NONE; 478 double_tap_mode_ != DOUBLE_TAP_MODE_NONE;
478 } 479 }
479 480
480 private: 481 private:
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 553
553 // Indicate current double-tap mode state. 554 // Indicate current double-tap mode state.
554 int double_tap_mode_; 555 int double_tap_mode_;
555 556
556 // On double-tap this will store the y coordinates of the touch. 557 // On double-tap this will store the y coordinates of the touch.
557 float double_tap_y_; 558 float double_tap_y_;
558 559
559 // The page's viewport and scale sometimes allow us to disable double-tap 560 // The page's viewport and scale sometimes allow us to disable double-tap
560 // gesture detection, 561 // gesture detection,
561 // according to the logic in ContentViewCore.onRenderCoordinatesUpdated(). 562 // according to the logic in ContentViewCore.onRenderCoordinatesUpdated().
562 bool support_double_tap_; 563 bool double_tap_support_enabled_;
563 564
564 // x, y coordinates for an Anchor on double-tap drag zoom. 565 // x, y coordinates for an Anchor on double-tap drag zoom.
565 float double_tap_drag_zoom_anchor_x_; 566 float double_tap_drag_zoom_anchor_x_;
566 float double_tap_drag_zoom_anchor_y_; 567 float double_tap_drag_zoom_anchor_y_;
567 568
568 // Used to track the last rawX/Y coordinates for moves. This gives absolute 569 // Used to track the last rawX/Y coordinates for moves. This gives absolute
569 // scroll distance. 570 // scroll distance.
570 // Useful for full screen tracking. 571 // Useful for full screen tracking.
571 float last_raw_x_; 572 float last_raw_x_;
572 float last_raw_y_; 573 float last_raw_y_;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 handled |= scale_gesture_listener_->OnTouchEvent(event); 618 handled |= scale_gesture_listener_->OnTouchEvent(event);
618 619
619 if (event.GetAction() == MotionEvent::ACTION_UP || 620 if (event.GetAction() == MotionEvent::ACTION_UP ||
620 event.GetAction() == MotionEvent::ACTION_CANCEL) { 621 event.GetAction() == MotionEvent::ACTION_CANCEL) {
621 // "Last finger raised" could be an end to movement, but it should 622 // "Last finger raised" could be an end to movement, but it should
622 // only terminate scrolling if the event did not cause a fling. 623 // only terminate scrolling if the event did not cause a fling.
623 if (was_touch_scrolling_ && !handled) 624 if (was_touch_scrolling_ && !handled)
624 EndTouchScrollIfNecessary(event.GetEventTime(), true); 625 EndTouchScrollIfNecessary(event.GetEventTime(), true);
625 626
626 // We shouldn't necessarily cancel a tap on ACTION_UP, as the double-tap 627 // We shouldn't necessarily cancel a tap on ACTION_UP, as the double-tap
627 // timeout may yet trigger a SINGLE_TAP_CONFIRMED. 628 // timeout may yet trigger a SINGLE_TAP.
628 if (event.GetAction() == MotionEvent::ACTION_CANCEL) 629 if (event.GetAction() == MotionEvent::ACTION_CANCEL)
629 SendTapCancelIfNecessary(event); 630 SendTapCancelIfNecessary(event);
630 631
631 current_down_event_.reset(); 632 current_down_event_.reset();
632 } 633 }
633 634
634 return true; 635 return true;
635 } 636 }
636 637
637 void GestureProvider::ResetGestureDetectors() { 638 void GestureProvider::ResetGestureDetectors() {
638 if (!current_down_event_) 639 if (!current_down_event_)
639 return; 640 return;
640 scoped_ptr<MotionEvent> cancel_event = current_down_event_->Cancel(); 641 scoped_ptr<MotionEvent> cancel_event = current_down_event_->Cancel();
641 gesture_listener_->OnTouchEvent(*cancel_event, false); 642 gesture_listener_->OnTouchEvent(*cancel_event, false);
642 scale_gesture_listener_->OnTouchEvent(*cancel_event); 643 scale_gesture_listener_->OnTouchEvent(*cancel_event);
643 } 644 }
644 645
645 void GestureProvider::CancelActiveTouchSequence() { 646 void GestureProvider::CancelActiveTouchSequence() {
646 if (!current_down_event_) 647 if (!current_down_event_)
647 return; 648 return;
648 OnTouchEvent(*current_down_event_->Cancel()); 649 OnTouchEvent(*current_down_event_->Cancel());
649 current_down_event_.reset(); 650 current_down_event_.reset();
650 } 651 }
651 652
652 void GestureProvider::UpdateMultiTouchSupport(bool support_multi_touch_zoom) { 653 void GestureProvider::SetMultiTouchSupportEnabled(bool enabled) {
653 scale_gesture_listener_->set_ignore_detector_events( 654 scale_gesture_listener_->set_ignore_detector_events(!enabled);
654 !support_multi_touch_zoom);
655 } 655 }
656 656
657 void GestureProvider::UpdateDoubleTapSupportForPlatform( 657 void GestureProvider::SetDoubleTapSupportForPlatformEnabled(bool enabled) {
658 bool support_double_tap) { 658 gesture_listener_->SetDoubleTapSupportForPlatformEnabled(enabled);
659 gesture_listener_->UpdateDoubleTapSupportForPlatform(support_double_tap);
660 } 659 }
661 660
662 void GestureProvider::UpdateDoubleTapSupportForPage(bool support_double_tap) { 661 void GestureProvider::SetDoubleTapSupportForPageEnabled(bool enabled) {
663 gesture_listener_->UpdateDoubleTapSupportForPage(support_double_tap); 662 gesture_listener_->SetDoubleTapSupportForPageEnabled(enabled);
664 } 663 }
665 664
666 bool GestureProvider::IsScrollInProgress() const { 665 bool GestureProvider::IsScrollInProgress() const {
667 // TODO(wangxianzhu): Also return true when fling is active once the UI knows 666 // TODO(wangxianzhu): Also return true when fling is active once the UI knows
668 // exactly when the fling ends. 667 // exactly when the fling ends.
669 return touch_scroll_in_progress_; 668 return touch_scroll_in_progress_;
670 } 669 }
671 670
672 bool GestureProvider::IsPinchInProgress() const { return pinch_in_progress_; } 671 bool GestureProvider::IsPinchInProgress() const { return pinch_in_progress_; }
673 672
674 bool GestureProvider::IsDoubleTapInProgress() const { 673 bool GestureProvider::IsDoubleTapInProgress() const {
675 return gesture_listener_->IsDoubleTapInProgress(); 674 return gesture_listener_->IsDoubleTapInProgress();
676 } 675 }
677 676
677 bool GestureProvider::IsClickDelayDisabled() const {
678 return gesture_listener_->IsClickDelayDisabled();
679 }
680
678 void GestureProvider::InitGestureDetectors(const Config& config) { 681 void GestureProvider::InitGestureDetectors(const Config& config) {
679 TRACE_EVENT0("input", "GestureProvider::InitGestureDetectors"); 682 TRACE_EVENT0("input", "GestureProvider::InitGestureDetectors");
680 gesture_listener_.reset( 683 gesture_listener_.reset(
681 new GestureListenerImpl(config.gesture_detector_config, 684 new GestureListenerImpl(config.gesture_detector_config,
682 config.snap_scroll_controller_config, 685 config.snap_scroll_controller_config,
683 config.disable_click_delay, 686 config.disable_click_delay,
684 this)); 687 this));
685 688
686 scale_gesture_listener_.reset( 689 scale_gesture_listener_.reset(
687 new ScaleGestureListenerImpl(config.scale_gesture_detector_config, this)); 690 new ScaleGestureListenerImpl(config.scale_gesture_detector_config, this));
(...skipping 10 matching lines...) Expand all
698 float velocity_y) { 701 float velocity_y) {
699 if (!velocity_x && !velocity_y) { 702 if (!velocity_x && !velocity_y) {
700 EndTouchScrollIfNecessary(time, true); 703 EndTouchScrollIfNecessary(time, true);
701 return; 704 return;
702 } 705 }
703 706
704 if (!touch_scroll_in_progress_) { 707 if (!touch_scroll_in_progress_) {
705 // The native side needs a GESTURE_SCROLL_BEGIN before GESTURE_FLING_START 708 // The native side needs a GESTURE_SCROLL_BEGIN before GESTURE_FLING_START
706 // to send the fling to the correct target. Send if it has not sent. 709 // to send the fling to the correct target. Send if it has not sent.
707 // The distance traveled in one second is a reasonable scroll start hint. 710 // The distance traveled in one second is a reasonable scroll start hint.
708 GestureEventParams::Data scroll_data; 711 GestureEventData::Details scroll_details;
709 scroll_data.scroll_begin.delta_x_hint = velocity_x; 712 scroll_details.scroll_begin.delta_x_hint = velocity_x;
710 scroll_data.scroll_begin.delta_y_hint = velocity_y; 713 scroll_details.scroll_begin.delta_y_hint = velocity_y;
711 Send(CreateGesture(GESTURE_SCROLL_BEGIN, time, x, y, scroll_data)); 714 Send(CreateGesture(GESTURE_SCROLL_BEGIN, time, x, y, scroll_details));
712 } 715 }
713 EndTouchScrollIfNecessary(time, false); 716 EndTouchScrollIfNecessary(time, false);
714 717
715 GestureEventParams::Data fling_data; 718 GestureEventData::Details fling_details;
716 fling_data.fling_start.velocity_x = velocity_x; 719 fling_details.fling_start.velocity_x = velocity_x;
717 fling_data.fling_start.velocity_y = velocity_y; 720 fling_details.fling_start.velocity_y = velocity_y;
718 Send(CreateGesture(GESTURE_FLING_START, time, x, y, fling_data)); 721 Send(CreateGesture(GESTURE_FLING_START, time, x, y, fling_details));
719 } 722 }
720 723
721 void GestureProvider::Send(const GestureEventParams& gesture) { 724 void GestureProvider::Send(const GestureEventData& gesture) {
722 DCHECK(!gesture.time.is_null()); 725 DCHECK(!gesture.time.is_null());
723 // The only valid events that should be sent without an active touch sequence 726 // The only valid events that should be sent without an active touch sequence
724 // are SHOW_PRESS and TAP_CONFIRMED, potentially triggered by the double-tap 727 // are SHOW_PRESS and TAP, potentially triggered by the double-tap
725 // delay timing out. 728 // delay timing out.
726 DCHECK(current_down_event_ || gesture.type == GESTURE_SINGLE_TAP_CONFIRMED || 729 DCHECK(current_down_event_ || gesture.type == GESTURE_TAP ||
727 gesture.type == GESTURE_SHOW_PRESS); 730 gesture.type == GESTURE_SHOW_PRESS);
728 731
729 switch (gesture.type) { 732 switch (gesture.type) {
730 case GESTURE_TAP_DOWN: 733 case GESTURE_TAP_DOWN:
731 needs_tap_ending_event_ = true; 734 needs_tap_ending_event_ = true;
732 break; 735 break;
733 case GESTURE_SINGLE_TAP_UNCONFIRMED: 736 case GESTURE_TAP_UNCONFIRMED:
734 needs_show_press_event_ = false; 737 needs_show_press_event_ = false;
735 break; 738 break;
736 case GESTURE_SINGLE_TAP_CONFIRMED: 739 case GESTURE_TAP:
737 if (needs_show_press_event_) 740 if (needs_show_press_event_)
738 Send(CreateGesture( 741 Send(CreateGesture(
739 GESTURE_SHOW_PRESS, gesture.time, gesture.x, gesture.y)); 742 GESTURE_SHOW_PRESS, gesture.time, gesture.x, gesture.y));
740 needs_tap_ending_event_ = false; 743 needs_tap_ending_event_ = false;
741 break; 744 break;
742 case GESTURE_DOUBLE_TAP: 745 case GESTURE_DOUBLE_TAP:
743 needs_tap_ending_event_ = false; 746 needs_tap_ending_event_ = false;
744 break; 747 break;
745 case GESTURE_TAP_CANCEL: 748 case GESTURE_TAP_CANCEL:
746 if (!needs_tap_ending_event_) 749 if (!needs_tap_ending_event_)
747 return; 750 return;
748 needs_tap_ending_event_ = false; 751 needs_tap_ending_event_ = false;
749 break; 752 break;
750 case GESTURE_SHOW_PRESS: 753 case GESTURE_SHOW_PRESS:
751 needs_show_press_event_ = false; 754 needs_show_press_event_ = false;
752 break; 755 break;
756 case GESTURE_LONG_PRESS:
757 DCHECK(!scale_gesture_listener_->IsScaleGestureDetectionInProgress());
758 current_longpress_time_ = gesture.time;
759 break;
753 case GESTURE_LONG_TAP: 760 case GESTURE_LONG_TAP:
754 needs_tap_ending_event_ = false; 761 needs_tap_ending_event_ = false;
755 current_longpress_time_ = base::TimeTicks(); 762 current_longpress_time_ = base::TimeTicks();
756 break; 763 break;
757 case GESTURE_LONG_PRESS:
758 DCHECK(!scale_gesture_listener_->IsScaleGestureDetectionInProgress());
759 current_longpress_time_ = gesture.time;
760 break;
761 case GESTURE_PINCH_UPDATE:
762 pinch_in_progress_ = true;
763 break;
764 case GESTURE_PINCH_END:
765 pinch_in_progress_ = false;
766 break;
767 case GESTURE_SCROLL_BEGIN: 764 case GESTURE_SCROLL_BEGIN:
768 touch_scroll_in_progress_ = true; 765 touch_scroll_in_progress_ = true;
769 SendTapCancelIfNecessary(*current_down_event_); 766 SendTapCancelIfNecessary(*current_down_event_);
770 break; 767 break;
771 case GESTURE_SCROLL_END: 768 case GESTURE_SCROLL_END:
772 touch_scroll_in_progress_ = false; 769 touch_scroll_in_progress_ = false;
773 break; 770 break;
771 case GESTURE_PINCH_BEGIN:
772 pinch_in_progress_ = true;
773 break;
774 case GESTURE_PINCH_END:
775 pinch_in_progress_ = false;
776 break;
774 default: 777 default:
775 break; 778 break;
776 }; 779 };
777 780
778 client_->OnGestureEvent(gesture); 781 client_->OnGestureEvent(gesture);
779 } 782 }
780 783
781 void GestureProvider::SendTapCancelIfNecessary(const MotionEvent& event) { 784 void GestureProvider::SendTapCancelIfNecessary(const MotionEvent& event) {
782 if (!needs_tap_ending_event_) 785 if (!needs_tap_ending_event_)
783 return; 786 return;
784 current_longpress_time_ = base::TimeTicks(); 787 current_longpress_time_ = base::TimeTicks();
785 Send(CreateGesture(GESTURE_TAP_CANCEL, event)); 788 Send(CreateGesture(GESTURE_TAP_CANCEL, event));
786 } 789 }
787 790
788 bool GestureProvider::SendLongTapIfNecessary(const MotionEvent& event) { 791 bool GestureProvider::SendLongTapIfNecessary(const MotionEvent& event) {
789 if (event.GetAction() == MotionEvent::ACTION_UP && 792 if (event.GetAction() == MotionEvent::ACTION_UP &&
790 !current_longpress_time_.is_null() && 793 !current_longpress_time_.is_null() &&
791 !scale_gesture_listener_->IsScaleGestureDetectionInProgress()) { 794 !scale_gesture_listener_->IsScaleGestureDetectionInProgress()) {
792 SendTapCancelIfNecessary(event); 795 SendTapCancelIfNecessary(event);
793 GestureEventParams::Data long_tap_data; 796 GestureEventData::Details long_tap_details;
794 long_tap_data.long_press.width = event.GetTouchMajor(); 797 long_tap_details.long_press.width = event.GetTouchMajor();
795 long_tap_data.long_press.height = long_tap_data.long_press.width; 798 long_tap_details.long_press.height = long_tap_details.long_press.width;
796 Send(CreateGesture(GESTURE_LONG_TAP, event, long_tap_data)); 799 Send(CreateGesture(GESTURE_LONG_TAP, event, long_tap_details));
797 return true; 800 return true;
798 } 801 }
799 return false; 802 return false;
800 } 803 }
801 804
802 void GestureProvider::EndTouchScrollIfNecessary(base::TimeTicks time, 805 void GestureProvider::EndTouchScrollIfNecessary(base::TimeTicks time,
803 bool send_scroll_end_event) { 806 bool send_scroll_end_event) {
804 if (!touch_scroll_in_progress_) 807 if (!touch_scroll_in_progress_)
805 return; 808 return;
806 touch_scroll_in_progress_ = false; 809 touch_scroll_in_progress_ = false;
807 if (send_scroll_end_event) 810 if (send_scroll_end_event)
808 Send(CreateGesture(GESTURE_SCROLL_END, time, 0, 0)); 811 Send(CreateGesture(GESTURE_SCROLL_END, time, 0, 0));
809 } 812 }
810 813
811 } // namespace ui 814 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/gesture_detection/gesture_provider.h ('k') | ui/events/gesture_detection/gesture_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698