Bug 1158617 - Don't dispatch a long-press after multiple fingers are down, even if their prevent-default status hasn't been resolved yet. r=bnicholson, a=lizzard
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 30 Apr 2015 14:45:50 -0400
changeset 267327 780f734ea28e7e2773d5abb466d4590520bd8270
parent 267326 d76300e69af3a4665fa7e4c6be27fd1b20cd143e
child 267328 c69d844f32da7b57f84b884da8e98ce85862dd17
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbnicholson, lizzard
bugs1158617
milestone39.0a2
Bug 1158617 - Don't dispatch a long-press after multiple fingers are down, even if their prevent-default status hasn't been resolved yet. r=bnicholson, a=lizzard
mobile/android/base/gfx/JavaPanZoomController.java
--- a/mobile/android/base/gfx/JavaPanZoomController.java
+++ b/mobile/android/base/gfx/JavaPanZoomController.java
@@ -122,16 +122,18 @@ class JavaPanZoomController
     /* Whether or not to wait for a double-tap before dispatching a single-tap */
     private boolean mWaitForDoubleTap;
     /* Used to change the scrollY direction */
     private boolean mNegateWheelScrollY;
     /* Whether the current event has been default-prevented. */
     private boolean mDefaultPrevented;
     /* Whether longpress events are enabled, or suppressed by robocop tests. */
     private boolean isLongpressEnabled;
+    /* Whether longpress detection should be ignored */
+    private boolean mIgnoreLongPress;
 
     // Handler to be notified when overscroll occurs
     private Overscroll mOverscroll;
 
     public JavaPanZoomController(PanZoomTarget target, View view, EventDispatcher eventDispatcher) {
         mTarget = target;
         mSubscroller = new SubdocumentScrollHelper(eventDispatcher);
         mX = new AxisX(mSubscroller);
@@ -388,21 +390,32 @@ class JavaPanZoomController
             break;
         }
     }
 
     /** This function must be called on the UI thread. */
     public void startingNewEventBlock(MotionEvent event, boolean waitingForTouchListeners) {
         checkMainThread();
         mSubscroller.cancel();
-        if (waitingForTouchListeners && (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
-            // this is the first touch point going down, so we enter the pending state
-            // setting the state will kill any animations in progress, possibly leaving
-            // the page in overscroll
-            setState(PanZoomState.WAITING_LISTENERS);
+        mIgnoreLongPress = false;
+        if (waitingForTouchListeners) {
+            if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
+                // this is the first touch point going down, so we enter the pending state
+                // setting the state will kill any animations in progress, possibly leaving
+                // the page in overscroll
+                setState(PanZoomState.WAITING_LISTENERS);
+            } else if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
+                // this is a second (or more) touch point going down, and we're waiting for
+                // the content listeners to respond. while we're waiting though we might end
+                // up triggering a long-press from the first touch point, which would be bad
+                // because from the user's point of view they are already in a multi-touch
+                // gesture. to prevent this from happening we set a flag that discards long-press
+                // gesture detections.
+                mIgnoreLongPress = true;
+            }
         }
     }
 
     /** This must be called on the UI thread. */
     @Override
     public void pageRectUpdated() {
         if (mState == PanZoomState.NOTHING) {
             synchronized (mTarget.getLock()) {
@@ -1352,17 +1365,17 @@ class JavaPanZoomController
      * longpress events that are spuriously created on slower test devices.
      */
     public void setIsLongpressEnabled(boolean isLongpressEnabled) {
         this.isLongpressEnabled = isLongpressEnabled;
     }
 
     @Override
     public void onLongPress(MotionEvent motionEvent) {
-        if (!isLongpressEnabled) {
+        if (!isLongpressEnabled || mIgnoreLongPress) {
             return;
         }
 
         GeckoEvent e = GeckoEvent.createLongPressEvent(motionEvent);
         GeckoAppShell.sendEventToGecko(e);
     }
 
     @Override