summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authormariakhomenko@chromium.org <mariakhomenko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-15 15:13:11 +0000
committermariakhomenko@chromium.org <mariakhomenko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-15 15:13:11 +0000
commitbd38a51821150cb872b6a3d5e01e25ff15c4f12b (patch)
treeec5afe000d81abdc06f054aec220f3a72d2fa546 /content
parent151905a7ff1135a90bfa191529797bc8e7795d87 (diff)
downloadchromium_src-bd38a51821150cb872b6a3d5e01e25ff15c4f12b.zip
chromium_src-bd38a51821150cb872b6a3d5e01e25ff15c4f12b.tar.gz
chromium_src-bd38a51821150cb872b6a3d5e01e25ff15c4f12b.tar.bz2
Fix stuck state when long press on a button is performed.
This makes sure that when a tap becomes a long press, we keep SHOW_PRESSED_STATE until either it becomes a LONG_TAP (finger is lifted), or SCROLL, or window focus is lost (a context menu has been opened). At which point we will send SHOW_PRESS_CANCEL. BUG=285712 Review URL: https://chromiumcodereview.appspot.com/23444068 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223283 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentView.java6
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java12
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java22
-rw-r--r--content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java47
4 files changed, 81 insertions, 6 deletions
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentView.java b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
index b047909..dd2847cd 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentView.java
@@ -449,6 +449,12 @@ public class ContentView extends FrameLayout
}
@Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ super.onWindowFocusChanged(hasWindowFocus);
+ mContentViewCore.onWindowFocusChanged(hasWindowFocus);
+ }
+
+ @Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return mContentViewCore.onKeyUp(keyCode, event);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index a55cebe..edbc53f 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -63,8 +63,8 @@ import org.chromium.content.browser.accessibility.BrowserAccessibilityManager;
import org.chromium.content.browser.input.AdapterInputConnection;
import org.chromium.content.browser.input.HandleView;
import org.chromium.content.browser.input.ImeAdapter;
-import org.chromium.content.browser.input.InputMethodManagerWrapper;
import org.chromium.content.browser.input.ImeAdapter.AdapterInputConnectionFactory;
+import org.chromium.content.browser.input.InputMethodManagerWrapper;
import org.chromium.content.browser.input.InsertionHandleController;
import org.chromium.content.browser.input.SelectPopupDialog;
import org.chromium.content.browser.input.SelectionHandleController;
@@ -76,7 +76,6 @@ import org.chromium.ui.gfx.DeviceDisplayInfo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -1682,6 +1681,15 @@ import java.util.Map;
mScrolledAndZoomedFocusedEditableNode = false;
}
+ /**
+ * @see View#onWindowFocusChanged(boolean)
+ */
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ if (!hasWindowFocus) {
+ mContentViewGestureHandler.onWindowFocusLost();
+ }
+ }
+
public void onFocusChanged(boolean gainFocus) {
if (!gainFocus) getContentViewClient().onImeStateChangeRequested(false);
if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus);
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 1cb1276..6912bcc 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
@@ -164,6 +164,10 @@ class ContentViewGestureHandler implements LongPressDelegate {
// confirmTouchEvent(), from either itself or onTouchEvent().
private int mTouchEventHandlingStackDepth;
+ // Keeps track of the last long press event, if we end up opening a context menu, we would need
+ // to potentially use the event to send GESUTRE_SHOW_PRESS_CANCEL to remove ::active styling
+ private MotionEvent mLastLongPressEvent;
+
static final int GESTURE_SHOW_PRESSED_STATE = 0;
static final int GESTURE_DOUBLE_TAP = 1;
static final int GESTURE_SINGLE_TAP_UP = 2;
@@ -366,9 +370,9 @@ class ContentViewGestureHandler implements LongPressDelegate {
void setTestDependencies(
LongPressDetector longPressDetector, GestureDetector gestureDetector,
OnGestureListener listener) {
- mLongPressDetector = longPressDetector;
- mGestureDetector = gestureDetector;
- mListener = listener;
+ if (longPressDetector != null) mLongPressDetector = longPressDetector;
+ if (gestureDetector != null) mGestureDetector = gestureDetector;
+ if (listener != null) mListener = listener;
}
private void initGestureDetectors(final Context context) {
@@ -608,7 +612,7 @@ class ContentViewGestureHandler implements LongPressDelegate {
if (!mZoomManager.isScaleGestureDetectionInProgress() &&
(mDoubleTapDragMode == DOUBLE_TAP_DRAG_MODE_NONE ||
isDoubleTapDragDisabled())) {
- sendShowPressCancelIfNecessary(e);
+ mLastLongPressEvent = e;
sendMotionEventAsGesture(GESTURE_LONG_PRESS, e, null);
}
}
@@ -858,6 +862,15 @@ class ContentViewGestureHandler implements LongPressDelegate {
}
}
+ /**
+ * Handle content view losing focus -- ensure that any remaining active state is removed.
+ */
+ void onWindowFocusLost() {
+ if (mLongPressDetector.isInLongPress() && mLastLongPressEvent != null) {
+ sendShowPressCancelIfNecessary(mLastLongPressEvent);
+ }
+ }
+
private MotionEvent obtainActionCancelMotionEvent() {
return MotionEvent.obtain(
SystemClock.uptimeMillis(),
@@ -1161,6 +1174,7 @@ class ContentViewGestureHandler implements LongPressDelegate {
if (sendMotionEventAsGesture(GESTURE_SHOW_PRESS_CANCEL, e, null)) {
mShowPressIsCalled = false;
+ mLastLongPressEvent = null;
}
}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java
index 15e1b25f..e05fcb5 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewGestureHandlerTest.java
@@ -656,6 +656,53 @@ public class ContentViewGestureHandlerTest extends InstrumentationTestCase {
}
/**
+ * Verify that a show pressed state gesture followed by a long press followed by the focus
+ * loss in the window due to context menu cancels show pressed.
+ * @throws Exception
+ */
+ @SmallTest
+ @Feature({"Gestures"})
+ public void testShowPressCancelOnWindowFocusLost() throws Exception {
+ final long time = SystemClock.uptimeMillis();
+ GestureRecordingMotionEventDelegate mockDelegate =
+ new GestureRecordingMotionEventDelegate();
+ mGestureHandler = new ContentViewGestureHandler(
+ getInstrumentation().getTargetContext(), mockDelegate, mMockZoomManager,
+ ContentViewCore.INPUT_EVENTS_DELIVERED_AT_VSYNC);
+ mLongPressDetector = new LongPressDetector(
+ getInstrumentation().getTargetContext(), mGestureHandler);
+ mGestureHandler.setTestDependencies(mLongPressDetector, null, null);
+
+ MotionEvent event = motionEvent(MotionEvent.ACTION_DOWN, time, time);
+ mGestureHandler.onTouchEvent(event);
+
+ mGestureHandler.sendShowPressedStateGestureForTesting();
+ assertEquals("A show pressed state event should have been sent",
+ ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE,
+ mockDelegate.mMostRecentGestureEvent.mType);
+ assertEquals("Only showPressedState should have been sent",
+ 1, mockDelegate.mGestureTypeList.size());
+
+ mLongPressDetector.startLongPressTimerIfNeeded(event);
+ mLongPressDetector.sendLongPressGestureForTest();
+
+ assertEquals("Only should have sent only LONG_PRESS event",
+ 2, mockDelegate.mGestureTypeList.size());
+ assertEquals("Should have a long press event next",
+ ContentViewGestureHandler.GESTURE_LONG_PRESS,
+ mockDelegate.mGestureTypeList.get(1).intValue());
+
+ // The long press triggers window focus loss by opening a context menu
+ mGestureHandler.onWindowFocusLost();
+
+ assertEquals("Only should have sent only GESTURE_SHOW_PRESS_CANCEL event",
+ 3, mockDelegate.mGestureTypeList.size());
+ assertEquals("Should have a long press event next",
+ ContentViewGestureHandler.GESTURE_SHOW_PRESS_CANCEL,
+ mockDelegate.mGestureTypeList.get(2).intValue());
+ }
+
+ /**
* Verify that a recent show pressed state gesture is canceled when scrolling begins.
* @throws Exception
*/