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

Unified Diff: content/browser/renderer_host/input/touch_disposition_gesture_filter.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, 10 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/input/touch_disposition_gesture_filter.cc
diff --git a/content/browser/renderer_host/input/touch_disposition_gesture_filter.cc b/content/browser/renderer_host/input/touch_disposition_gesture_filter.cc
deleted file mode 100644
index 7ae2efa34ab2d610848fe440f6eabf679977aca7..0000000000000000000000000000000000000000
--- a/content/browser/renderer_host/input/touch_disposition_gesture_filter.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-// 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/touch_disposition_gesture_filter.h"
-
-#include "base/auto_reset.h"
-#include "base/bind.h"
-#include "base/logging.h"
-
-using blink::WebGestureEvent;
-using blink::WebInputEvent;
-using blink::WebTouchEvent;
-using blink::WebTouchPoint;
-
-namespace content {
-namespace {
-
-WebGestureEvent CreateGesture(WebInputEvent::Type type) {
- DCHECK(WebInputEvent::isGestureEventType(type));
- WebGestureEvent event;
- event.type = type;
- event.sourceDevice = WebGestureEvent::Touchscreen;
- return event;
-}
-
-enum RequiredTouches {
- RT_NONE = 0,
- RT_START = 1 << 0,
- RT_CURRENT = 1 << 1,
-};
-
-struct DispositionHandlingInfo {
- // A bitwise-OR of |RequiredTouches|.
- int required_touches;
- blink::WebInputEvent::Type antecedent_event_type;
-
- DispositionHandlingInfo(int required_touches)
- : required_touches(required_touches) {}
-
- DispositionHandlingInfo(int required_touches,
- blink::WebInputEvent::Type antecedent_event_type)
- : required_touches(required_touches),
- antecedent_event_type(antecedent_event_type) {}
-};
-
-DispositionHandlingInfo Info(int required_touches) {
- return DispositionHandlingInfo(required_touches);
-}
-
-DispositionHandlingInfo Info(int required_touches,
- blink::WebInputEvent::Type antecedent_event_type) {
- return DispositionHandlingInfo(required_touches, antecedent_event_type);
-}
-
-// This approach to disposition handling is described at http://goo.gl/5G8PWJ.
-DispositionHandlingInfo GetDispositionHandlingInfo(
- blink::WebInputEvent::Type type) {
- switch (type) {
- case WebInputEvent::GestureTapDown:
- return Info(RT_START);
- case WebInputEvent::GestureTapCancel:
- return Info(RT_START);
- case WebInputEvent::GestureShowPress:
- return Info(RT_START);
- case WebInputEvent::GestureLongPress:
- return Info(RT_START);
- case WebInputEvent::GestureLongTap:
- return Info(RT_START | RT_CURRENT);
- case WebInputEvent::GestureTap:
- return Info(RT_START | RT_CURRENT, WebInputEvent::GestureTapUnconfirmed);
- case WebInputEvent::GestureTwoFingerTap:
- return Info(RT_START | RT_CURRENT);
- case WebInputEvent::GestureTapUnconfirmed:
- return Info(RT_START | RT_CURRENT);
- case WebInputEvent::GestureDoubleTap:
- return Info(RT_START | RT_CURRENT, WebInputEvent::GestureTapUnconfirmed);
- case WebInputEvent::GestureScrollBegin:
- return Info(RT_START | RT_CURRENT);
- case WebInputEvent::GestureScrollUpdate:
- return Info(RT_CURRENT, WebInputEvent::GestureScrollBegin);
- case WebInputEvent::GestureScrollEnd:
- return Info(RT_NONE, WebInputEvent::GestureScrollBegin);
- case WebInputEvent::GestureFlingStart:
- return Info(RT_NONE, WebInputEvent::GestureScrollBegin);
- case WebInputEvent::GestureFlingCancel:
- return Info(RT_NONE, WebInputEvent::GestureFlingStart);
- case WebInputEvent::GesturePinchBegin:
- return Info(RT_START, WebInputEvent::GestureScrollBegin);
- case WebInputEvent::GesturePinchUpdate:
- return Info(RT_CURRENT, WebInputEvent::GesturePinchBegin);
- case WebInputEvent::GesturePinchEnd:
- return Info(RT_NONE, WebInputEvent::GesturePinchBegin);
- default:
- NOTREACHED();
- return Info(RT_NONE);
- }
-}
-
-} // namespace
-
-// TouchDispositionGestureFilter
-
-TouchDispositionGestureFilter::TouchDispositionGestureFilter(
- TouchDispositionGestureFilterClient* client)
- : client_(client),
- needs_tap_ending_event_(false),
- needs_fling_ending_event_(false) {
- DCHECK(client_);
-}
-
-TouchDispositionGestureFilter::~TouchDispositionGestureFilter() {}
-
-TouchDispositionGestureFilter::PacketResult
-TouchDispositionGestureFilter::OnGestureEventPacket(
- const GestureEventPacket& packet) {
- if (packet.gesture_source() == GestureEventPacket::UNDEFINED ||
- packet.gesture_source() == GestureEventPacket::INVALID)
- return INVALID_PACKET_TYPE;
-
- if (packet.gesture_source() == GestureEventPacket::TOUCH_SEQUENCE_START)
- sequences_.push(GestureSequence());
-
- if (IsEmpty())
- return INVALID_PACKET_ORDER;
-
- if (packet.gesture_source() == GestureEventPacket::TOUCH_TIMEOUT &&
- Tail().IsEmpty()) {
- // Handle the timeout packet immediately if the packet preceding the timeout
- // has already been dispatched.
- FilterAndSendPacket(
- packet, Tail().state(), INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- return SUCCESS;
- }
-
- Tail().Push(packet);
- return SUCCESS;
-}
-
-void TouchDispositionGestureFilter::OnTouchEventAck(
- InputEventAckState ack_state) {
- // Spurious touch acks from the renderer should not trigger a crash.
- if (IsEmpty() || (Head().IsEmpty() && sequences_.size() == 1))
- return;
-
- if (Head().IsEmpty()) {
- CancelTapIfNecessary();
- CancelFlingIfNecessary();
- last_event_of_type_dropped_.clear();
- sequences_.pop();
- }
-
- GestureSequence& sequence = Head();
-
- // Dispatch the packet corresponding to the ack'ed touch, as well as any
- // additional timeout-based packets queued before the ack was received.
- bool touch_packet_for_current_ack_handled = false;
- while (!sequence.IsEmpty()) {
- const GestureEventPacket& packet = sequence.Front();
- DCHECK_NE(packet.gesture_source(), GestureEventPacket::UNDEFINED);
- DCHECK_NE(packet.gesture_source(), GestureEventPacket::INVALID);
-
- if (packet.gesture_source() != GestureEventPacket::TOUCH_TIMEOUT) {
- // We should handle at most one non-timeout based packet.
- if (touch_packet_for_current_ack_handled)
- break;
- sequence.UpdateState(packet.gesture_source(), ack_state);
- touch_packet_for_current_ack_handled = true;
- }
- FilterAndSendPacket(packet, sequence.state(), ack_state);
- sequence.Pop();
- }
- DCHECK(touch_packet_for_current_ack_handled);
-}
-
-bool TouchDispositionGestureFilter::IsEmpty() const {
- return sequences_.empty();
-}
-
-void TouchDispositionGestureFilter::FilterAndSendPacket(
- const GestureEventPacket& packet,
- const GestureSequence::GestureHandlingState& sequence_state,
- InputEventAckState ack_state) {
- for (size_t i = 0; i < packet.gesture_count(); ++i) {
- const blink::WebGestureEvent& gesture = packet.gesture(i);
- if (IsGesturePrevented(gesture.type, ack_state, sequence_state)) {
- last_event_of_type_dropped_.insert(gesture.type);
- CancelTapIfNecessary();
- continue;
- }
- last_event_of_type_dropped_.erase(gesture.type);
- SendGesture(gesture);
- }
-}
-
-void TouchDispositionGestureFilter::SendGesture(const WebGestureEvent& event) {
- switch (event.type) {
- case WebInputEvent::GestureLongTap:
- CancelTapIfNecessary();
- CancelFlingIfNecessary();
- break;
- case WebInputEvent::GestureTapDown:
- DCHECK(!needs_tap_ending_event_);
- needs_tap_ending_event_ = true;
- break;
- case WebInputEvent::GestureTapCancel:
- case WebInputEvent::GestureTap:
- case WebInputEvent::GestureTapUnconfirmed:
- case WebInputEvent::GestureDoubleTap:
- needs_tap_ending_event_ = false;
- break;
- case WebInputEvent::GestureScrollBegin:
- CancelTapIfNecessary();
- CancelFlingIfNecessary();
- break;
- case WebInputEvent::GestureFlingStart:
- CancelFlingIfNecessary();
- needs_fling_ending_event_ = true;
- break;
- case WebInputEvent::GestureFlingCancel:
- needs_fling_ending_event_ = false;
- break;
- default:
- break;
- }
- client_->ForwardGestureEvent(event);
-}
-
-void TouchDispositionGestureFilter::CancelTapIfNecessary() {
- if (!needs_tap_ending_event_)
- return;
-
- SendGesture(CreateGesture(WebInputEvent::GestureTapCancel));
- DCHECK(!needs_tap_ending_event_);
-}
-
-void TouchDispositionGestureFilter::CancelFlingIfNecessary() {
- if (!needs_fling_ending_event_)
- return;
-
- SendGesture(CreateGesture(WebInputEvent::GestureFlingCancel));
- DCHECK(!needs_fling_ending_event_);
-}
-
-// TouchDispositionGestureFilter::GestureSequence
-
-TouchDispositionGestureFilter::GestureSequence::GestureHandlingState::
- GestureHandlingState()
- : seen_ack(false),
- start_consumed(false),
- no_consumer(false) {}
-
-TouchDispositionGestureFilter::GestureSequence&
-TouchDispositionGestureFilter::Head() {
- DCHECK(!sequences_.empty());
- return sequences_.front();
-}
-
-TouchDispositionGestureFilter::GestureSequence&
-TouchDispositionGestureFilter::Tail() {
- DCHECK(!sequences_.empty());
- return sequences_.back();
-}
-
-TouchDispositionGestureFilter::GestureSequence::GestureSequence() {}
-
-TouchDispositionGestureFilter::GestureSequence::~GestureSequence() {}
-
-void TouchDispositionGestureFilter::GestureSequence::Push(
- const GestureEventPacket& packet) {
- packets_.push(packet);
-}
-
-void TouchDispositionGestureFilter::GestureSequence::Pop() {
- DCHECK(!IsEmpty());
- packets_.pop();
-}
-
-const GestureEventPacket&
-TouchDispositionGestureFilter::GestureSequence::Front() const {
- DCHECK(!IsEmpty());
- return packets_.front();
-}
-
-void TouchDispositionGestureFilter::GestureSequence::UpdateState(
- GestureEventPacket::GestureSource gesture_source,
- InputEventAckState ack_state) {
- DCHECK_NE(INPUT_EVENT_ACK_STATE_UNKNOWN, ack_state);
- // Permanent states will not be affected by subsequent ack's.
- if (state_.no_consumer || state_.start_consumed)
- return;
-
- // |NO_CONSUMER| should only be effective when the *first* touch is ack'ed.
- if (!state_.seen_ack &&
- ack_state == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
- state_.no_consumer = true;
- } else if (ack_state == INPUT_EVENT_ACK_STATE_CONSUMED) {
- if (gesture_source == GestureEventPacket::TOUCH_SEQUENCE_START ||
- gesture_source == GestureEventPacket::TOUCH_START) {
- state_.start_consumed = true;
- }
- }
- state_.seen_ack = true;
-}
-
-bool TouchDispositionGestureFilter::IsGesturePrevented(
- WebInputEvent::Type gesture_type,
- InputEventAckState current,
- const GestureSequence::GestureHandlingState& state) const {
-
- if (state.no_consumer)
- return false;
-
- DispositionHandlingInfo disposition_handling_info =
- GetDispositionHandlingInfo(gesture_type);
-
- int required_touches = disposition_handling_info.required_touches;
- bool current_consumed = current == INPUT_EVENT_ACK_STATE_CONSUMED;
- if ((required_touches & RT_START && state.start_consumed) ||
- (required_touches & RT_CURRENT && current_consumed) ||
- (last_event_of_type_dropped_.count(
- disposition_handling_info.antecedent_event_type) > 0)) {
- return true;
- }
- return false;
-}
-
-bool TouchDispositionGestureFilter::GestureSequence::IsEmpty() const {
- return packets_.empty();
-}
-
-} // namespace content

Powered by Google App Engine
This is Rietveld 408576698