summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-27 00:02:01 +0000
committerjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-27 00:02:01 +0000
commitd4075054ae6842d9866a9775dd939033506a3712 (patch)
treefcc0323e7553ebc7a9aaa23e45b59deaaaa9d867
parent222c682b384ff5c85c5e5cf7c82ab3ab9419ba91 (diff)
downloadchromium_src-d4075054ae6842d9866a9775dd939033506a3712.zip
chromium_src-d4075054ae6842d9866a9775dd939033506a3712.tar.gz
chromium_src-d4075054ae6842d9866a9775dd939033506a3712.tar.bz2
Merge 252282 "[Android] More eager gesture recognition hardening"
> [Android] More eager gesture recognition hardening > > Handle several corner cases of touch event handling, particularly if an > exception occurs between |onTouchEventHandlingBegin| and > |onTouchEventHandlingEnd| in ContentViewGestureHandler. > > BUG=344674,341495 > NOTRY=true > > Review URL: https://codereview.chromium.org/170673005 TBR=jdduke@chromium.org Review URL: https://codereview.chromium.org/177003024 git-svn-id: svn://svn.chromium.org/chrome/branches/1847/src@253644 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/android/content_view_core_impl.cc10
-rw-r--r--content/browser/renderer_host/input/gesture_event_packet.cc15
-rw-r--r--content/browser/renderer_host/input/gesture_event_packet.h2
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java55
4 files changed, 52 insertions, 30 deletions
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 795caa2..2f120b4 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -1034,7 +1034,12 @@ void ContentViewCoreImpl::OnTouchEventHandlingBegin(JNIEnv* env,
}
void ContentViewCoreImpl::OnTouchEventHandlingEnd(JNIEnv* env, jobject obj) {
- DCHECK(handling_touch_event_);
+ if (!handling_touch_event_)
+ return;
+
+ GestureEventPacket gesture_packet;
+ std::swap(gesture_packet, pending_gesture_packet_);
+
handling_touch_event_ = false;
RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
@@ -1043,8 +1048,7 @@ void ContentViewCoreImpl::OnTouchEventHandlingEnd(JNIEnv* env, jobject obj) {
// Note: Order is important here, as the touch may be ack'ed synchronously
TouchDispositionGestureFilter::PacketResult result =
- touch_disposition_gesture_filter_.OnGestureEventPacket(
- pending_gesture_packet_);
+ touch_disposition_gesture_filter_.OnGestureEventPacket(gesture_packet);
if (result != TouchDispositionGestureFilter::SUCCESS) {
NOTREACHED() << "Invalid touch gesture sequence detected.";
return;
diff --git a/content/browser/renderer_host/input/gesture_event_packet.cc b/content/browser/renderer_host/input/gesture_event_packet.cc
index 10b12e9..542e719 100644
--- a/content/browser/renderer_host/input/gesture_event_packet.cc
+++ b/content/browser/renderer_host/input/gesture_event_packet.cc
@@ -52,9 +52,24 @@ GestureEventPacket::GestureEventPacket(GestureSource source)
DCHECK_NE(gesture_source_, UNDEFINED);
}
+GestureEventPacket::GestureEventPacket(const GestureEventPacket& other)
+ : gesture_count_(other.gesture_count_),
+ gesture_source_(other.gesture_source_) {
+ std::copy(other.gestures_, other.gestures_ + other.gesture_count_, gestures_);
+}
+
GestureEventPacket::~GestureEventPacket() {}
+GestureEventPacket& GestureEventPacket::operator=(
+ const GestureEventPacket& other) {
+ gesture_count_ = other.gesture_count_;
+ gesture_source_ = other.gesture_source_;
+ std::copy(other.gestures_, other.gestures_ + other.gesture_count_, gestures_);
+ return *this;
+}
+
void GestureEventPacket::Push(const blink::WebGestureEvent& gesture) {
+ DCHECK(WebInputEvent::isGestureEventType(gesture.type));
CHECK_LT(gesture_count_, static_cast<size_t>(kMaxGesturesPerTouch));
gestures_[gesture_count_++] = gesture;
}
diff --git a/content/browser/renderer_host/input/gesture_event_packet.h b/content/browser/renderer_host/input/gesture_event_packet.h
index b277948..bebe099 100644
--- a/content/browser/renderer_host/input/gesture_event_packet.h
+++ b/content/browser/renderer_host/input/gesture_event_packet.h
@@ -26,7 +26,9 @@ class CONTENT_EXPORT GestureEventPacket {
};
GestureEventPacket();
+ GestureEventPacket(const GestureEventPacket& other);
~GestureEventPacket();
+ GestureEventPacket& operator=(const GestureEventPacket& other);
// Factory methods for creating a packet from a particular event.
static GestureEventPacket FromTouch(const blink::WebTouchEvent& event);
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
index 7983a77..92573f4 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java
@@ -781,41 +781,42 @@ class ContentViewGestureHandler {
private boolean processTouchEvent(MotionEvent event) {
if (!canHandle(event)) return false;
- mMotionEventDelegate.onTouchEventHandlingBegin(event);
-
- final boolean wasTouchScrolling = mTouchScrolling;
-
- mSnapScrollController.setSnapScrollingMode(event, isScaleGestureDetectionInProgress());
+ try {
+ mMotionEventDelegate.onTouchEventHandlingBegin(event);
- if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
- endDoubleTapDragIfNecessary(event);
- } else if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mGestureDetector.setIsLongpressEnabled(true);
- mCurrentDownEvent = MotionEvent.obtain(event);
- }
+ final boolean wasTouchScrolling = mTouchScrolling;
- boolean handled = mGestureDetector.onTouchEvent(event);
- handled |= processTouchEventForMultiTouch(event);
+ mSnapScrollController.setSnapScrollingMode(event, isScaleGestureDetectionInProgress());
- if (event.getAction() == MotionEvent.ACTION_UP
- || event.getAction() == MotionEvent.ACTION_CANCEL) {
- if (event.getAction() == MotionEvent.ACTION_CANCEL) {
- sendTapCancelIfNecessary(event);
+ if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
+ endDoubleTapDragIfNecessary(event);
+ } else if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ mGestureDetector.setIsLongpressEnabled(true);
+ mCurrentDownEvent = MotionEvent.obtain(event);
}
- // "Last finger raised" could be an end to movement, but it should
- // only terminate scrolling if the event did not cause a fling.
- if (wasTouchScrolling && !handled) {
- endTouchScrollIfNecessary(event.getEventTime(), true);
- }
+ boolean handled = mGestureDetector.onTouchEvent(event);
+ handled |= processTouchEventForMultiTouch(event);
- if (mCurrentDownEvent != null) recycleEvent(mCurrentDownEvent);
- mCurrentDownEvent = null;
- }
+ if (event.getAction() == MotionEvent.ACTION_UP
+ || event.getAction() == MotionEvent.ACTION_CANCEL) {
+ if (event.getAction() == MotionEvent.ACTION_CANCEL) {
+ sendTapCancelIfNecessary(event);
+ }
- mMotionEventDelegate.onTouchEventHandlingEnd();
+ // "Last finger raised" could be an end to movement, but it should
+ // only terminate scrolling if the event did not cause a fling.
+ if (wasTouchScrolling && !handled) {
+ endTouchScrollIfNecessary(event.getEventTime(), true);
+ }
- return handled;
+ if (mCurrentDownEvent != null) recycleEvent(mCurrentDownEvent);
+ mCurrentDownEvent = null;
+ }
+ return handled;
+ } finally {
+ mMotionEventDelegate.onTouchEventHandlingEnd();
+ }
}
private boolean isScaleGestureDetectionInProgress() {