diff options
author | jdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-27 00:02:01 +0000 |
---|---|---|
committer | jdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-27 00:02:01 +0000 |
commit | d4075054ae6842d9866a9775dd939033506a3712 (patch) | |
tree | fcc0323e7553ebc7a9aaa23e45b59deaaaa9d867 | |
parent | 222c682b384ff5c85c5e5cf7c82ab3ab9419ba91 (diff) | |
download | chromium_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
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() { |