Index: content/browser/renderer_host/input/content_gesture_provider.cc |
diff --git a/content/browser/renderer_host/input/content_gesture_provider.cc b/content/browser/renderer_host/input/content_gesture_provider.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4cfc7b6d1d67d3f18728e45915c0281841d003b9 |
--- /dev/null |
+++ b/content/browser/renderer_host/input/content_gesture_provider.cc |
@@ -0,0 +1,215 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/renderer_host/input/content_gesture_provider.h" |
+ |
+#include "base/auto_reset.h" |
+#include "base/command_line.h" |
+#include "base/logging.h" |
+#include "content/public/common/content_switches.h" |
+#include "third_party/WebKit/public/web/WebInputEvent.h" |
+#include "ui/events/gesture_detection/gesture_config_helper.h" |
+#include "ui/events/gesture_detection/motion_event.h" |
+ |
+using blink::WebGestureEvent; |
+using blink::WebInputEvent; |
+ |
+namespace content { |
+namespace { |
+ |
+WebGestureEvent CreateGesture(const ui::GestureEventData& data, |
+ float scale) { |
+ WebGestureEvent gesture; |
+ gesture.x = data.x * scale; |
+ gesture.y = data.y * scale; |
+ gesture.timeStampSeconds = (data.time - base::TimeTicks()).InSecondsF(); |
+ gesture.sourceDevice = WebGestureEvent::Touchscreen; |
+ |
+ switch (data.type) { |
+ case ui::GESTURE_SHOW_PRESS: |
+ gesture.type = WebInputEvent::GestureShowPress; |
+ gesture.data.showPress.width = data.details.show_press.width * scale; |
+ gesture.data.showPress.width = data.details.show_press.width * scale; |
+ break; |
+ case ui::GESTURE_DOUBLE_TAP: |
+ gesture.type = WebInputEvent::GestureDoubleTap; |
+ break; |
+ case ui::GESTURE_TAP: |
+ gesture.type = WebInputEvent::GestureTap; |
+ gesture.data.tap.tapCount = data.details.tap.tap_count; |
+ gesture.data.tap.width = data.details.tap.width * scale; |
+ gesture.data.tap.height = data.details.tap.height * scale; |
+ break; |
+ case ui::GESTURE_TAP_UNCONFIRMED: |
+ gesture.type = WebInputEvent::GestureTapUnconfirmed; |
+ gesture.data.tap.tapCount = data.details.tap.tap_count; |
+ gesture.data.tap.width = data.details.tap.width * scale; |
+ gesture.data.tap.height = data.details.tap.height * scale; |
+ break; |
+ case ui::GESTURE_LONG_PRESS: |
+ gesture.type = WebInputEvent::GestureLongPress; |
+ gesture.data.longPress.width = data.details.long_press.width * scale; |
+ gesture.data.longPress.height = data.details.long_press.height * scale; |
+ break; |
+ case ui::GESTURE_LONG_TAP: |
+ gesture.type = WebInputEvent::GestureLongTap; |
+ gesture.data.longPress.width = data.details.long_press.width * scale; |
+ gesture.data.longPress.height = data.details.long_press.height * scale; |
+ break; |
+ case ui::GESTURE_SCROLL_BEGIN: |
+ gesture.type = WebInputEvent::GestureScrollBegin; |
+ gesture.data.scrollBegin.deltaXHint = |
+ data.details.scroll_begin.delta_x_hint * scale; |
+ gesture.data.scrollBegin.deltaYHint = |
+ data.details.scroll_begin.delta_y_hint * scale; |
+ break; |
+ case ui::GESTURE_SCROLL_UPDATE: |
+ gesture.type = WebInputEvent::GestureScrollUpdate; |
+ gesture.data.scrollUpdate.deltaX = |
+ data.details.scroll_update.delta_x * scale; |
+ gesture.data.scrollUpdate.deltaY = |
+ data.details.scroll_update.delta_y * scale; |
+ gesture.data.scrollUpdate.velocityX = |
+ data.details.scroll_update.velocity_x * scale; |
+ gesture.data.scrollUpdate.velocityY = |
+ data.details.scroll_update.velocity_y * scale; |
+ break; |
+ case ui::GESTURE_SCROLL_END: |
+ gesture.type = WebInputEvent::GestureScrollEnd; |
+ break; |
+ case ui::GESTURE_FLING_START: |
+ gesture.type = WebInputEvent::GestureFlingStart; |
+ gesture.data.flingStart.velocityX = |
+ data.details.fling_start.velocity_x * scale; |
+ gesture.data.flingStart.velocityY = |
+ data.details.fling_start.velocity_y * scale; |
+ break; |
+ case ui::GESTURE_FLING_CANCEL: |
+ gesture.type = WebInputEvent::GestureFlingCancel; |
+ break; |
+ case ui::GESTURE_PINCH_BEGIN: |
+ gesture.type = WebInputEvent::GesturePinchBegin; |
+ break; |
+ case ui::GESTURE_PINCH_UPDATE: |
+ gesture.type = WebInputEvent::GesturePinchUpdate; |
+ gesture.data.pinchUpdate.scale = data.details.pinch_update.scale; |
+ break; |
+ case ui::GESTURE_PINCH_END: |
+ gesture.type = WebInputEvent::GesturePinchEnd; |
+ break; |
+ case ui::GESTURE_TAP_CANCEL: |
+ gesture.type = WebInputEvent::GestureTapCancel; |
+ break; |
+ case ui::GESTURE_TAP_DOWN: |
+ gesture.type = WebInputEvent::GestureTapDown; |
+ gesture.data.tapDown.width = data.details.tap_down.width * scale; |
+ gesture.data.tapDown.height = data.details.tap_down.height * scale; |
+ break; |
+ case ui::GESTURE_TYPE_INVALID: |
+ NOTREACHED() << "Invalid ui::GestureEventType provided."; |
+ break; |
+ } |
+ |
+ return gesture; |
+} |
+ |
+ui::TouchDispositionGestureFilter::TouchEventAck |
+ToTouchDispositionGestureFilterAck(InputEventAckState ack_state) { |
tdresser
2014/02/28 15:11:27
Looking at this more closely, I'm not convinced we
jdduke (slow)
2014/02/28 19:44:55
Sounds good. I think as this framework is adopted
|
+ switch (ack_state) { |
+ case INPUT_EVENT_ACK_STATE_CONSUMED: |
+ return ui::TouchDispositionGestureFilter::CONSUMED; |
+ case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: |
+ return ui::TouchDispositionGestureFilter::NOT_CONSUMED; |
+ case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: |
+ return ui::TouchDispositionGestureFilter::NO_CONSUMER_EXISTS; |
+ case INPUT_EVENT_ACK_STATE_IGNORED: |
+ return ui::TouchDispositionGestureFilter::CONSUMED; |
+ case INPUT_EVENT_ACK_STATE_UNKNOWN: |
+ break; |
+ }; |
+ NOTREACHED() << "Invalid ack state: " << ack_state; |
+ return ui::TouchDispositionGestureFilter::NO_CONSUMER_EXISTS; |
+} |
+ |
+ui::GestureProvider::Config GetGestureProviderConfig() { |
+ ui::GestureProvider::Config config = ui::DefaultGestureProviderConfig(); |
+ config.disable_click_delay = |
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableClickDelay); |
+ return config; |
+} |
+ |
+} // namespace |
+ |
+ContentGestureProvider::ContentGestureProvider( |
+ ContentGestureProviderClient* client, |
+ float touch_to_gesture_scale) |
+ : client_(client), |
+ touch_to_gesture_scale_(touch_to_gesture_scale), |
+ gesture_provider_(GetGestureProviderConfig(), this), |
+ gesture_filter_(this), |
+ handling_event_(false) {} |
+ |
+bool ContentGestureProvider::OnTouchEvent(const ui::MotionEvent& event) { |
+ DCHECK(!handling_event_); |
+ base::AutoReset<bool> handling_event(&handling_event_, true); |
+ |
+ pending_gesture_packet_ = ui::GestureEventDataPacket::FromTouch(event); |
+ |
+ if (!gesture_provider_.OnTouchEvent(event)) |
+ return false; |
+ |
+ ui::TouchDispositionGestureFilter::PacketResult result = |
+ gesture_filter_.OnGesturePacket(pending_gesture_packet_); |
+ if (result != ui::TouchDispositionGestureFilter::SUCCESS) { |
+ NOTREACHED() << "Invalid touch gesture sequence detected."; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+void ContentGestureProvider::OnTouchEventAck(InputEventAckState ack_state) { |
+ DCHECK_NE(INPUT_EVENT_ACK_STATE_UNKNOWN, ack_state); |
+ gesture_filter_.OnTouchEventAck( |
+ ToTouchDispositionGestureFilterAck(ack_state)); |
+} |
+ |
+void ContentGestureProvider::ResetGestureDetectors() { |
+ gesture_provider_.ResetGestureDetectors(); |
+} |
+ |
+void ContentGestureProvider::CancelActiveTouchSequence() { |
+ gesture_provider_.CancelActiveTouchSequence(); |
+} |
+ |
+void ContentGestureProvider::SetMultiTouchSupportEnabled(bool enabled) { |
+ gesture_provider_.SetMultiTouchSupportEnabled(enabled); |
+} |
+ |
+void ContentGestureProvider::SetDoubleTapSupportForPlatformEnabled( |
+ bool enabled) { |
+ gesture_provider_.SetDoubleTapSupportForPlatformEnabled(enabled); |
+} |
+ |
+void ContentGestureProvider::SetDoubleTapSupportForPageEnabled(bool enabled) { |
+ gesture_provider_.SetDoubleTapSupportForPageEnabled(enabled); |
+} |
+ |
+void ContentGestureProvider::OnGestureEvent( |
+ const ui::GestureEventData& event) { |
+ if (handling_event_) { |
+ pending_gesture_packet_.Push(event); |
+ return; |
+ } |
+ |
+ gesture_filter_.OnGesturePacket( |
+ ui::GestureEventDataPacket::FromTouchTimeout(event)); |
+} |
+ |
+void ContentGestureProvider::ForwardGestureEvent( |
+ const ui::GestureEventData& event) { |
+ client_->OnGestureEvent(CreateGesture(event, touch_to_gesture_scale_)); |
+} |
+ |
+} // namespace content |